Handle all your optional dependencies with a single call!
generalimport ├─ Dependency Diagram for ManderaGeneral ├─ Installation showing dependencies ├─ Information ├─ Examples │ ├─ Minimal Example │ ├─ Tests Showcase │ ├─ Recommended Setup │ └─ How It Works ├─ Attributes └─ Contributions
flowchart LR
2([library]) --> 3([file])
2([library]) --> 5([packager])
0([import]) --> 2([library])
1([tool]) --> 2([library])
0([import]) --> 3([file])
3([file]) --> 5([packager])
2([library]) --> 4([vector])
click 0 "https://github.com/ManderaGeneral/generalimport"
click 1 "https://github.com/ManderaGeneral/generaltool"
click 2 "https://github.com/ManderaGeneral/generallibrary"
click 3 "https://github.com/ManderaGeneral/generalfile"
click 4 "https://github.com/ManderaGeneral/generalvector"
click 5 "https://github.com/ManderaGeneral/generalpackager"
style 0 fill:#482
Package | Ver | Latest Release | Python | Platform | Cover |
---|---|---|---|---|---|
generalimport | 0.3.1 | 2022-10-27 16:21 CEST | 3.8, 3.9, 3.10, 3.11 | Windows, Ubuntu | 98.4 % |
Call generalimport
before importing any optional dependencies.
from generalimport import generalimport
generalimport("notinstalled")
from notinstalled import missing_func # No error
missing_func() # Error occurs here
MissingOptionalDependency: Optional dependency 'notinstalled' was used but it isn't installed.
Imports fail when they are used, not imported.
This means you don't need to keep checking if the package is installed before importing it. Simply import your optional package and use it like you would any package and let it fail wherever it fails, with a nice error message.
The beauty of this package is that the error raised isn't just any exception.
It has two base classes: unittest.case.SkipTest
and _pytest.outcomes.Skipped
(If available).
This means that if a test method uses an uninstalled optional package then that test is automatically skipped. This means no more manual skip decorators for optional dependencies!
from generalimport import generalimport
generalimport("optional_uninstalled_package")
from optional_uninstalled_package import missing_func
from unittest import TestCase
class MyTest(TestCase):
def test_missing_func(self):
self.assertEqual(3, missing_func(1, 2))
Ran 1 test in 0.002s
OK (skipped=1)
Skipped: Optional dependency 'optional_uninstalled_package' was used but it isn't installed.
Put this in your __init__.py
file to affect all imports inside the folder __init__.py
resides in.
from generalimport import generalimport
generalimport("your", "optional", "dependencies")
generalimport("*")
makes it handle all names (If missing of course)
generalimport("*")._scope = None
disables the scope
- Makes it handle missing imports anywhere
- For example it will override
pandas
internal custom optional dependency handling
- When
generalimport
is instantiated it creates a new importer forsys.meta_path
. - This importer will return 'fake' modules for matching names and scope.
- The scope ensures only your own imports are faked.
- The fake module will recursively return itself when asked for an attribute.
- When used in any way (__call__, __add__, __str__ etc) it raises
generalimport.MissingOptionalDependency
. - This exception has the 'skip-exceptions' from
unittest
andpytest
as bases, which means that tests will automatically be skipped.
Module: generalimport ├─ Class: FakeModule │ └─ Method: error_func ├─ Class: GeneralImporter │ ├─ Method: catch │ ├─ Method: create_module │ ├─ Method: exec_module │ └─ Method: find_spec ├─ Class: ImportCatcher │ └─ Method: handle ├─ Class: MissingOptionalDependency ├─ Function: fake_module_check ├─ Function: generalimport ├─ Function: get_importer ├─ Function: get_installed_modules_names ├─ Function: get_spec ├─ Function: import_module ├─ Function: module_is_installed ├─ Function: module_is_namespace ├─ Function: module_name_is_namespace ├─ Function: reset_generalimport └─ Function: spec_is_namespace
Issue-creation and discussions are most welcome!
Please hold off on submitting pull requests until all the necessary legal issues have been sorted out.