From 89424cce5fe7d5560de2b4c4d5b430ec19c8bc2c Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Tue, 6 May 2025 00:37:24 +0100 Subject: [PATCH] [ty] Do not emit errors if enums or NamedTuples constructed using functional syntax are used in type expressions (#17873) ## Summary This fixes some false positives that showed up in the primer diff for https://github.com/astral-sh/ruff/pull/17832 ## Test Plan new mdtests added that fail with false-positive diagnostics on `main` --- .../annotations/unsupported_special_types.md | 19 +++++++++++++++++++ crates/ty_python_semantic/src/types.rs | 11 +++++++++++ 2 files changed, 30 insertions(+) create mode 100644 crates/ty_python_semantic/resources/mdtest/annotations/unsupported_special_types.md diff --git a/crates/ty_python_semantic/resources/mdtest/annotations/unsupported_special_types.md b/crates/ty_python_semantic/resources/mdtest/annotations/unsupported_special_types.md new file mode 100644 index 0000000000..7b0a073662 --- /dev/null +++ b/crates/ty_python_semantic/resources/mdtest/annotations/unsupported_special_types.md @@ -0,0 +1,19 @@ +# Unsupported special types + +We do not understand the functional syntax for creating `NamedTuple`s, `TypedDict`s or `Enum`s yet. +But we also do not emit false positives when these are used in type expressions. + +```py +import collections +import enum +import typing + +# TODO: should not error (requires understanding metaclass `__call__`) +MyEnum = enum.Enum("MyEnum", ["foo", "bar", "baz"]) # error: [too-many-positional-arguments] + +MyTypedDict = typing.TypedDict("MyTypedDict", {"foo": int}) +MyNamedTuple1 = typing.NamedTuple("MyNamedTuple1", [("foo", int)]) +MyNamedTuple2 = collections.namedtuple("MyNamedTuple2", ["foo"]) + +def f(a: MyEnum, b: MyTypedDict, c: MyNamedTuple1, d: MyNamedTuple2): ... +``` diff --git a/crates/ty_python_semantic/src/types.rs b/crates/ty_python_semantic/src/types.rs index cf991b7d03..833acc95ca 100644 --- a/crates/ty_python_semantic/src/types.rs +++ b/crates/ty_python_semantic/src/types.rs @@ -4833,6 +4833,17 @@ impl<'db> Type<'db> { Some(KnownClass::UnionType) => Ok(todo_type!( "Support for `types.UnionType` instances in type expressions" )), + Some(KnownClass::NamedTuple) => Ok(todo_type!( + "Support for functional `typing.NamedTuple` syntax" + )), + _ if instance + .class() + .iter_mro(db) + .filter_map(ClassBase::into_class) + .any(|class| class.is_known(db, KnownClass::Enum)) => + { + Ok(todo_type!("Support for functional `enum` syntax")) + } _ => Err(InvalidTypeExpressionError { invalid_expressions: smallvec::smallvec![InvalidTypeExpression::InvalidType( *self