0

I seem to be running into a problem where I can't inherit from another class in the same module. Here's the MCVE I came up with.

The (uninteresting) contents of main.py:

#!/usr/bin/python

import foobar

if __name__ == "__main__":
    print("Hello, World!")

The contents of foobar/__init__.py:

class Singleton(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]

from foobar.this_one_works import Pucker
from foobar.csend import Csend

That Singleton class up there is shamelessly copy-pasted from here.

It's important to note that __init__ successfully imports the Pucker class from this_one_works.py. Here is the contents of the latter file:

class PuckerMeta():
    def __init__(self):
        pass

class Pucker(metaclass=PuckerMeta):
    def __init__(self):
        pass

The contents of foobar/csend.py:

class Csend(metaclass=Singleton):
    def __init__(self):
        pass

And now running main.py gives the following error:

Traceback (most recent call last):
  File "/home/sam/mcve/python/./main.py", line 3, in <module>
    import foobar
  File "/home/sam/mcve/python/foobar/__init__.py", line 9, in <module>
    from foobar.csend import Csend
  File "/home/sam/mcve/python/foobar/csend.py", line 1, in <module>
    class Csend(Singleton):
NameError: name 'Singleton' is not defined

I'm puzzled about the fact that importing foobar seems to find PuckerMeta okay, but not Singleton. Is there anything special about a class that's defined in __init__.py that means it can't be inherited from or something?

Oh and in case it matters, I'm on Python 3.9.2.

martineau
  • 119,623
  • 25
  • 170
  • 301
Lorraine
  • 1,189
  • 14
  • 30
  • `Singleton` is a global variable of the `foobar` module, not the `foobar.csend` module. You need to import it from `foobar`, which may be tricky in light of the circular import currently required to do so. – chepner Jul 06 '22 at 13:33
  • `__init__.py` doesn't use `PuckerMeta` directly; *`Pucker`* does, and where `Pucker` is created `PuckerMeta` *is* a globally defined name. – chepner Jul 06 '22 at 13:35
  • 1
    you have to import things in the file where you want to use them, i.e. you have to import `Singleton` inside `csend` – Anentropic Jul 06 '22 at 13:35
  • Off-topic, but consider [not bothering with `Singleton`](https://nedbatchelder.com/blog/202204/singleton_is_a_bad_idea.html) at all. – chepner Jul 06 '22 at 13:37

0 Answers0