jaclang 0.2.5__py3-none-any.whl → 0.3.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 (72) hide show
  1. jaclang/__init__.py +3 -3
  2. jaclang/cli/__init__.py +0 -1
  3. jaclang/cli/__jac_gen__/cli.py +4 -4
  4. jaclang/cli/__jac_gen__/cmds.py +1 -1
  5. jaclang/cli/__jac_gen__/cmds_impl.py +1 -1
  6. jaclang/core/__init__.py +5 -11
  7. jaclang/core/__jac_gen__/corelib.py +289 -0
  8. jaclang/core/__jac_gen__/corelib_impl.py +220 -0
  9. jaclang/core/corelib.jac +21 -34
  10. jaclang/core/corelib_impl.jac +317 -0
  11. jaclang/jac/__init__.py +1 -0
  12. jaclang/jac/__jac_gen__/jac_parser.py +2 -2
  13. jaclang/jac/absyntree.py +28 -8
  14. jaclang/jac/constant.py +3 -7
  15. jaclang/jac/parser.py +13 -9
  16. jaclang/jac/passes/main/__init__.py +2 -0
  17. jaclang/jac/passes/main/def_use_pass.py +3 -2
  18. jaclang/jac/passes/main/pyast_gen_pass.py +99 -34
  19. jaclang/jac/passes/main/schedules.py +6 -0
  20. jaclang/jac/passes/main/sym_tab_build_pass.py +3 -5
  21. jaclang/jac/passes/main/tests/test_jac_format_pass.py +22 -4
  22. jaclang/jac/passes/main/tests/test_type_check_pass.py +42 -0
  23. jaclang/jac/passes/main/type_check_pass.py +103 -0
  24. jaclang/jac/passes/tool/fuse_comments_pass.py +57 -39
  25. jaclang/jac/passes/tool/jac_formatter_pass.py +419 -192
  26. jaclang/jac/passes/transform.py +0 -39
  27. jaclang/jac/passes/utils/__init__.py +1 -0
  28. jaclang/jac/passes/utils/mypy_ast_build.py +302 -0
  29. jaclang/jac/plugin/__init__.py +5 -2
  30. jaclang/jac/plugin/default.py +20 -4
  31. jaclang/jac/plugin/feature.py +15 -6
  32. jaclang/jac/plugin/spec.py +34 -6
  33. jaclang/jac/tests/test_workspace.py +45 -5
  34. jaclang/jac/transpiler.py +4 -9
  35. jaclang/utils/helpers.py +0 -33
  36. jaclang/utils/lang_tools.py +3 -0
  37. jaclang/utils/test.py +3 -1
  38. jaclang/vendor/lark/py.typed +0 -0
  39. jaclang/vendor/mypy/checker.py +19 -12
  40. jaclang/vendor/mypy/checkexpr.py +31 -10
  41. jaclang/vendor/mypy/constraints.py +56 -38
  42. jaclang/vendor/mypy/expandtype.py +1 -0
  43. jaclang/vendor/mypy/meet.py +10 -1
  44. jaclang/vendor/mypy/messages.py +16 -4
  45. jaclang/vendor/mypy/moduleinspect.py +10 -4
  46. jaclang/vendor/mypy/py.typed +1 -0
  47. jaclang/vendor/mypy/semanal.py +18 -17
  48. jaclang/vendor/mypy/semanal_enum.py +7 -4
  49. jaclang/vendor/mypy/semanal_namedtuple.py +11 -1
  50. jaclang/vendor/mypy/semanal_typeddict.py +25 -11
  51. jaclang/vendor/mypy/stubdoc.py +18 -4
  52. jaclang/vendor/mypy/stubgen.py +80 -1
  53. jaclang/vendor/mypy/stubgenc.py +47 -5
  54. jaclang/vendor/mypy/stubtest.py +53 -3
  55. jaclang/vendor/mypy/stubutil.py +9 -9
  56. jaclang/vendor/mypy/test/testipc.py +16 -7
  57. jaclang/vendor/mypy/test/teststubtest.py +20 -2
  58. jaclang/vendor/mypy/types.py +1 -1
  59. jaclang/vendor/mypyc/irbuild/prebuildvisitor.py +2 -1
  60. jaclang/vendor/mypyc/test/test_run.py +2 -4
  61. jaclang/vendor/pluggy/py.typed +0 -0
  62. {jaclang-0.2.5.dist-info → jaclang-0.3.0.dist-info}/METADATA +1 -1
  63. {jaclang-0.2.5.dist-info → jaclang-0.3.0.dist-info}/RECORD +67 -62
  64. {jaclang-0.2.5.dist-info → jaclang-0.3.0.dist-info}/WHEEL +1 -1
  65. {jaclang-0.2.5.dist-info → jaclang-0.3.0.dist-info}/entry_points.txt +3 -0
  66. jaclang/core/arch_impl.jac +0 -131
  67. jaclang/core/element_impl.jac +0 -109
  68. jaclang/core/exec_ctx_impl.jac +0 -14
  69. jaclang/core/memory_impl.jac +0 -57
  70. jaclang/jac/tests/fixtures/__jac_gen__/hello_world.py +0 -5
  71. /jaclang/{jac/tests/fixtures → core}/__jac_gen__/__init__.py +0 -0
  72. {jaclang-0.2.5.dist-info → jaclang-0.3.0.dist-info}/top_level.txt +0 -0
@@ -349,6 +349,14 @@ class TypedDictAnalyzer:
349
349
  total = require_bool_literal_argument(
350
350
  self.api, defn.keywords["total"], "total", True
351
351
  )
352
+ if defn.keywords and defn.keywords.keys() != {"total"}:
353
+ for_function = ' for "__init_subclass__" of "TypedDict"'
354
+ for key in defn.keywords:
355
+ if key == "total":
356
+ continue
357
+ self.msg.unexpected_keyword_argument_for_function(
358
+ for_function, key, defn
359
+ )
352
360
  required_keys = {
353
361
  field
354
362
  for (field, t) in zip(fields, types)
@@ -420,6 +428,23 @@ class TypedDictAnalyzer:
420
428
  types = [ # unwrap Required[T] to just T
421
429
  t.item if isinstance(t, RequiredType) else t for t in types
422
430
  ]
431
+
432
+ # Perform various validations after unwrapping.
433
+ for t in types:
434
+ check_for_explicit_any(
435
+ t,
436
+ self.options,
437
+ self.api.is_typeshed_stub_file,
438
+ self.msg,
439
+ context=call,
440
+ )
441
+ if self.options.disallow_any_unimported:
442
+ for t in types:
443
+ if has_any_from_unimported_type(t):
444
+ self.msg.unimported_type_becomes_any(
445
+ "Type of a TypedDict key", t, call
446
+ )
447
+
423
448
  existing_info = None
424
449
  if isinstance(node.analyzed, TypedDictExpr):
425
450
  existing_info = node.analyzed.info
@@ -478,17 +503,6 @@ class TypedDictAnalyzer:
478
503
  # One of the types is not ready, defer.
479
504
  return None
480
505
  items, types, ok = res
481
- for t in types:
482
- check_for_explicit_any(
483
- t, self.options, self.api.is_typeshed_stub_file, self.msg, context=call
484
- )
485
-
486
- if self.options.disallow_any_unimported:
487
- for t in types:
488
- if has_any_from_unimported_type(t):
489
- self.msg.unimported_type_becomes_any(
490
- "Type of a TypedDict key", t, dictexpr
491
- )
492
506
  assert total is not None
493
507
  return args[0].value, items, types, total, tvar_defs, ok
494
508
 
@@ -44,11 +44,19 @@ def is_valid_type(s: str) -> bool:
44
44
  class ArgSig:
45
45
  """Signature info for a single argument."""
46
46
 
47
- def __init__(self, name: str, type: str | None = None, default: bool = False):
47
+ def __init__(
48
+ self,
49
+ name: str,
50
+ type: str | None = None,
51
+ *,
52
+ default: bool = False,
53
+ default_value: str = "...",
54
+ ) -> None:
48
55
  self.name = name
49
56
  self.type = type
50
57
  # Does this argument have a default value?
51
58
  self.default = default
59
+ self.default_value = default_value
52
60
 
53
61
  def is_star_arg(self) -> bool:
54
62
  return self.name.startswith("*") and not self.name.startswith("**")
@@ -67,6 +75,7 @@ class ArgSig:
67
75
  self.name == other.name
68
76
  and self.type == other.type
69
77
  and self.default == other.default
78
+ and self.default_value == other.default_value
70
79
  )
71
80
  return False
72
81
 
@@ -127,10 +136,10 @@ class FunctionSig(NamedTuple):
127
136
  if arg_type:
128
137
  arg_def += ": " + arg_type
129
138
  if arg.default:
130
- arg_def += " = ..."
139
+ arg_def += f" = {arg.default_value}"
131
140
 
132
141
  elif arg.default:
133
- arg_def += "=..."
142
+ arg_def += f"={arg.default_value}"
134
143
 
135
144
  args.append(arg_def)
136
145
 
@@ -400,7 +409,12 @@ def infer_ret_type_sig_from_docstring(docstr: str, name: str) -> str | None:
400
409
 
401
410
  def infer_ret_type_sig_from_anon_docstring(docstr: str) -> str | None:
402
411
  """Convert signature in form of "(self: TestClass, arg0) -> int" to their return type."""
403
- return infer_ret_type_sig_from_docstring("stub" + docstr.strip(), "stub")
412
+ lines = [
413
+ "stub" + line.strip()
414
+ for line in docstr.splitlines()
415
+ if line.strip().startswith("(")
416
+ ]
417
+ return infer_ret_type_sig_from_docstring("".join(lines), "stub")
404
418
 
405
419
 
406
420
  def parse_signature(sig: str) -> tuple[str, list[str], list[str]] | None:
@@ -99,6 +99,7 @@ from mypy.nodes import (
99
99
  NameExpr,
100
100
  OpExpr,
101
101
  OverloadedFuncDef,
102
+ SetExpr,
102
103
  Statement,
103
104
  StrExpr,
104
105
  TempNode,
@@ -499,15 +500,28 @@ class ASTStubGenerator(BaseStubGenerator, mypy.traverser.TraverserVisitor):
499
500
  if kind.is_named() and not any(arg.name.startswith("*") for arg in args):
500
501
  args.append(ArgSig("*"))
501
502
 
503
+ default = "..."
502
504
  if arg_.initializer:
503
505
  if not typename:
504
506
  typename = self.get_str_type_of_node(arg_.initializer, True, False)
507
+ potential_default, valid = self.get_str_default_of_node(
508
+ arg_.initializer
509
+ )
510
+ if valid and len(potential_default) <= 200:
511
+ default = potential_default
505
512
  elif kind == ARG_STAR:
506
513
  name = f"*{name}"
507
514
  elif kind == ARG_STAR2:
508
515
  name = f"**{name}"
509
516
 
510
- args.append(ArgSig(name, typename, default=bool(arg_.initializer)))
517
+ args.append(
518
+ ArgSig(
519
+ name,
520
+ typename,
521
+ default=bool(arg_.initializer),
522
+ default_value=default,
523
+ )
524
+ )
511
525
 
512
526
  if ctx.class_info is not None and all(
513
527
  arg.type is None and arg.default is False for arg in args
@@ -1282,6 +1296,70 @@ class ASTStubGenerator(BaseStubGenerator, mypy.traverser.TraverserVisitor):
1282
1296
  # This is some other unary expr, we cannot do anything with it (yet?).
1283
1297
  return expr
1284
1298
 
1299
+ def get_str_default_of_node(self, rvalue: Expression) -> tuple[str, bool]:
1300
+ """Get a string representation of the default value of a node.
1301
+
1302
+ Returns a 2-tuple of the default and whether or not it is valid.
1303
+ """
1304
+ if isinstance(rvalue, NameExpr):
1305
+ if rvalue.name in ("None", "True", "False"):
1306
+ return rvalue.name, True
1307
+ elif isinstance(rvalue, (IntExpr, FloatExpr)):
1308
+ return f"{rvalue.value}", True
1309
+ elif isinstance(rvalue, UnaryExpr):
1310
+ if isinstance(rvalue.expr, (IntExpr, FloatExpr)):
1311
+ return f"{rvalue.op}{rvalue.expr.value}", True
1312
+ elif isinstance(rvalue, StrExpr):
1313
+ return repr(rvalue.value), True
1314
+ elif isinstance(rvalue, BytesExpr):
1315
+ return "b" + repr(rvalue.value).replace("\\\\", "\\"), True
1316
+ elif isinstance(rvalue, TupleExpr):
1317
+ items_defaults = []
1318
+ for e in rvalue.items:
1319
+ e_default, valid = self.get_str_default_of_node(e)
1320
+ if not valid:
1321
+ break
1322
+ items_defaults.append(e_default)
1323
+ else:
1324
+ closing = ",)" if len(items_defaults) == 1 else ")"
1325
+ default = "(" + ", ".join(items_defaults) + closing
1326
+ return default, True
1327
+ elif isinstance(rvalue, ListExpr):
1328
+ items_defaults = []
1329
+ for e in rvalue.items:
1330
+ e_default, valid = self.get_str_default_of_node(e)
1331
+ if not valid:
1332
+ break
1333
+ items_defaults.append(e_default)
1334
+ else:
1335
+ default = "[" + ", ".join(items_defaults) + "]"
1336
+ return default, True
1337
+ elif isinstance(rvalue, SetExpr):
1338
+ items_defaults = []
1339
+ for e in rvalue.items:
1340
+ e_default, valid = self.get_str_default_of_node(e)
1341
+ if not valid:
1342
+ break
1343
+ items_defaults.append(e_default)
1344
+ else:
1345
+ if items_defaults:
1346
+ default = "{" + ", ".join(items_defaults) + "}"
1347
+ return default, True
1348
+ elif isinstance(rvalue, DictExpr):
1349
+ items_defaults = []
1350
+ for k, v in rvalue.items:
1351
+ if k is None:
1352
+ break
1353
+ k_default, k_valid = self.get_str_default_of_node(k)
1354
+ v_default, v_valid = self.get_str_default_of_node(v)
1355
+ if not (k_valid and v_valid):
1356
+ break
1357
+ items_defaults.append(f"{k_default}: {v_default}")
1358
+ else:
1359
+ default = "{" + ", ".join(items_defaults) + "}"
1360
+ return default, True
1361
+ return "...", False
1362
+
1285
1363
  def should_reexport(self, name: str, full_module: str, name_is_alias: bool) -> bool:
1286
1364
  is_private = self.is_private_name(name, full_module + "." + name)
1287
1365
  if (
@@ -1702,6 +1780,7 @@ def generate_stubs(options: Options) -> None:
1702
1780
  doc_dir=options.doc_dir,
1703
1781
  include_private=options.include_private,
1704
1782
  export_less=options.export_less,
1783
+ include_docstrings=options.include_docstrings,
1705
1784
  )
1706
1785
  num_modules = len(all_modules)
1707
1786
  if not options.quiet and num_modules > 0:
@@ -136,10 +136,12 @@ class DocstringSignatureGenerator(SignatureGenerator):
136
136
  """Infer property type from docstring or docstring signature."""
137
137
  if ctx.docstring is not None:
138
138
  inferred = infer_ret_type_sig_from_anon_docstring(ctx.docstring)
139
- if not inferred:
140
- inferred = infer_ret_type_sig_from_docstring(ctx.docstring, ctx.name)
141
- if not inferred:
142
- inferred = infer_prop_type_from_docstring(ctx.docstring)
139
+ if inferred:
140
+ return inferred
141
+ inferred = infer_ret_type_sig_from_docstring(ctx.docstring, ctx.name)
142
+ if inferred:
143
+ return inferred
144
+ inferred = infer_prop_type_from_docstring(ctx.docstring)
143
145
  return inferred
144
146
  else:
145
147
  return None
@@ -249,6 +251,26 @@ class InspectionStubGenerator(BaseStubGenerator):
249
251
  self.resort_members = self.is_c_module
250
252
  super().__init__(_all_, include_private, export_less, include_docstrings)
251
253
  self.module_name = module_name
254
+ if self.is_c_module:
255
+ # Add additional implicit imports.
256
+ # C-extensions are given more lattitude since they do not import the typing module.
257
+ self.known_imports.update(
258
+ {
259
+ "typing": [
260
+ "Any",
261
+ "Callable",
262
+ "ClassVar",
263
+ "Dict",
264
+ "Iterable",
265
+ "Iterator",
266
+ "List",
267
+ "NamedTuple",
268
+ "Optional",
269
+ "Tuple",
270
+ "Union",
271
+ ]
272
+ }
273
+ )
252
274
 
253
275
  def get_default_function_sig(
254
276
  self, func: object, ctx: FunctionContext
@@ -617,11 +639,31 @@ class InspectionStubGenerator(BaseStubGenerator):
617
639
  if inferred[0].args and inferred[0].args[0].name == "cls":
618
640
  decorators.append("@classmethod")
619
641
 
642
+ if docstring:
643
+ docstring = self._indent_docstring(docstring)
620
644
  output.extend(
621
645
  self.format_func_def(inferred, decorators=decorators, docstring=docstring)
622
646
  )
623
647
  self._fix_iter(ctx, inferred, output)
624
648
 
649
+ def _indent_docstring(self, docstring: str) -> str:
650
+ """Fix indentation of docstring extracted from pybind11 or other binding generators."""
651
+ lines = docstring.splitlines(keepends=True)
652
+ indent = self._indent + " "
653
+ if len(lines) > 1:
654
+ if not all(line.startswith(indent) or not line.strip() for line in lines):
655
+ # if the docstring is not indented, then indent all but the first line
656
+ for i, line in enumerate(lines[1:]):
657
+ if line.strip():
658
+ lines[i + 1] = indent + line
659
+ # if there's a trailing newline, add a final line to visually indent the quoted docstring
660
+ if lines[-1].endswith("\n"):
661
+ if len(lines) > 1:
662
+ lines.append(indent)
663
+ else:
664
+ lines[-1] = lines[-1][:-1]
665
+ return "".join(lines)
666
+
625
667
  def _fix_iter(
626
668
  self, ctx: FunctionContext, inferred: list[FunctionSig], output: list[str]
627
669
  ) -> None:
@@ -671,7 +713,7 @@ class InspectionStubGenerator(BaseStubGenerator):
671
713
  if fget:
672
714
  alt_docstr = getattr(fget, "__doc__", None)
673
715
  if alt_docstr and docstring:
674
- docstring += alt_docstr
716
+ docstring += "\n" + alt_docstr
675
717
  elif alt_docstr:
676
718
  docstring = alt_docstr
677
719
 
@@ -55,6 +55,17 @@ MISSING: typing_extensions.Final = Missing()
55
55
  T = TypeVar("T")
56
56
  MaybeMissing: typing_extensions.TypeAlias = Union[T, Missing]
57
57
 
58
+
59
+ class Unrepresentable:
60
+ """Marker object for unrepresentable parameter defaults."""
61
+
62
+ def __repr__(self) -> str:
63
+ return "<unrepresentable>"
64
+
65
+
66
+ UNREPRESENTABLE: typing_extensions.Final = Unrepresentable()
67
+
68
+
58
69
  _formatter: typing_extensions.Final = FancyFormatter(sys.stdout, sys.stderr, False)
59
70
 
60
71
 
@@ -102,7 +113,19 @@ class Error:
102
113
  self.stub_object = stub_object
103
114
  self.runtime_object = runtime_object
104
115
  self.stub_desc = stub_desc or str(getattr(stub_object, "type", stub_object))
105
- self.runtime_desc = runtime_desc or _truncate(repr(runtime_object), 100)
116
+
117
+ if runtime_desc is None:
118
+ runtime_sig = safe_inspect_signature(runtime_object)
119
+ if runtime_sig is None:
120
+ self.runtime_desc = _truncate(repr(runtime_object), 100)
121
+ else:
122
+ runtime_is_async = inspect.iscoroutinefunction(runtime_object)
123
+ description = describe_runtime_callable(
124
+ runtime_sig, is_async=runtime_is_async
125
+ )
126
+ self.runtime_desc = _truncate(description, 100)
127
+ else:
128
+ self.runtime_desc = runtime_desc
106
129
 
107
130
  def is_missing_stub(self) -> bool:
108
131
  """Whether or not the error is for something missing from the stub."""
@@ -705,6 +728,7 @@ def _verify_arg_default_value(
705
728
  if (
706
729
  stub_default is not UNKNOWN
707
730
  and stub_default is not ...
731
+ and runtime_arg.default is not UNREPRESENTABLE
708
732
  and (
709
733
  stub_default != runtime_arg.default
710
734
  # We want the types to match exactly, e.g. in case the stub has
@@ -1057,7 +1081,9 @@ def verify_funcitem(
1057
1081
  if signature:
1058
1082
  stub_sig = Signature.from_funcitem(stub)
1059
1083
  runtime_sig = Signature.from_inspect_signature(signature)
1060
- runtime_sig_desc = f'{"async " if runtime_is_coroutine else ""}def {signature}'
1084
+ runtime_sig_desc = describe_runtime_callable(
1085
+ signature, is_async=runtime_is_coroutine
1086
+ )
1061
1087
  stub_desc = str(stub_sig)
1062
1088
  else:
1063
1089
  runtime_sig_desc, stub_desc = None, None
@@ -1564,7 +1590,27 @@ def is_read_only_property(runtime: object) -> bool:
1564
1590
 
1565
1591
  def safe_inspect_signature(runtime: Any) -> inspect.Signature | None:
1566
1592
  try:
1567
- return inspect.signature(runtime)
1593
+ try:
1594
+ return inspect.signature(runtime)
1595
+ except ValueError:
1596
+ if (
1597
+ hasattr(runtime, "__text_signature__")
1598
+ and "<unrepresentable>" in runtime.__text_signature__
1599
+ ):
1600
+ # Try to fix up the signature. Workaround for
1601
+ # https://github.com/python/cpython/issues/87233
1602
+ sig = runtime.__text_signature__.replace("<unrepresentable>", "...")
1603
+ sig = inspect._signature_fromstr(inspect.Signature, runtime, sig) # type: ignore[attr-defined]
1604
+ assert isinstance(sig, inspect.Signature)
1605
+ new_params = [
1606
+ parameter.replace(default=UNREPRESENTABLE)
1607
+ if parameter.default is ...
1608
+ else parameter
1609
+ for parameter in sig.parameters.values()
1610
+ ]
1611
+ return sig.replace(parameters=new_params)
1612
+ else:
1613
+ raise
1568
1614
  except Exception:
1569
1615
  # inspect.signature throws ValueError all the time
1570
1616
  # catch RuntimeError because of https://bugs.python.org/issue39504
@@ -1573,6 +1619,10 @@ def safe_inspect_signature(runtime: Any) -> inspect.Signature | None:
1573
1619
  return None
1574
1620
 
1575
1621
 
1622
+ def describe_runtime_callable(signature: inspect.Signature, *, is_async: bool) -> str:
1623
+ return f'{"async " if is_async else ""}def {signature}'
1624
+
1625
+
1576
1626
  def is_subtype_helper(left: mypy.types.Type, right: mypy.types.Type) -> bool:
1577
1627
  """Checks whether ``left`` is a subtype of ``right``."""
1578
1628
  left = mypy.types.get_proper_type(left)
@@ -611,6 +611,14 @@ class BaseStubGenerator:
611
611
  self.sig_generators = self.get_sig_generators()
612
612
  # populated by visit_mypy_file
613
613
  self.module_name: str = ""
614
+ # These are "soft" imports for objects which might appear in annotations but not have
615
+ # a corresponding import statement.
616
+ self.known_imports = {
617
+ "_typeshed": ["Incomplete"],
618
+ "typing": ["Any", "TypeVar", "NamedTuple"],
619
+ "collections.abc": ["Generator"],
620
+ "typing_extensions": ["TypedDict", "ParamSpec", "TypeVarTuple"],
621
+ }
614
622
 
615
623
  def get_sig_generators(self) -> list[SignatureGenerator]:
616
624
  return []
@@ -702,15 +710,7 @@ class BaseStubGenerator:
702
710
  for name in self._all_ or ():
703
711
  self.import_tracker.reexport(name)
704
712
 
705
- # These are "soft" imports for objects which might appear in annotations but not have
706
- # a corresponding import statement.
707
- known_imports = {
708
- "_typeshed": ["Incomplete"],
709
- "typing": ["Any", "TypeVar", "NamedTuple"],
710
- "collections.abc": ["Generator"],
711
- "typing_extensions": ["TypedDict", "ParamSpec", "TypeVarTuple"],
712
- }
713
- for pkg, imports in known_imports.items():
713
+ for pkg, imports in self.known_imports.items():
714
714
  for t in imports:
715
715
  # require=False means that the import won't be added unless require_name() is called
716
716
  # for the object during generation.
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import sys
4
4
  import time
5
- from multiprocessing import Process, Queue
5
+ from multiprocessing import Queue, get_context
6
6
  from unittest import TestCase, main
7
7
 
8
8
  import pytest
@@ -35,10 +35,17 @@ def server_multi_message_echo(q: Queue[str]) -> None:
35
35
 
36
36
 
37
37
  class IPCTests(TestCase):
38
+ def setUp(self) -> None:
39
+ if sys.platform == "linux":
40
+ # The default "fork" start method is potentially unsafe
41
+ self.ctx = get_context("forkserver")
42
+ else:
43
+ self.ctx = get_context("spawn")
44
+
38
45
  def test_transaction_large(self) -> None:
39
- queue: Queue[str] = Queue()
46
+ queue: Queue[str] = self.ctx.Queue()
40
47
  msg = "t" * 200000 # longer than the max read size of 100_000
41
- p = Process(target=server, args=(msg, queue), daemon=True)
48
+ p = self.ctx.Process(target=server, args=(msg, queue), daemon=True)
42
49
  p.start()
43
50
  connection_name = queue.get()
44
51
  with IPCClient(connection_name, timeout=1) as client:
@@ -49,9 +56,9 @@ class IPCTests(TestCase):
49
56
  p.join()
50
57
 
51
58
  def test_connect_twice(self) -> None:
52
- queue: Queue[str] = Queue()
59
+ queue: Queue[str] = self.ctx.Queue()
53
60
  msg = "this is a test message"
54
- p = Process(target=server, args=(msg, queue), daemon=True)
61
+ p = self.ctx.Process(target=server, args=(msg, queue), daemon=True)
55
62
  p.start()
56
63
  connection_name = queue.get()
57
64
  with IPCClient(connection_name, timeout=1) as client:
@@ -69,8 +76,10 @@ class IPCTests(TestCase):
69
76
  assert p.exitcode == 0
70
77
 
71
78
  def test_multiple_messages(self) -> None:
72
- queue: Queue[str] = Queue()
73
- p = Process(target=server_multi_message_echo, args=(queue,), daemon=True)
79
+ queue: Queue[str] = self.ctx.Queue()
80
+ p = self.ctx.Process(
81
+ target=server_multi_message_echo, args=(queue,), daemon=True
82
+ )
74
83
  p.start()
75
84
  connection_name = queue.get()
76
85
  with IPCClient(connection_name, timeout=1) as client:
@@ -72,7 +72,6 @@ class Tuple(Sequence[_T_co]): ...
72
72
  class NamedTuple(tuple[Any, ...]): ...
73
73
  def overload(func: _T) -> _T: ...
74
74
  def type_check_only(func: _T) -> _T: ...
75
- def deprecated(__msg: str) -> Callable[[_T], _T]: ...
76
75
  def final(func: _T) -> _T: ...
77
76
  """
78
77
 
@@ -449,6 +448,16 @@ class StubtestUnit(unittest.TestCase):
449
448
  error=None,
450
449
  )
451
450
 
451
+ # Simulate "<unrepresentable>"
452
+ yield Case(
453
+ stub="def f11() -> None: ...",
454
+ runtime="""
455
+ def f11(text=None) -> None: pass
456
+ f11.__text_signature__ = "(text=<unrepresentable>)"
457
+ """,
458
+ error="f11",
459
+ )
460
+
452
461
  @collect_cases
453
462
  def test_static_class_method(self) -> Iterator[Case]:
454
463
  yield Case(
@@ -687,7 +696,8 @@ class StubtestUnit(unittest.TestCase):
687
696
  )
688
697
  yield Case(
689
698
  stub="""
690
- from typing import deprecated, final
699
+ from typing import final
700
+ from typing_extensions import deprecated
691
701
  class Foo:
692
702
  @overload
693
703
  @final
@@ -2388,6 +2398,14 @@ class StubtestMiscUnit(unittest.TestCase):
2388
2398
  == "def (a, b, *, c, d = ..., **kwargs)"
2389
2399
  )
2390
2400
 
2401
+ def test_builtin_signature_with_unrepresentable_default(self) -> None:
2402
+ sig = mypy.stubtest.safe_inspect_signature(bytes.hex)
2403
+ assert sig is not None
2404
+ assert (
2405
+ str(mypy.stubtest.Signature.from_inspect_signature(sig))
2406
+ == "def (self, sep = ..., bytes_per_sep = ...)"
2407
+ )
2408
+
2391
2409
  def test_config_file(self) -> None:
2392
2410
  runtime = "temp = 5\n"
2393
2411
  stub = "from decimal import Decimal\ntemp: Decimal\n"
@@ -126,7 +126,7 @@ LITERAL_TYPE_NAMES: Final = ("typing.Literal", "typing_extensions.Literal")
126
126
  ANNOTATED_TYPE_NAMES: Final = ("typing.Annotated", "typing_extensions.Annotated")
127
127
 
128
128
  # Supported @deprecated type names
129
- DEPRECATED_TYPE_NAMES: Final = ("typing.deprecated", "typing_extensions.deprecated")
129
+ DEPRECATED_TYPE_NAMES: Final = ("warnings.deprecated", "typing_extensions.deprecated")
130
130
 
131
131
  # We use this constant in various places when checking `tuple` subtyping:
132
132
  TUPLE_LIKE_INSTANCE_NAMES: Final = (
@@ -122,9 +122,10 @@ class PreBuildVisitor(ExtendedTraverserVisitor):
122
122
  self.funcs_to_decorators[dec.func] = decorators_to_store
123
123
  super().visit_decorator(dec)
124
124
 
125
- def visit_func_def(self, fdef: FuncItem) -> None:
125
+ def visit_func_def(self, fdef: FuncDef) -> None:
126
126
  # TODO: What about overloaded functions?
127
127
  self.visit_func(fdef)
128
+ self.visit_symbol_node(fdef)
128
129
 
129
130
  def visit_lambda_expr(self, expr: LambdaExpr) -> None:
130
131
  self.visit_func(expr)
@@ -172,12 +172,10 @@ class TestRun(MypycDataSuite):
172
172
  # new by distutils, shift the mtime of all of the
173
173
  # generated artifacts back by a second.
174
174
  fudge_dir_mtimes(WORKDIR, -1)
175
- # On Ubuntu, changing the mtime doesn't work reliably. As
175
+ # On some OS, changing the mtime doesn't work reliably. As
176
176
  # a workaround, sleep.
177
- #
178
177
  # TODO: Figure out a better approach, since this slows down tests.
179
- if sys.platform == "linux":
180
- time.sleep(1.0)
178
+ time.sleep(1.0)
181
179
 
182
180
  step += 1
183
181
  with chdir_manager(".."):
File without changes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: jaclang
3
- Version: 0.2.5
3
+ Version: 0.3.0
4
4
  Home-page: https://github.com/Jaseci-Labs/jaclang
5
5
  Author: Jason Mars
6
6
  Author-email: jason@jaseci.org