Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change result of type(object)?

Tags:

python

string

oop

I'm using a 3rd-party Python module that does something horrible, like:

def foo(x):
    if type(x) is str:
        do_useful_thing()

I've got a class that subclasses str:

class mystr(str):
   ....

I'd like to call foo() on a mystr instance, but it fails because type(mystr) != type(str). Is there any way I can make my class so that type(mystr) == type(str) and hence get foo to accept it?

I know the right solution is for the 3rd-party module to use isinstance, but unfortunately I cannot change that.

like image 916
xorsyst Avatar asked May 02 '19 18:05

xorsyst


People also ask

How do you change the type of an object in Python?

To convert between types you simply use the type name as a function. In addition, several built-in functions are supplied to perform special kinds of conversions. All of these functions return a new object representing the converted value. Converts x to an integer.

Does type return a string in Python?

Python has a built-in function called instance() that compares the value with the type given. It the value and type given matches it will return true otherwise false. Using isinstance(), you can test for string, float, int, list, tuple, dict, set, class, etc.


2 Answers

Posting as an answer the consensus from the comments section: Even if it were possible to do this sort of thing, it's a really bad idea. Even if you got it to work some of the time, it would cause weird things to break somewhere else.

The right answer is to reach out to the author of the third-party library and to try to resolve it with them. Or, if possible, to fork that library and maintain your own version that doesn't have this restriction.

like image 193
Daniel Pryden Avatar answered Oct 13 '22 01:10

Daniel Pryden


You could hijack the type builtin for the 3rd-party module.

So if the 3rd-party code is this:

# bar.py (a.k.a, crappy 3rd-party code)
def foo(x):
    if type(x) is str:
        return True
    return False

You could write something like this:

import bar

class MyStr(str):
    pass

# Returns False.... BOOO!
bar.foo(MyStr())

def fake_type(a):
    if isinstance(a, MyStr):
        return str
    else:
        return type(a)

bar.type = fake_type

# This should now return True :-)
bar.foo(MyStr())

And don't forget to go tell the the 3rd-party to fix their code so that you can get rid of this hack later.

like image 40
Kyle Willmon Avatar answered Oct 13 '22 01:10

Kyle Willmon