mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-02-05 16:36:56 +07:00
The introduction of TypeVarTuples and the concept of unpacked tuple types made us revise all the places where we match sequences of types in type inference. For instance, when matching type parameters and type arguments for generic specialization in: * type hints, i.e. xs: MyGeneric[int, str] = MyGeneric() * constructor invocations, i.e. xs = MyGeneric[int, str]() * class declarations, i.e. class MyGeneric(Base[T1, T2, str]): ... * type alias declarations, i.e. MyAlias: TypeAlias = MyGeneric[T, int] as well as during type matching of all generic types, both normal non-variadic and existing "built-in" generic variadics in the type system, namely tuples and Callables. Previously, this logic was spread across numerous places in PyTypeChecker and PyTypingTypeProvider, all with their own subtle differences. The first attempt of PEP 646 support put all the code for uniform matching of type parameters directly in PyTypeChecker, significantly complicating its already arcane internals. I've introduced a unified API for that called PyTypeParameterMapping. It still retains some of the former quirks in form of its Option flags, controlling in particular how we handle having some of the expected types unmatched (imagine expecting MyGeneric[T1, T2, *Ts] and receiving MyGeneric[int]), but I'm planning to gradually eliminate this conditional logic. The same class is now also responsible for matching parameter types of callables that already allowed to fix some of the known problems, such as ignoring their arity (PY-16994), but I'm going to extract a separate API entity for that, since matching of callable signatures is a much more complicated task involving compatibility of different types of parameters (positional-only, keyword-only, defaults, varargs, etc.). Another positive side effect of these changes is that substitution of type parameters during type inference became more consistent, and we no longer lose useful type information by replacing all unbound type parameters with Any. It's particularly visible in type checker errors where we stopped dropping unbound type parameters from messages about mismatched parameter-argument types. Among other improvements in this changeset are proper scoping for TypeVarTuples, consistent with other type parameters, and recognizing TypeVarTuples and unpacked tuples in types of *args parameters in function bodies, e.g. `*args: *Ts` translates to "args" parameter having the type `tuple[*Ts]`. Confusing PyNoMatchedType used only for reporting of missing arguments for *args parameters annotated with unpacked tuples in the type checker inspection, e.g. def f(*args: *tuple[int, str]): ... f(42) # a type checker error about a missing argument for str was also removed from the type system in favor of a simpler approach with handling such errors directly in the inspection. We might need such a general type in the future, but it has to be well thought-through. GitOrigin-RevId: 63db6202254205863657f014632d141d340fe147