Repository navigation
feat: add opt-in SQBRPYTHON rules for project Python - #1487
Merged
Merged
Conversation
Depend on fensu-facts and fensu-native 0.30.0 without their Python bindings and add the Python rule family to the catalogue: two SQLBuild layout rules and 62 Fensu core rules in bands by Fensu family. The family runs only when a selector names SQBRPYTHON or one of its codes, so selecting SQBR does not turn on Python linting. Evaluation follows.
…n rules Add an integer built-in option kind with a minimum, shown by sqb rules show and returned as RuleOption.integer by the Python catalogue, and declare each Python rule's Fensu thresholds with Fensu's defaults.
…t Python rules When a selected rule reads Python, the rules request now carries every supported project Python file with the digest of its bytes, plus the interpreter version, so the memo, speculation and delta compiles see a Python edit. Without a Python rule selected no Python file is read.
…core rules Each project Python file is placed the way Fensu places files: files under python/ belong to the runtime package imported as python, with domains directly below it; other supported files sit under their own folder and run only the file-local rules. A unit's main.py is an entry and main module. Fensu decides which file runs project-, scope- and package-wide rules, its project questions are answered from one walk of the project, and node functions and everything outside python/ count as loaded for reachability. Findings keep Fensu's text, move to 1-based character columns, and rules for the python/ package never report outside it. A file the parser rejects fails the run. Python rules no longer make model rules read every model or change the model cache key.
… named SQBRPYTHON001 reports modules directly under python/ and node-kind or role folders at its root; SQBRPYTHON002 reports generic package names such as common/ or shared/ anywhere under python/, except utils/ at its root. Each folder is reported once, on its __init__.py or else its first file.
…ject answers are unchanged The Python rules keep their findings per file in python.json beside the bulk rules cache. An entry holds while the file's bytes, its rules and thresholds, the ruleset and the Python version are the same, and the project questions its rules asked, such as whether an imported module exists, still have the same answers. Rules that read the whole project also key on every Python source. A speculative evaluation holds this write with the bulk cache write until it is published.
… unit tests The compiler differential E2E only runs in the merge queue, so a discovery code without a corpus case surfaced there first. This check reads the declared cases without compiling them, so it fails on the pull request.
…le definitions Each package file's context carried every loaded definition whenever a project-wide Python rule ran, so evaluation grew with files times definitions. A guard now bounds 4000 modules with 12000 findings.
…inputs Naming one Python code next to SQBR no longer selects every default Python rule. Layout rules that read folders now answer their cached queries from project-relative paths, so adding a subdomain re-checks the package. Python selectors and options no longer change the model-rule cache key, and the Python cache key covers only the Python rules and their options.
…RPYTHON306 Functions decorated with @audit_factory are loaded by SQLBuild, and imports through python/ folders without __init__.py resolve, so neither is reported as unreachable. The finding's remediation no longer points at a setting SQLBuild does not have.
…caches see layout changes Fensu spells planned query paths with /, while a Windows project directory uses backslashes, so the paths stayed absolute and folder answers never changed. A query for the project directory itself now uses the index's root path.
…st outgrows it rules list now prints more than CPython's 8 KiB stdout buffer, so it fails its write instead of dropping the final flush. build --help stays between 4 and 8 KiB and does not grow with the rule catalogue.
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Nov 14, 2026
The dense and varied compile guards assert that their fixture selects every built-in rule. The SQBRPYTHON rules are only selected by name, so the fixture now names them, and the cold guard counts one rule-cache miss per project Python file.
… a near-limit budget The 4000-module unreachable-definitions case ran at about 5.2 s against its 5 s budget on the debug test profile, and at 2000 modules the code it guards against fits well inside the budget. The case now times 500 and 2000 modules in five interleaved pairs and bounds the median ratio at 6.5: the current code measures 4.9 to 5.7 and the earlier per-file context copy 7.4 to 8.7. The default-rules case keeps its absolute budget, and both scaling tests take a shared lock so they never time each other's work.
…ble definition Without a result check the ratio guard would pass if SQBRPYTHON306 stopped walking this project, because both runs would get cheaper together. The large run must report each unit's function and the shared helper.
…hon rules The dense fixture now selects the SQBRPYTHON rules by name. The delta compile project reuses it, but its cases author minimal custom-rule and factory modules that those rules reject, so the stored compile failed its Rules and one edit no longer found the selection it rewrites. The delta project now swaps back to its previous selection.
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Nov 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Project Python (
python/, hooks, providers) had no Rules coverage, so layout drift, missing annotations and dead code went unchecked. Fensu already implements these checks as core rules.Changes
SQBRPYTHONfamily: Fensu's core Python rules under SQLBuild codes, plus twopython/layout rules (001, 002). Thresholds are whole-number options in[rules.rule_options].SQBRPYTHONor one of its codes;SQBRalone leaves it out. 306 (unreachable definitions) and 507 need their exact code.@audit_factory), code outsidepython/, and imports through folders without__init__.pyas reachable.python.json), keyed on the file, the Python rules and options, and the project answers it read. Python settings never change the model-rule cache key.Verification
rules runvscompile, cache sequence.make check-cipasses.DuckShop: new
edge_cases/python_rules/{conforming,violations}fixtures with expected findings; the conforming one covers audit factories and namespace imports.