From c95cdb3d1dc535fe7ad0a280b96bcdc3cd28ace6 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Fri, 15 Aug 2025 10:50:54 +0100 Subject: [PATCH] Add regression test and comment for `GenericContext::from_type_params` --- .../mdtest/generics/pep695/classes.md | 29 +++++++++++++++++++ .../ty_python_semantic/src/types/generics.rs | 6 ++++ 2 files changed, 35 insertions(+) diff --git a/crates/ty_python_semantic/resources/mdtest/generics/pep695/classes.md b/crates/ty_python_semantic/resources/mdtest/generics/pep695/classes.md index 261c3d370d..5b6fd1c675 100644 --- a/crates/ty_python_semantic/resources/mdtest/generics/pep695/classes.md +++ b/crates/ty_python_semantic/resources/mdtest/generics/pep695/classes.md @@ -617,5 +617,34 @@ class C[T](C): ... class D[T](D[int]): ... ``` +## Tuple as a PEP-695 generic class + +Our special handling for `tuple` does not break if `tuple` is defined as a PEP-695 generic class in +typeshed: + +```toml +[environment] +python-version = "3.12" +typeshed = "/typeshed" +``` + +`/typeshed/stdlib/builtins.pyi`: + +```pyi +class tuple[T]: ... +``` + +`/typeshed/stdlib/typing_extensions.pyi`: + +```pyi +def reveal_type(obj, /): ... +``` + +`main.py`: + +```py +reveal_type((1, 2, 3)) # revealed: tuple[Literal[1], Literal[2], Literal[3]] +``` + [crtp]: https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern [f-bound]: https://en.wikipedia.org/wiki/Bounded_quantification#F-bounded_quantification diff --git a/crates/ty_python_semantic/src/types/generics.rs b/crates/ty_python_semantic/src/types/generics.rs index 2fbfef5ddd..235489d038 100644 --- a/crates/ty_python_semantic/src/types/generics.rs +++ b/crates/ty_python_semantic/src/types/generics.rs @@ -148,6 +148,12 @@ impl<'db> GenericContext<'db> { .collect(); match known_class { + // As of 15/08/2025, this branch is never taken, since `tuple` in typeshed + // does not have any PEP-695 type parameters. However, it will presumably + // at some point have its stub definition rewritten to use PEP-695 type parameters, + // and a custom typeshed could also reasonably define `tuple` in `builtins.pyi` + // with PEP-695 type parameters. (We have a regression test for this in + // `generics/pep695/classes.md`.) Some(KnownClass::Tuple) => { assert_eq!( variables.len(),