Skip to content

Add RegularCallableTypeOf and into_regular_callable in ty_extensions#23909

Merged
dhruvmanila merged 8 commits intomainfrom
dhruv/callable-type-of-regression
Mar 13, 2026
Merged

Add RegularCallableTypeOf and into_regular_callable in ty_extensions#23909
dhruvmanila merged 8 commits intomainfrom
dhruv/callable-type-of-regression

Conversation

@dhruvmanila
Copy link
Member

Summary

fixes: astral-sh/ty#3020

Test Plan

Add a regression test case that currently fails on main.

@dhruvmanila dhruvmanila added the testing Related to testing Ruff itself label Mar 12, 2026
@dhruvmanila dhruvmanila added the ty Multi-file analysis & type inference label Mar 12, 2026
@astral-sh-bot astral-sh-bot bot requested a review from oconnor663 March 12, 2026 05:31
@astral-sh-bot
Copy link

astral-sh-bot bot commented Mar 12, 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 12, 2026

mypy_primer results

Changes were detected when running on open source projects
scikit-build-core (https://github.com/scikit-build/scikit-build-core)
+ src/scikit_build_core/build/wheel.py:99:20: error[no-matching-overload] No overload of bound method `__init__` matches arguments
- Found 59 diagnostics
+ Found 60 diagnostics

@astral-sh-bot
Copy link

astral-sh-bot bot commented Mar 12, 2026

Memory usage report

Memory usage unchanged ✅

@dhruvmanila
Copy link
Member Author

Oh, of course this would mean that the test cases that is relying on this behavior would fail 🤦

@dhruvmanila dhruvmanila marked this pull request as draft March 12, 2026 05:41
@dhruvmanila dhruvmanila changed the title Update CallableTypeOf to always use Regular callable type kind Add RegularCallableTypeOf and into_regular_type in ty_extensions Mar 12, 2026
@dhruvmanila
Copy link
Member Author

There are some things to do:

  • Change all existing references to use these "regular" variants except for the few that actually requires using the existing variants
  • Add documentation to explain the difference between these two variants

But, I'm opening this up for feedback (and name bike shedding ;)) before I make those large changes.

@dhruvmanila dhruvmanila marked this pull request as ready for review March 12, 2026 11:48
Comment on lines +16 to +21
def f(a: int, b: str, /) -> None: ...

static_assert(is_assignable_to(Callable[[int, str], None], RegularCallableTypeOf[f]))
static_assert(is_subtype_of(Callable[[int, str], None], RegularCallableTypeOf[f]))
static_assert(is_assignable_to(Callable[[int, str], None], TypeOf[into_regular_callable(f)]))
static_assert(is_subtype_of(Callable[[int, str], None], TypeOf[into_regular_callable(f)]))
Copy link
Member

Choose a reason for hiding this comment

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

I guess another solution would be to use a callback protocol for these kinds of assertions? This protocol:

class Foo(Protocol):
    def __call__(self, *, x: int): ...

is equivalent to this type:

def func(*, x: int): ...

type Foo = RegularCallableTypeOf[func]

and then we don't need another special form. But the disadvantage of that is that we're relying on our Protocol subtyping/assignability checks being correct, and there are some complications there. So it's probably better to go with what you have right now.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, definitely! I think on a long-term horizon Protocol is the way to go here and then we can remove these variants.

Relatedly, I've been using Protocol to do these relation checks locally sometimes and I haven't faced any issues yet :)

Copy link
Member Author

Choose a reason for hiding this comment

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

@AlexWaygood AlexWaygood changed the title Add RegularCallableTypeOf and into_regular_type in ty_extensions Add RegularCallableTypeOf and into_regular_callable in ty_extensions Mar 12, 2026
@charliermarsh
Copy link
Member

Superficially this reminds me a bit of astral-sh/ty#1452 / #23560

@dhruvmanila dhruvmanila force-pushed the dhruv/callable-type-of-regression branch from 4c85833 to 7592954 Compare March 12, 2026 16:04
@dhruvmanila
Copy link
Member Author

(Going to look at the replacement again tomorrow morning to make sure they're all correct and then merge.)

@carljm carljm removed their request for review March 13, 2026 01:18
@dhruvmanila
Copy link
Member Author

So, the convention is to always use the regular variants unless you explicitly wants to test against the function-like behavior of the callable.

Another convention would've been to always use the regular variants when you're checking a relation between two callables except in cases where you want to check the relation which involves at least one function-like callable, and use non-regular variant in other tests.

I'm going with the former in this PR.

@dhruvmanila dhruvmanila merged commit ce8f75f into main Mar 13, 2026
51 checks passed
@dhruvmanila dhruvmanila deleted the dhruv/callable-type-of-regression branch March 13, 2026 03:56
carljm added a commit that referenced this pull request Mar 13, 2026
* main: (94 commits)
  Fix shell injection via `shell=True` in subprocess calls (#23894)
  [ty] Refactor `relation.rs` to store state on a struct rather than passing around 7 arguments every time we recurse (#23837)
  Don't return code actions for non-Python documents (#23905)
  [ty] Make the default database truly statically infallible (#23929)
  [ty] Add `Download` button to ty playground which creates a zip export (#23478)
  [ty] Respect `kw_only` overwrites in dataclasses (#23930)
  [ty] Clarify in diagnostics that `from __future__ import annotations` only stringifies type annotations (#23928)
  [ty]  Add a `Copy Markdown` button to playground (#23002)
  [ty] Fix folding range classification of lines starting with `#` (#23831)
  [ty] Fix folding ranges for notebooks (#23830)
  [ty] fix too-many-cycle panics when inferring literal type loop variables (#23875)
  Add `RegularCallableTypeOf` and `into_regular_callable` in `ty_extensions` (#23909)
  [ty] treat properties as full structural types (#23925)
  [ty] Avoid duplicated work during multi-inference (#23923)
  [ty]: make `possibly-missing-attribute` ignored by default
  [ty]: split out `possibly-missing-submodule` from `possibly-missing-attribute`
  Update astral-sh/setup-uv action to v7.5.0 (#23922)
  [ty] Show truthiness in ConstraintSet display and simplify falsy error message (#23913)
  Bump 0.15.6 (#23919)
  [ty] Narrow type context during collection literal inference (#23844)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

testing Related to testing Ruff itself ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ty_extensions.CallableTypeOf always considers the callable as function-like

4 participants