Skip to content

Fix ASYNC200 regression on foo("x").bar patterns (#26.4.2)#455

Merged
Zac-HD merged 3 commits intopython-trio:mainfrom
Zac-HD:claude/fix-async200-regression-QK6lA
May 1, 2026
Merged

Fix ASYNC200 regression on foo("x").bar patterns (#26.4.2)#455
Zac-HD merged 3 commits intopython-trio:mainfrom
Zac-HD:claude/fix-async200-regression-QK6lA

Conversation

@Zac-HD
Copy link
Copy Markdown
Member

@Zac-HD Zac-HD commented May 1, 2026

The canonical-qualname resolver introduced in 26.4.1 recursed through ast.Call/cst.Call unconditionally, which collapsed nested calls inside an attribute chain into a dotted name (e.g. read_session("a").get resolved to read_session.get). This caused user-configured ASYNC200 patterns like *session.get to flag method calls on the return value of an unrelated function -- a false positive that did not exist in 25.5.3.

Only unwrap Call at the outermost position; calls inside an attribute chain now make the whole expression unresolvable (None), since the target of the trailing attribute is a return value we can't determine statically. Top-level shapes like trio.open_nursery() still resolve as before.

Adds:

  • eval-file regression case in tests/eval_files/async200.py
  • direct unit test for resolve_canonical_ast / resolve_canonical_cst
  • changelog entry for 26.4.2 and version bump

https://claude.ai/code/session_01BWheK2fZPMDhbfS1LCR2zc

claude and others added 3 commits April 30, 2026 21:22
The canonical-qualname resolver introduced in 26.4.1 recursed through
ast.Call/cst.Call unconditionally, which collapsed nested calls inside an
attribute chain into a dotted name (e.g. `read_session("a").get` resolved
to `read_session.get`). This caused user-configured ASYNC200 patterns
like `*session.get` to flag method calls on the return value of an
unrelated function -- a false positive that did not exist in 25.5.3.

Only unwrap Call at the outermost position; calls inside an attribute
chain now make the whole expression unresolvable (None), since the
target of the trailing attribute is a return value we can't determine
statically. Top-level shapes like `trio.open_nursery()` still resolve
as before.

Adds:
  - eval-file regression case in tests/eval_files/async200.py
  - direct unit test for resolve_canonical_ast / resolve_canonical_cst
  - changelog entry for 26.4.2 and version bump

https://claude.ai/code/session_01BWheK2fZPMDhbfS1LCR2zc
- Move `resolve_canonical_ast` / `resolve_canonical_cst` import to the top
  of tests/test_flake8_async.py (ruff PLC0415 / import-not-at-top).
- Black reformat of `_resolve_attr_chain_ast` signature.

https://claude.ai/code/session_01BWheK2fZPMDhbfS1LCR2zc
@Zac-HD Zac-HD merged commit 6a885cd into python-trio:main May 1, 2026
10 checks passed
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