Improve pySpecs robustness: graceful failures, regex support, and reusable API#512
Merged
Improve pySpecs robustness: graceful failures, regex support, and reusable API#512
Conversation
af909a0 to
bbb3c3b
Compare
shigoel
reviewed
Mar 6, 2026
shigoel
reviewed
Mar 6, 2026
shigoel
previously approved these changes
Mar 6, 2026
4d5ec7c to
620f665
Compare
shigoel
approved these changes
Mar 9, 2026
620f665 to
f258635
Compare
Improves the robustness of the pySpecs command so it reports failures gracefully — including regex usage — instead of aborting, and extracts the core logic into a reusable API with CLI flags for skipping definitions, controlling verbosity, and selecting log events. - Graceful failure handling: when a Python import cannot be resolved, the translator now registers the imported names as opaque extern types and continues, rather than aborting. Overload stubs with unexpected bodies produce a warning instead of failing. - Regex support: `from re import compile` is recognized via the built-in prelude, so Python files that use regex no longer trigger unknown-identifier errors. - Reusable API: the translation logic that was inline in the CLI callback is extracted into a self-contained entry point in SimpleAPI, returning structured errors instead of calling exitFailure. - CLI flags: --skip omits named top-level definitions (overloads kept), --quiet suppresses logging and warnings, --log enables event types. - Warning pipeline: warnings are collected during translation and returned as data; a three-level verbosity setting controls reporting. - Composable assertion expressions: the expression tree is refactored from fused nodes into orthogonal building blocks, making serialization a direct structural recursion with no special cases. - Readable DDM output: ensure(pred, msg) format, infix comparisons, indented class member blocks. - Event logging cleanup: global mutable reference replaced by a context- threaded event set.
Replace FileMaps.ppSourceRange (which used panic! for missing paths) with a local ppErr helper that returns an error via throw instead. Remove redundant variable alias in SimpleAPI. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
f258635 to
ca0593a
Compare
aqjune-aws
approved these changes
Mar 9, 2026
MikaelMayer
approved these changes
Mar 9, 2026
github-merge-queue bot
pushed a commit
that referenced
this pull request
Mar 11, 2026
…cts (#537) ## Summary Extend the Strata `pySpecs` Python-to-spec translator to handle the full range of assertion patterns found across service specification files. Before this change the translator emitted warnings on many common patterns; after, it handles all constructs without warnings. Builds on the robustness and API improvements from #512. ## Details - **F-string messages.** Assertion messages that use Python f-strings are now preserved semantically (distinguishing literal text from interpolated expressions) rather than being flattened to a single string. - **For-loop quantifiers.** `for item in kwargs["field"]` loops are translated to `forallList` quantifiers. The element type is inferred from `typing.List` or `typing.Sequence` annotations in the corresponding TypedDict. `for k, v in dict.items()` tuple unpacking is handled similarly via `forallDict`, with key/value types inferred from `Dict` or `Mapping` annotations. - **Conditional implication.** When assertions appear inside an `if` block (e.g. `if "Items" in kwargs:`), the condition becomes an antecedent: `implies(condition, assertion)`. Else-branch assertions receive the negated condition. - **`__init__` as class fields.** Rather than treating `__init__` as a regular method, the translator now extracts `self.field = self._ClassName()` assignments as typed class fields with an optional constant value. Unhandled `__init__` patterns emit warnings. - **Type-checked numeric comparisons.** Comparison assertions (`>=`, `<=`) now use type inference to choose between integer and floating-point operators. When a float-typed field is compared against an integer literal (e.g. `SampleSize >= 0`), the bound is promoted to float automatically. Negative integer bounds (`>= -1`) are also supported. - **Negative-integer DDM encoding.** Fixed the `negSucc` round-trip in the DDM serialization layer so that `-1` renders as `"-1"` rather than `"-0"`. - **DDM operator precedences.** Subscript, comparison, and implication operators have explicit precedences so the pretty-printer no longer emits unnecessary parentheses. - **Test coverage.** Positive tests cover f-strings, for-loops, dict iteration, conditionals, `__init__` fields, float/int comparisons, and negative bounds. A separate negative-test file (`warnings.py`) verifies that unsupported patterns produce the expected warnings. Test assertions now throw descriptive errors instead of panicking. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.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.
Summary
Improves the robustness of the
pySpecscommand so it reports failuresgracefully — including regex usage — instead of aborting, and extracts
the core logic into a reusable API with CLI flags for skipping
definitions, controlling verbosity, and selecting log events.
Details
the translator now registers the imported names as opaque extern types
and continues, rather than aborting. This means downstream references
to those names still produce valid (if incomplete) output. Overload
stubs with unexpected bodies produce a warning instead of failing.
from re import compileis recognized via thebuilt-in prelude, so Python files that use regex no longer trigger
unknown-identifier errors. A test confirms this import resolves
without warnings.
callback is extracted into a self-contained entry point in SimpleAPI.
It validates inputs, parses skip-name strings, translates, writes
output, and reports warnings — all returning structured errors instead
of calling
exitFailure. The CLI callback now delegates to this.--skip <name>omits named top-level definitions fromoutput (overloaded variants are always kept).
--quietsuppresseslogging and warnings.
--log <event>enables specific event types.and returned to the caller as data, rather than being printed to
stderr internally. A three-level verbosity setting (none / summary /
detail) controls how they are reported.
preconditions and postconditions is refactored from fused nodes
(e.g., "length >= N" as one node) into orthogonal building blocks
(length, integer literal, greater-or-equal, etc.). This makes
serialization a direct structural recursion with no special cases.
ensure(pred, msg).Comparisons use infix
>=/<=. Class member blocks are indentedon separate lines. These changes make the generated specs easier to
read and diff.
reference; the set of enabled events is threaded through the
translation context. Import messages now report after completion
(past tense) and include warning counts.
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.