Skip to content

Commit 109d3e4

Browse files
committed
update tests
1 parent 17541f8 commit 109d3e4

File tree

2 files changed

+38
-4
lines changed

2 files changed

+38
-4
lines changed

crates/ty_python_semantic/resources/mdtest/generics/pep695/variables.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ def constrained_non_singletons[T: (int, str)](t: T) -> None:
431431
def constrained_singletons[T: (Literal[True], Literal[False])](t: T) -> None:
432432
static_assert(is_singleton(T))
433433

434-
def constrained_single_valued[T: (Literal[True], tuple[()])](t: T) -> None:
434+
def constrained_single_valued[T: (Literal[True], Literal[42])](t: T) -> None:
435435
static_assert(is_single_valued(T))
436436
```
437437

crates/ty_python_semantic/resources/mdtest/type_properties/is_single_valued.md

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@ static_assert(is_single_valued(Literal[1]))
1313
static_assert(is_single_valued(Literal["abc"]))
1414
static_assert(is_single_valued(Literal[b"abc"]))
1515

16-
static_assert(is_single_valued(tuple[()]))
17-
static_assert(is_single_valued(tuple[Literal[True], Literal[1]]))
18-
1916
static_assert(not is_single_valued(str))
2017
static_assert(not is_single_valued(Never))
2118
static_assert(not is_single_valued(Any))
@@ -35,6 +32,43 @@ static_assert(is_single_valued(TypeOf[types.FunctionType.__get__]))
3532
static_assert(is_single_valued(TypeOf[A.method.__get__]))
3633
```
3734

35+
Tuple types are not single-valued, because the type `tuple[int, str]` means "any two-element
36+
instance of `tuple` where the first element is `int` and the second is `str`, *or* any instance of a
37+
subclass of `tuple[int, str]`". It's easy to create a subclass of `tuple[int, str]` that is
38+
Liskov-compliant but not single-valued, which therefore means that `tuple[int, str]` cannot be
39+
single-valued, as it is a supertype of its subclass, so can only be single-valued if all its
40+
subtypes are single-valued:
41+
42+
```py
43+
from ty_extensions import is_single_valued, static_assert
44+
45+
class EmptyTupleSubclass(tuple[()]):
46+
def __eq__(self, other: object) -> bool:
47+
return isinstance(other, EmptyTupleSubclass) and len(other) == 0
48+
49+
static_assert(not is_single_valued(tuple[()]))
50+
static_assert(not is_single_valued(EmptyTupleSubclass))
51+
52+
class SingleElementTupleSubclass(tuple[int]):
53+
def __eq__(self, other: object) -> bool:
54+
return isinstance(other, SingleElementTupleSubclass) and len(other) == 1 and isinstance(other[0], int)
55+
56+
static_assert(not is_single_valued(tuple[int]))
57+
static_assert(not is_single_valued(SingleElementTupleSubclass))
58+
59+
class TwoElementTupleSubclass(tuple[str, bytes]):
60+
def __eq__(self, other: object) -> bool:
61+
return (
62+
isinstance(other, TwoElementTupleSubclass)
63+
and len(other) == 2
64+
and isinstance(other[0], str)
65+
and isinstance(other[1], bytes)
66+
)
67+
68+
static_assert(not is_single_valued(tuple[str, bytes]))
69+
static_assert(not is_single_valued(TwoElementTupleSubclass))
70+
```
71+
3872
An enum literal is only considered single-valued if it has no custom `__eq__`/`__ne__` method, or if
3973
these methods always return `True`/`False`, respectively. Otherwise, the single member of the enum
4074
literal type might not compare equal to itself.

0 commit comments

Comments
 (0)