{"id":7423,"library":"mo-imports","title":"More Imports! - Delayed importing","description":"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.","status":"active","version":"7.685.25166","language":"en","source_language":"en","source_url":"https://github.com/klahnakoski/mo-imports","tags":["imports","lazy loading","delayed loading","cyclic dependencies","module management","python3"],"install":[{"cmd":"pip install mo-imports","lang":"bash","label":"Install latest version"}],"dependencies":[],"imports":[{"note":"Used to declare an expected variable in a module that will be provided by another module to break cyclic dependencies.","symbol":"expect","correct":"from mo_imports import expect"},{"note":"Used to make a variable available to modules that have declared it as 'expected'.","symbol":"export","correct":"from mo_imports import export"},{"note":"Creates a proxy object that imports the specified module variable only upon its first use (e.g., calling, item access, attribute access).","symbol":"delay_import","correct":"from mo_imports import delay_import"}],"quickstart":{"code":"import os\n\n# Example for breaking cyclic dependencies with expect/export\n# File: foos.py\n# from mo_imports import expect\n# bar = expect(\"bar\")\n# def foo():\n#     return bar() + \" from foo\"\n#\n# File: bars.py\n# from mo_imports import export\n# from foos import foo\n# def bar():\n#    return foo() + \" from bar\"\n# export(\"bar\", bar)\n\n# Simulating the usage (actual usage requires separate files)\n# To demonstrate, imagine 'foos.py' defines 'bar' as expect('bar')\n# and 'bars.py' defines 'bar' and then export('bar', bar)\n\n# Example for delayed import\n# File: lazy_module.py\n# def some_function():\n#     return \"Function from lazy_module\"\n\n# File: main_app.py\nfrom mo_imports import delay_import\n\n# Instead of: from lazy_module import some_function\n# We use delay_import:\nlazy_function = delay_import(\"lazy_module.some_function\")\n\nprint(f\"Initial state: {lazy_function}\") # This is a proxy object, not the actual function yet\n\n# The import happens when lazy_function is first 'used'\n# For a function, this means when it's called.\ntry:\n    result = lazy_function()\n    print(f\"Result from delayed import: {result}\")\nexcept ImportError as e:\n    print(f\"Caught expected ImportError: {e}\")\n    print(\"Note: For this example to run correctly, 'lazy_module.py' must exist in the Python path.\")\n\n# For demonstration, let's create a dummy lazy_module.py temporarily\nwith open('lazy_module.py', 'w') as f:\n    f.write('def some_function():\\n    return \"Function from lazy_module\"\\n')\n\n# Rerun the delayed import to show it working\nimport sys\n# Remove from sys.modules to force re-import if it was loaded before\nif 'lazy_module' in sys.modules:\n    del sys.modules['lazy_module']\n\nlazy_function_working = delay_import(\"lazy_module.some_function\")\nprint(f\"Result from delayed import after creating file: {lazy_function_working()}\")\n\n# Clean up the dummy file\nos.remove('lazy_module.py')\n","lang":"python","description":"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."},"warnings":[{"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.","message":"The `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.","severity":"gotcha","affected_versions":"All versions"},{"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.","message":"The 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.","severity":"deprecated","affected_versions":"All versions"},{"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`.","message":"When 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.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"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`.","cause":"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.","error":"NameError: name 'my_variable' is not defined"},{"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.","cause":"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.","error":"AttributeError: 'DelayImport' object has no attribute 'some_attribute'"}]}