infer.py 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. """Utilities for type argument inference."""
  2. from __future__ import annotations
  3. from typing import NamedTuple, Sequence
  4. from mypy.constraints import (
  5. SUBTYPE_OF,
  6. SUPERTYPE_OF,
  7. infer_constraints,
  8. infer_constraints_for_callable,
  9. )
  10. from mypy.nodes import ArgKind
  11. from mypy.solve import solve_constraints
  12. from mypy.types import CallableType, Instance, Type, TypeVarId
  13. class ArgumentInferContext(NamedTuple):
  14. """Type argument inference context.
  15. We need this because we pass around ``Mapping`` and ``Iterable`` types.
  16. These types are only known by ``TypeChecker`` itself.
  17. It is required for ``*`` and ``**`` argument inference.
  18. https://github.com/python/mypy/issues/11144
  19. """
  20. mapping_type: Instance
  21. iterable_type: Instance
  22. def infer_function_type_arguments(
  23. callee_type: CallableType,
  24. arg_types: Sequence[Type | None],
  25. arg_kinds: list[ArgKind],
  26. formal_to_actual: list[list[int]],
  27. context: ArgumentInferContext,
  28. strict: bool = True,
  29. allow_polymorphic: bool = False,
  30. ) -> list[Type | None]:
  31. """Infer the type arguments of a generic function.
  32. Return an array of lower bound types for the type variables -1 (at
  33. index 0), -2 (at index 1), etc. A lower bound is None if a value
  34. could not be inferred.
  35. Arguments:
  36. callee_type: the target generic function
  37. arg_types: argument types at the call site (each optional; if None,
  38. we are not considering this argument in the current pass)
  39. arg_kinds: nodes.ARG_* values for arg_types
  40. formal_to_actual: mapping from formal to actual variable indices
  41. """
  42. # Infer constraints.
  43. constraints = infer_constraints_for_callable(
  44. callee_type, arg_types, arg_kinds, formal_to_actual, context
  45. )
  46. # Solve constraints.
  47. type_vars = callee_type.type_var_ids()
  48. return solve_constraints(type_vars, constraints, strict, allow_polymorphic)
  49. def infer_type_arguments(
  50. type_var_ids: list[TypeVarId], template: Type, actual: Type, is_supertype: bool = False
  51. ) -> list[Type | None]:
  52. # Like infer_function_type_arguments, but only match a single type
  53. # against a generic type.
  54. constraints = infer_constraints(template, actual, SUPERTYPE_OF if is_supertype else SUBTYPE_OF)
  55. return solve_constraints(type_var_ids, constraints)