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 tests/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
from datetime import date, timedelta
from pathlib import Path

# Tests import the template's own files; never leave bytecode inside it.
sys.dont_write_bytecode = True

REPO = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(REPO / "wiki"))

Expand Down
44 changes: 44 additions & 0 deletions tests/test_no_bytecode.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""Lint runs must leave no bytecode behind. The template ships no
.gitignore, so a wikilint/__pycache__/ written by a lint run would be
swept into the wiki's history by the agent's next `git add -A`; and the
test suite must not litter the template it tests."""

import shutil
import subprocess
import sys
import tempfile
import unittest
from pathlib import Path

from helpers import REPO


def pycache_dirs(root):
return sorted(p.relative_to(root).as_posix() for p in Path(root).rglob("__pycache__"))


class TestNoBytecode(unittest.TestCase):
def test_lint_run_writes_no_pycache_in_an_install(self):
with tempfile.TemporaryDirectory() as tmp:
install = Path(tmp) / "w"
shutil.copytree(REPO / "wiki", install,
ignore=shutil.ignore_patterns("__pycache__"))
(install / "raw" / "inbox").mkdir(parents=True)
result = subprocess.run(
[sys.executable, "lint.py", "check"], cwd=install,
capture_output=True, text=True,
env={"PATH": "/usr/bin:/bin"}, # no inherited PYTHONDONTWRITEBYTECODE
)
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
self.assertEqual(pycache_dirs(install), [])

def test_suite_does_not_write_bytecode(self):
self.assertTrue(sys.dont_write_bytecode)

def test_compile_check_writes_nothing(self):
source = (REPO / "tests" / "test_variants.py").read_text()
self.assertNotIn("py_compile", source)


if __name__ == "__main__":
unittest.main()
7 changes: 3 additions & 4 deletions tests/test_variants.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
hook correctness properties, for the shipped template and the feature-named
extension configs in extension_configs.py."""

import py_compile
import unittest

from helpers import REPO, VARIANTS, load_variant_config
Expand All @@ -13,10 +12,10 @@

class TestEngineIdentity(unittest.TestCase):
def test_everything_compiles(self):
# Builtin compile() checks syntax without writing .pyc files.
for variant in VARIANTS:
py_compile.compile(str(REPO / variant / "lint.py"), doraise=True)
for p in (REPO / variant / "wikilint").glob("*.py"):
py_compile.compile(str(p), doraise=True)
for p in [REPO / variant / "lint.py", *(REPO / variant / "wikilint").glob("*.py")]:
compile(p.read_text(encoding="utf-8"), str(p), "exec")


class TestConfigSanity(unittest.TestCase):
Expand Down
3 changes: 3 additions & 0 deletions wiki/lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,8 @@ def index_entry_extra(fields):

if __name__ == "__main__":
import sys
# No __pycache__: the wiki repo ships no .gitignore, so cached bytecode
# would land in history on the next `git add -A`. Recompiling is cheap.
sys.dont_write_bytecode = True
from wikilint import main
sys.exit(main(CONFIG, index_entry_extra))
Loading