This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author SinTh0r4s
Recipients SinTh0r4s
Date 2020-12-27.18:01:56
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1609092117.63.0.33154013313.issue42757@roundup.psfhosted.org>
In-reply-to
Content
Greetings,

tl;dr Depending on how a class is imported it will have a differenct class name and therefore prototype. I ran into this issue when i used a class variable to implement an event bus.

To reproduce you need a module and a submodule. The example creates two child classes that and collects their references for further use in a class/static variable in the parent. Depending on the import description this might be broken. Here, the code:

module
  |--main.py
  |--child.py
  |--submodule
       |-parent.py
       |-__init.py__

parent.py:
    class Parent:

        listeners = []

        def __init__(self):
            Parent.listeners.append(self)
            print("Parent: " + str(len(Parent.listeners)))

child.py
    from submodule.parent import Parent

    class Child(Parent):

        def __init__(self):
            super(Child, self).__init__()
            print("Child: " + str(Parent.listeners))

main.py
    from module.child import Child
    from module.submodule.parent import Parent

    class ChildLocal(Parent):

        def __init__(self):
            super(ChildLocal, self).__init__()
            print("ChildLocal: " + str(Parent.listeners))


if __name__ == '__main__':
    child= Child()
    local = ChildLocal()

Result:
    Parent: 1
    Child: [<module.submodule.Child object at 0x0000020F51EE2DC8>]
    Parent: 1
    ChildLocal: [<__main__.ChildLocal object at 0x0000020F51EE2E48>]
Here, the parent object is imported in two different ways and two separate parental classes are created. Hence, each parent class collects only one child

If Parent is importet in child.py as 'from module.submodule.parent import Parent" (difference is the module.) the result looks as follows:
    Parent: 1
    Child: [<module.submodule.Child object at 0x00000182B0982DC8>]
    Parent: 2
    ChildLocal: [<module.submodule.Child object at 0x00000182B0982DC8>, <__main__.ChildLocal object at 0x00000182B0982E48>]
Here, both children are registered in the same parent class as intenden

In conclusion, there is a nasty (to debug) difference between a relative import path and a project root path. I am quite certain this behaviour is as intenden, but on the little chance it isn't i wanted to bring this to attentions, since it is a nightmare to find. Is it intended?

Cheers,
Sin
History
Date User Action Args
2020-12-27 18:01:57SinTh0r4ssetrecipients: + SinTh0r4s
2020-12-27 18:01:57SinTh0r4ssetmessageid: <1609092117.63.0.33154013313.issue42757@roundup.psfhosted.org>
2020-12-27 18:01:57SinTh0r4slinkissue42757 messages
2020-12-27 18:01:56SinTh0r4screate