Skip to content

Pyright fails if builtins.tuple has a decorator #10836

@JelleZijlstra

Description

@JelleZijlstra

In python/typeshed#14599, I'm attempting to add the @disjoint_base decorator from PEP 800 to the stdlib where it makes sense. Pyright runs into trouble if I add the decorator to the stub for builtins.tuple.

To reproduce, use a small program like this:

def f(x: tuple[int, int]) -> None:
    print(x[0] + x[1])

Apply this patch to builtins.pyi:

diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi
index c7ab95482..4b5468066 100644
--- a/stdlib/builtins.pyi
+++ b/stdlib/builtins.pyi
@@ -71,6 +71,7 @@ from typing_extensions import (  # noqa: Y023
     TypeIs,
     TypeVarTuple,
     deprecated,
+    disjoint_base,
 )
 
 if sys.version_info >= (3, 14):
@@ -1009,6 +1010,7 @@ class slice(Generic[_StartT_co, _StopT_co, _StepT_co]):
 
     def indices(self, len: SupportsIndex, /) -> tuple[int, int, int]: ...
 
+@disjoint_base
 class tuple(Sequence[_T_co]):
     def __new__(cls, iterable: Iterable[_T_co] = ..., /) -> Self: ...
     def __len__(self) -> int: ...

And run pyright on the sample:

/Users/jelle/py/typeshed/basic.py
  /Users/jelle/py/typeshed/basic.py:1:10 - error: Type "tuple[_T_co@tuple, ...]" is already specialized (reportInvalidTypeArguments)
  /Users/jelle/py/typeshed/basic.py:2:11 - error: Operator "+" not supported for types "_T_co@tuple" and "_T_co@tuple" (reportOperatorIssue)
  /Users/jelle/py/typeshed/basic.py:2:11 - error: Argument type is unknown
    Argument corresponds to parameter "values" in function "print" (reportUnknownArgumentType)
3 errors, 0 warnings, 0 informations

It seems to lose its knowledge about tuple needing special casing.

It's also reproducible if you just add an identity decorator to the class like this:

diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi
index c7ab95482..2333ac0cd 100644
--- a/stdlib/builtins.pyi
+++ b/stdlib/builtins.pyi
@@ -1009,6 +1009,9 @@ class slice(Generic[_StartT_co, _StopT_co, _StepT_co]):
 
     def indices(self, len: SupportsIndex, /) -> tuple[int, int, int]: ...
 
+def f[T](x: T, /) -> T: ...
+
+@f
 class tuple(Sequence[_T_co]):
     def __new__(cls, iterable: Iterable[_T_co] = ..., /) -> Self: ...
     def __len__(self) -> int: ...

Metadata

Metadata

Assignees

No one assigned

    Labels

    addressed in next versionIssue is fixed and will appear in next published versionbugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions