-
-
Couldn't load subscription status.
- Fork 19
Description
Hi,
I'd like to request support for importing Basilisp libraries directly into Python applications like any standard Python library, without requiring explicit Basilisp bootstrapping or the user needing to know the library is written in Basilisp.
The goal is to enable writing Python packages in Basilisp that can be seamlessly imported into Python code, with Basilisp being implicitly bootstrapped as needed.
The Bootstrapping section of the Basilisp docs mentions basilisp.main.bootstrap and basilisp.main.init as bootstrapping methods, but it's unclear what happens when bootstrapping occurs multiple times, for example, if two Basilisp-based libraries each bootstrap themselves in their __init__.py.
The basilisp.main module also lists basilisp.main.bootstrap_python, but it's still unclear whether calling it multiple times is safe, or if the runtime will even be available without re-importing the module.
From reviewing the code, basilisp.main.init seems the most promising option
Lines 15 to 30 in 0fead05
| def init(opts: Optional[CompilerOpts] = None) -> None: | |
| """ | |
| Initialize the runtime environment for Basilisp code evaluation. | |
| Basilisp only needs to be initialized once per Python VM invocation. Subsequent | |
| imports of Basilisp namespaces will work using Python's standard ``import`` | |
| statement and :external:py:func:`importlib.import_module` function. | |
| If you want to execute a Basilisp file which is stored in a well-formed package | |
| or module structure, you probably want to use :py:func:`bootstrap`. | |
| """ | |
| logconfig.configure_root_logger() | |
| runtime.init_ns_var() | |
| runtime.bootstrap_core(opts if opts is not None else compiler_opts()) | |
| importer.hook_imports() | |
| importlib.import_module("basilisp.core") |
Possibly in combination with a runtime check, such as whether BasilispImporter is already present in sys.meta_path, as done here:
basilisp/src/basilisp/importer.py
Lines 424 to 432 in 0fead05
| def hook_imports() -> None: | |
| """Hook into Python's import machinery with a custom Basilisp code | |
| importer. | |
| Once this is called, Basilisp code may be called from within Python code | |
| using standard `import module.submodule` syntax.""" | |
| if any(isinstance(o, BasilispImporter) for o in sys.meta_path): | |
| return | |
| sys.meta_path.insert(0, BasilispImporter()) |
Could you please advise of whether any of the existing bootstrapping methods can safely be used in this way (i.e., called multiple times at runtime) or suggest what changes might be needed to support this use case?
thanks