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.

Title: Class has two prototypes
Type: enhancement Stage:
Components: Versions: Python 3.7
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: SinTh0r4s
Priority: normal Keywords:

Created on 2020-12-27 18:01 by SinTh0r4s, last changed 2022-04-11 14:59 by admin.

Messages (1)
msg383856 - (view) Author: Johann Bernhardt (SinTh0r4s) Date: 2020-12-27 18:01

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:

    class Parent:

        listeners = []

        def __init__(self):
            print("Parent: " + str(len(Parent.listeners)))
    from submodule.parent import Parent

    class Child(Parent):

        def __init__(self):
            super(Child, self).__init__()
            print("Child: " + str(Parent.listeners))
    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()

    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 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?

Date User Action Args
2022-04-11 14:59:39adminsetgithub: 86923
2020-12-27 18:01:57SinTh0r4screate