A Python package for various lazy (discouraged) import strategies.
Project description
bumimport
So you're about to append to sys.path in order to import something when a Neckbeard on Stack Overflow tells you it's "bad practice"...
Well, the Neckbeard is right, and you probably should learn how to use the import system properly. However, if you insist on being a Bum, here's a safer alternative.
You might be tempted to append to sys.path so that you can import a module from another directory like importing module1 in main.py in the example below.
├── main.py
├── bucket_o_modules/
│ ├── module1.py
│ ├── module2.py
Of course, you can just add __init__.py to bucket_o_modules/ so that you can import module1 from bucket_o_modules in main.py.
├── main.py
├── bucket_o_modules/
│ ├── __init__.py
│ ├── module1.py
│ ├── module2.py
However, this only works when main.py and bucket_o_modules/ are in the same package. Not to mention, a more complicated file structure would require you to add __init__.py to every subdirectory.
├── main.py
├── bucket_o_modules/
│ ├── __init__.py
│ ├── module1.py
│ ├── extra_special_modules/
│ │ ├── __init__.py
│ │ ├── module2.py
This has its own downsides. module1 and module2 now have to be imported from different packages, bucket_o_modules and bucket_o_modules.extra_special_modules, respectively. You can get arround this by adding code within each __init__.py to "pull up" each of the modules into each package's parent package, but by now you can probably see this is getting tedious, and it would be annoying to maintain as the contents of bucket_o_modules/ change.
This is where bumimport comes into play.
Instead of using the following code to import any module from bucket_o_modules/:
import importlib
import sys
sys.path.append("/path/to/bucket_o_modules/")
mod = importlib.import_module("module1")
Use the following:
import sys
import bumimport
bumimport.flat_import(__name__, "/path/to/bucket_o_modules/")
mod = getattr(sys.modules[__name__], "module1")
flat_import adds all the modules within bucket_o_modules/ to the module __name__ (the current module) as attributes. Those attributes can then be accessed with getattr().
Likewise, instead of using the following code to import any module from bucket_o_modules/ or any of its subdirectories:
import importlib
import os
import sys
for root, _, _ in os.walk("/path/to/bucket_o_modules/"):
sys.path.append(root)
mod = importlib.import_module("module1")
Use the exact same code as before:
import sys
import bumimport
bumimport.flat_import(__name__, "/path/to/bucket_o_modules/")
mod = getattr(sys.modules[__name__], "module1")
bumimport really thrives when you use it in a single __init__.py in the root of a package. Consider the following file structure:
├── main.py
├── bucket_o_modules/
│ ├── __init__.py
│ ├── module1.py
│ ├── extra_special_modules/
│ │ ├── module2.py
If __init__.py contains the following:
from bumimport import flat_import as _flat_import
_flat_import(__name__, __file__)
Then the following code can be used in main.py:
import bucket_o_modules
mod1 = getattr(bucket_o_modules, "module1")
mod2 = getattr(bucket_o_modules, "module2")
Now you can access the modules in bucket_o_modules/ as if it was a flattened package. Additionally, modules with invalid names like os, mod.ule1, or mod-ule1 can still be accessed (getattr() required for any name that breaks dot notation).
bumimport is safer because it never modifies sys.path which means there is no risk of modules getting masked. It also prevents any module with the same name as an existing attribute from being added which means there's no confusion over which module you end up having access to. Lastly, the imported modules are never added to sys.modules which means there will never be conflicts with the standard library.
Installation
-
With pip:
pip install bumimport
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bumimport-1.1.0.tar.gz.
File metadata
- Download URL: bumimport-1.1.0.tar.gz
- Upload date:
- Size: 17.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.7.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4f909f40884e5789f2fdd76a969b1d013151fde57037426ea684d1da5d5f23eb
|
|
| MD5 |
6bd935b56c3e187be5135d1ac774e6be
|
|
| BLAKE2b-256 |
a1f15cf817a18790cb063c8b344ed934b4133ad4e8fc81a670c40037bfe9e95d
|
File details
Details for the file bumimport-1.1.0-py3-none-any.whl.
File metadata
- Download URL: bumimport-1.1.0-py3-none-any.whl
- Upload date:
- Size: 16.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.7.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cd0fe35e9a81dbdc927276493ed7d090556167c466b64d8cdd657d1a35d24793
|
|
| MD5 |
255e915e394a60ab8131c58e7d4db314
|
|
| BLAKE2b-256 |
23078de18b6c4624f79c26e3d35fd63b7cda368621fe10a9000efa5f4c991c54
|