0

I am currently working on a Python package. The package can be imported or it can also run from command line with -m switch. Inside the package I am building a dependency injection container using - python-dependency-injector.

Now, here is my understanding of the __init__.py and __main__.py files -

  1. If package is imported - the content of __init__.py is executed.
  2. If package is ran from command line with -m - the content of __main__.py is executed.

For me weirdly, in either cases content of both files is being executed. Either I import the package or run it from command line the control flows through __init__.py to __main__.py and so on. All I am doing inside these files is building the dependency injection container -

from .containers import Container
container = Container()
container.init_resources()
container.wire(packages=[__name__])

When I run the package from command line I also get a RunTimeWarning as - RunTimeWarning: 'package.__main__.py' found in sys_modules after import of package 'package', but prior to execution of 'package.__main__'; this may result in unpredictable behavior

And to fix this I added del sys.modules['package.__main__'] in __init__.py.

Here is my folder structure -

src
  \package
     \__init__.py
     \__main__.py
     \readers
        \__init__.py
        \reader_module.py
     \writers
        \__init__.py
        \writer_module.py
     \utility
     \__init__.py
     \container_module.py
  test.py <-- imports the package
arpymastro
  • 751
  • 3
  • 16
  • 34
  • 2
    You do realize that doing `python -m package` will run `__init__.py` and THEN run `__main__.py`? Are you importing `__main__`? – Tim Roberts Jul 13 '23 at 05:58
  • @TimRoberts nope I dint knew that. Please excuse my limited knowledge. Nope, I am not importing `__main__.py`. How I can restrict `__init__.py` run when I want to run my package from command line? – arpymastro Jul 13 '23 at 06:41
  • What is in `__init__.py`? – Tim Roberts Jul 13 '23 at 06:54
  • In general do not try to restrict execution in `__init__.py`. The `__init__.py` should do things important to use the module and it is called every time you want to to use the module for a reason. If you have things in `__init__.py` that break the execution when using `-m` then you probably need to redesign your package. – Nopileos Jul 13 '23 at 06:57
  • @TimRoberts Inside `__init__.py` i have container registeration code. Inside `__main__.py` I would be importing a module. – arpymastro Jul 13 '23 at 08:48
  • @Nopileos how I can restrict rhe execution of `__main__.py` when my package is imported? – arpymastro Jul 13 '23 at 08:48
  • When importing a package, the `__main__.py` won't be imported automatically. If it gets imported, there must be an explicit `import` (or equivalent) – VPfB Jul 13 '23 at 08:57
  • @VPfB I am not importing `__main__.py` explicitly. My doubt is it may be getting loaded because of the dependency-injector package I am using. – arpymastro Jul 13 '23 at 10:59
  • @arpymastro (using lower level `importlib` functions is what I meant with "import equivalent"). You could debug what is pulling in the module in a quick&dirty way, just add temporarily a `raise ...` (`1/0` will do as well) as the first statement of the `__main__.py` to get a traceback. – VPfB Jul 13 '23 at 12:02
  • @VPfB I tried raising and it line - `container.wire(packages=[__name__])` causing the `__main__.py` to execute. – arpymastro Jul 13 '23 at 13:16

1 Answers1

0

I figured that the dependency-injector package is causing to load __main__.py file when I import my package. Specifically, when the container is wired - container.wire(packages=[__name__]).|

For now, I have decided to keep __main__.py empty.

arpymastro
  • 751
  • 3
  • 16
  • 34