Skip to content
Open
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
15 changes: 8 additions & 7 deletions conformance/results/mypy/generics_defaults.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@ generics_defaults.py:139: error: Expression is of type "tuple[*tuple[str, int],
generics_defaults.py:152: error: TypeVar default must be a subtype of the bound type [misc]
generics_defaults.py:159: error: TypeVar default must be one of the constraint types [misc]
generics_defaults.py:177: error: Expression is of type "int", not "Any" [assert-type]
generics_defaults.py:203: error: Can only replace ParamSpec with a parameter types list or another ParamSpec, got "str" [valid-type]
generics_defaults.py:204: error: Expression is of type "tuple[Any, ...]", not "tuple[int, str]" [assert-type]
generics_defaults.py:205: error: Expression is of type "def (*Any, **Any) -> None", not "Callable[[float, bool], None]" [assert-type]
generics_defaults.py:211: error: Can only replace ParamSpec with a parameter types list or another ParamSpec, got "str" [valid-type]
generics_defaults.py:212: error: Expression is of type "tuple[Any, ...]", not "tuple[int, str]" [assert-type]
generics_defaults.py:213: error: Expression is of type "def (*Any, **Any) -> None", not "Callable[[float, bool], None]" [assert-type]
"""
conformance_automated = "Fail"
errors_diff = """
Line 188: Expected 1 errors
Line 189: Expected 1 errors
Line 201: Expected 1 errors
Line 139: Unexpected errors ['generics_defaults.py:139: error: Expression is of type "tuple[*tuple[str, int], ...]", not "tuple[str, int]" [assert-type]']
Line 203: Unexpected errors ['generics_defaults.py:203: error: Can only replace ParamSpec with a parameter types list or another ParamSpec, got "str" [valid-type]']
Line 204: Unexpected errors ['generics_defaults.py:204: error: Expression is of type "tuple[Any, ...]", not "tuple[int, str]" [assert-type]']
Line 205: Unexpected errors ['generics_defaults.py:205: error: Expression is of type "def (*Any, **Any) -> None", not "Callable[[float, bool], None]" [assert-type]']
Line 211: Unexpected errors ['generics_defaults.py:211: error: Can only replace ParamSpec with a parameter types list or another ParamSpec, got "str" [valid-type]']
Line 212: Unexpected errors ['generics_defaults.py:212: error: Expression is of type "tuple[Any, ...]", not "tuple[int, str]" [assert-type]']
Line 213: Unexpected errors ['generics_defaults.py:213: error: Expression is of type "def (*Any, **Any) -> None", not "Callable[[float, bool], None]" [assert-type]']
"""
21 changes: 11 additions & 10 deletions conformance/results/pycroscope/generics_defaults.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Numerous issues; does not support TypeVarTuple and ParamSpec defaults.
"""
conformance_automated = "Fail"
errors_diff = """
Line 201: Expected 1 errors
Line 33: Unexpected errors ['./generics_defaults.py:33:16: ~DefaultStrT@./generics_defaults.py.NoNonDefaults is not equivalent to str']
Line 34: Unexpected errors ['./generics_defaults.py:34:16: ~DefaultIntT@./generics_defaults.py.NoNonDefaults is not equivalent to int']
Line 73: Unexpected errors ['./generics_defaults.py:73:16: ~T1@./generics_defaults.py.AllTheDefaults is not equivalent to Any[explicit]']
Expand All @@ -14,10 +15,10 @@ Line 77: Unexpected errors ['./generics_defaults.py:77:16: ~DefaultBoolT@./gen
Line 122: Unexpected errors ['./generics_defaults.py:122:16: (**__P: **DefaultP@./generics_defaults.py.Class_ParamSpec) -> None is not equivalent to (str, int, /) -> None']
Line 124: Unexpected errors ['./generics_defaults.py:124:16: ./generics_defaults.py.Class_ParamSpec[AnySig()] is not equivalent to ./generics_defaults.py.Class_ParamSpec[tuple[bool, bool]]']
Line 144: Unexpected errors ['./generics_defaults.py:144:60: Incompatible argument type for default: expected TypeForm[object] but got Literal[typing.Unpack[DefaultTs]] [incompatible_argument]']
Line 203: Unexpected errors ["./generics_defaults.py:203:36: Invalid type annotation [<class 'bytes'>] [invalid_annotation]", './generics_defaults.py:203:17: ParamSpec specialization must use list form, Concatenate[..., P], P, or ... [invalid_annotation]']
Line 204: Unexpected errors ['./generics_defaults.py:204:16: tuple[int] is not equivalent to tuple[int, str]']
Line 205: Unexpected errors ['./generics_defaults.py:205:16: (...) -> None is not equivalent to (float | int, bool, /) -> None']
Line 208: Unexpected errors ['./generics_defaults.py:208:16: (...) -> None is not equivalent to (bytes, /) -> None']
Line 211: Unexpected errors ["./generics_defaults.py:211:38: Invalid type annotation [<class 'bytes'>] [invalid_annotation]", './generics_defaults.py:211:18: ParamSpec specialization must use list form, Concatenate[..., P], P, or ... [invalid_annotation]']
Line 212: Unexpected errors ['./generics_defaults.py:212:16: tuple[int] is not equivalent to tuple[int, str]']
Line 213: Unexpected errors ['./generics_defaults.py:213:16: (...) -> None is not equivalent to (float | int, bool, /) -> None']
Line 216: Unexpected errors ['./generics_defaults.py:216:16: (...) -> None is not equivalent to (bytes, /) -> None']
"""
output = """
./generics_defaults.py:24:0: non-default TypeVars cannot follow ones with defaults [invalid_type_parameter]
Expand All @@ -35,10 +36,10 @@ output = """
./generics_defaults.py:152:50: TypeVar default must be assignable to its bound [incompatible_call]
./generics_defaults.py:159:51: TypeVar default must be one of its constraints [incompatible_call]
./generics_defaults.py:176:12: Any[generic_argument] is not equivalent to int
./generics_defaults.py:188:0: TypeVars with defaults cannot follow TypeVarTuples [invalid_type_parameter]
./generics_defaults.py:203:36: Invalid type annotation [<class 'bytes'>] [invalid_annotation]
./generics_defaults.py:203:17: ParamSpec specialization must use list form, Concatenate[..., P], P, or ... [invalid_annotation]
./generics_defaults.py:204:16: tuple[int] is not equivalent to tuple[int, str]
./generics_defaults.py:205:16: (...) -> None is not equivalent to (float | int, bool, /) -> None
./generics_defaults.py:208:16: (...) -> None is not equivalent to (bytes, /) -> None
./generics_defaults.py:189:0: TypeVars with defaults cannot follow TypeVarTuples [invalid_type_parameter]
./generics_defaults.py:211:38: Invalid type annotation [<class 'bytes'>] [invalid_annotation]
./generics_defaults.py:211:18: ParamSpec specialization must use list form, Concatenate[..., P], P, or ... [invalid_annotation]
./generics_defaults.py:212:16: tuple[int] is not equivalent to tuple[int, str]
./generics_defaults.py:213:16: (...) -> None is not equivalent to (float | int, bool, /) -> None
./generics_defaults.py:216:16: (...) -> None is not equivalent to (bytes, /) -> None
"""
10 changes: 7 additions & 3 deletions conformance/results/pyrefly/generics_defaults.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
conformant = "Pass"
conformance_automated = "Pass"
conformant = "Partial"
notes = """
Does not flag a ``ParamSpec`` with a default following a ``TypeVarTuple`` without a default.
"""
conformance_automated = "Fail"
errors_diff = """
Line 201: Expected 1 errors
"""
output = """
ERROR generics_defaults.py:24:7-31: Type parameter `T` without a default cannot follow type parameter `DefaultStrT` with a default [invalid-type-var]
ERROR generics_defaults.py:66:8-27: Expected 5 type arguments for `AllTheDefaults`, got 1 [bad-specialization]
ERROR generics_defaults.py:152:51-54: Expected default `int` of `Invalid1` to be assignable to the upper bound of `str` [invalid-type-var]
ERROR generics_defaults.py:159:52-55: Expected default `int` of `Invalid2` to be one of the following constraints: `float`, `str` [invalid-type-var]
ERROR generics_defaults.py:177:12-27: assert_type(int, Any) failed [assert-type]
ERROR generics_defaults.py:188:7-11: TypeVar `T5` with a default cannot follow TypeVarTuple `Ts` [invalid-type-var]
ERROR generics_defaults.py:189:7-11: TypeVar `T5` with a default cannot follow TypeVarTuple `Ts` [invalid-type-var]
"""
10 changes: 7 additions & 3 deletions conformance/results/pyright/generics_defaults.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
conformant = "Pass"
conformant = "Partial"
notes = """
Does not flag a ``ParamSpec`` with a default following a ``TypeVarTuple`` without a default.
"""
output = """
generics_defaults.py:24:7 - error: "T" cannot appear after "DefaultStrT" in type parameter list because it has no default type (reportGeneralTypeIssues)
generics_defaults.py:66:23 - error: Too few type arguments provided for "AllTheDefaults"; expected 2 but received 1 (reportInvalidTypeArguments)
generics_defaults.py:152:51 - error: TypeVar default type must be a subtype of the bound type (reportGeneralTypeIssues)
generics_defaults.py:159:52 - error: TypeVar default type must be one of the constrained types (reportGeneralTypeIssues)
generics_defaults.py:177:13 - error: "assert_type" mismatch: expected "Any" but received "int" (reportAssertTypeFailure)
generics_defaults.py:188:7 - error: TypeVar "T5" has a default value and cannot follow TypeVarTuple "Ts" (reportGeneralTypeIssues)
generics_defaults.py:189:7 - error: TypeVar "T5" has a default value and cannot follow TypeVarTuple "Ts" (reportGeneralTypeIssues)
"""
conformance_automated = "Pass"
conformance_automated = "Fail"
errors_diff = """
Line 201: Expected 1 errors
"""
ignore_errors = ["Access to generic instance variable through class is ambiguous"]
2 changes: 1 addition & 1 deletion conformance/results/results.html
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ <h3>Python Type System Conformance Test Results</h3>
<tr><th class="column col1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;generics_defaults</th>
<th class="column col2 partially-conformant"><div class="hover-text">Partial<span class="tooltip-text" id="bottom"><p>Does not detect a TypeVar with a default used after a TypeVarTuple.</p><p>Does not fully support defaults on TypeVarTuple and ParamSpec.</p></span></div></th>
<th class="column col2 conformant">Pass</th>
<th class="column col2 conformant">Pass</th>
<th class="column col2 not-conformant">Unknown</th>
<th class="column col2 conformant">Pass</th>
<th class="column col2 partially-conformant"><div class="hover-text">Partial<span class="tooltip-text" id="bottom"><p>Numerous issues; does not support TypeVarTuple and ParamSpec defaults.</p></span></div></th>
<th class="column col2 partially-conformant"><div class="hover-text">Partial<span class="tooltip-text" id="bottom"><p>Does not forbid a `TypeVar` immediately following a `TypeVarTuple` in a parameter list from having a default.</p><p>Does not support `TypeVarTuple`.</p></span></div></th>
Expand Down
25 changes: 14 additions & 11 deletions conformance/results/ty/generics_defaults.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@ Does not forbid a `TypeVar` immediately following a `TypeVarTuple` in a paramete
Does not support `TypeVarTuple`.
"""
errors_diff = """
Line 188: Expected 1 errors
Line 189: Expected 1 errors
Line 201: Expected 1 errors
Line 139: Unexpected errors ['generics_defaults.py:139:5: error[type-assertion-failure] Type `tuple[@Todo(TypeVarTuple), ...]` does not match asserted type `tuple[str, int]`']
Line 140: Unexpected errors ['generics_defaults.py:140:5: error[type-assertion-failure] Type `Class_TypeVarTuple` does not match asserted type `@Todo`']
Line 200: Unexpected errors ['generics_defaults.py:200:17: error[invalid-type-form] The first argument to `Callable` must be either a list of types, ParamSpec, Concatenate, or `...`']
Line 204: Unexpected errors ['generics_defaults.py:204:5: error[type-assertion-failure] Type `@Todo` does not match asserted type `tuple[int, str]`']
Line 205: Unexpected errors ['generics_defaults.py:205:5: error[type-assertion-failure] Type `@Todo` does not match asserted type `(int | float, bool, /) -> None`']
Line 207: Unexpected errors ['generics_defaults.py:207:5: error[type-assertion-failure] Type `@Todo` does not match asserted type `tuple[int, str]`']
Line 208: Unexpected errors ['generics_defaults.py:208:5: error[type-assertion-failure] Type `@Todo` does not match asserted type `(bytes, /) -> None`']
Line 203: Unexpected errors ['generics_defaults.py:203:17: error[invalid-type-form] The first argument to `Callable` must be either a list of types, ParamSpec, Concatenate, or `...`']
Line 208: Unexpected errors ['generics_defaults.py:208:17: error[invalid-type-form] The first argument to `Callable` must be either a list of types, ParamSpec, Concatenate, or `...`']
Line 212: Unexpected errors ['generics_defaults.py:212:5: error[type-assertion-failure] Type `@Todo` does not match asserted type `tuple[int, str]`']
Line 213: Unexpected errors ['generics_defaults.py:213:5: error[type-assertion-failure] Type `@Todo` does not match asserted type `(int | float, bool, /) -> None`']
Line 215: Unexpected errors ['generics_defaults.py:215:5: error[type-assertion-failure] Type `@Todo` does not match asserted type `tuple[int, str]`']
Line 216: Unexpected errors ['generics_defaults.py:216:5: error[type-assertion-failure] Type `@Todo` does not match asserted type `(bytes, /) -> None`']
"""
output = """
generics_defaults.py:24:40: error[invalid-generic-class] Type parameter `T` without a default cannot follow earlier parameter `DefaultStrT` with a default
Expand All @@ -22,9 +24,10 @@ generics_defaults.py:140:5: error[type-assertion-failure] Type `Class_TypeVarTup
generics_defaults.py:152:51: error[invalid-type-variable-default] TypeVar default is not assignable to the TypeVar's upper bound
generics_defaults.py:159:52: error[invalid-type-variable-default] TypeVar default is inconsistent with the TypeVar's constraints: `int` is not one of the constraints of `Invalid2`
generics_defaults.py:177:1: error[type-assertion-failure] Type `int` does not match asserted type `Any`
generics_defaults.py:200:17: error[invalid-type-form] The first argument to `Callable` must be either a list of types, ParamSpec, Concatenate, or `...`
generics_defaults.py:204:5: error[type-assertion-failure] Type `@Todo` does not match asserted type `tuple[int, str]`
generics_defaults.py:205:5: error[type-assertion-failure] Type `@Todo` does not match asserted type `(int | float, bool, /) -> None`
generics_defaults.py:207:5: error[type-assertion-failure] Type `@Todo` does not match asserted type `tuple[int, str]`
generics_defaults.py:208:5: error[type-assertion-failure] Type `@Todo` does not match asserted type `(bytes, /) -> None`
generics_defaults.py:203:17: error[invalid-type-form] The first argument to `Callable` must be either a list of types, ParamSpec, Concatenate, or `...`
generics_defaults.py:208:17: error[invalid-type-form] The first argument to `Callable` must be either a list of types, ParamSpec, Concatenate, or `...`
generics_defaults.py:212:5: error[type-assertion-failure] Type `@Todo` does not match asserted type `tuple[int, str]`
generics_defaults.py:213:5: error[type-assertion-failure] Type `@Todo` does not match asserted type `(int | float, bool, /) -> None`
generics_defaults.py:215:5: error[type-assertion-failure] Type `@Todo` does not match asserted type `tuple[int, str]`
generics_defaults.py:216:5: error[type-assertion-failure] Type `@Todo` does not match asserted type `(bytes, /) -> None`
"""
9 changes: 7 additions & 2 deletions conformance/results/zuban/generics_defaults.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
conformance_automated = "Pass"
conformant = "Partial"
notes = """
Does not flag a ``ParamSpec`` with a default following a ``TypeVarTuple`` without a default.
"""
conformance_automated = "Fail"
errors_diff = """
Line 201: Expected 1 errors
"""
output = """
generics_defaults.py:24: error: "T" cannot appear after "DefaultStrT" in type parameter list because it has no default type [misc]
generics_defaults.py:66: error: "AllTheDefaults" expects between 2 and 5 type arguments, but 1 given [type-arg]
generics_defaults.py:152: error: TypeVar default must be a subtype of the bound type [misc]
generics_defaults.py:159: error: TypeVar default must be one of the constraint types [misc]
generics_defaults.py:177: error: Expression is of type "int", not "Any" [misc]
generics_defaults.py:188: error: TypeVar defaults are ambiguous after a TypeVarTuple [misc]
generics_defaults.py:189: error: TypeVar defaults are ambiguous after a TypeVarTuple [misc]
"""
14 changes: 11 additions & 3 deletions conformance/tests/generics_defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,24 +183,32 @@ def func1(x: int | set[T4]) -> T4:

Ts = TypeVarTuple("Ts")
T5 = TypeVar("T5", default=bool)
TsD = TypeVarTuple("TsD", default=Unpack[tuple[int, str]])


class Foo5(Generic[*Ts, T5]): ... # E


# > It is allowed to have a ``ParamSpec`` with a default following a
# > ``TypeVarTuple`` with a default, as there can be no ambiguity between a
# > ``TypeVarTuple`` **with a default**, as there can be no ambiguity between a
# > type argument for the ``ParamSpec`` and one for the ``TypeVarTuple``.
# > When the ``TypeVarTuple`` has no default, a ``ParamSpec`` with a default
# > following it is not allowed (same rule as for ``TypeVar``).

P = ParamSpec("P", default=[float, bool])


class Foo6(Generic[*Ts, P]):
class Foo6(Generic[*Ts, P]): # E: Ts has no default
x: tuple[*Ts]
y: Callable[P, None]


def test_foo6(a: Foo6[int, str], b: Foo6[int, str, [bytes]]):
class Foo6b(Generic[*TsD, P]): # OK: TsD has a default
x: tuple[*TsD]
y: Callable[P, None]


def test_foo6b(a: Foo6b[int, str], b: Foo6b[int, str, [bytes]]):
assert_type(a.x, tuple[int, str])
assert_type(a.y, Callable[[float, bool], None])

Expand Down
8 changes: 6 additions & 2 deletions docs/spec/generics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2098,8 +2098,10 @@ should be bound to the ``TypeVarTuple`` or the defaulted ``TypeVar``.
Foo[int, str, float]

It is allowed to have a ``ParamSpec`` with a default following a
``TypeVarTuple`` with a default, as there can be no ambiguity between a type argument
for the ``ParamSpec`` and one for the ``TypeVarTuple``.
``TypeVarTuple`` **with a default**, as there can be no ambiguity between a
type argument for the ``ParamSpec`` and one for the ``TypeVarTuple``.
When the ``TypeVarTuple`` has no default, a ``ParamSpec`` with a default
following it is not allowed (same rule as for ``TypeVar``).

::

Expand All @@ -2108,6 +2110,8 @@ for the ``ParamSpec`` and one for the ``TypeVarTuple``.
Foo[int, str] # Ts = (int, str), P = [float, bool]
Foo[int, str, [bytes]] # Ts = (int, str), P = [bytes]

class Bar[*Ts, **P = [float, bool]]: ... # Type checker error: Ts has no default

Binding rules
"""""""""""""

Expand Down