Skip to content

Report one bad-context-manager error per broken with-item - #5095

Open
nitishagar wants to merge 1 commit into
facebook:mainfrom
nitishagar:fix/duplicate-bad-context-manager-5079
Open

nitishagar wants to merge 1 commit into
facebook:mainfrom
nitishagar:fix/duplicate-bad-context-manager-5079

Conversation

@nitishagar

Copy link
Copy Markdown
Contributor

Fixes #5079

Problem

A context manager that fails both protocol halves produced two bad-context-manager errors with an identical header and range:

from contextlib import asynccontextmanager

@asynccontextmanager
async def async_context():
    yield

with async_context():  # TWO identical errors appear here
    print("This will cause an error at runtime")

Both errors read "Cannot use _AsyncGeneratorContextManager[None] as a context manager"; they differ only in the detail line (__enter__ vs __exit__ missing). The error collector intentionally does not merge diagnostics whose details differ, so the pair always displayed.

Change

context_value checks the protocol in two halves (enter, exit), each attributing failures to the with-item's range under the shared bad-context-manager context. Each half's diagnostics are now collected in their own delayed collector, and only the first failing half's errors are forwarded:

  • enter broken → the enter error survives (it carries the actionable "Did you mean __aenter__?" hint, which is exactly the fix a user needs for the issue's case);
  • enter fine → exit errors forwarded byte-for-byte as before, including the existing two-call consolidation for bad __exit__ signatures;
  • the exit half is still fully evaluated so its return type keeps feeding the bool | None check.

An object failing only one half still yields exactly one error naming that half; async with on async context managers is unaffected.

Test plan

  • New testcase! reproducing the issue (async CM in sync with → exactly 1 error) — written first and verified failing ("expected 1 errors, but got 2") before the fix
  • Tests pinning the old two-error shape updated deliberately (with-item with 42 case + LSP diagnostics snapshot) — the PR changes that pinned shape, hence the edits
  • cargo test -p pyrefly --lib -- --skip test::lsp: 7741 passed, 0 failed (the two missing-source LSP interaction failures also fail on unmodified main)
  • Formatting and linting clean

A context manager that fails both protocol halves — most commonly an
`@asynccontextmanager` result used in a sync `with`, which has neither
`__enter__` nor `__exit__` — produced two `bad-context-manager` errors
with the same header and range, differing only in the detail line
(issue facebook#5079). The error collector deliberately does not merge errors
whose details differ, so the pair always displayed.

Collect each protocol half's diagnostics in its own delayed collector
inside `context_value` and forward only the first failing half's: when
the enter half fails, the enter error wins (it carries the actionable
"Did you mean `__aenter__`" hint); otherwise the exit half's errors are
forwarded exactly as before, including its two-call consolidation. The
exit half is still fully evaluated so its return type keeps feeding the
`bool | None` check. Tests that pinned the old two-error shape for `with
42` and in the LSP diagnostics snapshot are updated to the single-error
shape for the same reason.
@meta-cla meta-cla Bot added the cla signed label Oct 4, 2026
@github-actions github-actions Bot added the size/s label Oct 4, 2026
@meta-codesync

meta-codesync Bot commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

This pull request has been imported. If you are a Meta employee, you can view this in D123266669. (Because this pull request was imported automatically, there will not be any future comments.)

@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown

Diff from mypy_primer, showing the effect of this PR on open source code:

============================================================
SUMMARY
============================================================
Total: +0 new errors, -68 fixed errors
By preset: +0/-68 (default), +0/-68 (strict)

Projects with changes (6):
  prefect: +0 -2
  scikit-learn: +0 -60
  streamlit: +0 -2
  core: +0 -1
  xarray: +0 -1
  spack: +0 -2
============================================================

FULL DIFF DETAILS
------------------------------------------------------------

prefect (https://github.com/PrefectHQ/prefect)
- ERROR src/integrations/prefect-gcp/prefect_gcp/workers/cloud_run_v2.py:806:14-59: Cannot use `ResourceWarning` as a context manager [bad-context-manager]
- ERROR src/integrations/prefect-gcp/prefect_gcp/workers/cloud_run_v2.py:1417:14-45: Cannot use `ResourceWarning` as a context manager [bad-context-manager]

scikit-learn (https://github.com/scikit-learn/scikit-learn)
- ERROR sklearn/cluster/tests/test_hierarchical.py:110:14-31: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/cluster/tests/test_hierarchical.py:118:18-35: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/decomposition/tests/test_dict_learning.py:257:14-58: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/decomposition/tests/test_fastica.py:453:14-58: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/ensemble/tests/test_forest.py:1153:10-27: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/ensemble/tests/test_iforest.py:43:10-27: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/ensemble/tests/test_stacking.py:476:10-54: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/ensemble/tests/test_stacking.py:480:10-54: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/ensemble/tests/test_stacking.py:486:10-54: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/linear_model/tests/test_logistic.py:1167:10-54: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/linear_model/tests/test_logistic.py:1667:10-54: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/linear_model/tests/test_logistic.py:1700:10-54: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/linear_model/tests/test_logistic.py:1710:10-54: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/linear_model/tests/test_logistic.py:2637:10-54: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/linear_model/tests/test_logistic.py:2698:10-49: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/linear_model/tests/test_logistic.py:2709:10-49: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/metrics/tests/test_classification.py:3165:10-27: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/metrics/tests/test_common.py:843:10-27: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/metrics/tests/test_common.py:923:10-27: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/metrics/tests/test_common.py:1240:10-27: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/metrics/tests/test_common.py:1293:10-27: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/metrics/tests/test_dist_metrics.py:114:14-58: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/metrics/tests/test_dist_metrics.py:223:14-58: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/metrics/tests/test_pairwise.py:293:10-57: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/metrics/tests/test_score_objects.py:709:10-27: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/neural_network/tests/test_mlp.py:75:14-58: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/neural_network/tests/test_mlp.py:351:14-58: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/neural_network/tests/test_mlp.py:435:14-58: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/neural_network/tests/test_mlp.py:535:10-54: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/neural_network/tests/test_mlp.py:558:10-54: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/neural_network/tests/test_mlp.py:672:10-54: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/preprocessing/tests/test_discretization.py:89:10-47: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/svm/tests/test_sparse.py:499:10-54: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/svm/tests/test_sparse.py:502:10-54: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/tests/test_common.py:118:10-120:6: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/tests/test_common.py:262:14-55: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/tests/test_common.py:297:10-51: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/tests/test_common.py:354:14-55: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/tests/test_common.py:378:14-55: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/tests/test_docstring_parameters.py:312:14-53: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/tree/tests/test_tree.py:1619:10-27: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/utils/discovery.py:94:10-49: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/utils/discovery.py:176:10-49: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/utils/discovery.py:234:10-49: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/utils/estimator_checks.py:1660:10-49: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/utils/estimator_checks.py:1666:14-53: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/utils/estimator_checks.py:1690:18-57: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/utils/estimator_checks.py:2729:14-53: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/utils/estimator_checks.py:3030:10-49: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/utils/estimator_checks.py:4184:10-49: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/utils/tests/test_estimator_checks.py:936:14-58: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/utils/tests/test_estimator_checks.py:946:14-58: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/utils/tests/test_show_versions.py:16:10-27: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/utils/tests/test_show_versions.py:32:10-27: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/utils/tests/test_testing.py:146:14-31: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/utils/tests/test_testing.py:150:14-73: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/utils/tests/test_testing.py:154:14-58: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/utils/tests/test_testing.py:158:14-51: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/utils/tests/test_testing.py:162:14-58: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]
- ERROR sklearn/utils/tests/test_testing.py:166:14-51: Cannot use `(*args: Unknown, **kwargs: Unknown) -> Unknown` as a context manager [bad-context-manager]

streamlit (https://github.com/streamlit/streamlit)
- ERROR lib/tests/streamlit/components/v2/test_component_path_utils.py:233:10-48: Cannot use `object` as a context manager [bad-context-manager]
- ERROR lib/tests/streamlit/components/v2/test_component_path_utils.py:244:10-51: Cannot use `object` as a context manager [bad-context-manager]

core (https://github.com/home-assistant/core)
- ERROR homeassistant/components/nmap_tracker/__init__.py:291:20-35: Cannot use `None` as a context manager [bad-context-manager]

xarray (https://github.com/pydata/xarray)
- ERROR xarray/tests/test_distributed.py:310:14-18: Cannot use `None` as a context manager [bad-context-manager]

spack (https://github.com/spack/spack)
- ERROR lib/spack/spack/test/cmd/buildcache.py:1326:10-17: Cannot use `list[Unknown]` as a context manager [bad-context-manager]
- ERROR lib/spack/spack/test/cmd/buildcache.py:1351:10-17: Cannot use `list[Unknown]` as a context manager [bad-context-manager]

This branch has not been deployed

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: duplicate bad-context-manager error

2 participants