Skip to content

[ty] Improve keyword argument narrowing for nested dictionaries#24010

Merged
ibraheemdev merged 1 commit intomainfrom
ibraheem/dict-unpack-narrowing
Mar 20, 2026
Merged

[ty] Improve keyword argument narrowing for nested dictionaries#24010
ibraheemdev merged 1 commit intomainfrom
ibraheem/dict-unpack-narrowing

Conversation

@ibraheemdev
Copy link
Member

Fixes a bug in #23436 where nested dictionary literals are not tracked, e.g.,

def f(a: int, b: str): ...

x = {"inner": {"a": 1, "b": "a"}}
f(**x["inner"])

This is unlikely to have an ecosystem impact, but seems worth doing nonetheless.

@ibraheemdev ibraheemdev added the ty Multi-file analysis & type inference label Mar 17, 2026
@astral-sh-bot
Copy link

astral-sh-bot bot commented Mar 17, 2026

Typing conformance results

No changes detected ✅

Current numbers
The percentage of diagnostics emitted that were expected errors held steady at 85.29%. The percentage of expected errors that received a diagnostic held steady at 78.13%. The number of fully passing files held steady at 64/132.

@astral-sh-bot
Copy link

astral-sh-bot bot commented Mar 17, 2026

Memory usage report

Memory usage unchanged ✅

@astral-sh-bot
Copy link

astral-sh-bot bot commented Mar 17, 2026

ecosystem-analyzer results

Lint rule Added Removed Changed
invalid-await 0 40 0
invalid-return-type 0 1 0
Total 0 41 0

Full report with detailed diff (timing results)

Copy link
Contributor

@carljm carljm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change adds false negatives for direct assignments to nested keys:

def f(*, b: int): ...

x: dict[str, dict[str, int]] = {"a": {"b": 1}}
x["a"]["b"] = 1

# This should be an error: x has no top-level key "b".
f(**x)

This is correctly an error on main, but a false negative with this PR.

@ibraheemdev
Copy link
Member Author

@carljm that example seems to error correctly on this PR?

➜  sandbox git:(ibraheem/dict-unpack-narrowing) ✗ cargo run --bin ty --manifest-path ~/dev/astral/ruff/Cargo.toml check main.py
error[invalid-argument-type]: Argument to function `f` is incorrect
  --> main.py:23:3
   |
22 | # This should be an error: x has no top-level key "b".
23 | f(**x)
   |   ^^^ Expected `int`, found `dict[str, int]`
   |
info: Function defined here
  --> main.py:17:5
   |
15 | #         self.mylist = [None, None, None]
16 |
17 | def f(*, b: int): ...
   |     ^    ------ Parameter declared here
18 |
19 | x: dict[str, dict[str, int]] = {"a": {"b": 1}}
   |
info: rule `invalid-argument-type` is enabled by default

Found 1 diagnostic

Copy link
Contributor

@carljm carljm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Weird, sorry! I'm sure I tested that... not sure what I did wrong. Maybe I had an earlier branch checked out by accident. Never mind!

@ibraheemdev ibraheemdev merged commit b6f3b5c into main Mar 20, 2026
53 checks passed
@ibraheemdev ibraheemdev deleted the ibraheem/dict-unpack-narrowing branch March 20, 2026 11:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants