basilisp
Advanced tools
+2
-3
@@ -1,6 +0,5 @@ | ||
| Metadata-Version: 2.1 | ||
| Metadata-Version: 2.3 | ||
| Name: basilisp | ||
| Version: 0.3.5 | ||
| Version: 0.3.6 | ||
| Summary: A Clojure-like lisp written for Python | ||
| Home-page: https://github.com/basilisp-lang/basilisp | ||
| License: Eclipse Public License 1.0 (EPL-1.0) | ||
@@ -7,0 +6,0 @@ Author: Christopher Rink |
+1
-1
| [tool.poetry] | ||
| name = "basilisp" | ||
| version = "0.3.5" | ||
| version = "0.3.6" | ||
| description = "A Clojure-like lisp written for Python" | ||
@@ -5,0 +5,0 @@ authors = ["Christopher Rink <chrisrink10@gmail.com>"] |
@@ -60,5 +60,3 @@ import importlib.util | ||
| def pytest_collect_file( # pylint: disable=unused-argument | ||
| file_path: Path, path, parent | ||
| ): | ||
| def pytest_collect_file(file_path: Path, parent): | ||
| """Primary PyTest hook to identify Basilisp test files.""" | ||
@@ -181,3 +179,3 @@ if file_path.suffix == ".lpy": | ||
| def _get_fully_qualified_module_name(file: Path) -> str: | ||
| def _get_fully_qualified_module_names(file: Path) -> list[str]: | ||
| """Return the fully qualified module name (from the import root) for a module given | ||
@@ -188,19 +186,13 @@ its location. | ||
| there, we derive a Python module name referring to the given module path.""" | ||
| top = None | ||
| for p in file.parents: | ||
| if _is_package(p): | ||
| top = p | ||
| else: | ||
| break | ||
| paths = [] | ||
| for pth in sys.path: | ||
| root = Path(pth) | ||
| if file.is_relative_to(root): | ||
| elems = list(file.with_suffix("").relative_to(pth).parts) | ||
| if elems[-1] == "__init__": | ||
| elems.pop() | ||
| paths.append(".".join(elems)) | ||
| return paths | ||
| if top is None or top == file.parent: | ||
| return file.stem | ||
| root = top.parent | ||
| elems = list(file.with_suffix("").relative_to(root).parts) | ||
| if elems[-1] == "__init__": | ||
| elems.pop() | ||
| return ".".join(elems) | ||
| class BasilispFile(pytest.File): | ||
@@ -257,7 +249,18 @@ """Files represent a test module in Python or a test namespace in Basilisp.""" | ||
| def _import_module(self) -> runtime.BasilispModule: | ||
| modname = _get_fully_qualified_module_name(self.path) | ||
| module = importlib.import_module(modname) | ||
| assert isinstance(module, runtime.BasilispModule) | ||
| return module | ||
| modnames = _get_fully_qualified_module_names(self.path) | ||
| assert modnames, "Must have at least one module name" | ||
| exc: Optional[ModuleNotFoundError] = None | ||
| for modname in modnames: | ||
| try: | ||
| module = importlib.import_module(modname) | ||
| except ModuleNotFoundError as e: | ||
| exc = e | ||
| else: | ||
| assert isinstance(module, runtime.BasilispModule) | ||
| return module | ||
| assert exc is not None, "Must have an exception or module" | ||
| raise exc | ||
| def collect(self): | ||
@@ -264,0 +267,0 @@ """Collect all tests from the namespace (module) given. |
+29
-19
@@ -135,3 +135,5 @@ import importlib.util | ||
| class BasilispImporter(MetaPathFinder, SourceLoader): # pylint: disable=abstract-method | ||
| class BasilispImporter( # type: ignore[misc] # pylint: disable=abstract-method | ||
| MetaPathFinder, SourceLoader | ||
| ): | ||
| """Python import hook to allow directly loading Basilisp code within | ||
@@ -301,3 +303,3 @@ Python.""" | ||
| path_stats: Mapping[str, int], | ||
| ns: runtime.Namespace, | ||
| module: BasilispModule, | ||
| ) -> None: | ||
@@ -324,3 +326,3 @@ """Load and execute a cached Basilisp module.""" | ||
| compiler.PythonASTOptimizer(), | ||
| ns, | ||
| module, | ||
| ) | ||
@@ -333,3 +335,3 @@ | ||
| path_stats: Mapping[str, int], | ||
| ns: runtime.Namespace, | ||
| module: BasilispModule, | ||
| ) -> None: | ||
@@ -363,3 +365,3 @@ """Load and execute a non-cached Basilisp module.""" | ||
| ), | ||
| ns, | ||
| module, | ||
| collect_bytecode=all_bytecode.append, | ||
@@ -402,19 +404,27 @@ ) | ||
| # as direct Python variable access to functions and other def'ed values. | ||
| ns_name = demunge(fullname) | ||
| ns: runtime.Namespace = runtime.Namespace.get_or_create(sym.symbol(ns_name)) | ||
| ns.module = module | ||
| module.__basilisp_namespace__ = ns | ||
| if fullname == runtime.CORE_NS: | ||
| ns: runtime.Namespace = runtime.Namespace.get_or_create(runtime.CORE_NS_SYM) | ||
| ns.module = module | ||
| module.__basilisp_namespace__ = ns | ||
| # Check if a valid, cached version of this Basilisp namespace exists and, if so, | ||
| # load it and bypass the expensive compilation process below. | ||
| if os.getenv(_NO_CACHE_ENVVAR, "").lower() == "true": | ||
| self._exec_module(fullname, spec.loader_state, path_stats, ns) | ||
| else: | ||
| try: | ||
| self._exec_cached_module(fullname, spec.loader_state, path_stats, ns) | ||
| except (EOFError, ImportError, OSError) as e: | ||
| logger.debug(f"Failed to load cached Basilisp module: {e}") | ||
| self._exec_module(fullname, spec.loader_state, path_stats, ns) | ||
| # Set the currently importing module so it can be attached to the namespace when | ||
| # it is created. | ||
| with runtime.bindings( | ||
| {runtime.Var.find_safe(runtime.IMPORT_MODULE_VAR_SYM): module} | ||
| ): | ||
| # Check if a valid, cached version of this Basilisp namespace exists and, if so, | ||
| # load it and bypass the expensive compilation process below. | ||
| if os.getenv(_NO_CACHE_ENVVAR, "").lower() == "true": | ||
| self._exec_module(fullname, spec.loader_state, path_stats, module) | ||
| else: | ||
| try: | ||
| self._exec_cached_module( | ||
| fullname, spec.loader_state, path_stats, module | ||
| ) | ||
| except (EOFError, ImportError, OSError) as e: | ||
| logger.debug(f"Failed to load cached Basilisp module: {e}") | ||
| self._exec_module(fullname, spec.loader_state, path_stats, module) | ||
| def hook_imports() -> None: | ||
@@ -421,0 +431,0 @@ """Hook into Python's import machinery with a custom Basilisp code |
@@ -40,2 +40,3 @@ import ast | ||
| from basilisp.lang.interfaces import ISeq | ||
| from basilisp.lang.runtime import BasilispModule | ||
| from basilisp.lang.typing import CompilerOpts, ReaderForm | ||
@@ -113,3 +114,2 @@ from basilisp.lang.util import genname | ||
| def _emit_ast_string( | ||
| ns: runtime.Namespace, | ||
| module: ast.AST, | ||
@@ -130,3 +130,3 @@ ) -> None: # pragma: no cover | ||
| else: | ||
| runtime.add_generated_python(to_py_str(module), which_ns=ns) | ||
| runtime.add_generated_python(to_py_str(module)) | ||
@@ -162,3 +162,3 @@ | ||
| if not ns.module.__basilisp_bootstrapped__: | ||
| _bootstrap_module(ctx.generator_context, ctx.py_ast_optimizer, ns) | ||
| _bootstrap_module(ctx.generator_context, ctx.py_ast_optimizer, ns.module) | ||
@@ -188,3 +188,3 @@ last = _sentinel | ||
| _emit_ast_string(ns, ast_module) | ||
| _emit_ast_string(ast_module) | ||
@@ -207,3 +207,3 @@ bytecode = compile(ast_module, ctx.filename, "exec") | ||
| py_ast: GeneratedPyAST, | ||
| ns: runtime.Namespace, | ||
| module: BasilispModule, | ||
| source_filename: str, | ||
@@ -222,12 +222,12 @@ collect_bytecode: Optional[BytecodeCollector] = None, | ||
| module = ast.Module(body=list(module_body), type_ignores=[]) | ||
| module = optimizer.visit(module) | ||
| ast.fix_missing_locations(module) | ||
| module_ast = ast.Module(body=list(module_body), type_ignores=[]) | ||
| module_ast = optimizer.visit(module_ast) | ||
| ast.fix_missing_locations(module_ast) | ||
| _emit_ast_string(ns, module) | ||
| _emit_ast_string(module_ast) | ||
| bytecode = compile(module, source_filename, "exec") | ||
| bytecode = compile(module_ast, source_filename, "exec") | ||
| if collect_bytecode: | ||
| collect_bytecode(bytecode) | ||
| exec(bytecode, ns.module.__dict__) # pylint: disable=exec-used # nosec 6102 | ||
| exec(bytecode, module.__dict__) # pylint: disable=exec-used # nosec 6102 | ||
@@ -238,3 +238,3 @@ | ||
| optimizer: PythonASTOptimizer, | ||
| ns: runtime.Namespace, | ||
| module: BasilispModule, | ||
| collect_bytecode: Optional[BytecodeCollector] = None, | ||
@@ -245,8 +245,8 @@ ) -> None: | ||
| optimizer, | ||
| py_module_preamble(ns), | ||
| ns, | ||
| py_module_preamble(), | ||
| module, | ||
| source_filename=gctx.filename, | ||
| collect_bytecode=collect_bytecode, | ||
| ) | ||
| ns.module.__basilisp_bootstrapped__ = True | ||
| module.__basilisp_bootstrapped__ = True | ||
@@ -257,3 +257,3 @@ | ||
| ctx: CompilerContext, | ||
| ns: runtime.Namespace, | ||
| module: BasilispModule, | ||
| collect_bytecode: Optional[BytecodeCollector] = None, | ||
@@ -268,3 +268,3 @@ ) -> None: | ||
| """ | ||
| _bootstrap_module(ctx.generator_context, ctx.py_ast_optimizer, ns) | ||
| _bootstrap_module(ctx.generator_context, ctx.py_ast_optimizer, module) | ||
@@ -278,3 +278,3 @@ for form in _flatmap_forms(forms): | ||
| nodes, | ||
| ns, | ||
| module, | ||
| source_filename=ctx.filename, | ||
@@ -289,3 +289,3 @@ collect_bytecode=collect_bytecode, | ||
| optimizer: PythonASTOptimizer, | ||
| ns: runtime.Namespace, | ||
| module: BasilispModule, | ||
| ) -> None: | ||
@@ -298,5 +298,5 @@ """Compile cached bytecode into the given module. | ||
| and then proceeds to compile a collection of bytecodes into the module.""" | ||
| _bootstrap_module(gctx, optimizer, ns) | ||
| _bootstrap_module(gctx, optimizer, module) | ||
| for bytecode in code: | ||
| exec(bytecode, ns.module.__dict__) # pylint: disable=exec-used # nosec 6102 | ||
| exec(bytecode, module.__dict__) # pylint: disable=exec-used # nosec 6102 | ||
@@ -303,0 +303,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
1153040
0.24%17867
0.2%