jaclang 0.4.6__py3-none-any.whl → 0.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of jaclang might be problematic. Click here for more details.

Files changed (152) hide show
  1. jaclang/__init__.py +5 -2
  2. jaclang/cli/cli.py +57 -10
  3. jaclang/cli/cmdreg.py +16 -9
  4. jaclang/compiler/__jac_gen__/jac_parser.py +11 -15
  5. jaclang/compiler/absyntree.py +53 -19
  6. jaclang/compiler/codeloc.py +3 -1
  7. jaclang/compiler/{transpiler.py → compile.py} +3 -2
  8. jaclang/compiler/constant.py +4 -0
  9. jaclang/compiler/parser.py +156 -108
  10. jaclang/compiler/passes/ir_pass.py +1 -0
  11. jaclang/compiler/passes/main/__init__.py +2 -1
  12. jaclang/compiler/passes/main/def_impl_match_pass.py +1 -0
  13. jaclang/compiler/passes/main/def_use_pass.py +1 -0
  14. jaclang/compiler/passes/main/import_pass.py +18 -18
  15. jaclang/compiler/passes/main/pyast_gen_pass.py +1228 -853
  16. jaclang/compiler/passes/main/pyast_load_pass.py +3 -1
  17. jaclang/compiler/passes/main/pybc_gen_pass.py +46 -0
  18. jaclang/compiler/passes/main/pyout_pass.py +6 -7
  19. jaclang/compiler/passes/main/schedules.py +5 -9
  20. jaclang/compiler/passes/main/sub_node_tab_pass.py +1 -0
  21. jaclang/compiler/passes/main/sym_tab_build_pass.py +21 -9
  22. jaclang/compiler/passes/main/tests/test_decl_def_match_pass.py +2 -1
  23. jaclang/compiler/passes/main/tests/test_def_use_pass.py +2 -1
  24. jaclang/compiler/passes/main/tests/test_import_pass.py +2 -1
  25. jaclang/compiler/passes/main/tests/test_pyast_build_pass.py +1 -0
  26. jaclang/compiler/passes/main/tests/test_pyast_gen_pass.py +15 -38
  27. jaclang/compiler/passes/main/tests/test_pybc_gen_pass.py +25 -0
  28. jaclang/compiler/passes/main/tests/test_sub_node_pass.py +1 -1
  29. jaclang/compiler/passes/main/tests/test_sym_tab_build_pass.py +2 -1
  30. jaclang/compiler/passes/main/tests/test_type_check_pass.py +17 -1
  31. jaclang/compiler/passes/main/type_check_pass.py +9 -6
  32. jaclang/compiler/passes/tool/__init__.py +1 -0
  33. jaclang/compiler/passes/tool/ast_printer_pass.py +1 -0
  34. jaclang/compiler/passes/tool/fuse_comments_pass.py +1 -1
  35. jaclang/compiler/passes/tool/jac_formatter_pass.py +69 -32
  36. jaclang/compiler/passes/tool/schedules.py +1 -0
  37. jaclang/compiler/passes/tool/sym_tab_printer_pass.py +1 -0
  38. jaclang/compiler/passes/tool/tests/test_ast_print_pass.py +2 -1
  39. jaclang/compiler/passes/tool/tests/test_fuse_comments_pass.py +1 -0
  40. jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +4 -3
  41. jaclang/compiler/passes/tool/tests/test_symtab_print_pass.py +2 -1
  42. jaclang/compiler/passes/transform.py +1 -0
  43. jaclang/compiler/passes/utils/mypy_ast_build.py +203 -17
  44. jaclang/compiler/symtable.py +1 -0
  45. jaclang/compiler/tests/test_importer.py +3 -2
  46. jaclang/compiler/tests/test_parser.py +1 -0
  47. jaclang/compiler/tests/test_workspace.py +1 -0
  48. jaclang/compiler/workspace.py +18 -5
  49. jaclang/core/construct.py +9 -32
  50. jaclang/{compiler → core}/importer.py +95 -85
  51. jaclang/core/utils.py +17 -12
  52. jaclang/plugin/__init__.py +1 -0
  53. jaclang/plugin/default.py +145 -43
  54. jaclang/plugin/feature.py +65 -19
  55. jaclang/plugin/spec.py +56 -34
  56. jaclang/plugin/tests/test_features.py +9 -0
  57. jaclang/utils/helpers.py +1 -0
  58. jaclang/utils/lang_tools.py +13 -19
  59. jaclang/utils/tests/test_lang_tools.py +2 -1
  60. jaclang/utils/treeprinter.py +2 -1
  61. jaclang/vendor/lark/common.py +3 -1
  62. jaclang/vendor/lark/lexer.py +6 -12
  63. jaclang/vendor/lark/parsers/lalr_parser.py +1 -0
  64. jaclang/vendor/mypy/applytype.py +2 -1
  65. jaclang/vendor/mypy/binder.py +1 -1
  66. jaclang/vendor/mypy/build.py +7 -9
  67. jaclang/vendor/mypy/checker.py +57 -33
  68. jaclang/vendor/mypy/checkexpr.py +42 -29
  69. jaclang/vendor/mypy/checkmember.py +13 -1
  70. jaclang/vendor/mypy/checkpattern.py +1 -1
  71. jaclang/vendor/mypy/checkstrformat.py +2 -4
  72. jaclang/vendor/mypy/constraints.py +10 -5
  73. jaclang/vendor/mypy/dmypy_server.py +3 -3
  74. jaclang/vendor/mypy/dmypy_util.py +62 -3
  75. jaclang/vendor/mypy/errors.py +1 -1
  76. jaclang/vendor/mypy/evalexpr.py +1 -0
  77. jaclang/vendor/mypy/expandtype.py +29 -29
  78. jaclang/vendor/mypy/fastparse.py +51 -31
  79. jaclang/vendor/mypy/inspections.py +5 -3
  80. jaclang/vendor/mypy/join.py +4 -4
  81. jaclang/vendor/mypy/main.py +6 -6
  82. jaclang/vendor/mypy/message_registry.py +1 -2
  83. jaclang/vendor/mypy/messages.py +31 -23
  84. jaclang/vendor/mypy/metastore.py +1 -2
  85. jaclang/vendor/mypy/modulefinder.py +2 -22
  86. jaclang/vendor/mypy/nodes.py +22 -20
  87. jaclang/vendor/mypy/options.py +4 -0
  88. jaclang/vendor/mypy/parse.py +6 -2
  89. jaclang/vendor/mypy/patterns.py +6 -6
  90. jaclang/vendor/mypy/plugin.py +3 -1
  91. jaclang/vendor/mypy/plugins/attrs.py +52 -10
  92. jaclang/vendor/mypy/plugins/common.py +2 -1
  93. jaclang/vendor/mypy/plugins/enums.py +3 -2
  94. jaclang/vendor/mypy/plugins/functools.py +1 -0
  95. jaclang/vendor/mypy/renaming.py +1 -1
  96. jaclang/vendor/mypy/report.py +15 -15
  97. jaclang/vendor/mypy/semanal.py +22 -13
  98. jaclang/vendor/mypy/semanal_enum.py +1 -1
  99. jaclang/vendor/mypy/semanal_namedtuple.py +1 -2
  100. jaclang/vendor/mypy/semanal_shared.py +3 -6
  101. jaclang/vendor/mypy/semanal_typeddict.py +16 -5
  102. jaclang/vendor/mypy/server/astdiff.py +15 -9
  103. jaclang/vendor/mypy/server/astmerge.py +5 -5
  104. jaclang/vendor/mypy/stats.py +0 -5
  105. jaclang/vendor/mypy/stubdoc.py +1 -1
  106. jaclang/vendor/mypy/stubgen.py +12 -21
  107. jaclang/vendor/mypy/stubgenc.py +16 -8
  108. jaclang/vendor/mypy/stubtest.py +57 -48
  109. jaclang/vendor/mypy/stubutil.py +28 -15
  110. jaclang/vendor/mypy/subtypes.py +4 -4
  111. jaclang/vendor/mypy/test/helpers.py +2 -2
  112. jaclang/vendor/mypy/test/meta/test_parse_data.py +1 -0
  113. jaclang/vendor/mypy/test/meta/test_update_data.py +1 -0
  114. jaclang/vendor/mypy/test/testargs.py +1 -0
  115. jaclang/vendor/mypy/test/testcheck.py +4 -1
  116. jaclang/vendor/mypy/test/testconstraints.py +25 -7
  117. jaclang/vendor/mypy/test/testerrorstream.py +1 -0
  118. jaclang/vendor/mypy/test/testformatter.py +2 -2
  119. jaclang/vendor/mypy/test/testparse.py +6 -4
  120. jaclang/vendor/mypy/test/testpythoneval.py +1 -0
  121. jaclang/vendor/mypy/test/testreports.py +1 -0
  122. jaclang/vendor/mypy/test/teststubgen.py +1 -2
  123. jaclang/vendor/mypy/test/teststubtest.py +98 -4
  124. jaclang/vendor/mypy/test/testtypes.py +1 -1
  125. jaclang/vendor/mypy/test/testutil.py +22 -0
  126. jaclang/vendor/mypy/typeanal.py +302 -158
  127. jaclang/vendor/mypy/typeops.py +22 -13
  128. jaclang/vendor/mypy/types.py +33 -34
  129. jaclang/vendor/mypy/typestate.py +2 -2
  130. jaclang/vendor/mypy/util.py +7 -6
  131. jaclang/vendor/mypy/version.py +1 -1
  132. jaclang/vendor/mypyc/analysis/ircheck.py +1 -0
  133. jaclang/vendor/mypyc/codegen/emitfunc.py +5 -3
  134. jaclang/vendor/mypyc/codegen/emitmodule.py +12 -12
  135. jaclang/vendor/mypyc/codegen/emitwrapper.py +2 -2
  136. jaclang/vendor/mypyc/ir/class_ir.py +10 -6
  137. jaclang/vendor/mypyc/irbuild/builder.py +3 -4
  138. jaclang/vendor/mypyc/irbuild/function.py +5 -3
  139. jaclang/vendor/mypyc/irbuild/nonlocalcontrol.py +1 -2
  140. jaclang/vendor/mypyc/irbuild/prepare.py +6 -6
  141. jaclang/vendor/mypyc/primitives/registry.py +15 -5
  142. jaclang/vendor/mypyc/test/test_run.py +1 -2
  143. jaclang/vendor/mypyc/transform/uninit.py +3 -3
  144. jaclang/vendor/pluggy/_callers.py +1 -0
  145. jaclang/vendor/pluggy/_hooks.py +6 -10
  146. jaclang/vendor/pluggy/_result.py +1 -0
  147. jaclang/vendor/pluggy/_tracing.py +1 -0
  148. {jaclang-0.4.6.dist-info → jaclang-0.5.0.dist-info}/METADATA +1 -1
  149. {jaclang-0.4.6.dist-info → jaclang-0.5.0.dist-info}/RECORD +152 -150
  150. {jaclang-0.4.6.dist-info → jaclang-0.5.0.dist-info}/WHEEL +0 -0
  151. {jaclang-0.4.6.dist-info → jaclang-0.5.0.dist-info}/entry_points.txt +0 -0
  152. {jaclang-0.4.6.dist-info → jaclang-0.5.0.dist-info}/top_level.txt +0 -0
@@ -9,6 +9,7 @@ from typing_extensions import Protocol
9
9
 
10
10
  from mypy import errorcodes as codes, message_registry, nodes
11
11
  from mypy.errorcodes import ErrorCode
12
+ from mypy.expandtype import expand_type
12
13
  from mypy.messages import (
13
14
  MessageBuilder,
14
15
  format_type_bare,
@@ -47,6 +48,7 @@ from mypy.semanal_shared import (
47
48
  paramspec_args,
48
49
  paramspec_kwargs,
49
50
  )
51
+ from mypy.state import state
50
52
  from mypy.tvar_scope import TypeVarLikeScope
51
53
  from mypy.types import (
52
54
  ANNOTATED_TYPE_NAMES,
@@ -84,6 +86,7 @@ from mypy.types import (
84
86
  TypeOfAny,
85
87
  TypeQuery,
86
88
  TypeType,
89
+ TypeVarId,
87
90
  TypeVarLikeType,
88
91
  TypeVarTupleType,
89
92
  TypeVarType,
@@ -1730,40 +1733,32 @@ class TypeAnalyser(SyntheticTypeVisitor[Type], TypeAnalyzerPluginInterface):
1730
1733
  yield
1731
1734
  self.tvar_scope = old_scope
1732
1735
 
1733
- def find_type_var_likes(
1734
- self, t: Type, include_callables: bool = True
1735
- ) -> TypeVarLikeList:
1736
- return t.accept(
1737
- TypeVarLikeQuery(
1738
- self.api, self.tvar_scope, include_callables=include_callables
1739
- )
1740
- )
1736
+ def find_type_var_likes(self, t: Type) -> TypeVarLikeList:
1737
+ visitor = FindTypeVarVisitor(self.api, self.tvar_scope)
1738
+ t.accept(visitor)
1739
+ return visitor.type_var_likes
1741
1740
 
1742
1741
  def infer_type_variables(
1743
1742
  self, type: CallableType
1744
- ) -> list[tuple[str, TypeVarLikeExpr]]:
1745
- """Return list of unique type variables referred to in a callable."""
1746
- names: list[str] = []
1747
- tvars: list[TypeVarLikeExpr] = []
1743
+ ) -> tuple[list[tuple[str, TypeVarLikeExpr]], bool]:
1744
+ """Infer type variables from a callable.
1745
+
1746
+ Return tuple with these items:
1747
+ - list of unique type variables referred to in a callable
1748
+ - whether there is a reference to the Self type
1749
+ """
1750
+ visitor = FindTypeVarVisitor(self.api, self.tvar_scope)
1748
1751
  for arg in type.arg_types:
1749
- for name, tvar_expr in self.find_type_var_likes(arg):
1750
- if name not in names:
1751
- names.append(name)
1752
- tvars.append(tvar_expr)
1752
+ arg.accept(visitor)
1753
+
1753
1754
  # When finding type variables in the return type of a function, don't
1754
1755
  # look inside Callable types. Type variables only appearing in
1755
1756
  # functions in the return type belong to those functions, not the
1756
1757
  # function we're currently analyzing.
1757
- for name, tvar_expr in self.find_type_var_likes(
1758
- type.ret_type, include_callables=False
1759
- ):
1760
- if name not in names:
1761
- names.append(name)
1762
- tvars.append(tvar_expr)
1758
+ visitor.include_callables = False
1759
+ type.ret_type.accept(visitor)
1763
1760
 
1764
- if not names:
1765
- return [] # Fast path
1766
- return list(zip(names, tvars))
1761
+ return visitor.type_var_likes, visitor.has_self_type
1767
1762
 
1768
1763
  def bind_function_type_variables(
1769
1764
  self, fun_type: CallableType, defn: Context
@@ -1789,11 +1784,7 @@ class TypeAnalyser(SyntheticTypeVisitor[Type], TypeAnalyzerPluginInterface):
1789
1784
  binding = self.tvar_scope.bind_new(var.name, var_expr)
1790
1785
  defs.append(binding)
1791
1786
  return defs, has_self_type
1792
- typevars = self.infer_type_variables(fun_type)
1793
- has_self_type = find_self_type(
1794
- fun_type,
1795
- lambda name: self.api.lookup_qualified(name, defn, suppress_errors=True),
1796
- )
1787
+ typevars, has_self_type = self.infer_type_variables(fun_type)
1797
1788
  # Do not define a new type variable if already defined in scope.
1798
1789
  typevars = [
1799
1790
  (name, tvar)
@@ -1970,8 +1961,7 @@ TypeVarLikeList = List[Tuple[str, TypeVarLikeExpr]]
1970
1961
  class MsgCallback(Protocol):
1971
1962
  def __call__(
1972
1963
  self, __msg: str, __ctx: Context, *, code: ErrorCode | None = None
1973
- ) -> None:
1974
- ...
1964
+ ) -> None: ...
1975
1965
 
1976
1966
 
1977
1967
  def get_omitted_any(
@@ -2037,14 +2027,14 @@ def get_omitted_any(
2037
2027
  return any_type
2038
2028
 
2039
2029
 
2040
- def fix_type_var_tuple_argument(any_type: Type, t: Instance) -> None:
2030
+ def fix_type_var_tuple_argument(t: Instance) -> None:
2041
2031
  if t.type.has_type_var_tuple_type:
2042
2032
  args = list(t.args)
2043
2033
  assert t.type.type_var_tuple_prefix is not None
2044
2034
  tvt = t.type.defn.type_vars[t.type.type_var_tuple_prefix]
2045
2035
  assert isinstance(tvt, TypeVarTupleType)
2046
2036
  args[t.type.type_var_tuple_prefix] = UnpackType(
2047
- Instance(tvt.tuple_fallback.type, [any_type])
2037
+ Instance(tvt.tuple_fallback.type, [args[t.type.type_var_tuple_prefix]])
2048
2038
  )
2049
2039
  t.args = tuple(args)
2050
2040
 
@@ -2058,28 +2048,47 @@ def fix_instance(
2058
2048
  use_generic_error: bool = False,
2059
2049
  unexpanded_type: Type | None = None,
2060
2050
  ) -> None:
2061
- """Fix a malformed instance by replacing all type arguments with Any.
2051
+ """Fix a malformed instance by replacing all type arguments with TypeVar default or Any.
2062
2052
 
2063
2053
  Also emit a suitable error if this is not due to implicit Any's.
2064
2054
  """
2065
- if len(t.args) == 0:
2066
- if use_generic_error:
2067
- fullname: str | None = None
2068
- else:
2069
- fullname = t.type.fullname
2070
- any_type = get_omitted_any(
2071
- disallow_any, fail, note, t, options, fullname, unexpanded_type
2072
- )
2073
- t.args = (any_type,) * len(t.type.type_vars)
2074
- fix_type_var_tuple_argument(any_type, t)
2075
- return
2076
- # Construct the correct number of type arguments, as
2077
- # otherwise the type checker may crash as it expects
2078
- # things to be right.
2079
- any_type = AnyType(TypeOfAny.from_error)
2080
- t.args = tuple(any_type for _ in t.type.type_vars)
2081
- fix_type_var_tuple_argument(any_type, t)
2082
- t.invalid = True
2055
+ arg_count = len(t.args)
2056
+ min_tv_count = sum(not tv.has_default() for tv in t.type.defn.type_vars)
2057
+ max_tv_count = len(t.type.type_vars)
2058
+ if arg_count < min_tv_count or arg_count > max_tv_count:
2059
+ # Don't use existing args if arg_count doesn't match
2060
+ if arg_count > max_tv_count:
2061
+ # Already wrong arg count error, don't emit missing type parameters error as well.
2062
+ disallow_any = False
2063
+ t.args = ()
2064
+ arg_count = 0
2065
+
2066
+ args: list[Type] = [*(t.args[:max_tv_count])]
2067
+ any_type: AnyType | None = None
2068
+ env: dict[TypeVarId, Type] = {}
2069
+
2070
+ for tv, arg in itertools.zip_longest(t.type.defn.type_vars, t.args, fillvalue=None):
2071
+ if tv is None:
2072
+ continue
2073
+ if arg is None:
2074
+ if tv.has_default():
2075
+ arg = tv.default
2076
+ else:
2077
+ if any_type is None:
2078
+ fullname = None if use_generic_error else t.type.fullname
2079
+ any_type = get_omitted_any(
2080
+ disallow_any, fail, note, t, options, fullname, unexpanded_type
2081
+ )
2082
+ arg = any_type
2083
+ args.append(arg)
2084
+ env[tv.id] = arg
2085
+ t.args = tuple(args)
2086
+ fix_type_var_tuple_argument(t)
2087
+ if not t.type.has_type_var_tuple_type:
2088
+ with state.strict_optional_set(options.strict_optional):
2089
+ fixed = expand_type(t, env)
2090
+ assert isinstance(fixed, Instance)
2091
+ t.args = fixed.args
2083
2092
 
2084
2093
 
2085
2094
  def instantiate_type_alias(
@@ -2114,18 +2123,19 @@ def instantiate_type_alias(
2114
2123
  if any(unknown_unpack(a) for a in args):
2115
2124
  # This type is not ready to be validated, because of unknown total count.
2116
2125
  # Note that we keep the kind of Any for consistency.
2117
- return set_any_tvars(node, ctx.line, ctx.column, options, special_form=True)
2126
+ return set_any_tvars(node, [], ctx.line, ctx.column, options, special_form=True)
2118
2127
 
2119
- exp_len = len(node.alias_tvars)
2128
+ max_tv_count = len(node.alias_tvars)
2120
2129
  act_len = len(args)
2121
2130
  if (
2122
- exp_len > 0
2131
+ max_tv_count > 0
2123
2132
  and act_len == 0
2124
2133
  and not (empty_tuple_index and node.tvar_tuple_index is not None)
2125
2134
  ):
2126
2135
  # Interpret bare Alias same as normal generic, i.e., Alias[Any, Any, ...]
2127
2136
  return set_any_tvars(
2128
2137
  node,
2138
+ args,
2129
2139
  ctx.line,
2130
2140
  ctx.column,
2131
2141
  options,
@@ -2133,7 +2143,7 @@ def instantiate_type_alias(
2133
2143
  fail=fail,
2134
2144
  unexpanded_type=unexpanded_type,
2135
2145
  )
2136
- if exp_len == 0 and act_len == 0:
2146
+ if max_tv_count == 0 and act_len == 0:
2137
2147
  if no_args:
2138
2148
  assert isinstance(node.target, Instance) # type: ignore[misc]
2139
2149
  # Note: this is the only case where we use an eager expansion. See more info about
@@ -2141,7 +2151,7 @@ def instantiate_type_alias(
2141
2151
  return Instance(node.target.type, [], line=ctx.line, column=ctx.column)
2142
2152
  return TypeAliasType(node, [], line=ctx.line, column=ctx.column)
2143
2153
  if (
2144
- exp_len == 0
2154
+ max_tv_count == 0
2145
2155
  and act_len > 0
2146
2156
  and isinstance(node.target, Instance) # type: ignore[misc]
2147
2157
  and no_args
@@ -2154,10 +2164,18 @@ def instantiate_type_alias(
2154
2164
  if any(isinstance(a, UnpackType) for a in args):
2155
2165
  # A variadic unpack in fixed size alias (fixed unpacks must be flattened by the caller)
2156
2166
  fail(message_registry.INVALID_UNPACK_POSITION, ctx, code=codes.VALID_TYPE)
2157
- return set_any_tvars(node, ctx.line, ctx.column, options, from_error=True)
2158
- correct = act_len == exp_len
2167
+ return set_any_tvars(
2168
+ node, [], ctx.line, ctx.column, options, from_error=True
2169
+ )
2170
+ min_tv_count = sum(not tv.has_default() for tv in node.alias_tvars)
2171
+ fill_typevars = act_len != max_tv_count
2172
+ correct = min_tv_count <= act_len <= max_tv_count
2159
2173
  else:
2160
- correct = act_len >= exp_len - 1
2174
+ min_tv_count = sum(
2175
+ not tv.has_default() and not isinstance(tv, TypeVarTupleType)
2176
+ for tv in node.alias_tvars
2177
+ )
2178
+ correct = act_len >= min_tv_count
2161
2179
  for a in args:
2162
2180
  if isinstance(a, UnpackType):
2163
2181
  unpacked = get_proper_type(a.type)
@@ -2167,22 +2185,34 @@ def instantiate_type_alias(
2167
2185
  ):
2168
2186
  # Variadic tuple is always correct.
2169
2187
  correct = True
2170
- if not correct:
2171
- if use_standard_error:
2172
- # This is used if type alias is an internal representation of another type,
2173
- # for example a generic TypedDict or NamedTuple.
2174
- msg = wrong_type_arg_count(exp_len, str(act_len), node.name)
2175
- else:
2176
- if node.tvar_tuple_index is not None:
2177
- exp_len_str = f"at least {exp_len - 1}"
2188
+ fill_typevars = not correct
2189
+ if fill_typevars:
2190
+ if not correct:
2191
+ if use_standard_error:
2192
+ # This is used if type alias is an internal representation of another type,
2193
+ # for example a generic TypedDict or NamedTuple.
2194
+ msg = wrong_type_arg_count(
2195
+ max_tv_count, max_tv_count, str(act_len), node.name
2196
+ )
2178
2197
  else:
2179
- exp_len_str = str(exp_len)
2180
- msg = (
2181
- "Bad number of arguments for type alias,"
2182
- f" expected: {exp_len_str}, given: {act_len}"
2183
- )
2184
- fail(msg, ctx, code=codes.TYPE_ARG)
2185
- return set_any_tvars(node, ctx.line, ctx.column, options, from_error=True)
2198
+ if node.tvar_tuple_index is not None:
2199
+ msg = (
2200
+ "Bad number of arguments for type alias,"
2201
+ f" expected at least {min_tv_count}, given {act_len}"
2202
+ )
2203
+ elif min_tv_count != max_tv_count:
2204
+ msg = (
2205
+ "Bad number of arguments for type alias,"
2206
+ f" expected between {min_tv_count} and {max_tv_count}, given {act_len}"
2207
+ )
2208
+ else:
2209
+ msg = (
2210
+ "Bad number of arguments for type alias,"
2211
+ f" expected {min_tv_count}, given {act_len}"
2212
+ )
2213
+ fail(msg, ctx, code=codes.TYPE_ARG)
2214
+ args = []
2215
+ return set_any_tvars(node, args, ctx.line, ctx.column, options, from_error=True)
2186
2216
  elif node.tvar_tuple_index is not None:
2187
2217
  # We also need to check if we are not performing a type variable tuple split.
2188
2218
  unpack = find_unpack_in_list(args)
@@ -2197,7 +2227,7 @@ def instantiate_type_alias(
2197
2227
  if act_prefix < exp_prefix or act_suffix < exp_suffix:
2198
2228
  fail("TypeVarTuple cannot be split", ctx, code=codes.TYPE_ARG)
2199
2229
  return set_any_tvars(
2200
- node, ctx.line, ctx.column, options, from_error=True
2230
+ node, [], ctx.line, ctx.column, options, from_error=True
2201
2231
  )
2202
2232
  # TODO: we need to check args validity w.r.t alias.alias_tvars.
2203
2233
  # Otherwise invalid instantiations will be allowed in runtime context.
@@ -2217,6 +2247,7 @@ def instantiate_type_alias(
2217
2247
 
2218
2248
  def set_any_tvars(
2219
2249
  node: TypeAlias,
2250
+ args: list[Type],
2220
2251
  newline: int,
2221
2252
  newcolumn: int,
2222
2253
  options: Options,
@@ -2233,7 +2264,33 @@ def set_any_tvars(
2233
2264
  type_of_any = TypeOfAny.special_form
2234
2265
  else:
2235
2266
  type_of_any = TypeOfAny.from_omitted_generics
2236
- if disallow_any and node.alias_tvars:
2267
+ any_type = AnyType(type_of_any, line=newline, column=newcolumn)
2268
+
2269
+ env: dict[TypeVarId, Type] = {}
2270
+ used_any_type = False
2271
+ has_type_var_tuple_type = False
2272
+ for tv, arg in itertools.zip_longest(node.alias_tvars, args, fillvalue=None):
2273
+ if tv is None:
2274
+ continue
2275
+ if arg is None:
2276
+ if tv.has_default():
2277
+ arg = tv.default
2278
+ else:
2279
+ arg = any_type
2280
+ used_any_type = True
2281
+ if isinstance(tv, TypeVarTupleType):
2282
+ # TODO Handle TypeVarTuple defaults
2283
+ has_type_var_tuple_type = True
2284
+ arg = UnpackType(Instance(tv.tuple_fallback.type, [any_type]))
2285
+ args.append(arg)
2286
+ env[tv.id] = arg
2287
+ t = TypeAliasType(node, args, newline, newcolumn)
2288
+ if not has_type_var_tuple_type:
2289
+ fixed = expand_type(t, env)
2290
+ assert isinstance(fixed, TypeAliasType)
2291
+ t.args = fixed.args
2292
+
2293
+ if used_any_type and disallow_any and node.alias_tvars:
2237
2294
  assert fail is not None
2238
2295
  if unexpanded_type:
2239
2296
  type_str = (
@@ -2249,15 +2306,7 @@ def set_any_tvars(
2249
2306
  Context(newline, newcolumn),
2250
2307
  code=codes.TYPE_ARG,
2251
2308
  )
2252
- any_type = AnyType(type_of_any, line=newline, column=newcolumn)
2253
-
2254
- args: list[Type] = []
2255
- for tv in node.alias_tvars:
2256
- if isinstance(tv, TypeVarTupleType):
2257
- args.append(UnpackType(Instance(tv.tuple_fallback.type, [any_type])))
2258
- else:
2259
- args.append(any_type)
2260
- return TypeAliasType(node, args, newline, newcolumn)
2309
+ return t
2261
2310
 
2262
2311
 
2263
2312
  def flatten_tvars(lists: list[list[T]]) -> list[T]:
@@ -2269,67 +2318,6 @@ def flatten_tvars(lists: list[list[T]]) -> list[T]:
2269
2318
  return result
2270
2319
 
2271
2320
 
2272
- class TypeVarLikeQuery(TypeQuery[TypeVarLikeList]):
2273
- """Find TypeVar and ParamSpec references in an unbound type."""
2274
-
2275
- def __init__(
2276
- self,
2277
- api: SemanticAnalyzerCoreInterface,
2278
- scope: TypeVarLikeScope,
2279
- *,
2280
- include_callables: bool = True,
2281
- ) -> None:
2282
- super().__init__(flatten_tvars)
2283
- self.api = api
2284
- self.scope = scope
2285
- self.include_callables = include_callables
2286
- # Only include type variables in type aliases args. This would be anyway
2287
- # that case if we expand (as target variables would be overridden with args)
2288
- # and it may cause infinite recursion on invalid (diverging) recursive aliases.
2289
- self.skip_alias_target = True
2290
-
2291
- def _seems_like_callable(self, type: UnboundType) -> bool:
2292
- if not type.args:
2293
- return False
2294
- return isinstance(type.args[0], (EllipsisType, TypeList, ParamSpecType))
2295
-
2296
- def visit_unbound_type(self, t: UnboundType) -> TypeVarLikeList:
2297
- name = t.name
2298
- node = None
2299
- # Special case P.args and P.kwargs for ParamSpecs only.
2300
- if name.endswith("args"):
2301
- if name.endswith(".args") or name.endswith(".kwargs"):
2302
- base = ".".join(name.split(".")[:-1])
2303
- n = self.api.lookup_qualified(base, t)
2304
- if n is not None and isinstance(n.node, ParamSpecExpr):
2305
- node = n
2306
- name = base
2307
- if node is None:
2308
- node = self.api.lookup_qualified(name, t)
2309
- if (
2310
- node
2311
- and isinstance(node.node, TypeVarLikeExpr)
2312
- and self.scope.get_binding(node) is None
2313
- ):
2314
- assert isinstance(node.node, TypeVarLikeExpr)
2315
- return [(name, node.node)]
2316
- elif not self.include_callables and self._seems_like_callable(t):
2317
- return []
2318
- elif node and node.fullname in LITERAL_TYPE_NAMES:
2319
- return []
2320
- elif node and node.fullname in ANNOTATED_TYPE_NAMES and t.args:
2321
- # Don't query the second argument to Annotated for TypeVars
2322
- return self.query_types([t.args[0]])
2323
- else:
2324
- return super().visit_unbound_type(t)
2325
-
2326
- def visit_callable_type(self, t: CallableType) -> TypeVarLikeList:
2327
- if self.include_callables:
2328
- return super().visit_callable_type(t)
2329
- else:
2330
- return []
2331
-
2332
-
2333
2321
  class DivergingAliasDetector(TrivialSyntheticTypeTranslator):
2334
2322
  """See docstring of detect_diverging_alias() for details."""
2335
2323
 
@@ -2493,24 +2481,27 @@ def validate_instance(t: Instance, fail: MsgCallback, empty_tuple_index: bool) -
2493
2481
  # TODO: is it OK to fill with TypeOfAny.from_error instead of special form?
2494
2482
  return False
2495
2483
  if t.type.has_type_var_tuple_type:
2496
- correct = len(t.args) >= len(t.type.type_vars) - 1
2484
+ min_tv_count = sum(
2485
+ not tv.has_default() and not isinstance(tv, TypeVarTupleType)
2486
+ for tv in t.type.defn.type_vars
2487
+ )
2488
+ correct = len(t.args) >= min_tv_count
2497
2489
  if any(
2498
2490
  isinstance(a, UnpackType) and isinstance(get_proper_type(a.type), Instance)
2499
2491
  for a in t.args
2500
2492
  ):
2501
2493
  correct = True
2502
- if not correct:
2503
- exp_len = f"at least {len(t.type.type_vars) - 1}"
2494
+ if not t.args:
2495
+ if not (empty_tuple_index and len(t.type.type_vars) == 1):
2496
+ # The Any arguments should be set by the caller.
2497
+ return False
2498
+ elif not correct:
2504
2499
  fail(
2505
- f"Bad number of arguments, expected: {exp_len}, given: {len(t.args)}",
2500
+ f"Bad number of arguments, expected: at least {min_tv_count}, given: {len(t.args)}",
2506
2501
  t,
2507
2502
  code=codes.TYPE_ARG,
2508
2503
  )
2509
2504
  return False
2510
- elif not t.args:
2511
- if not (empty_tuple_index and len(t.type.type_vars) == 1):
2512
- # The Any arguments should be set by the caller.
2513
- return False
2514
2505
  else:
2515
2506
  # We also need to check if we are not performing a type variable tuple split.
2516
2507
  unpack = find_unpack_in_list(t.args)
@@ -2530,17 +2521,22 @@ def validate_instance(t: Instance, fail: MsgCallback, empty_tuple_index: bool) -
2530
2521
  elif any(isinstance(a, UnpackType) for a in t.args):
2531
2522
  # A variadic unpack in fixed size instance (fixed unpacks must be flattened by the caller)
2532
2523
  fail(message_registry.INVALID_UNPACK_POSITION, t, code=codes.VALID_TYPE)
2524
+ t.args = ()
2533
2525
  return False
2534
2526
  elif len(t.args) != len(t.type.type_vars):
2535
2527
  # Invalid number of type parameters.
2536
- if t.args:
2528
+ arg_count = len(t.args)
2529
+ min_tv_count = sum(not tv.has_default() for tv in t.type.defn.type_vars)
2530
+ max_tv_count = len(t.type.type_vars)
2531
+ if arg_count and (arg_count < min_tv_count or arg_count > max_tv_count):
2537
2532
  fail(
2538
2533
  wrong_type_arg_count(
2539
- len(t.type.type_vars), str(len(t.args)), t.type.name
2534
+ min_tv_count, max_tv_count, str(arg_count), t.type.name
2540
2535
  ),
2541
2536
  t,
2542
2537
  code=codes.TYPE_ARG,
2543
2538
  )
2539
+ t.invalid = True
2544
2540
  return False
2545
2541
  return True
2546
2542
 
@@ -2576,3 +2572,151 @@ def unknown_unpack(t: Type) -> bool:
2576
2572
  ):
2577
2573
  return True
2578
2574
  return False
2575
+
2576
+
2577
+ class FindTypeVarVisitor(SyntheticTypeVisitor[None]):
2578
+ """Type visitor that looks for type variable types and self types."""
2579
+
2580
+ def __init__(
2581
+ self, api: SemanticAnalyzerCoreInterface, scope: TypeVarLikeScope
2582
+ ) -> None:
2583
+ self.api = api
2584
+ self.scope = scope
2585
+ self.type_var_likes: list[tuple[str, TypeVarLikeExpr]] = []
2586
+ self.has_self_type = False
2587
+ self.seen_aliases: set[TypeAliasType] | None = None
2588
+ self.include_callables = True
2589
+
2590
+ def _seems_like_callable(self, type: UnboundType) -> bool:
2591
+ if not type.args:
2592
+ return False
2593
+ return isinstance(type.args[0], (EllipsisType, TypeList, ParamSpecType))
2594
+
2595
+ def visit_unbound_type(self, t: UnboundType) -> None:
2596
+ name = t.name
2597
+ node = None
2598
+
2599
+ # Special case P.args and P.kwargs for ParamSpecs only.
2600
+ if name.endswith("args"):
2601
+ if name.endswith((".args", ".kwargs")):
2602
+ base = ".".join(name.split(".")[:-1])
2603
+ n = self.api.lookup_qualified(base, t)
2604
+ if n is not None and isinstance(n.node, ParamSpecExpr):
2605
+ node = n
2606
+ name = base
2607
+ if node is None:
2608
+ node = self.api.lookup_qualified(name, t)
2609
+ if node and node.fullname in SELF_TYPE_NAMES:
2610
+ self.has_self_type = True
2611
+ if (
2612
+ node
2613
+ and isinstance(node.node, TypeVarLikeExpr)
2614
+ and self.scope.get_binding(node) is None
2615
+ ):
2616
+ if (name, node.node) not in self.type_var_likes:
2617
+ self.type_var_likes.append((name, node.node))
2618
+ elif not self.include_callables and self._seems_like_callable(t):
2619
+ if find_self_type(
2620
+ t, lambda name: self.api.lookup_qualified(name, t, suppress_errors=True)
2621
+ ):
2622
+ self.has_self_type = True
2623
+ return
2624
+ elif node and node.fullname in LITERAL_TYPE_NAMES:
2625
+ return
2626
+ elif node and node.fullname in ANNOTATED_TYPE_NAMES and t.args:
2627
+ # Don't query the second argument to Annotated for TypeVars
2628
+ self.process_types([t.args[0]])
2629
+ elif t.args:
2630
+ self.process_types(t.args)
2631
+
2632
+ def visit_type_list(self, t: TypeList) -> None:
2633
+ self.process_types(t.items)
2634
+
2635
+ def visit_callable_argument(self, t: CallableArgument) -> None:
2636
+ t.typ.accept(self)
2637
+
2638
+ def visit_any(self, t: AnyType) -> None:
2639
+ pass
2640
+
2641
+ def visit_uninhabited_type(self, t: UninhabitedType) -> None:
2642
+ pass
2643
+
2644
+ def visit_none_type(self, t: NoneType) -> None:
2645
+ pass
2646
+
2647
+ def visit_erased_type(self, t: ErasedType) -> None:
2648
+ pass
2649
+
2650
+ def visit_deleted_type(self, t: DeletedType) -> None:
2651
+ pass
2652
+
2653
+ def visit_type_var(self, t: TypeVarType) -> None:
2654
+ self.process_types([t.upper_bound, t.default] + t.values)
2655
+
2656
+ def visit_param_spec(self, t: ParamSpecType) -> None:
2657
+ self.process_types([t.upper_bound, t.default])
2658
+
2659
+ def visit_type_var_tuple(self, t: TypeVarTupleType) -> None:
2660
+ self.process_types([t.upper_bound, t.default])
2661
+
2662
+ def visit_unpack_type(self, t: UnpackType) -> None:
2663
+ self.process_types([t.type])
2664
+
2665
+ def visit_parameters(self, t: Parameters) -> None:
2666
+ self.process_types(t.arg_types)
2667
+
2668
+ def visit_partial_type(self, t: PartialType) -> None:
2669
+ pass
2670
+
2671
+ def visit_instance(self, t: Instance) -> None:
2672
+ self.process_types(t.args)
2673
+
2674
+ def visit_callable_type(self, t: CallableType) -> None:
2675
+ # FIX generics
2676
+ self.process_types(t.arg_types)
2677
+ t.ret_type.accept(self)
2678
+
2679
+ def visit_tuple_type(self, t: TupleType) -> None:
2680
+ self.process_types(t.items)
2681
+
2682
+ def visit_typeddict_type(self, t: TypedDictType) -> None:
2683
+ self.process_types(list(t.items.values()))
2684
+
2685
+ def visit_raw_expression_type(self, t: RawExpressionType) -> None:
2686
+ pass
2687
+
2688
+ def visit_literal_type(self, t: LiteralType) -> None:
2689
+ pass
2690
+
2691
+ def visit_union_type(self, t: UnionType) -> None:
2692
+ self.process_types(t.items)
2693
+
2694
+ def visit_overloaded(self, t: Overloaded) -> None:
2695
+ self.process_types(t.items) # type: ignore[arg-type]
2696
+
2697
+ def visit_type_type(self, t: TypeType) -> None:
2698
+ t.item.accept(self)
2699
+
2700
+ def visit_ellipsis_type(self, t: EllipsisType) -> None:
2701
+ pass
2702
+
2703
+ def visit_placeholder_type(self, t: PlaceholderType) -> None:
2704
+ return self.process_types(t.args)
2705
+
2706
+ def visit_type_alias_type(self, t: TypeAliasType) -> None:
2707
+ # Skip type aliases in already visited types to avoid infinite recursion.
2708
+ if self.seen_aliases is None:
2709
+ self.seen_aliases = set()
2710
+ elif t in self.seen_aliases:
2711
+ return
2712
+ self.seen_aliases.add(t)
2713
+ self.process_types(t.args)
2714
+
2715
+ def process_types(self, types: list[Type] | tuple[Type, ...]) -> None:
2716
+ # Redundant type check helps mypyc.
2717
+ if isinstance(types, list):
2718
+ for t in types:
2719
+ t.accept(self)
2720
+ else:
2721
+ for t in types:
2722
+ t.accept(self)