astral-sh / ruff

An extremely fast Python linter and code formatter, written in Rust.
https://docs.astral.sh/ruff
MIT License
33.33k stars 1.11k forks source link

[red-knot] remove TODO catch-all case in infer_unary_expression #14548

Open carljm opened 1 week ago

carljm commented 1 week ago

Currently, the method TypeInferenceBuilder::infer_unary_expression handles some common cases, and has a catch-all arm that simply infers a "todo" type.

This issue is to remove that todo catch-all case, and replace it with correct handling of all missing cases.

For many of the unhandled types (e.g. Type::FunctionLiteral, Type::ClassLiteral, Type::SubclassOf) the correct handling will be to treat it as a Type::Instance type (an instance of types.FunctionType, or an instance of the meta-type of a class) and let the normal instance handling from typeshed take care of it.

(note: edited description for correctness, which will make some comments below look out-of-context)

AlexWaygood commented 1 week ago

For many of the unhandled types (e.g. Type::FunctionLiteral, Type::ClassLiteral, Type::SubclassOf) the correct handling will simply be an unsupported-operator diagnostic.

Hmm, I don't think that's correct when it comes to Type::ClassLiteral and Type::SubclassOf. We need to treat a class as an instance of its metaclass when determining if a unary operation is supported on that class or not. (Same deal as #14200.)

carljm commented 1 week ago

Yes, good point! I looked at functions and then thoughtlessly lumped classes in with them.

Even for functions, we should treat them as an instance of types.FunctionType and defer to typeshed, rather than hardcoding the unsupported-operator diagnostic.