Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

isinstance behavior with module reload

Given the following two .py files:

aclass.py

class A(object):
    pass

main.py

def importer(klass):
    """
    Used to import classes from there python qalname
    """
    import_ = lambda m, k: getattr(__import__(m, fromlist=k), k)
    klass = klass.split('.')
    module = '.'.join(klass[:-1])
    klass = klass[-1]
    return import_(module, klass)

from aclass import A

import_A = importer('aclass.A')
print isinstance(A(), import_A)  # Expected to be true 
print isinstance(import_A(), A)  # Expected to be true 

At this stage, everything works fine (my program prints True\nTrue) But if I modify the importer method to enforce a reload, ie:

this line:

    import_ = lambda m, k: getattr(__import__(m, fromlist=k), k)

is replaced by:

    import_ = lambda m, k: getattr(reload(__import__(m, fromlist=k)), k)

my programs returns

False
False

And I do not understand this behavior.

like image 730
ohe Avatar asked Jan 13 '23 17:01

ohe


1 Answers

Reloading a module means re-executing its content, in this case class A(object): pass. So it creates another different class. It's the same behavior as:

class A(object):
    pass
a = A()
class A(object):          # a different class
    pass
print isinstance(a, A)    # False

This should be enough to explain why a bare reload() is usually a bad idea. I'm sure others could point to frameworks that implement more sophisticated reloading procedures, e.g. patching the old class to be considered equal to the new one.

like image 124
Armin Rigo Avatar answered Jan 21 '23 13:01

Armin Rigo