Registry / testing / mo-imports

mo-imports

JSON →
library7.685.25166pypypi✓ verified 85d ago

mo-imports is a Python library designed to simplify and manage complex import patterns, especially those involving cyclic dependencies. It provides mechanisms like 'expect/export' and 'delay_import' to make late importing cleaner and avoid common Python import pitfalls. The library is currently in a beta development status, with version 7.685.25166 released on June 15, 2025, and generally follows a frequent release schedule.

pip install mo-imports
INSTALL
IMPORT
SIG · MO-IMPORTS
M
mo-imports
testingpythonv7.685.25166
Install
1.6s avg
Import
67ms
Disk
16MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v7.685.25166 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.920 runs
installs and imports cleanly · install 0.0s · import 0.069s · 17.9MB
glibc
py 3.103.920 runs
installs and imports cleanly · install 1.6s · import 0.065s · 18MB
16MB installed
● package 16MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

expect
from mo_imports import expect
Used to declare an expected variable in a module that will be provided by another module to break cyclic dependencies.
export
from mo_imports import export
Used to make a variable available to modules that have declared it as 'expected'.
delay_import
from mo_imports import delay_import
Creates a proxy object that imports the specified module variable only upon its first use (e.g., calling, item access, attribute access).

The `mo-imports` library offers two primary patterns: `expect`/`export` for breaking cyclic dependencies and `delay_import` for deferring module loading until the first access. The `delay_import` example demonstrates how a module's content is loaded only when its components are first invoked, leading to cleaner code and potentially faster startup times if imports are expensive and not always used.

import os # Example for breaking cyclic dependencies with expect/export # File: foos.py # from mo_imports import expect # bar = expect("bar") # def foo(): # return bar() + " from foo" # # File: bars.py # from mo_imports import export # from foos import foo # def bar(): # return foo() + " from bar" # export("bar", bar) # Simulating the usage (actual usage requires separate files) # To demonstrate, imagine 'foos.py' defines 'bar' as expect('bar') # and 'bars.py' defines 'bar' and then export('bar', bar) # Example for delayed import # File: lazy_module.py # def some_function(): # return "Function from lazy_module" # File: main_app.py from mo_imports import delay_import # Instead of: from lazy_module import some_function # We use delay_import: lazy_function = delay_import("lazy_module.some_function") print(f"Initial state: {lazy_function}") # This is a proxy object, not the actual function yet # The import happens when lazy_function is first 'used' # For a function, this means when it's called. try: result = lazy_function() print(f"Result from delayed import: {result}") except ImportError as e: print(f"Caught expected ImportError: {e}") print("Note: For this example to run correctly, 'lazy_module.py' must exist in the Python path.") # For demonstration, let's create a dummy lazy_module.py temporarily with open('lazy_module.py', 'w') as f: f.write('def some_function():\n return "Function from lazy_module"\n') # Rerun the delayed import to show it working import sys # Remove from sys.modules to force re-import if it was loaded before if 'lazy_module' in sys.modules: del sys.modules['lazy_module'] lazy_function_working = delay_import("lazy_module.some_function") print(f"Result from delayed import after creating file: {lazy_function_working()}") # Clean up the dummy file os.remove('lazy_module.py')
Debug
Known issues
gotchaThe `delay_import` function only triggers the actual import when the proxy object's `__call__`, `__getitem__`, or `__getattr__` methods are invoked. This means that direct use of the proxy as a sentinel, placeholder, or default value without one of these operations will NOT trigger the import, leading to unexpected behavior.
fix
Ensure that the `delay_import` proxy object is accessed via a method call, item access, or attribute access to force the underlying import. Do not rely on it for cases where the module content needs to be present without such an explicit access pattern.
affects: All versions
deprecatedThe library explicitly discourages 'Bad Solution' patterns for handling imports, such as 'end-of-file imports', 'inline imports', and the '_late_import()' pattern. These methods often lead to linter warnings, missed imports, increased overhead, or reduced code readability.
fix
Refactor code to utilize `mo-imports`' `expect`/`export` or `delay_import` patterns, or other standard Python import practices that avoid these anti-patterns, keeping imports at the top of the file where possible.
affects: All versions
gotchaWhen using the `expect`/`export` pattern, attempting to use an `expect`-ed variable before its corresponding `export` has been executed will result in a `NameError` or similar runtime error, as the variable will not yet be bound.
fix
Carefully design module import order and ensure that the module performing the `export` is imported and executed before any module attempts to use a variable declared with `expect`.
affects: All versions
Errors
Common errors & fixes
NameError: name 'my_variable' is not defined
You are using a variable declared with `mo_imports.expect('my_variable')` in one module, but the module responsible for `mo_imports.export('my_variable', value)` has not yet been imported or executed when 'my_variable' is accessed.
fix
Review your module import order. Ensure that the module exporting the variable is imported before the module that expects it. The `expect` call sets up a placeholder, but the actual value is only bound upon `export`.
AttributeError: 'DelayImport' object has no attribute 'some_attribute'
You are attempting to access an attribute or call a method on a `delay_import` proxy object, but the underlying module has not yet been loaded because no triggering operation (call, item access, attribute access) has occurred.
fix
Ensure that the `delay_import` proxy is interacted with in a way that triggers the actual import, such as calling it (`obj()`) if it's a function, accessing an item (`obj['key']`) if it's a dictionary-like object, or accessing an attribute (`obj.attr`) if it's a module/class. If the object itself is meant to be a simple value, `delay_import` might not be the appropriate tool.
Upgrade
Version history
7.685.25166latest on PyPI · released Jun 15, 2025
Audit
Dependencies

No dependency data recorded yet.

Agent activity
8 hits · last 30 days
node
6
Resources
mo-imports — pip install mo-imports · libregistry