mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 02:54:26 +00:00
sys.modules is consulted before sys.meta_path, so everything site pulls in from .pth files -- setuptools' _distutils_hack and 24 editable-install finders on a dev host -- resolved straight out of the cache and never reached the Blocker. An overlay with a smuggled 'import _distutils_hack' passed the guard before this change and fails after it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
52 lines
1.6 KiB
Python
52 lines
1.6 KiB
Python
"""Run the .env generator with every non-stdlib, non-repo import blocked.
|
|
|
|
Executed as a subprocess, never imported. Argv is ``<repo-root> <out-path>``.
|
|
A blocked import propagates so the traceback names the offending chain.
|
|
|
|
``sys.modules`` is consulted before ``sys.meta_path``, and ``site`` preloads
|
|
whatever the interpreter's ``.pth`` files pull in (setuptools' ``_distutils_hack``,
|
|
an editable-install finder). Those entries are dropped first, otherwise a
|
|
third-party import would resolve straight out of the cache, unblocked.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
REPO = Path(sys.argv[1]).resolve()
|
|
OUT = Path(sys.argv[2])
|
|
sys.path.insert(0, str(REPO))
|
|
|
|
REPO_TOP = frozenset(
|
|
{"cli", "utils", "plugins", "filter_plugins", "lookup_plugins", "module_utils"}
|
|
)
|
|
STDLIB = frozenset(sys.stdlib_module_names)
|
|
|
|
|
|
class Blocker:
|
|
def find_spec(self, fullname, path=None, target=None):
|
|
top = fullname.split(".")[0]
|
|
if top in STDLIB or top in REPO_TOP:
|
|
return
|
|
raise ModuleNotFoundError(f"No module named {fullname!r}", name=fullname)
|
|
|
|
|
|
for _name in list(sys.modules):
|
|
_top = _name.split(".")[0]
|
|
if _top not in STDLIB and _top not in REPO_TOP and _name != "__main__":
|
|
del sys.modules[_name]
|
|
|
|
sys.meta_path.insert(0, Blocker())
|
|
|
|
from cli.meta.env.__main__ import ( # noqa: E402
|
|
build_env,
|
|
parse_static_env_with_comments,
|
|
write_dotenv,
|
|
)
|
|
|
|
static, comments = parse_static_env_with_comments(REPO / "default.env")
|
|
eb = build_env(static, repo_root=REPO, comments=comments)
|
|
write_dotenv(eb, OUT)
|
|
print(len(eb.values))
|