A flexible library for dynamically rewriting Python imports at runtime using metapath hooks.
Import Rewriter allows you to transparently redirect imports in Python code without modifying the source. This is useful for:
- Providing mock implementations during testing
- Implementing feature toggles or A/B testing at the module level
- Creating compatibility layers for different library versions
- Redirecting imports for dependency injection
- Implementing module aliases for refactoring
- Vendoring dependencies at runtime
The library works by intercepting the Python import system using metapath hooks and rewriting the import statements in the Abstract Syntax Tree (AST) before execution.
pip install import-rewriter
from import_rewriter import install_import_rewriter
# Redirect imports of 'legacy_module' to use 'modern_module' instead
install_import_rewriter({
'legacy_module': 'modern_module',
'requests': 'my_custom_requests'
})
# Now when your code does:
import legacy_module
# It will actually import 'modern_module'
- Transparently rewrites imports without changing the original code
- Handles both
import x
andfrom x import y
statements - Can be enabled/disabled at runtime
- Minimal performance impact for non-rewritten imports
- Works with standard Python imports, no special syntax required
- Preserves import aliases (
import x as y
)
Installs the import rewriting hook with the specified mapping.
Parameters:
import_map
(dict): A dictionary mapping original import names to replacement names.
Returns:
- The finder instance that was installed (can be used to uninstall later).
Example:
finder = install_import_rewriter({
'pandas': 'custom_pandas',
'tensorflow': 'tensorflow_lite'
})
To remove the hook and restore normal import behavior:
import sys
sys.meta_path.remove(finder)
You can selectively rewrite imports for specific modules or packages:
install_import_rewriter({
'pandas.DataFrame': 'my_package.DataFrame',
'numpy.array': 'my_package.fast_array'
})
You can change the import mapping at runtime:
finder = install_import_rewriter()
finder.import_map['requests'] = 'mock_requests' # Add new mapping
Import Rewriter uses three key components:
- MetaPath Finder: Intercepts import requests before they're processed by the standard import machinery.
- AST Transformer: Parses and modifies the abstract syntax tree of the source code.
- Custom Loader: Executes the modified code in the module's namespace.
When a module is imported, the finder intercepts the request, the transformer rewrites any matching imports, and the loader executes the modified code.
- Only rewrites imports in modules that are loaded after the hook is installed
- Cannot rewrite imports in c-extensions, built-in, or frozen modules
- May have unpredictable interactions with other import hooks
GPLv3
Contributions are welcome! Please feel free to submit a Pull Request.