{"id":4879,"library":"apipkg","title":"apipkg: Namespace Control and Lazy-Import Mechanism","description":"apipkg is a Python package that provides a mechanism for namespace control and lazy-importing modules and objects. It allows delaying the actual import of a module until its attributes or functions are accessed, leading to improved startup performance and reduced memory consumption. The current version is 3.0.2, and it maintains an active release cadence with updates addressing compatibility and bug fixes.","status":"active","version":"3.0.2","language":"en","source_language":"en","source_url":"https://github.com/pytest-dev/apipkg","tags":["lazy-load","namespace","import-control","performance","utility"],"install":[{"cmd":"pip install apipkg","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"symbol":"initpkg","correct":"import apipkg\napipkg.initpkg(__name__, { ... })"},{"symbol":"ApiModule","correct":"from apipkg import ApiModule"},{"symbol":"AliasModule","correct":"from apipkg import AliasModule"}],"quickstart":{"code":"import apipkg\nimport sys\nimport os\n\n# Simulate a package structure:\n# mypkg/__init__.py\n# mypkg/_mypkg/somemodule.py\n# mypkg/_mypkg/othermodule.py\n\n# Create dummy files for demonstration\nos.makedirs('mypkg/_mypkg', exist_ok=True)\nwith open('mypkg/__init__.py', 'w') as f:\n    f.write(\"import apipkg\\napipkg.initpkg(__name__, { 'path': { 'Class1': '_mypkg.somemodule:Class1', 'clsattr': '_mypkg.othermodule:Class2.attr' } })\")\nwith open('mypkg/_mypkg/somemodule.py', 'w') as f:\n    f.write('class Class1:\\n    def __init__(self):\\n        print(\"Class1 initialized\")\\n        self.name = \"Class1 instance\"')\nwith open('mypkg/_mypkg/othermodule.py', 'w') as f:\n    f.write('class Class2:\\n    attr = 42\\n    def __init__(self):\\n        print(\"Class2 initialized\")')\n\n# Add the current directory to sys.path to allow importing 'mypkg'\nsys.path.insert(0, os.getcwd())\n\nprint(\"Importing mypkg...\")\nimport mypkg\nprint(\"mypkg imported.\")\n\nprint(\"Accessing mypkg.path...\")\nprint(mypkg.path)\n\nprint(\"Accessing mypkg.path.Class1 (triggers _mypkg.somemodule import)...\")\ninstance1 = mypkg.path.Class1()\nprint(f\"Instance name: {instance1.name}\")\n\nprint(\"Accessing mypkg.path.clsattr (triggers _mypkg.othermodule import)...\")\nvalue = mypkg.path.clsattr\nprint(f\"Attribute value: {value}\")\n\n# Clean up dummy files\nos.remove('mypkg/__init__.py')\nos.remove('mypkg/_mypkg/somemodule.py')\nos.remove('mypkg/_mypkg/othermodule.py')\nos.rmdir('mypkg/_mypkg')\nos.rmdir('mypkg')\n\n# Remove from sys.path and sys.modules for clean execution in a script\nsys.path.pop(0)\nif 'mypkg' in sys.modules: del sys.modules['mypkg']\nif 'mypkg._mypkg.somemodule' in sys.modules: del sys.modules['mypkg._mypkg.somemodule']\nif 'mypkg._mypkg.othermodule' in sys.modules: del sys.modules['mypkg._mypkg.othermodule']","lang":"python","description":"This example demonstrates how to use `apipkg.initpkg` within a package's `__init__.py` to create a lazy-loading namespace. It defines a `mypkg` with `path` as a sub-namespace, and `Class1` and `clsattr` are only imported from their respective (simulated) modules when first accessed. The output clearly shows when the underlying modules are actually imported."},"warnings":[{"fix":"Upgrade Python to 3.7+ or pin `apipkg` to a compatible version (e.g., `apipkg<3.0.0`).","message":"Version 3.0.0 dropped support for older Python versions, requiring Python 3.7 or newer. Users on older Python environments will need to remain on `apipkg < 3.0.0`.","severity":"breaking","affected_versions":"< 3.0.0"},{"fix":"Upgrade to `apipkg >= 2.1.0` to benefit from race condition fixes.","message":"Versions prior to 2.1.0 contained race conditions during module import and attribute creation, which could lead to unexpected behavior or import failures, especially in multi-threaded contexts or complex import graphs. Version 2.1.0 (and subsequent versions) include fixes for these issues.","severity":"gotcha","affected_versions":"< 2.1.0"},{"fix":"Ensure you are using `apipkg >= 3.0.0` with Python 3.7+ to avoid `__spec__` related issues. If vendoring, ensure the vendored version includes relevant fixes.","message":"Older `apipkg` versions (especially pre-2.0.0, but also affecting some 3.x versions bundled with `py` library) might not correctly preserve the `__spec__` attribute, leading to `KeyError: '__spec__'` errors when used with newer Python versions (3.7+, 3.11+) and tools like `pytest` or `tox`. Version 2.0.0 introduced `__spec__` transfer, and further compatibility fixes have been integrated in later 3.x releases.","severity":"gotcha","affected_versions":"< 2.0.0, potentially some 3.x versions with specific Python 3.11+ setups"},{"fix":"Update to `apipkg >= 3.0.2` if you are vendoring the library.","message":"Version 3.0.2 introduced a fix to make import paths 'vendoring-friendly'. If you are vendoring `apipkg` into your project, older versions might encounter issues related to incorrect import paths.","severity":"gotcha","affected_versions":"< 3.0.2"}],"env_vars":null,"last_verified":"2026-04-12T00:00:00.000Z","next_check":"2026-07-11T00:00:00.000Z"}