Skip to content

Do not rewrite asserts in class bodies (#9582) - #14867

Closed
l46983284-cpu wants to merge 1 commit into
pytest-dev:mainfrom
l46983284-cpu:fix-9582-class-body-assert-rewrite
Closed

Do not rewrite asserts in class bodies (#9582)#14867
l46983284-cpu wants to merge 1 commit into
pytest-dev:mainfrom
l46983284-cpu:fix-9582-class-body-assert-rewrite

Conversation

@l46983284-cpu

Copy link
Copy Markdown

Closes #9582.

Assert rewriting currently breaks class-body asserts in namespaces that forbid redefinition. For each assert in a class body the rewriter emits an assignment to its temporary name plus a cleanup assignment to the same name (@py_assert1 = ... followed by @py_assert1 = None), i.e. two assignments of one key in the class namespace. A plain class namespace tolerates that; Enum's does not, so the class body fails at creation time with TypeError: '@py_assert1' already defined as True.

Following the point made in the issue about the class execution namespace having special meaning, and yuvalshi0's analysis showing that a full fix cannot know which custom namespaces forbid redefinition, this takes the conservative route: asserts appearing directly in a class body are no longer rewritten. Asserts inside methods — including methods of Enum subclasses — keep full rewriting and diagnostics.

Trade-off, stated honestly: asserts written directly in a class body now produce a plain AssertionError without the rewritten explanation. This affects any class-body assert, not just Enum. I believe strictly-better applies here: today those asserts either crash the test module at collection (Enum) or work; after this change they always work, at the cost of less verbose output when they fail.

Adds unit tests (class-body assert stays a plain ast.Assert node, including inside if blocks; method asserts still rewritten) and end-to-end pytester tests reproducing the exact Enum case from the issue, plus a two-asserts-per-body case covering the counter-reset trap.

@psf-chronographer psf-chronographer Bot added the bot:chronographer:provided (automation) changelog entry is part of PR label Aug 12, 2026
Assert rewriting breaks class-body asserts in namespaces that forbid
redefinition (e.g. Enum): the temporary-variable cleanup emits a second
assignment to the same @py_assertN name, raising TypeError. Per the class
execution namespace argument in the issue, skip rewriting asserts that
appear directly in a class body; asserts in methods keep full rewriting.

Signed-off-by: Alex Chen <l46983284@gmail.com>
@The-Compiler

Copy link
Copy Markdown
Member
image

...sigh.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:chronographer:provided (automation) changelog entry is part of PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Assert statements in Enum subclass definitions case errors when assertion rewriting is enabled

2 participants