25

I'm currently in pdb trace to figure this out

ipdb> isinstance(var, Type)
False
ipdb> type(var)
<class 'module.Type'>
ipdb> Type
<class 'module.Type'>

Why can this happen?

P. S. isinstance(var, type(var)) returns True as expected

evgeniuz
  • 2,599
  • 5
  • 30
  • 36
  • 5
    There could be multiple types known as `Type` (say at different points in time). Could you produce a complete example that demonstrates the problem? – NPE May 14 '12 at 11:55
  • 14
    is there any `import`/`reload` magic in your code? – Roman Bodnarchuk May 14 '12 at 11:57
  • @RomanBodnarchuk, I don't think so. Can you provide examples of such magic? – evgeniuz May 14 '12 at 12:01
  • @Shark http://docs.python.org/library/functions.html#reload – Roman Bodnarchuk May 14 '12 at 12:22
  • @RomanBodnarchuk no, there is definitely no reload statement in my source code. – evgeniuz May 14 '12 at 12:26
  • 7
    I just hit the same problem today. It was absolute import vs relative import. Try `print repr(var.__class__), repr(Type)`. I resolved the problem by changing the relative import to absolute import. I will create a code that demonstrates the problem. – Kenji Noguchi Feb 17 '15 at 23:17

3 Answers3

28
  1. I can only guess, but if you do in module

    class Type(object): pass
    var = Type()
    class Type(object): pass
    

    then both types look like <class 'module.Type'>, but are nevertheless different.

    You could check that with

    print(id(Type), id(var.__class__))
    

    or with

    print(Type is var.__class__)
    

    Note that these comparisons work for both old-, and new-style classes. For new-style classes, they are equivalent to print(Type is type(var)). But this is not the case for old-style classes.

  2. Another quite common trap is that you call this module with

    python -m module
    

    or

    python module.py
    

    making it known as __main__ module. If it is imported somewhere else under its true name, it is known under that name as well with a different name space.

  3. Another guess could be that you are working with ABCs or otherwise let the class have a __instancecheck__() method.

0 _
  • 10,524
  • 11
  • 77
  • 109
glglgl
  • 89,107
  • 13
  • 149
  • 217
  • I have defined only one Type across all of my source files. And I'm not fiddling with hidden methods. Only `__str__`, `__iter__`, `__len__`. So this is not the case. Also, this class is subclass of `object`. – evgeniuz May 14 '12 at 11:55
  • BTW, I'm currently in pdb session. What should I check to determine cause? – evgeniuz May 14 '12 at 12:07
  • You might consider taking a look at `id(type(var))`, `type(var) is Type`, etc. – Karl Knechtel May 14 '12 at 13:40
  • for old-style classes, compare `Type is var.__class__`, because `Type is type(var)` can fail. This remains relevant, because of `distutils` classes that are monkey-patched by `setuptools`. – 0 _ Jan 06 '16 at 16:16
  • #2 Solved it for me. Changed `from module.sub_module.thing import SpecificThing` to `import module.sub_module.thing as thing` and then referenced `thing.SpecificThing` in the code and the problem was fixed. This was fixed even though I was using IPython autoreload as described below. – Connor Ferster Jan 07 '22 at 05:03
12

Users of the "autoreload" setting in iPython will probably run into this. When a class is reloaded, it will become a new class with the exact same name. Instances of the old class will not have their type updated:

# After reloading the Role class

[ins] In [19]: y = Role()

[ins] In [20]: isinstance(x, Role)
Out[20]: False

[nav] In [21]: isinstance(y, Role)
Out[21]: True

[ins] In [22]: type(x)
Out[22]: myproject.auth.Role

[ins] In [23]: type(y)
Out[23]: myproject.auth.Role
Hubro
  • 56,214
  • 69
  • 228
  • 381
  • 1
    Any option aside `imp.reload(module)` and re-instantiating `x`? I could open a question – OverLordGoldDragon Dec 07 '20 at 08:47
  • I had this when I used importlib.reload in the wrong order: library 1 called library 2, but I did importlib.reload for library 1 first before library 2, so every isinstance failed. – MCK Apr 23 '21 at 15:36
  • 1
    @Hubro you saved my life. I just ran into this problem and it took me over an hour to find your solution. – FredMaster Jul 16 '21 at 15:16
0

I encountered this problem as well, for me to problem laid in my imports. I imported Type once from parent.child.Type and once from child.Type. I assume that when using the full path the module is imported from the installed pip package, whereas using the relative path it is imported as a new module on the fly.

cimere
  • 667
  • 1
  • 8
  • 22
meesg
  • 13
  • 3
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Dec 09 '21 at 18:57