Skip to content

[ty] A configuration setting for isinstance narrowing#26360

Draft
sharkdp wants to merge 3 commits into
mainfrom
david/isinstance-mode
Draft

[ty] A configuration setting for isinstance narrowing#26360
sharkdp wants to merge 3 commits into
mainfrom
david/isinstance-mode

Conversation

@sharkdp

@sharkdp sharkdp commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Test Plan

@sharkdp sharkdp added the ty Multi-file analysis & type inference label Jun 25, 2026
@astral-sh-bot

astral-sh-bot Bot commented Jun 25, 2026

Copy link
Copy Markdown

Typing conformance results

No changes detected ✅

Current numbers
The percentage of diagnostics emitted that were expected errors held steady at 94.47%. The percentage of expected errors that received a diagnostic held steady at 89.19%. The number of fully passing files held steady at 95/134.

@astral-sh-bot

astral-sh-bot Bot commented Jun 25, 2026

Copy link
Copy Markdown

Memory usage report

Summary

Project Old New Diff Outcome
prefect 448.05MB 448.07MB +0.00% (18.68kB)
sphinx 166.58MB 166.59MB +0.00% (7.46kB)
trio 70.26MB 70.26MB +0.00% (2.40kB)
flake8 28.94MB 28.94MB +0.00% (176.00B)

Significant changes

Click to expand detailed breakdown

prefect

Name Old New Diff Outcome
all_narrowing_constraints_for_expression 5.19MB 5.20MB +0.30% (15.91kB)
infer_expression_types_impl 37.77MB 37.77MB +0.00% (1.28kB)
infer_definition_types 49.91MB 49.91MB +0.00% (712.00B)
analyze_non_terminal_call 1.77MB 1.77MB +0.01% (192.00B)
member_lookup_with_policy_inner 10.21MB 10.21MB +0.00% (136.00B)
infer_expression_type_impl 219.20kB 219.33kB +0.06% (128.00B)
infer_scope_types_impl 30.11MB 30.11MB +0.00% (112.00B)
StaticClassLiteral<'db>::implicit_attribute_inner_ 810.38kB 810.47kB +0.01% (96.00B)
loop_header_reachability 251.37kB 251.41kB +0.02% (40.00B)
infer_unpack_types 631.55kB 631.59kB +0.01% (40.00B)
infer_statement_types_impl 812.33kB 812.37kB +0.00% (40.00B)
Project 34.74kB 34.78kB +0.09% (32.00B)

sphinx

Name Old New Diff Outcome
all_narrowing_constraints_for_expression 1.93MB 1.93MB +0.29% (5.80kB)
infer_expression_types_impl 14.77MB 14.77MB +0.01% (832.00B)
infer_definition_types 13.67MB 13.67MB +0.00% (568.00B)
infer_statement_types_impl 482.02kB 482.10kB +0.02% (88.00B)
loop_header_reachability 228.66kB 228.72kB +0.03% (64.00B)
analyze_non_terminal_call 662.77kB 662.83kB +0.01% (56.00B)
Project 13.74kB 13.78kB +0.23% (32.00B)
infer_unpack_types 305.88kB 305.91kB +0.01% (32.00B)
member_lookup_with_policy_inner 4.28MB 4.28MB +0.00% (8.00B)
StaticClassLiteral<'db>::implicit_attribute_inner_ 605.77kB 605.77kB +0.00% (8.00B)
infer_expression_type_impl 223.74kB 223.75kB +0.00% (8.00B)
infer_scope_types_impl 8.10MB 8.10MB +0.00% (8.00B)

trio

Name Old New Diff Outcome
all_narrowing_constraints_for_expression 457.70kB 459.45kB +0.38% (1.75kB)
infer_expression_types_impl 4.37MB 4.37MB +0.01% (352.00B)
infer_definition_types 3.96MB 3.96MB +0.00% (128.00B)
analyze_non_terminal_call 376.73kB 376.83kB +0.02% (96.00B)
Project 8.49kB 8.53kB +0.37% (32.00B)
infer_scope_types_impl 2.40MB 2.40MB +0.00% (16.00B)
loop_header_reachability 71.16kB 71.17kB +0.01% (8.00B)
member_lookup_with_policy_inner 1.03MB 1.03MB +0.00% (8.00B)
StaticClassLiteral<'db>::implicit_attribute_inner_ 93.97kB 93.98kB +0.01% (8.00B)
infer_expression_type_impl 37.85kB 37.86kB +0.02% (8.00B)
infer_statement_types_impl 34.34kB 34.35kB +0.02% (8.00B)

flake8

Name Old New Diff Outcome
all_narrowing_constraints_for_expression 71.97kB 72.11kB +0.20% (144.00B)
Project 7.62kB 7.65kB +0.41% (32.00B)

@astral-sh-bot

astral-sh-bot Bot commented Jun 25, 2026

Copy link
Copy Markdown

ecosystem-analyzer results

No diagnostic changes detected ✅

Flaky changes detected. This PR summary excludes flaky changes; see the HTML report for details.

Full report with detailed diff (timing results)

/// Configures semantic type inference behavior.
#[serde(skip_serializing_if = "Option::is_none")]
#[option_group]
pub semantics: Option<SemanticsOptions>,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd have expected the setting to be part of AnalysisOptions, or maybe a sub table in there. What was your reasoning for moving it into a separate section (sorry for commenting while draft, you don't have to answer right away, I just felt worth bringing this up)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

So for, I spent zero time on thinking about the placement of this new option. I just wanted something available for me to play with (and write mdtests that can switch the setting). But thanks for bringing it up, will keep that in mind when we actually choose to add this option!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Sounds good. I'd have to check on AnalysisOptions. I think one key question will be is whether this option can be at a per file level using overrides (I don't remember whether we allow this for some analysis options or not)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

whether this option can be at a per file level

Oh, right, that is important! Pretty sure we want a semantic change like the one proposed here to apply globally, and not per-file.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Mypy actually often allows these kinds of settings to be applied per-file, which can be very useful if you're looking to transition your project from very lax settings (when you've only just started using a type checker) to stricter settings, and you want to do so incrementally. A strategy I've used in the past to successfully add mypy --strict to a project is to start with mypy's strict-optional setting being disabled for several files, and then gradually work down the list of files that have it disabled in following PRs.

@sharkdp sharkdp Jun 26, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

My thinking was that this could lead to inconsistencies? Now that I think about it more, I'm not sure how that would look exactly for a setting like this, but I imagine it could be strange that importing symbol A, and then narrowing it with isinstance(...) might lead to a different result than importing A*, a version of A that was narrowed from A in the exporting module (which seems unlikely, but is possible).

for x in xs:
reveal_type(x) # revealed: Item
else:
reveal_type(xs) # revealed: Item | (list[Item] & ~list[Unknown])

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The second union element here is problematic...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think we need to "simplify" this to list[Item] & ~Bottom[list[Unknown]] & Any such that we can easily recognize that it has a bottom materialization of Never, which will make it cause much fewer (no?) false positives.

@sharkdp sharkdp force-pushed the david/isinstance-mode branch from ecaf875 to 7d7972e Compare June 25, 2026 15:46
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.

3 participants