Skip to content

[pyrefly] Contextualize dict subscript literals for Any - #4391

Open
lyydsheep wants to merge 1 commit into
facebook:mainfrom
lyydsheep:codex/issue-4301-contextual-dict-subscript
Open

[pyrefly] Contextualize dict subscript literals for Any#4391
lyydsheep wants to merge 1 commit into
facebook:mainfrom
lyydsheep:codex/issue-4301-contextual-dict-subscript

Conversation

@lyydsheep

Copy link
Copy Markdown
Contributor

Fixes #4301

A dict literal assigned through an explicitly annotated dict[str, Any] subscript now receives a soft value hint, avoiding a spurious implicit-any-empty-container diagnostic. Unannotated and narrow dictionary targets retain their existing diagnostics and inference behavior.

Validation:

  • cargo test -p pyrefly test::inference::test_implicit_any
  • cargo test -p pyrefly test::dict
  • python3 test.py --no-test --no-tensor-shapes --no-conformance --no-jsonschema

The local .scratch planning files are intentionally not part of this PR.

@meta-cla meta-cla Bot added the cla signed label Aug 1, 2026
@github-actions github-actions Bot added the size/s label Aug 1, 2026
@meta-codesync

meta-codesync Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

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

@IBlackVoid

Copy link
Copy Markdown
Contributor

Heads up rather than having this show up unannounced — I opened #4409 with a more general take on the same bug. You got here first, and I'd rather flag it than surprise you.

Same idea, but keyed on whether the placeholder can escape rather than on the target's shape, which turned out to matter more than I expected. Measured, both patches applied to the same base and run on the same inputs:

case main #4391 #4409
dict[str, Any] (the report) error fixed fixed
dict[int, Any] error error fixed
MutableMapping[str, Any] error error fixed
defaultdict[str, Any] error error fixed
list[Any] error error fixed
hand-written __setitem__ error error fixed
x = {} then x["y"] = {...} error error error

The key-type condition in the qname match is what narrows yours: the key has nothing to do with whether the value is Any, so dict[int, Any] gets missed. Real code hits this — test_configparser.py does cf["A"] = {} where cf is a MutableMapping, not a builtins.dict.

Digging further also turned up a second root cause behind the same diagnostic: checking against Any never pins the placeholder either, which produces the identical false positive on attribute assignment, return position, default arguments and TypedDict fields.

Genuinely happy to fold this into your PR instead of landing it separately if you'd prefer — the analysis is the part I care about, not whose branch it goes in on.

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

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

tornado (https://github.com/tornadoweb/tornado)
- ERROR tornado/options.py:134:37-39: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR tornado/options.py:505:39-41: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]

cloud-init (https://github.com/canonical/cloud-init)
- ERROR cloudinit/sources/DataSourceIBMCloud.py:398:27-29: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]

rotki (https://github.com/rotki/rotki)
- ERROR rotkehlchen/chain/balances.py:233:54-56: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR rotkehlchen/chain/ethereum/modules/liquity/statistics.py:205:32-34: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]

prefect (https://github.com/PrefectHQ/prefect)
- ERROR src/integrations/prefect-kubernetes/prefect_kubernetes/worker.py:311:40-42: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR src/prefect/_internal/result_records.py:179:37-39: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR src/prefect/cli/deploy/_config.py:248:46-48: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR src/prefect/cli/deploy/_config.py:286:47-49: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]

colour (https://github.com/colour-science/colour)
- ERROR colour/plotting/colorimetry.py:689:33-35: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]

scikit-learn (https://github.com/scikit-learn/scikit-learn)
- ERROR sklearn/utils/_bunch.py:34:56-58: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]

materialize (https://github.com/MaterializeInc/materialize)
- ERROR misc/python/materialize/workload_replay/executor.py:155:40-42: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]

freqtrade (https://github.com/freqtrade/freqtrade)
- ERROR freqtrade/commands/list_commands.py:175:39-41: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR freqtrade/commands/list_commands.py:178:35-37: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR freqtrade/configuration/config_validation.py:305:37-39: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR freqtrade/configuration/config_validation.py:315:36-38: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR freqtrade/loggers/__init__.py:91:33-35: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]

comtypes (https://github.com/enthought/comtypes)
- ERROR comtypes/client/dynamic.py:72:33-35: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR comtypes/client/lazybind.py:95:35-37: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]

schemathesis (https://github.com/schemathesis/schemathesis)
- ERROR src/schemathesis/specs/openapi/_hypothesis.py:1163:25-27: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]

streamlit (https://github.com/streamlit/streamlit)
- ERROR lib/streamlit/config_util.py:482:48-50: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR scripts/sync_vscode_devcontainer.py:151:53-55: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]

strawberry (https://github.com/strawberry-graphql/strawberry)
- ERROR strawberry/cli/commands/upgrade/_run_codemod.py:41:40-42: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR strawberry/cli/commands/upgrade/_run_codemod.py:44:49-51: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR strawberry/cli/commands/upgrade/_run_codemod.py:45:45-47: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]

zulip (https://github.com/zulip/zulip)
- ERROR zerver/data_import/mattermost.py:1013:48-50: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR zerver/data_import/mattermost.py:1013:67-69: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR zerver/data_import/mattermost.py:1032:64-68: The type of this argument is unknown [unknown-argument-type]
- ERROR zerver/data_import/mattermost.py:1034:63-81: The type of this argument is unknown [unknown-argument-type]
- ERROR zerver/data_import/rocketchat.py:1043:48-50: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR zerver/data_import/rocketchat.py:1043:60-62: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR zerver/data_import/rocketchat.py:1043:73-75: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR zerver/data_import/rocketchat.py:1047:12-47: Implicit conversion of `list[Unknown]` to `bool` is not allowed [implicit-bool]
- ERROR zerver/data_import/rocketchat.py:1068:53-55: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR zerver/data_import/rocketchat.py:1068:65-67: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR zerver/data_import/rocketchat.py:1068:78-80: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR zerver/data_import/rocketchat.py:1076:12-52: Implicit conversion of `list[Unknown]` to `bool` is not allowed [implicit-bool]
- ERROR zerver/lib/events.py:381:34-36: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR zerver/lib/events.py:656:49-51: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR zerver/lib/events.py:700:34-36: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR zerver/lib/events.py:916:34-36: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]

hydpy (https://github.com/hydpy-dev/hydpy)
- ERROR hydpy/core/propertytools.py:36:52-54: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]

dd-trace-py (https://github.com/DataDog/dd-trace-py)
- ERROR ddtrace/_trace/trace_handlers.py:1134:28-30: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR ddtrace/contrib/internal/ray/core/utils.py:78:28-30: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]

pandas (https://github.com/pandas-dev/pandas)
- ERROR pandas/core/arrays/arrow/array.py:1064:27-29: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]

core (https://github.com/home-assistant/core)
- ERROR homeassistant/components/device_automation/__init__.py:195:34-36: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
+ ERROR homeassistant/components/fronius/diagnostics.py:26:9-42: The type of this argument is unknown [unknown-argument-type]
- ERROR homeassistant/components/fronius/diagnostics.py:24:42-44: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR homeassistant/components/fronius/diagnostics.py:29:9-84: `dict[str, dict[str, Any]] | None` is not assignable to dict key `logger` with type `dict[Unknown, Unknown]` [bad-assignment]
- ERROR homeassistant/components/fronius/diagnostics.py:32:9-82: `dict[str, dict[str, Any]] | None` is not assignable to dict key `meter` with type `dict[Unknown, Unknown]` [bad-assignment]
- ERROR homeassistant/components/fronius/diagnostics.py:35:9-88: `dict[str, dict[str, Any]] | None` is not assignable to dict key `ohmpilot` with type `dict[Unknown, Unknown]` [bad-assignment]
- ERROR homeassistant/components/fronius/diagnostics.py:38:9-40:18: `dict[str, dict[str, Any]] | None` is not assignable to dict key `power_flow` with type `dict[Unknown, Unknown]` [bad-assignment]
- ERROR homeassistant/components/fronius/diagnostics.py:43:9-86: `dict[str, dict[str, Any]] | None` is not assignable to dict key `storage` with type `dict[Unknown, Unknown]` [bad-assignment]
- ERROR homeassistant/components/github/diagnostics.py:37:28-30: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR homeassistant/components/hive/__init__.py:33:30-32: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR homeassistant/components/ios/__init__.py:262:32-34: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR homeassistant/components/mqtt/config_flow.py:4552:54-56: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR homeassistant/components/mqtt/config_flow.py:4562:53-55: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR homeassistant/components/mqtt/config_flow.py:5199:37-39: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR homeassistant/components/nest/config_flow.py:173:32-34: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR homeassistant/components/radarr/helpers.py:49:28-30: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR homeassistant/components/recorder/core.py:1426:54-74: `dict[Unknown, Unknown]` is not assignable to dict key `conv` with type `str` [bad-assignment]
- ERROR homeassistant/components/scrape/__init__.py:246:44-46: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR homeassistant/components/scrape/__init__.py:247:50-52: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR homeassistant/components/sonarr/helpers.py:70:28-30: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR homeassistant/components/sql/__init__.py:123:48-50: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR homeassistant/helpers/entity_registry.py:955:56-60: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]

dedupe (https://github.com/dedupeio/dedupe)
- ERROR dedupe/predicates.py:140:27-29: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]
- ERROR dedupe/predicates.py:142:31-33: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]

spack (https://github.com/spack/spack)
+ ERROR lib/spack/spack/ci/gitlab.py:449:25-29: The type of this argument is unknown [unknown-argument-type]
+ ERROR lib/spack/spack/ci/gitlab.py:449:61-64: The type of this argument is unknown [unknown-argument-type]
- ERROR lib/spack/spack/spec.py:2452:44-89: `str` is not assignable to dict key `compiler` with type `int` [bad-assignment]

poetry (https://github.com/python-poetry/poetry)
- ERROR src/poetry/packages/locker.py:643:30-32: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]

PyGithub (https://github.com/PyGithub/PyGithub)
- ERROR github/Branch.py:257:64-66: Cannot infer type of empty container; it will be treated as containing `Any` [implicit-any-empty-container]

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.

implicit-any-empty-container false positive when assigning dict containing None to dict[str, Any]

3 participants