QueryResult abstraction to help with SGraph Quqery Lang queries#152
Merged
villelaitila merged 4 commits intosoftagram:mainfrom Apr 7, 2026
Conversation
Contributor
villelaitila
commented
Apr 7, 2026
- Add exclude_attrs support to ModelCompare and fix set intersection bug
- Add SGraph Query Language (P1+P2) — architecture-native filtering and dependency queries
- feat(query): add max_depth parameter to chain search
- feat(query): return QueryResult with chains from query()
… dependency queries Parser: recursive descent with 9-level priority (OR, AND, parens, ---, --->, -->, --, NOT, attribute filters, keyword/path fallback). Expressions: 14 AST node types covering element selection, attribute filtering, direct/transitive dependency search, shortest path, and boolean logic. Evaluator: ghost-parent view model pattern — result elements preserve correct paths without copying the full ancestor tree. Supports chain search (DFS, max depth 20, cycle prevention) and shortest path (undirected BFS). 78 tests covering parser token recognition, precedence, and integration tests against a realistic multi-module test model with dependency chains.
The chain search operator (--->) had a hardcoded depth cap of 20 hops, which prevented finding lineage chains deeper than that. Add a max_depth parameter to query() and evaluate() that plumbs through to the chain search DFS. Default remains 20 to preserve existing behavior. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The query() function now returns a QueryResult dataclass instead of a
raw SGraph. This bundles two pieces of information that callers
previously had to compute themselves:
result.subgraph – the filtered SGraph (same as before)
result.chains – tuple of ordered SElement tuples discovered by
chain searches (--->)
For non-chain queries (filters, attribute matches), chains is the
empty tuple — always present, never None.
The chain elements are the ORIGINAL model instances (not subgraph
copies), so callers can use ``elem is original`` identity checks and
access full attrs without worrying about parallel object hierarchies.
Internally _eval_chain_search already had the ordered chain in the
DFS recursion (the ``chain`` parameter); it just didn't expose it.
A new optional ``chain_collector`` parameter threads through
evaluate() into the DFS, picking up the path tuple at every match.
The chain_collector is intentionally NOT threaded through NotExpr
branches: chains found inside a NOT are the EXCLUDED set, not the
user-visible result, and surfacing them would mislead.
BREAKING CHANGE: query() now returns QueryResult instead of SGraph.
Callers that previously did ``query(...).rootNode`` must either
- migrate to ``query(...).subgraph.rootNode``, or
- continue calling sgraph.query.evaluator.evaluate() directly, which
still returns SGraph for use as an internal helper.
The 78 tests in tests/test_query.py adapted by updating only one
shared helper function (``get_all_paths``) to read .subgraph if
present. All 78 tests still pass.
Default Python repr (`<sgraph.sgraph.SGraph object at 0x...>`) is
unhelpful in logs and obscures object identity when the same model
is bound to several variables/dict keys. The new repr shows the
root path, element count, and id, e.g.:
<SGraph empty elements=0 id=0x10ad>
<SGraph root=/junit4 elements=42 id=0x10ad>
<SGraph roots=[a,b,c,...] count=12 elements=10000+ id=0x10bd>
Element count uses an iterative bounded walk
(_REPR_COUNT_LIMIT = 10000), so repr() stays cheap on multi-million
node models — important because debuggers, loggers, and exception
formatters call repr() at arbitrary moments. The body is wrapped
in try/except so a malformed model can never crash a logger.
Also commits the existing untracked tests/mini_model.xml fixture
that the new multi-root tests depend on, and updates the stale
README example.
Softagram Impact Report for pull/152 (head commit: 7240444)TL;DR Arch. Impact: 105 | Changed code files: 11 | Directly impacted code files: 38⭐ Change Overview
⭐ Details of Dependency Changes
[] 📄 Full report
Impact Report explained. Give feedback on this report to support@softagram.com |
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.

