Skip to content

[ty] Improve support for Callable type context#23888

Merged
ibraheemdev merged 1 commit intomainfrom
ibraheem/callable-tcx
Mar 27, 2026
Merged

[ty] Improve support for Callable type context#23888
ibraheemdev merged 1 commit intomainfrom
ibraheem/callable-tcx

Conversation

@ibraheemdev
Copy link
Copy Markdown
Member

Improves literal promotion and generic call inference that involve Callable type context. Resolves astral-sh/ty#3016.

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

astral-sh-bot bot commented Mar 11, 2026

Typing conformance results

No changes detected ✅

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

@astral-sh-bot
Copy link
Copy Markdown

astral-sh-bot bot commented Mar 11, 2026

mypy_primer results

Changes were detected when running on open source projects
attrs (https://github.com/python-attrs/attrs)
- tests/test_validators.py:787:21: error[invalid-argument-type] Argument to function `and_` is incorrect: Expected `(Any, Attribute[int], int, /) -> Any`, found `(Any, Attribute[Literal[10]], Literal[10], /) -> Any`
- Found 671 diagnostics
+ Found 670 diagnostics

@astral-sh-bot
Copy link
Copy Markdown

astral-sh-bot bot commented Mar 11, 2026

Memory usage report

Summary

Project Old New Diff Outcome
prefect 715.67MB 715.66MB -0.00% (5.79kB) ⬇️
trio 117.78MB 117.76MB -0.01% (15.23kB) ⬇️
flake8 48.04MB 48.03MB -0.03% (15.54kB) ⬇️
sphinx 264.89MB 264.83MB -0.02% (62.07kB) ⬇️

Significant changes

Click to expand detailed breakdown

prefect

Name Old New Diff Outcome
infer_expression_types_impl 61.73MB 61.76MB +0.04% (25.12kB) ⬇️
infer_definition_types 88.69MB 88.72MB +0.03% (22.84kB) ⬇️
infer_expression_type_impl 13.80MB 13.82MB +0.08% (11.98kB) ⬇️
FunctionType 8.69MB 8.68MB -0.11% (9.48kB) ⬇️
Type<'db>::class_member_with_policy_ 17.72MB 17.71MB -0.05% (9.42kB) ⬇️
StaticClassLiteral<'db>::try_mro_ 5.87MB 5.86MB -0.15% (9.14kB) ⬇️
CallableType 2.09MB 2.08MB -0.40% (8.44kB) ⬇️
cached_protocol_interface 413.43kB 405.62kB -1.89% (7.80kB) ⬇️
Type<'db>::apply_specialization_ 3.59MB 3.59MB -0.21% (7.68kB) ⬇️
Type<'db>::expand_eagerly__::interned_arguments 1008.00B 8.44kB +757.14% (7.45kB) ⬇️
Type<'db>::expand_eagerly__ 964.00B 7.64kB +711.62% (6.70kB) ⬇️
StaticClassLiteral<'db>::implicit_attribute_inner_ 9.93MB 9.93MB +0.06% (5.62kB) ⬇️
Type<'db>::apply_specialization_::interned_arguments 2.88MB 2.88MB -0.19% (5.47kB) ⬇️
Type<'db>::member_lookup_with_policy_ 16.19MB 16.19MB -0.03% (4.52kB) ⬇️
FunctionType<'db>::signature_ 3.99MB 3.98MB -0.11% (4.50kB) ⬇️
... 34 more

trio

Name Old New Diff Outcome
FunctionType<'db>::last_definition_signature_ 237.70kB 241.23kB +1.49% (3.54kB) ⬇️
Type<'db>::expand_eagerly__ 364.00B 3.47kB +875.82% (3.11kB) ⬇️
Type<'db>::expand_eagerly__::interned_arguments 360.00B 3.16kB +800.00% (2.81kB) ⬇️
StaticClassLiteral<'db>::try_mro_ 825.29kB 822.56kB -0.33% (2.73kB) ⬇️
FunctionType 1.48MB 1.49MB +0.17% (2.53kB) ⬇️
infer_expression_type_impl 1.32MB 1.32MB -0.18% (2.50kB) ⬇️
CallableType 582.28kB 580.03kB -0.39% (2.25kB) ⬇️
Type<'db>::class_member_with_policy_ 2.00MB 2.00MB -0.11% (2.20kB) ⬇️
Type<'db>::apply_specialization_ 730.12kB 728.00kB -0.29% (2.12kB) ⬇️
Type<'db>::member_lookup_with_policy_ 1.81MB 1.81MB -0.11% (2.11kB) ⬇️
Type<'db>::try_call_dunder_get_ 1.37MB 1.37MB -0.15% (2.04kB) ⬇️
cached_protocol_interface 129.32kB 127.61kB -1.32% (1.71kB) ⬇️
Type<'db>::class_member_with_policy_::interned_arguments 1.11MB 1.11MB -0.14% (1.62kB) ⬇️
FunctionType<'db>::signature_ 1.07MB 1.06MB -0.14% (1.56kB) ⬇️
Type<'db>::apply_specialization_::interned_arguments 641.80kB 640.31kB -0.23% (1.48kB) ⬇️
... 25 more

flake8

Name Old New Diff Outcome
CallableType 168.40kB 166.36kB -1.21% (2.04kB) ⬇️
FunctionType 436.50kB 434.56kB -0.44% (1.94kB) ⬇️
Type<'db>::expand_eagerly__ 124.00B 1.97kB +1529.03% (1.85kB) ⬇️
Type<'db>::expand_eagerly__::interned_arguments 144.00B 1.83kB +1200.00% (1.69kB) ⬇️
Type<'db>::try_call_dunder_get_ 376.75kB 375.18kB -0.42% (1.57kB) ⬇️
infer_scope_types_impl 998.78kB 997.41kB -0.14% (1.37kB) ⬇️
Type<'db>::class_member_with_policy_ 569.98kB 568.68kB -0.23% (1.30kB) ⬇️
StaticClassLiteral<'db>::try_mro_ 322.69kB 321.39kB -0.40% (1.30kB) ⬇️
Type<'db>::member_lookup_with_policy_ 488.42kB 487.16kB -0.26% (1.27kB) ⬇️
FunctionType<'db>::signature_ 359.20kB 358.15kB -0.29% (1.05kB) ⬇️
Type<'db>::apply_specialization_ 216.65kB 215.68kB -0.45% (988.00B) ⬇️
Type<'db>::class_member_with_policy_::interned_arguments 307.33kB 306.41kB -0.30% (936.00B) ⬇️
infer_definition_types 1.82MB 1.82MB +0.04% (828.00B) ⬇️
cached_protocol_interface 43.63kB 42.93kB -1.61% (720.00B) ⬇️
Type<'db>::apply_specialization_::interned_arguments 203.12kB 202.50kB -0.31% (640.00B) ⬇️
... 20 more

sphinx

Name Old New Diff Outcome
Type<'db>::class_member_with_policy_ 7.63MB 7.62MB -0.13% (9.92kB) ⬇️
FunctionType 3.10MB 3.10MB -0.23% (7.19kB) ⬇️
CallableType 1.10MB 1.10MB -0.62% (7.03kB) ⬇️
Type<'db>::member_lookup_with_policy_ 6.51MB 6.51MB -0.11% (7.02kB) ⬇️
StaticClassLiteral<'db>::try_mro_ 2.07MB 2.06MB -0.30% (6.28kB) ⬇️
infer_expression_types_impl 21.47MB 21.48MB +0.02% (4.75kB) ⬇️
Type<'db>::try_call_dunder_get_ 4.96MB 4.95MB -0.09% (4.46kB) ⬇️
Type<'db>::class_member_with_policy_::interned_arguments 4.02MB 4.01MB -0.10% (4.16kB) ⬇️
FunctionType<'db>::signature_ 2.26MB 2.26MB -0.17% (3.91kB) ⬇️
Type<'db>::expand_eagerly__::interned_arguments 5.84kB 9.63kB +65.06% (3.80kB) ⬇️
Type<'db>::expand_eagerly__ 11.86kB 15.08kB +27.17% (3.22kB) ⬇️
Type<'db>::apply_specialization_ 1.64MB 1.64MB -0.16% (2.72kB) ⬇️
infer_scope_types_impl 15.50MB 15.49MB -0.02% (2.53kB) ⬇️
code_generator_of_static_class 530.48kB 528.07kB -0.45% (2.41kB) ⬇️
cached_protocol_interface 187.49kB 185.38kB -1.13% (2.11kB) ⬇️
... 25 more

@astral-sh-bot
Copy link
Copy Markdown

astral-sh-bot bot commented Mar 11, 2026

ecosystem-analyzer results

Lint rule Added Removed Changed
invalid-await 0 40 0
invalid-argument-type 0 1 0
invalid-assignment 0 1 0
invalid-return-type 0 1 0
unused-ignore-comment 1 0 0
Total 1 43 0

Changes in flaky projects detected. Raw diff output excludes flaky projects; see the HTML report for details.

Raw diff:

Expression (https://github.com/cognitedata/Expression)
- tests/test_compose.py:21:16 error[invalid-assignment] Object of type `(Never, /) -> Never` is not assignable to `(int, /) -> int`

attrs (https://github.com/python-attrs/attrs)
+ typing-examples/baseline.py:101:74 warning[unused-ignore-comment] Unused `ty: ignore` directive
- tests/test_validators.py:807:21 error[invalid-argument-type] Argument to function `and_` is incorrect: Expected `(Any, Attribute[int], int, /) -> Any`, found `(Any, Attribute[Literal[10]], Literal[10], /) -> Any`

Full report with detailed diff (timing results)

@ibraheemdev ibraheemdev force-pushed the ibraheem/callable-tcx branch from b229936 to 7c2c8ee Compare March 11, 2026 13:07
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Mar 11, 2026

Merging this PR will not alter performance

✅ 28 untouched benchmarks
⏩ 30 skipped benchmarks1


Comparing ibraheem/callable-tcx (cd669df) with main (30e8e1c)

Open in CodSpeed

Footnotes

  1. 30 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

carljm
carljm previously requested changes Mar 14, 2026
Copy link
Copy Markdown
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.

Left a few comments. @dcreager I'm wondering if you'd be a better reviewer here, as you'd be better equipped to catch if this is doing anything that will cause trouble down the line for the new constraint solver.

@carljm carljm assigned dcreager and unassigned carljm Mar 14, 2026
@ibraheemdev ibraheemdev force-pushed the ibraheem/callable-tcx branch 3 times, most recently from 3c8c523 to 2b4e381 Compare March 17, 2026 07:02
@carljm carljm dismissed their stale review March 17, 2026 18:46

addressed

@ibraheemdev ibraheemdev force-pushed the ibraheem/callable-tcx branch from 2b4e381 to cd669df Compare March 27, 2026 21:15
Comment on lines +1909 to +1912
for (typevar, ty) in iter::zip(
specialization.generic_context(db).variables(db),
specialization.types(db),
) {
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 could've sworn we had a helper method for this, since it seems like a common thing to grab from a Specialization. But it seems we don't!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think I added this at some point in a PR that was never merged... I'll add it in a followup.

/// This is the case for any type which may contain types in non-covariant position within it,
/// e.g., nominal instances of a generic class, or callables.
pub(crate) fn may_prefer_declared_type(self, db: &'db dyn Db) -> bool {
self.class_specialization(db).is_some() || self.expand_eagerly(db).is_callable_type()
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.

Does this need to verify that the nominal class has any non-covariant typevars in its generic context? Given all of the uses of "may" it seems like it's okay for this to return true even if there aren't actually any non-covariant typevars. So this is just used as an optimization for known-no cases.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yup, this just an optimization that allows us to ignore the type context if it returns false.

@ibraheemdev ibraheemdev merged commit 6e76b4c into main Mar 27, 2026
49 checks passed
@ibraheemdev ibraheemdev deleted the ibraheem/callable-tcx branch March 27, 2026 21:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ecosystem-analyzer ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Promote literals in contravariant position, not just invariant

3 participants