Skip to content

Report failed assertion expressions - #698

Closed
filiplajszczak wants to merge 1 commit into
spylang:mainfrom
filiplajszczak:assert_expression_diagnostics
Closed

filiplajszczak wants to merge 1 commit into
spylang:mainfrom
filiplajszczak:assert_expression_diagnostics

Conversation

@filiplajszczak

Copy link
Copy Markdown
Contributor

Use the original assertion expression as the default message when an assertion fails. For example:

AssertionError: assert actual == expected

Preserve the source expression through redshift and embed it in compiled output, so interpreted, Doppler, and C execution report the same expression without requiring the .spy source file at runtime. Explicit messages such as assert condition, "message" remain unchanged.

Add parser characterization for plain assertions and assertions with explicit messages, then extend the cross-backend assertion tests to cover a simple comparison and preservation of the original expression when redshift can transform it.

This differs from CPython's plain assert, which raises an AssertionError without retaining the failed expression. It establishes source-expression reporting as a basis for pytest-like assertion diagnostics in hypothetical future spytest. Later changes could attach values for evaluated expressions and subexpressions while preserving CPython's evaluation semantics. Unlike pytest, SPy can retain the required information in its own compiler pipeline rather than through external AST rewriting hackery.

Use the original assertion expression as the default message when an assertion fails. For example:

```text
AssertionError: assert actual == expected
```

Preserve the source expression through redshift and embed it in compiled output, so interpreted, Doppler, and C execution report the same expression without requiring the `.spy` source file at runtime. Explicit messages such as `assert condition, "message"` remain unchanged.

Add parser characterization for plain assertions and assertions with explicit messages, then extend the cross-backend assertion tests to cover a simple comparison and preservation of the original expression when redshift can transform it.

This differs from CPython's plain `assert`, which raises an `AssertionError` without retaining the failed expression. It establishes source-expression reporting as a basis for pytest-like assertion diagnostics in hypothetical future `spytest`. Later changes could attach values for evaluated expressions and subexpressions while preserving CPython's evaluation semantics. Unlike pytest, SPy can retain the required information in its own compiler pipeline rather than through external AST rewriting hackery.
@filiplajszczak
filiplajszczak force-pushed the assert_expression_diagnostics branch from 1a76ab7 to ae9ea60 Compare September 12, 2026 10:19
@antocuni

Copy link
Copy Markdown
Member

I'm not sure this is actually needed.
This is what we get now with the current behavior:

def main(args: list[str]) -> None:
    assert len(args) == 2
    print(args[0], args[1])
❯ spy /tmp/x.spy  # interp
Traceback (most recent call last):
  * x::main at /tmp/x.spy:2
  |     assert len(args) == 2
  |     |___________________|

AssertionError: assertion failed
  | /tmp/x.spy:2
  |     assert len(args) == 2
  |     |___________________| assertion failed



❯ spy build -x /tmp/x.spy   # compiled
[debug] /tmp/build/x 
AssertionError: assertion failed
   --> /tmp/x.spy:2
  2 |     assert len(args) == 2
    | ^^^^^^^^^^^^^^^^^^^^^^^^^

In both cases, we can see the source code which triggered the assert. I don't understand what this would buy us, especially considering that we cannot catch exceptions yet :)


It establishes source-expression reporting as a basis for pytest-like assertion diagnostics in hypothetical future spytest

I think that when it's time to write spytest, we will have a better understanding of what we want to do and how, no need to anticipate it now.
For example, AFAIK pytest does its diagnostics by rewriting the asserts at the AST level, so we could do something similar at blue-time in SPy.

So, I'm leaning towards closing this PR, unless there are good reasons to merge which I currently don't see.

@filiplajszczak

Copy link
Copy Markdown
Contributor Author

Thanks, that makes sense.

We may return to this when SPy can catch exceptions.

Interestingly, a related approach has been discussed in CPython: python/cpython#105799

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