Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
* Added a compiler metadata flag for suppressing warnings when Var indirection is unavoidable (#1052)

### Fixed
* Basilisp now respects the value of Python's `sys.dont_write_bytecode` flag when generating bytecode (#1054)

## [v0.2.2]
### Added
* Added the `-p`/`--include-path` CLI command to prepend entries to the `sys.path` as an alternative to `PYTHONPATH` (#1027)
Expand Down
8 changes: 3 additions & 5 deletions docs/compiler.rst
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,12 @@ Namespace Caching

The Basilisp compiler aggressively caches compiled namespace modules because compilation is relatively expensive and leads to significant slowdowns when starting Basilisp.
Basilisp namespaces are cached using the `same mechanism as the Python compiler uses <https://docs.python.org/3/reference/import.html#cached-bytecode-invalidation>`_ -- namespaces are cached as bytecode and only recomputed when the ``mtime`` of the source file differs from the ``mtime`` stored in the header of the cached file.
Cache files are stored with an ``.lpyc`` prefix and respect the Python ``PYTHONCACHEPREFIX`` (:external:py:data:`sys.pycache_prefix`) setting.

There may be times when the caching behavior is undesirable for whatever reason.
Often in development, it is not desirable to allow namespace caching since such files may get out of sync of other uncached modules you are frequently updating, causing hard-to-diagnose bugs.
In such cases, you can tell the Basilisp import mechanism to always ignore the cached copy of a namespace using the ``BASILISP_DO_NOT_CACHE_NAMESPACES`` environment variable.

.. code-block:: bash

export BASILISP_DO_NOT_CACHE_NAMESPACES=true
In such cases, you can tell the Basilisp import mechanism to always ignore the cached copy of a namespace using the ``BASILISP_DO_NOT_CACHE_NAMESPACES`` environment variable or ``--disable-ns-cache`` CLI flag.
Additionally, it is possible to disable Basilisp's generation of bytecode files using the standard Python ``PYTHONDONTWRITEBYTECODE`` environment variable or :external:py:data:`sys.dont_write_bytecode` value.

.. _direct_linking:

Expand Down
4 changes: 4 additions & 0 deletions src/basilisp/importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,10 @@ def _exec_module(
collect_bytecode=all_bytecode.append,
)

if sys.dont_write_bytecode:
logger.debug(f"Skipping bytecode generation for '{fullname}'")
return

# Cache the bytecode that was collected through the compilation run.
cache_file_bytes = _basilisp_bytecode(
path_stats["mtime"], path_stats["size"], all_bytecode
Expand Down
15 changes: 15 additions & 0 deletions tests/basilisp/importer_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,21 @@ def test_import_module_with_cache(
using_cache = load_namespace(cached_module_ns)
assert cached_module_ns == using_cache.find(sym.symbol("val")).value

def test_import_module_without_writing_cache(
self,
monkeypatch,
module_dir,
make_new_module,
load_namespace,
):
monkeypatch.setattr(sys, "dont_write_bytecode", True)
module_path = ["importer", "namespace", "no_bytecode.lpy"]
make_new_module(*module_path, ns_name="importer.namespace.no-bytecode")
load_namespace("importer.namespace.no-bytecode")
assert not os.path.exists(
importer._cache_from_source(os.path.join(module_dir, *module_path))
)

def test_import_module_with_invalid_cache_magic_number(
self, module_dir, cached_module_ns, cached_module_file, load_namespace
):
Expand Down