Automatically import modules from a namespace package - python-3.x

Is there a way to automatically import modules from an implicit namespace package (PEP420), if we are not allowed to have __init__.py files?
I decided to split my package mylib into two namespace packages: mylib-core and mylib-extra.
Before, when I would run import mylib, I would automatically import mylib.module, mylib.module2, etc., using code in my __init__.py file:
# __init__.py
__all__ = [
'module1',
'module2',
]
from . import *
Is there a way to accomplish the same behaviour in a namespace package? I have a lot of existing code that expects this behaviour.

Related

How to import from a renamed submodule?

My project requires patching of another project's code. Seems simple enough:
project/
__init__.py
from .patched_project import fixed_project
my_project.py
patched_project.py
from .my_project import useful_function
import other_project as fixed_project
# use useful_function with fixed_project
In theory, I can now install this package and the fixed_project can be imported via from project import fixed_project (which works without issue).
However, user's have become accustom to performing from other_project import submodule in all their other projects. As such, they would expect to now use from project.fixed_project import submodule. But this results in ModuleNotFoundError. Why? Does python not run the __init__.py and see fixed_project? A solution like:
from project import fixed_project
submodule = fixed_project.submodule
works, but feels unpythonic. Normally, if one can do the above, I would expect that from project.fixed_project import submodule should work. What am I misunderstanding? Is it expected that __init__.py breaks submodule importing of renamed modules with __init__.py? Is there something that I was suppose to add to the __init__.py so that subpackage, subsubpackage, and subsubsubpackage importing could be performed?

Using python __init__.py to import common modules of multiple sripts

I have a python package i'm working on with the below structure:
package/
__init__.py
script1.py
script2.py
script3.py
all 3 scripts have common imports for example:
import sys
import socket
import subprocess
i think it would be more efficient and also 'prettier' if those common imports could be done in the __init__.py module rather being imported time after time in each script. I've tried to move those imports to the init module , but then they're no longer recognized in their respective python scripts.
What would be the best approach to unify common imports for a python package?

Importing submodules

I am new to python and i m having a really bad time to overcome a problem with the importing system.
Lets say i have the file system presented below:
/src
/src/main.py
/src/submodules/
/src/submodules/submodule.py
/src/submodules/subsubmodules
/src/submodules/subsubmodules/subsubmodule.py
All the folders (src, submodules, subsubmodules) have and empty __init__.py file.
In submodule.py i have:
from subsubmodules import subsubmodule
In main.py i have:
from submodules import submodule
When i run submodule.py python accepts the import. But when i run main.py python raises error for the import of subsubmodule.py because /src/submodules/subsubmodules/ folder is not in the path.
Only solution is to change the import of submodule.py to
from submodules.subsubmodules import subsubmodule
This seems to me as an awful solution because after that i cannot run submodule.py and i m sure that something else is the key to that.
An other solution is to add the following code to the __init__.py file:
import os
import sys
import inspect
cmd_subfolder = os.path.split(inspect.getfile(inspect.currentframe()))[0]
if cmd_subfolder not in sys.path:
sys.path.insert(0, cmd_subfolder)
Is there any way to do this using just the importing system of python and not other methods that do it manually using, for example sys.path or other modules like os, inspect etc..?
How can i import modules without caring about the modules they import?
You can run subsubmodule.py as
python3 -m submodule.subsubmodules.subsubmodule
If you want a shorter way to invoke it, you're free to add a shell or Python script for that on the top level of your package.
This is how imports work in Python 3; there are reasons for that.
You can avoid this issue by using sys.path in your program.
sys.path.insert(0, './lib')
import subsubmodule
For this code, you can put all your imports to a lib folder.
You can read the official documentation on Python packages where this is explained in depth.

Importing custom module cleanly

I would like to import a class from my submodule without having to use the from submodule.submodule import Class syntax. Instead I would just like to do from submodule import Class like a normal Python3 module.
I feel this should have been answered a million times, and while there are several similarly named questions on SO, none of them provide a clear, simple solution with a bare-bones example.
I'm trying to get the simplest test working with this setup:
.
├── main.py
└── test
├── __init__.py
└── test.py
In my test module, I have the following contents:
test.py
class Test:
def __init__(self):
print('hello')
__init__.py
from test import Test
__all__ = ['Test']
In the upper-level main.py I have the following:
from test import Test
Test()
When I try to run main.py I get:
ImportError: cannot import name 'Test'
I know I could replace the import statement in main.py with from test.test import Test, but my understanding was that one of the points of __init__.py was to make submodules accessible at the package level (with __all__ allowing to import all with from test import *)
According to PEP 404:
In Python 3, implicit relative imports within packages are no longer
available - only absolute imports and explicit relative imports are
supported. In addition, star imports (e.g. from x import *) are only
permitted in module level code.
If you change __init__.py to:
from test.test import Test
__all__ = ['Test']
then your code works:
$ python3 main.py
hello
But now it works only on python3 (and your original code works only on python2).
To have code that works on both lines of python, we have to use explicit relative import:
from .test import Test
__all__ = ['Test']
Code execution:
$ python2 main.py
hello
$ python3 main.py
hello

how do I import module in parent directory?

How can I import module at parent directory?
In following package, I want to use techniques module in main.py
I am using __all__ to ignore tests when import trade.
trade/
__init__.py
htmlparser.py
utils.py
techniques.py
tests/
testdata.json
main.py
__init__.py:
__all__ = ["techniques", "utils", "htmlparser"]

Resources