Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions crates/ty_ide/src/inlay_hints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7235,21 +7235,20 @@ mod tests {
);

assert_snapshot!(test.inlay_hints(), @r#"

def f(xyxy: object):
if isinstance(xyxy, list):
x[: Top[list[Unknown]]] = xyxy

---------------------------------------------
info[inlay-hint-location]: Inlay Hint Target
--> stdlib/ty_extensions.pyi:24:1
--> stdlib/ty_extensions.pyi:44:1
|
22 | CallableTypeOf: _SpecialForm
23 |
24 | Top: _SpecialForm
42 | """
43 |
44 | Top: _SpecialForm
| ^^^
25 | """
26 | `Top[T]` represents the "top materialization" of `T`.
45 | """
46 | `Top[T]` represents the "top materialization" of `T`.
|
info: Source
--> main2.py:4:13
Expand Down
12 changes: 11 additions & 1 deletion crates/ty_python_semantic/resources/corpus/ty_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@
This is a regression test for https://github.com/astral-sh/ty/issues/366
"""

from ty_extensions import CallableTypeOf, Intersection, Not, TypeOf
from ty_extensions import (
CallableTypeOf,
Intersection,
Not,
RegularCallableTypeOf,
TypeOf,
)


class A: ...
Expand All @@ -28,3 +34,7 @@ def _(x: TypeOf[1j]):

def _(x: CallableTypeOf[str]):
pass


def _(x: RegularCallableTypeOf[str]):
pass
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,7 @@ def f_okay(c: Callable[[], None]):
### Subclasses should return themselves, not superclass

```py
from ty_extensions import into_callable
from ty_extensions import into_regular_callable

class Base:
def __init__(self) -> None:
Expand All @@ -526,7 +526,7 @@ class A(Base):
pass

# revealed: () -> A
reveal_type(into_callable(A))
reveal_type(into_regular_callable(A))
```

[gradual form]: https://typing.python.org/en/latest/spec/glossary.html#term-gradual-form
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,11 @@ reveal_type(Baz.__supertype__) # revealed: type | NewType
```py
from collections.abc import Callable
from typing_extensions import NewType
from ty_extensions import CallableTypeOf
from ty_extensions import RegularCallableTypeOf

Foo = NewType("Foo", int)

def _(obj: CallableTypeOf[Foo]):
def _(obj: RegularCallableTypeOf[Foo]):
reveal_type(obj) # revealed: (int, /) -> Foo

def f(_: Callable[[int], Foo]): ...
Expand All @@ -105,15 +105,15 @@ g(Foo) # error: [invalid-argument-type]

```py
from typing import NewType, Callable, Any
from ty_extensions import CallableTypeOf
from ty_extensions import RegularCallableTypeOf

N = NewType("N", int)
i = N(42)

y: Callable[..., Any] = i # error: [invalid-assignment] "Object of type `N` is not assignable to `(...) -> Any`"

# error: [invalid-type-form] "Expected the first argument to `ty_extensions.CallableTypeOf` to be a callable object, but got an object of type `N`"
def f(x: CallableTypeOf[i]):
# error: [invalid-type-form] "Expected the first argument to `ty_extensions.RegularCallableTypeOf` to be a callable object, but got an object of type `N`"
def f(x: RegularCallableTypeOf[i]):
reveal_type(x) # revealed: Unknown

class SomethingCallable:
Expand All @@ -125,7 +125,7 @@ j = N2(SomethingCallable())

z: Callable[[str], bytes] = j # fine

def g(x: CallableTypeOf[j]):
def g(x: RegularCallableTypeOf[j]):
reveal_type(x) # revealed: (a: str) -> bytes
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -894,12 +894,12 @@ reveal_type(generic_context(C.f))
This makes sure that we don't bind `self` if it's not a positional parameter:

```py
from ty_extensions import CallableTypeOf
from ty_extensions import RegularCallableTypeOf

class C:
def method(*args, **kwargs) -> None: ...

def _(c: CallableTypeOf[C().method]):
def _(c: RegularCallableTypeOf[C().method]):
reveal_type(c) # revealed: (...) -> None
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@ instance to the first argument. The bound-method object therefore has a differen
the first argument:

```py
from ty_extensions import CallableTypeOf
from ty_extensions import RegularCallableTypeOf
from typing import Callable

class C1:
def method(self: C1, x: int) -> str:
return str(x)

def _(
accessed_on_class: CallableTypeOf[C1.method],
accessed_on_instance: CallableTypeOf[C1().method],
accessed_on_class: RegularCallableTypeOf[C1.method],
accessed_on_instance: RegularCallableTypeOf[C1().method],
):
reveal_type(accessed_on_class) # revealed: (self: C1, x: int) -> str
reveal_type(accessed_on_instance) # revealed: (x: int) -> str
Expand All @@ -41,8 +41,8 @@ class C2:
non_descriptor_callable: NonDescriptorCallable2 = NonDescriptorCallable2()

def _(
accessed_on_class: CallableTypeOf[C2.non_descriptor_callable],
accessed_on_instance: CallableTypeOf[C2().non_descriptor_callable],
accessed_on_class: RegularCallableTypeOf[C2.non_descriptor_callable],
accessed_on_instance: RegularCallableTypeOf[C2().non_descriptor_callable],
):
reveal_type(accessed_on_class) # revealed: (c2: C2, x: int) -> str
reveal_type(accessed_on_instance) # revealed: (c2: C2, x: int) -> str
Expand All @@ -68,8 +68,8 @@ However, when they are accessed on instances of `C3`, they have different signat

```py
def _(
method_accessed_on_instance: CallableTypeOf[C3().method],
callable_accessed_on_instance: CallableTypeOf[C3().non_descriptor_callable],
method_accessed_on_instance: RegularCallableTypeOf[C3().method],
callable_accessed_on_instance: RegularCallableTypeOf[C3().non_descriptor_callable],
):
reveal_type(method_accessed_on_instance) # revealed: (x: int) -> str
reveal_type(callable_accessed_on_instance) # revealed: (c3: C3, x: int) -> str
Expand Down Expand Up @@ -301,7 +301,7 @@ The callable type of a type object is not function-like.

```py
from typing import ClassVar
from ty_extensions import CallableTypeOf
from ty_extensions import RegularCallableTypeOf

class WithNew:
def __new__(self, x: int) -> WithNew:
Expand All @@ -312,8 +312,8 @@ class WithInit:
pass

class C:
with_new: ClassVar[CallableTypeOf[WithNew]]
with_init: ClassVar[CallableTypeOf[WithInit]]
with_new: ClassVar[RegularCallableTypeOf[WithNew]]
with_init: ClassVar[RegularCallableTypeOf[WithInit]]

C.with_new(1)
C().with_new(1)
Expand Down
26 changes: 13 additions & 13 deletions crates/ty_python_semantic/resources/mdtest/call/methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -848,7 +848,7 @@ properties are understood correctly for these functions and methods.
```py
import types
from typing import Callable
from ty_extensions import static_assert, CallableTypeOf, is_assignable_to, TypeOf
from ty_extensions import static_assert, RegularCallableTypeOf, is_assignable_to, TypeOf

def f(obj: type) -> None: ...

Expand Down Expand Up @@ -912,18 +912,18 @@ reveal_type("foo".startswith)
static_assert(is_assignable_to(TypeOf["foo".startswith], Callable))

def _(
a: CallableTypeOf[types.FunctionType.__get__],
b: CallableTypeOf[f],
c: CallableTypeOf[f.__get__],
d: CallableTypeOf[types.FunctionType.__call__],
e: CallableTypeOf[f.__call__],
f: CallableTypeOf[property],
g: CallableTypeOf[property.__get__],
h: CallableTypeOf[MyClass.my_property.__get__],
i: CallableTypeOf[property.__set__],
j: CallableTypeOf[MyClass.my_property.__set__],
k: CallableTypeOf[str.startswith],
l: CallableTypeOf["foo".startswith],
a: RegularCallableTypeOf[types.FunctionType.__get__],
b: RegularCallableTypeOf[f],
c: RegularCallableTypeOf[f.__get__],
d: RegularCallableTypeOf[types.FunctionType.__call__],
e: RegularCallableTypeOf[f.__call__],
f: RegularCallableTypeOf[property],
g: RegularCallableTypeOf[property.__get__],
h: RegularCallableTypeOf[MyClass.my_property.__get__],
i: RegularCallableTypeOf[property.__set__],
j: RegularCallableTypeOf[MyClass.my_property.__set__],
k: RegularCallableTypeOf[str.startswith],
l: RegularCallableTypeOf["foo".startswith],
):
# revealed: Overload[(self: FunctionType, instance: None, owner: type, /) -> Unknown, (self: FunctionType, instance: object, owner: type | None = None, /) -> Unknown]
reveal_type(a)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,28 +45,28 @@ reveal_type(C(1))
When we coerce a generic callable into a `Callable` type, it remembers that it is generic:

```py
from ty_extensions import into_callable
from ty_extensions import into_regular_callable

# revealed: [T](t: T) -> T
reveal_type(into_callable(identity))
reveal_type(into_regular_callable(identity))
# revealed: ty_extensions.GenericContext[T@identity]
reveal_type(generic_context(into_callable(identity)))
reveal_type(generic_context(into_regular_callable(identity)))
# revealed: Literal[1]
reveal_type(into_callable(identity)(1))
reveal_type(into_regular_callable(identity)(1))

# revealed: [**P, T](c: (**P) -> T) -> ((**P) -> T)
reveal_type(into_callable(identity2))
reveal_type(into_regular_callable(identity2))
# revealed: ty_extensions.GenericContext[P@identity2, T@identity2]
reveal_type(generic_context(into_callable(identity2)))
reveal_type(generic_context(into_regular_callable(identity2)))
# revealed: [T](t: T) -> T
reveal_type(into_callable(identity2)(identity))
reveal_type(into_regular_callable(identity2)(identity))

# revealed: [T](t: T) -> C[T]
reveal_type(into_callable(C))
reveal_type(into_regular_callable(C))
# revealed: ty_extensions.GenericContext[T@C]
reveal_type(generic_context(into_callable(C)))
reveal_type(generic_context(into_regular_callable(C)))
# revealed: C[int]
reveal_type(into_callable(C)(1))
reveal_type(into_regular_callable(C)(1))
```

## Naming a generic `Callable`: type aliases
Expand Down
Loading
Loading