Skip to content

refactor: split the author-time guard subsystem out of feature_chain_parser - #907

Merged
TomKaltofen merged 4 commits into
mainfrom
refactor/split-author-time-guards
Jul 31, 2026
Merged

refactor: split the author-time guard subsystem out of feature_chain_parser#907
TomKaltofen merged 4 commits into
mainfrom
refactor/split-author-time-guards

Conversation

@TKaltofen

Copy link
Copy Markdown
Collaborator

feature_chain_parser.py mixed two separable concerns: the runtime name-parsing and
matching path (parse_name, match_configuration_feature_chain_parser,
build_effective_options), and a class-definition-time validation and guard-installation
subsystem that only used the class as a namespace. The author-time cluster now lives in
feature_chain_author_guards.py as module-level functions taking the owner class.

Parser: 1130 -> 691 lines. New module: 470 lines.

What moved

validate_name_binding, warn_captureless_without_binding, warn_universal_optional_matcher,
check_required_when, install_required_when_guard, install_name_path_presence_guard,
_matcher_is_staticmethod, _reject_staticmethod_matcher, _resolve_match_arguments,
_pattern_named_and_total_groups, _flatten_patterns, _str_reachable_values, plus the six
guard flags and ContextVars. Bodies, docstrings and comments moved verbatim; the only edits are
call requalification.

Import direction

One-way: the guards import the parser, never the reverse. So there are no compatibility
re-exports. FeatureGroup.__init_subclass__ and FeatureChainParserMixin.__init_subclass__
import the new module directly, in the same call order as before.

The plugin-author surface is unchanged: none of the moved names was exported from
mloda.provider, and downstream plugin code only ever calls
FeatureChainParser.parse_feature_name, which stays put.

Behavior note

The three author diagnostics that moved (the captureless-pattern warning, the universal-matcher
warning, and the contained required_when predicate raise) now log under
...feature_chainer.feature_chain_author_guards instead of ...feature_chainer.feature_chain_parser.
Anyone silencing them by logger name needs the new name. Nothing in the docs pins a logger name.

Tests

A new split-boundary test pins module ownership, that the runtime match path and the four parser
members the guards call back into stay in the parser, that the parser does not import the guards
(static AST plus a fresh-interpreter check), and that no moved name reappears as a
FeatureChainParser attribute.

tox green: 7543 passed, 170 skipped, ruff, mypy --strict, bandit.

@TKaltofen
TKaltofen requested a review from TomKaltofen as a code owner July 30, 2026 17:24
…parser

feature_chain_parser.py mixed the runtime name-parsing and matching path with
a class-definition-time validation and guard-installation subsystem that only
used the class as a namespace. The author-time cluster now lives in
feature_chain_author_guards.py as module-level functions.

The import direction is one-way (the guards import the parser, never the
reverse), so there are no compatibility re-exports: the two __init_subclass__
hooks import the new module directly. A split-boundary test pins ownership,
the acyclic direction, and the absence of re-exports.

Parser: 1130 -> 691 lines.
…y bank

Review follow-ups to the split:

- the split-boundary test now also pins the four parser members the guards
  module calls back into, so moving one of them fails visibly;
- the clean-interpreter subprocess runs from the repo root, so it can never
  validate an installed copy instead of the tree;
- the two build_effective_options raise tests assert no WARNING on any logger
  again, restoring the invariant they state; the split had narrowed them to a
  single logger name;
- the guards module docstring names the parser-private surface it depends on;
- memory-bank/systemPatterns.md records the new module and the one-way import.
Both lines already carry a public reference (#763, and the test class name),
so the identifier added nothing a reader outside the tracker could use.
The branch first recorded this in memory-bank/systemPatterns.md, which main
retired in the meantime; property-mapping.md is where that content landed and
where the class-definition behavior is specified rather than mentioned.
@TKaltofen
TKaltofen force-pushed the refactor/split-author-time-guards branch from f64f433 to 6841004 Compare July 30, 2026 17:34
@TomKaltofen
TomKaltofen merged commit a806bdf into main Jul 31, 2026
18 checks passed
@TomKaltofen
TomKaltofen deleted the refactor/split-author-time-guards branch July 31, 2026 07:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants