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
@@ -538,12 +538,16 @@ class TypeChecker(NodeVisitor[None], CheckerPluginInterface):
538
538
  # print("XXX in pass %d, class %s, function %s" %
539
539
  # (self.pass_num, type_name, node.fullname or node.name))
540
540
  done.add(node)
541
- with self.tscope.class_scope(
542
- active_typeinfo
543
- ) if active_typeinfo else nullcontext():
544
- with self.scope.push_class(
545
- active_typeinfo
546
- ) if active_typeinfo else nullcontext():
541
+ with (
542
+ self.tscope.class_scope(active_typeinfo)
543
+ if active_typeinfo
544
+ else nullcontext()
545
+ ):
546
+ with (
547
+ self.scope.push_class(active_typeinfo)
548
+ if active_typeinfo
549
+ else nullcontext()
550
+ ):
547
551
  self.check_partial(node)
548
552
  return True
549
553
 
@@ -652,7 +656,7 @@ class TypeChecker(NodeVisitor[None], CheckerPluginInterface):
652
656
  if not defn.items:
653
657
  # In this case we have already complained about none of these being
654
658
  # valid overloads.
655
- return None
659
+ return
656
660
  if len(defn.items) == 1:
657
661
  self.fail(message_registry.MULTIPLE_OVERLOADS_REQUIRED, defn)
658
662
 
@@ -698,7 +702,6 @@ class TypeChecker(NodeVisitor[None], CheckerPluginInterface):
698
702
  defn, found_method_base_classes, defn.impl
699
703
  )
700
704
  self.check_inplace_operator_method(defn)
701
- return None
702
705
 
703
706
  def extract_callable_type(
704
707
  self, inner_type: Type | None, ctx: Context
@@ -733,7 +736,9 @@ class TypeChecker(NodeVisitor[None], CheckerPluginInterface):
733
736
  # At this point we should have set the impl already, and all remaining
734
737
  # items are decorators
735
738
 
736
- if self.msg.errors.file in self.msg.errors.ignored_files:
739
+ if self.msg.errors.file in self.msg.errors.ignored_files or (
740
+ self.is_typeshed_stub and self.options.test_env
741
+ ):
737
742
  # This is a little hacky, however, the quadratic check here is really expensive, this
738
743
  # method has no side effects, so we should skip it if we aren't going to report
739
744
  # anything. In some other places we swallow errors in stubs, but this error is very
@@ -1957,7 +1962,7 @@ class TypeChecker(NodeVisitor[None], CheckerPluginInterface):
1957
1962
  return
1958
1963
  typ = get_proper_type(typ)
1959
1964
  if not isinstance(typ, TupleType) or not all(
1960
- [is_string_literal(item) for item in typ.items]
1965
+ is_string_literal(item) for item in typ.items
1961
1966
  ):
1962
1967
  self.msg.note(
1963
1968
  "__match_args__ must be a tuple containing string literals for checking "
@@ -4099,9 +4104,11 @@ class TypeChecker(NodeVisitor[None], CheckerPluginInterface):
4099
4104
  if star_lv:
4100
4105
  list_expr = ListExpr(
4101
4106
  [
4102
- self.temp_node(rv_type, context)
4103
- if not isinstance(rv_type, UnpackType)
4104
- else StarExpr(self.temp_node(rv_type.type, context))
4107
+ (
4108
+ self.temp_node(rv_type, context)
4109
+ if not isinstance(rv_type, UnpackType)
4110
+ else StarExpr(self.temp_node(rv_type.type, context))
4111
+ )
4105
4112
  for rv_type in star_rv_types
4106
4113
  ]
4107
4114
  )
@@ -5429,7 +5436,7 @@ class TypeChecker(NodeVisitor[None], CheckerPluginInterface):
5429
5436
 
5430
5437
  def visit_continue_stmt(self, s: ContinueStmt) -> None:
5431
5438
  self.binder.handle_continue()
5432
- return None
5439
+ return
5433
5440
 
5434
5441
  def visit_match_stmt(self, s: MatchStmt) -> None:
5435
5442
  with self.binder.frame_context(can_skip=False, fall_through=0):
@@ -5654,6 +5661,15 @@ class TypeChecker(NodeVisitor[None], CheckerPluginInterface):
5654
5661
  format_type_distinctly(*base_classes, options=self.options, bare=True),
5655
5662
  "and",
5656
5663
  )
5664
+
5665
+ new_errors = []
5666
+ for base in base_classes:
5667
+ if base.type.is_final:
5668
+ new_errors.append((pretty_names_list, f'"{base.type.name}" is final'))
5669
+ if new_errors:
5670
+ errors.extend(new_errors)
5671
+ return None
5672
+
5657
5673
  try:
5658
5674
  info, full_name = _make_fake_typeinfo_and_full_name(
5659
5675
  base_classes, curr_module
@@ -5670,10 +5686,14 @@ class TypeChecker(NodeVisitor[None], CheckerPluginInterface):
5670
5686
  self.check_multiple_inheritance(info)
5671
5687
  info.is_intersection = True
5672
5688
  except MroError:
5673
- errors.append((pretty_names_list, "inconsistent method resolution order"))
5689
+ errors.append(
5690
+ (pretty_names_list, "would have inconsistent method resolution order")
5691
+ )
5674
5692
  return None
5675
5693
  if local_errors.has_new_errors():
5676
- errors.append((pretty_names_list, "incompatible method signatures"))
5694
+ errors.append(
5695
+ (pretty_names_list, "would have incompatible method signatures")
5696
+ )
5677
5697
  return None
5678
5698
 
5679
5699
  curr_module.names[full_name] = SymbolTableNode(GDEF, info)
@@ -7088,8 +7108,7 @@ class TypeChecker(NodeVisitor[None], CheckerPluginInterface):
7088
7108
  notes: list[str] | None = None,
7089
7109
  code: ErrorCode | None = None,
7090
7110
  outer_context: Context | None = None,
7091
- ) -> bool:
7092
- ...
7111
+ ) -> bool: ...
7093
7112
 
7094
7113
  @overload
7095
7114
  def check_subtype(
@@ -7103,8 +7122,7 @@ class TypeChecker(NodeVisitor[None], CheckerPluginInterface):
7103
7122
  *,
7104
7123
  notes: list[str] | None = None,
7105
7124
  outer_context: Context | None = None,
7106
- ) -> bool:
7107
- ...
7125
+ ) -> bool: ...
7108
7126
 
7109
7127
  def check_subtype(
7110
7128
  self,
@@ -7614,8 +7632,7 @@ class TypeChecker(NodeVisitor[None], CheckerPluginInterface):
7614
7632
  type_ranges: list[TypeRange] | None,
7615
7633
  ctx: Context,
7616
7634
  default: None = None,
7617
- ) -> tuple[Type | None, Type | None]:
7618
- ...
7635
+ ) -> tuple[Type | None, Type | None]: ...
7619
7636
 
7620
7637
  @overload
7621
7638
  def conditional_types_with_intersection(
@@ -7624,8 +7641,7 @@ class TypeChecker(NodeVisitor[None], CheckerPluginInterface):
7624
7641
  type_ranges: list[TypeRange] | None,
7625
7642
  ctx: Context,
7626
7643
  default: Type,
7627
- ) -> tuple[Type, Type]:
7628
- ...
7644
+ ) -> tuple[Type, Type]: ...
7629
7645
 
7630
7646
  def conditional_types_with_intersection(
7631
7647
  self,
@@ -7659,9 +7675,10 @@ class TypeChecker(NodeVisitor[None], CheckerPluginInterface):
7659
7675
  possible_target_types = []
7660
7676
  for tr in type_ranges:
7661
7677
  item = get_proper_type(tr.item)
7662
- if not isinstance(item, Instance) or tr.is_upper_bound:
7663
- return yes_type, no_type
7664
- possible_target_types.append(item)
7678
+ if isinstance(item, (Instance, NoneType)):
7679
+ possible_target_types.append(item)
7680
+ if not possible_target_types:
7681
+ return yes_type, no_type
7665
7682
 
7666
7683
  out = []
7667
7684
  errors: list[tuple[str, str]] = []
@@ -7669,6 +7686,11 @@ class TypeChecker(NodeVisitor[None], CheckerPluginInterface):
7669
7686
  if not isinstance(v, Instance):
7670
7687
  return yes_type, no_type
7671
7688
  for t in possible_target_types:
7689
+ if isinstance(t, NoneType):
7690
+ errors.append(
7691
+ (f'"{v.type.name}" and "NoneType"', '"NoneType" is final')
7692
+ )
7693
+ continue
7672
7694
  intersection = self.intersect_instances((v, t), errors)
7673
7695
  if intersection is None:
7674
7696
  continue
@@ -7712,7 +7734,11 @@ class TypeChecker(NodeVisitor[None], CheckerPluginInterface):
7712
7734
  elif isinstance(typ, TypeType):
7713
7735
  # Type[A] means "any type that is a subtype of A" rather than "precisely type A"
7714
7736
  # we indicate this by setting is_upper_bound flag
7715
- types.append(TypeRange(typ.item, is_upper_bound=True))
7737
+ is_upper_bound = True
7738
+ if isinstance(typ.item, NoneType):
7739
+ # except for Type[None], because "'NoneType' is not an acceptable base type"
7740
+ is_upper_bound = False
7741
+ types.append(TypeRange(typ.item, is_upper_bound=is_upper_bound))
7716
7742
  elif isinstance(typ, Instance) and typ.type.fullname == "builtins.type":
7717
7743
  object_type = Instance(typ.type.mro[-1], [])
7718
7744
  types.append(TypeRange(object_type, is_upper_bound=True))
@@ -7891,15 +7917,13 @@ def conditional_types(
7891
7917
  current_type: Type,
7892
7918
  proposed_type_ranges: list[TypeRange] | None,
7893
7919
  default: None = None,
7894
- ) -> tuple[Type | None, Type | None]:
7895
- ...
7920
+ ) -> tuple[Type | None, Type | None]: ...
7896
7921
 
7897
7922
 
7898
7923
  @overload
7899
7924
  def conditional_types(
7900
7925
  current_type: Type, proposed_type_ranges: list[TypeRange] | None, default: Type
7901
- ) -> tuple[Type, Type]:
7902
- ...
7926
+ ) -> tuple[Type, Type]: ...
7903
7927
 
7904
7928
 
7905
7929
  def conditional_types(
@@ -8200,7 +8224,7 @@ def convert_to_typetype(type_map: TypeMap) -> TypeMap:
8200
8224
  if isinstance(t, TypeVarType):
8201
8225
  t = t.upper_bound
8202
8226
  # TODO: should we only allow unions of instances as per PEP 484?
8203
- if not isinstance(get_proper_type(t), (UnionType, Instance)):
8227
+ if not isinstance(get_proper_type(t), (UnionType, Instance, NoneType)):
8204
8228
  # unknown type; error was likely reported earlier
8205
8229
  return {}
8206
8230
  converted_type_map[expr] = TypeType.make_normalized(typ)
@@ -422,6 +422,9 @@ class ExpressionChecker(ExpressionVisitor[Type]):
422
422
  if node.typeddict_type:
423
423
  # We special-case TypedDict, because they don't define any constructor.
424
424
  result = self.typeddict_callable(node)
425
+ elif node.fullname == "types.NoneType":
426
+ # We special case NoneType, because its stub definition is not related to None.
427
+ result = TypeType(NoneType())
425
428
  else:
426
429
  result = type_object_type(node, self.named_type)
427
430
  if isinstance(result, CallableType) and isinstance( # type: ignore[misc]
@@ -557,13 +560,13 @@ class ExpressionChecker(ExpressionVisitor[Type]):
557
560
  if is_expr_literal_type(typ):
558
561
  self.msg.cannot_use_function_with_type(e.callee.name, "Literal", e)
559
562
  continue
560
- if (
561
- node
562
- and isinstance(node.node, TypeAlias)
563
- and isinstance(get_proper_type(node.node.target), AnyType)
564
- ):
565
- self.msg.cannot_use_function_with_type(e.callee.name, "Any", e)
566
- continue
563
+ if node and isinstance(node.node, TypeAlias):
564
+ target = get_proper_type(node.node.target)
565
+ if isinstance(target, AnyType):
566
+ self.msg.cannot_use_function_with_type(e.callee.name, "Any", e)
567
+ continue
568
+ if isinstance(target, NoneType):
569
+ continue
567
570
  if (
568
571
  isinstance(typ, IndexExpr)
569
572
  and isinstance(typ.analyzed, (TypeApplication, TypeAliasExpr))
@@ -799,7 +802,7 @@ class ExpressionChecker(ExpressionVisitor[Type]):
799
802
  context: Context,
800
803
  orig_callee: Type | None,
801
804
  ) -> Type:
802
- if args and all([ak in (ARG_NAMED, ARG_STAR2) for ak in arg_kinds]):
805
+ if args and all(ak in (ARG_NAMED, ARG_STAR2) for ak in arg_kinds):
803
806
  # ex: Point(x=42, y=1337, **extras)
804
807
  # This is a bit ugly, but this is a price for supporting all possible syntax
805
808
  # variants for TypedDict constructors.
@@ -2290,15 +2293,17 @@ class ExpressionChecker(ExpressionVisitor[Type]):
2290
2293
  unknown = UninhabitedType()
2291
2294
  unknown.ambiguous = True
2292
2295
  inferred_args = [
2293
- expand_type(
2294
- a,
2295
- {
2296
- v.id: unknown
2297
- for v in list(callee_type.variables) + free_vars
2298
- },
2296
+ (
2297
+ expand_type(
2298
+ a,
2299
+ {
2300
+ v.id: unknown
2301
+ for v in list(callee_type.variables) + free_vars
2302
+ },
2303
+ )
2304
+ if a is not None
2305
+ else None
2299
2306
  )
2300
- if a is not None
2301
- else None
2302
2307
  for a in poly_inferred_args
2303
2308
  ]
2304
2309
  else:
@@ -3040,6 +3045,7 @@ class ExpressionChecker(ExpressionVisitor[Type]):
3040
3045
  # Return early if possible; otherwise record info, so we can
3041
3046
  # check for ambiguity due to 'Any' below.
3042
3047
  if not args_contain_any:
3048
+ self.chk.store_types(m)
3043
3049
  return ret_type, infer_type
3044
3050
  p_infer_type = get_proper_type(infer_type)
3045
3051
  if isinstance(p_infer_type, CallableType):
@@ -4297,9 +4303,7 @@ class ExpressionChecker(ExpressionVisitor[Type]):
4297
4303
  left_variants = [base_type]
4298
4304
  base_type = get_proper_type(base_type)
4299
4305
  if isinstance(base_type, UnionType):
4300
- left_variants = [
4301
- item for item in flatten_nested_unions(base_type.relevant_items())
4302
- ]
4306
+ left_variants = list(flatten_nested_unions(base_type.relevant_items()))
4303
4307
  right_type = self.accept(arg)
4304
4308
 
4305
4309
  # Step 1: We first try leaving the right arguments alone and destructure
@@ -5036,6 +5040,7 @@ class ExpressionChecker(ExpressionVisitor[Type]):
5036
5040
  item = get_proper_type(
5037
5041
  set_any_tvars(
5038
5042
  alias,
5043
+ [],
5039
5044
  ctx.line,
5040
5045
  ctx.column,
5041
5046
  self.chk.options,
@@ -5059,6 +5064,8 @@ class ExpressionChecker(ExpressionVisitor[Type]):
5059
5064
  return type_object_type(tuple_fallback(item).type, self.named_type)
5060
5065
  elif isinstance(item, TypedDictType):
5061
5066
  return self.typeddict_callable_from_context(item)
5067
+ elif isinstance(item, NoneType):
5068
+ return TypeType(item, line=item.line, column=item.column)
5062
5069
  elif isinstance(item, AnyType):
5063
5070
  return AnyType(TypeOfAny.from_another_any, source_any=item)
5064
5071
  else:
@@ -5138,14 +5145,18 @@ class ExpressionChecker(ExpressionVisitor[Type]):
5138
5145
  tp = get_proper_type(tp)
5139
5146
 
5140
5147
  if isinstance(tp, CallableType):
5141
- if len(tp.variables) != len(args) and not any(
5148
+ min_arg_count = sum(not v.has_default() for v in tp.variables)
5149
+ has_type_var_tuple = any(
5142
5150
  isinstance(v, TypeVarTupleType) for v in tp.variables
5143
- ):
5151
+ )
5152
+ if (
5153
+ len(args) < min_arg_count or len(args) > len(tp.variables)
5154
+ ) and not has_type_var_tuple:
5144
5155
  if tp.is_type_obj() and tp.type_object().fullname == "builtins.tuple":
5145
5156
  # TODO: Specialize the callable for the type arguments
5146
5157
  return tp
5147
5158
  self.msg.incompatible_type_application(
5148
- len(tp.variables), len(args), ctx
5159
+ min_arg_count, len(tp.variables), len(args), ctx
5149
5160
  )
5150
5161
  return AnyType(TypeOfAny.from_error)
5151
5162
  return self.apply_generic_arguments(
@@ -5153,11 +5164,15 @@ class ExpressionChecker(ExpressionVisitor[Type]):
5153
5164
  )
5154
5165
  if isinstance(tp, Overloaded):
5155
5166
  for it in tp.items:
5156
- if len(it.variables) != len(args) and not any(
5167
+ min_arg_count = sum(not v.has_default() for v in it.variables)
5168
+ has_type_var_tuple = any(
5157
5169
  isinstance(v, TypeVarTupleType) for v in it.variables
5158
- ):
5170
+ )
5171
+ if (
5172
+ len(args) < min_arg_count or len(args) > len(it.variables)
5173
+ ) and not has_type_var_tuple:
5159
5174
  self.msg.incompatible_type_application(
5160
- len(it.variables), len(args), ctx
5175
+ min_arg_count, len(it.variables), len(args), ctx
5161
5176
  )
5162
5177
  return AnyType(TypeOfAny.from_error)
5163
5178
  return Overloaded(
@@ -6445,14 +6460,12 @@ class ExpressionChecker(ExpressionVisitor[Type]):
6445
6460
  return self.named_type("builtins.bool")
6446
6461
 
6447
6462
  @overload
6448
- def narrow_type_from_binder(self, expr: Expression, known_type: Type) -> Type:
6449
- ...
6463
+ def narrow_type_from_binder(self, expr: Expression, known_type: Type) -> Type: ...
6450
6464
 
6451
6465
  @overload
6452
6466
  def narrow_type_from_binder(
6453
6467
  self, expr: Expression, known_type: Type, skip_non_overlapping: bool
6454
- ) -> Type | None:
6455
- ...
6468
+ ) -> Type | None: ...
6456
6469
 
6457
6470
  def narrow_type_from_binder(
6458
6471
  self, expr: Expression, known_type: Type, skip_non_overlapping: bool = False
@@ -1107,11 +1107,19 @@ def analyze_class_attribute_access(
1107
1107
  is_classmethod = (
1108
1108
  is_decorated and cast(Decorator, node.node).func.is_class
1109
1109
  ) or (isinstance(node.node, FuncBase) and node.node.is_class)
1110
+ is_staticmethod = (
1111
+ is_decorated and cast(Decorator, node.node).func.is_static
1112
+ ) or (isinstance(node.node, FuncBase) and node.node.is_static)
1110
1113
  t = get_proper_type(t)
1111
1114
  if isinstance(t, FunctionLike) and is_classmethod:
1112
1115
  t = check_self_arg(t, mx.self_type, False, mx.context, name, mx.msg)
1113
1116
  result = add_class_tvars(
1114
- t, isuper, is_classmethod, mx.self_type, original_vars=original_vars
1117
+ t,
1118
+ isuper,
1119
+ is_classmethod,
1120
+ is_staticmethod,
1121
+ mx.self_type,
1122
+ original_vars=original_vars,
1115
1123
  )
1116
1124
  if not mx.is_lvalue:
1117
1125
  result = analyze_descriptor_access(result, mx)
@@ -1224,6 +1232,7 @@ def add_class_tvars(
1224
1232
  t: ProperType,
1225
1233
  isuper: Instance | None,
1226
1234
  is_classmethod: bool,
1235
+ is_staticmethod: bool,
1227
1236
  original_type: Type,
1228
1237
  original_vars: Sequence[TypeVarLikeType] | None = None,
1229
1238
  ) -> Type:
@@ -1242,6 +1251,7 @@ def add_class_tvars(
1242
1251
  isuper: Current instance mapped to the superclass where method was defined, this
1243
1252
  is usually done by map_instance_to_supertype()
1244
1253
  is_classmethod: True if this method is decorated with @classmethod
1254
+ is_staticmethod: True if this method is decorated with @staticmethod
1245
1255
  original_type: The value of the type B in the expression B.foo() or the corresponding
1246
1256
  component in case of a union (this is used to bind the self-types)
1247
1257
  original_vars: Type variables of the class callable on which the method was accessed
@@ -1267,6 +1277,7 @@ def add_class_tvars(
1267
1277
  t = freshen_all_functions_type_vars(t)
1268
1278
  if is_classmethod:
1269
1279
  t = bind_self(t, original_type, is_classmethod=True)
1280
+ if is_classmethod or is_staticmethod:
1270
1281
  assert isuper is not None
1271
1282
  t = expand_type_by_instance(t, isuper)
1272
1283
  freeze_all_type_vars(t)
@@ -1280,6 +1291,7 @@ def add_class_tvars(
1280
1291
  item,
1281
1292
  isuper,
1282
1293
  is_classmethod,
1294
+ is_staticmethod,
1283
1295
  original_type,
1284
1296
  original_vars=original_vars,
1285
1297
  ),
@@ -197,7 +197,7 @@ class PatternChecker(PatternVisitor[PatternType]):
197
197
  capture_types[node].append((expr, typ))
198
198
 
199
199
  captures: dict[Expression, Type] = {}
200
- for var, capture_list in capture_types.items():
200
+ for capture_list in capture_types.values():
201
201
  typ = UninhabitedType()
202
202
  for _, other in capture_list:
203
203
  typ = join_types(typ, other)
@@ -417,8 +417,7 @@ class StringFormatterChecker:
417
417
  ):
418
418
  # TODO: add support for some custom specs like datetime?
419
419
  self.msg.fail(
420
- "Unrecognized format"
421
- ' specification "{}"'.format(spec.format_spec[1:]),
420
+ f'Unrecognized format specification "{spec.format_spec[1:]}"',
422
421
  call,
423
422
  code=codes.STRING_FORMATTING,
424
423
  )
@@ -534,8 +533,7 @@ class StringFormatterChecker:
534
533
  expr = self.get_expr_by_name(key, call)
535
534
  if not expr:
536
535
  self.msg.fail(
537
- "Cannot find replacement for named"
538
- ' format specifier "{}"'.format(key),
536
+ f'Cannot find replacement for named format specifier "{key}"',
539
537
  call,
540
538
  code=codes.STRING_FORMATTING,
541
539
  )
@@ -978,9 +978,12 @@ class ConstraintBuilderVisitor(TypeVisitor[List[Constraint]]):
978
978
  res.append(Constraint(template_arg, SUBTYPE_OF, suffix))
979
979
  res.append(Constraint(template_arg, SUPERTYPE_OF, suffix))
980
980
  elif isinstance(tvar, TypeVarTupleType):
981
- # Handle variadic type variables covariantly for consistency.
981
+ # Consider variadic type variables to be invariant.
982
+ res.extend(
983
+ infer_constraints(template_arg, mapped_arg, SUBTYPE_OF)
984
+ )
982
985
  res.extend(
983
- infer_constraints(template_arg, mapped_arg, self.direction)
986
+ infer_constraints(template_arg, mapped_arg, SUPERTYPE_OF)
984
987
  )
985
988
  return res
986
989
  if (
@@ -1209,9 +1212,11 @@ class ConstraintBuilderVisitor(TypeVisitor[List[Constraint]]):
1209
1212
  arg_types=cactual.arg_types[prefix_len:],
1210
1213
  arg_kinds=cactual.arg_kinds[prefix_len:],
1211
1214
  arg_names=cactual.arg_names[prefix_len:],
1212
- variables=cactual.variables
1213
- if not type_state.infer_polymorphic
1214
- else [],
1215
+ variables=(
1216
+ cactual.variables
1217
+ if not type_state.infer_polymorphic
1218
+ else []
1219
+ ),
1215
1220
  imprecise_arg_kinds=cactual.imprecise_arg_kinds,
1216
1221
  )
1217
1222
  else:
@@ -251,8 +251,8 @@ class Server:
251
251
  while True:
252
252
  with server:
253
253
  data = receive(server)
254
- sys.stdout = WriteToConn(server, "stdout") # type: ignore[assignment]
255
- sys.stderr = WriteToConn(server, "stderr") # type: ignore[assignment]
254
+ sys.stdout = WriteToConn(server, "stdout", sys.stdout.isatty())
255
+ sys.stderr = WriteToConn(server, "stderr", sys.stderr.isatty())
256
256
  resp: dict[str, Any] = {}
257
257
  if "command" not in data:
258
258
  resp = {"error": "No command found in request"}
@@ -1142,7 +1142,7 @@ def fix_module_deps(graph: mypy.build.Graph) -> None:
1142
1142
  This can make some suppressed dependencies non-suppressed, and vice versa (if modules
1143
1143
  have been added to or removed from the build).
1144
1144
  """
1145
- for module, state in graph.items():
1145
+ for state in graph.values():
1146
1146
  new_suppressed = []
1147
1147
  new_dependencies = []
1148
1148
  for dep in state.dependencies + state.suppressed:
@@ -5,8 +5,10 @@ This should be pretty lightweight and not depend on other mypy code (other than
5
5
 
6
6
  from __future__ import annotations
7
7
 
8
+ import io
8
9
  import json
9
- from typing import Any, Final, Iterable
10
+ from types import TracebackType
11
+ from typing import Any, Final, Iterable, Iterator, TextIO
10
12
 
11
13
  from mypy.ipc import IPCBase
12
14
 
@@ -40,12 +42,66 @@ def send(connection: IPCBase, data: Any) -> None:
40
42
  connection.write(json.dumps(data))
41
43
 
42
44
 
43
- class WriteToConn:
45
+ class WriteToConn(TextIO):
44
46
  """Helper class to write to a connection instead of standard output."""
45
47
 
46
- def __init__(self, server: IPCBase, output_key: str = "stdout"):
48
+ def __init__(self, server: IPCBase, output_key: str, isatty: bool) -> None:
47
49
  self.server = server
48
50
  self.output_key = output_key
51
+ self._isatty = isatty
52
+
53
+ def __enter__(self) -> TextIO:
54
+ return self
55
+
56
+ def __exit__(
57
+ self,
58
+ t: type[BaseException] | None,
59
+ value: BaseException | None,
60
+ traceback: TracebackType | None,
61
+ ) -> None:
62
+ pass
63
+
64
+ def __iter__(self) -> Iterator[str]:
65
+ raise io.UnsupportedOperation
66
+
67
+ def __next__(self) -> str:
68
+ raise io.UnsupportedOperation
69
+
70
+ def close(self) -> None:
71
+ pass
72
+
73
+ def fileno(self) -> int:
74
+ raise OSError
75
+
76
+ def flush(self) -> None:
77
+ pass
78
+
79
+ def isatty(self) -> bool:
80
+ return self._isatty
81
+
82
+ def read(self, n: int = 0) -> str:
83
+ raise io.UnsupportedOperation
84
+
85
+ def readable(self) -> bool:
86
+ return False
87
+
88
+ def readline(self, limit: int = 0) -> str:
89
+ raise io.UnsupportedOperation
90
+
91
+ def readlines(self, hint: int = 0) -> list[str]:
92
+ raise io.UnsupportedOperation
93
+
94
+ def seek(self, offset: int, whence: int = 0) -> int:
95
+ raise io.UnsupportedOperation
96
+
97
+ def seekable(self) -> bool:
98
+ return False
99
+
100
+ def tell(self) -> int:
101
+ raise io.UnsupportedOperation
102
+
103
+ def truncate(self, size: int | None = 0) -> int:
104
+ raise io.UnsupportedOperation
49
105
 
50
106
  def write(self, output: str) -> int:
51
107
  resp: dict[str, Any] = {}
@@ -53,6 +109,9 @@ class WriteToConn:
53
109
  send(self.server, resp)
54
110
  return len(output)
55
111
 
112
+ def writable(self) -> bool:
113
+ return True
114
+
56
115
  def writelines(self, lines: Iterable[str]) -> None:
57
116
  for s in lines:
58
117
  self.write(s)
@@ -179,7 +179,7 @@ class ErrorWatcher:
179
179
  *,
180
180
  filter_errors: bool | Callable[[str, ErrorInfo], bool] = False,
181
181
  save_filtered_errors: bool = False,
182
- ):
182
+ ) -> None:
183
183
  self.errors = errors
184
184
  self._has_new_errors = False
185
185
  self._filter = filter_errors
@@ -6,6 +6,7 @@ Used by stubtest; in a separate file because things break if we don't
6
6
  put it in a mypyc-compiled file.
7
7
 
8
8
  """
9
+
9
10
  import ast
10
11
  from typing import Final
11
12