From 9b18d476eac3569f148ec6f7f56b2f26d344bf3f Mon Sep 17 00:00:00 2001 From: Edbert Chan Date: Thu, 10 Sep 2026 17:09:17 -0700 Subject: [PATCH] test: register a gate module before executing it Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_013sYZswUQ3HEnUEdVWrUbvq Change-Id: I8b93e3c486069b3c04e42b40193f35a17a15a3d6 --- tests/test_check_docstrings_match_regexes.py | 32 ++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tests/test_check_docstrings_match_regexes.py b/tests/test_check_docstrings_match_regexes.py index 3bc7f11b..bd80c8cf 100644 --- a/tests/test_check_docstrings_match_regexes.py +++ b/tests/test_check_docstrings_match_regexes.py @@ -18,6 +18,7 @@ import importlib.util import sys +import tempfile import unittest from pathlib import Path from types import ModuleType @@ -32,10 +33,41 @@ def _load(path: Path) -> ModuleType: sys.path.insert(0, str(SCRIPTS)) spec = importlib.util.spec_from_file_location(f"gate_{path.stem}", path) module = importlib.util.module_from_spec(spec) + sys.modules[spec.name] = module spec.loader.exec_module(module) return module +class TestGateLoader(unittest.TestCase): + """A gate module must be registered in sys.modules before it executes. + + @dataclass resolves its own module through sys.modules[cls.__module__] on + Python 3.12+. A module built with module_from_spec is not registered there, + so that lookup returns None and the decorator raises AttributeError before + any assertion in this file runs. CI pins Python 3.9, where the lookup takes + a different path, so only a newer local interpreter sees it. + """ + + def test_a_gate_using_dataclass_loads(self): + with tempfile.TemporaryDirectory() as tmp: + gate = Path(tmp) / "check_dataclass_probe.py" + gate.write_text( + "from __future__ import annotations\n" + "from dataclasses import dataclass\n" + "@dataclass\n" + "class Promise:\n" + " text: str\n" + 'PROMISED_CATCH = ("x",)\n' + 'PROMISED_ALLOW = ()\n' + "def flags_exemplar(s):\n" + " return Promise(s).text == 'x'\n", + encoding="utf-8", + ) + module = _load(gate) + self.assertTrue(module.flags_exemplar("x")) + self.assertFalse(module.flags_exemplar("y")) + + class GatesDeclareTheirPromises(unittest.TestCase): @classmethod def setUpClass(cls) -> None: