Summary
This seems like a bug, it's because of https://github.com/astral-sh/ruff/blob/ae98756eec21f75856532c27611249be8c92dd0b/crates/ty_python_semantic/src/types/callable.rs#L381-L383
if other.is_function_like(db) && !self.is_function_like(db) {
return ConstraintSet::from_bool(constraints, false);
}
But, this means that we need to be careful in how we write tests because then if CallableTypeOf is used only on the RHS and the LHS is just Callable then the condition is always going to be false and the test is probably not testing what it's suppose to.
I see a couple of test cases with this pattern (https://github.com/astral-sh/ruff/blob/ae98756eec21f75856532c27611249be8c92dd0b/crates/ty_python_semantic/resources/mdtest/type_properties/implies_subtype_of.md?plain=1#L484-L486, https://github.com/astral-sh/ruff/blob/ae98756eec21f75856532c27611249be8c92dd0b/crates/ty_python_semantic/resources/mdtest/type_properties/is_subtype_of.md?plain=1#L2240-L2242) which are all not ... so it might not be testing what it's suppose to.
I think CallableTypeOf should always use CallableTypeKind::Regular to avoid this subtle behavior
Regression test: https://play.ty.dev/787cd60e-047d-42da-a131-ed54eee88f61
from typing import Callable
from ty_extensions import CallableTypeOf, static_assert, is_assignable_to, is_subtype_of
def f(a: int, b: str, /) -> None: ...
# These are `false` on main which isn't correct
static_assert(is_assignable_to(Callable[[int, str], None], CallableTypeOf[f]))
static_assert(is_subtype_of(Callable[[int, str], None], CallableTypeOf[f]))
Version
ty 0.0.21 (c1ad9f2 2026-03-06)
Summary
This seems like a bug, it's because of https://github.com/astral-sh/ruff/blob/ae98756eec21f75856532c27611249be8c92dd0b/crates/ty_python_semantic/src/types/callable.rs#L381-L383
But, this means that we need to be careful in how we write tests because then if
CallableTypeOfis used only on the RHS and the LHS is justCallablethen the condition is always going to befalseand the test is probably not testing what it's suppose to.I see a couple of test cases with this pattern (https://github.com/astral-sh/ruff/blob/ae98756eec21f75856532c27611249be8c92dd0b/crates/ty_python_semantic/resources/mdtest/type_properties/implies_subtype_of.md?plain=1#L484-L486, https://github.com/astral-sh/ruff/blob/ae98756eec21f75856532c27611249be8c92dd0b/crates/ty_python_semantic/resources/mdtest/type_properties/is_subtype_of.md?plain=1#L2240-L2242) which are all
not ...so it might not be testing what it's suppose to.I think
CallableTypeOfshould always useCallableTypeKind::Regularto avoid this subtle behaviorRegression test: https://play.ty.dev/787cd60e-047d-42da-a131-ed54eee88f61
Version
ty 0.0.21 (c1ad9f2 2026-03-06)