jaclang 0.2.5__py3-none-any.whl → 0.3.1__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.
- jaclang/__init__.py +3 -3
- jaclang/cli/__init__.py +0 -1
- jaclang/cli/__jac_gen__/cli.py +4 -4
- jaclang/cli/__jac_gen__/cmds.py +1 -1
- jaclang/cli/__jac_gen__/cmds_impl.py +1 -1
- jaclang/core/__init__.py +5 -11
- jaclang/core/__jac_gen__/corelib.py +289 -0
- jaclang/core/__jac_gen__/corelib_impl.py +220 -0
- jaclang/core/corelib.jac +21 -34
- jaclang/core/corelib_impl.jac +317 -0
- jaclang/jac/__init__.py +1 -0
- jaclang/jac/__jac_gen__/jac_parser.py +2 -2
- jaclang/jac/absyntree.py +28 -8
- jaclang/jac/constant.py +3 -7
- jaclang/jac/parser.py +13 -9
- jaclang/jac/passes/main/__init__.py +2 -0
- jaclang/jac/passes/main/def_use_pass.py +3 -2
- jaclang/jac/passes/main/pyast_gen_pass.py +99 -34
- jaclang/jac/passes/main/schedules.py +6 -0
- jaclang/jac/passes/main/sym_tab_build_pass.py +3 -5
- jaclang/jac/passes/main/tests/test_jac_format_pass.py +22 -4
- jaclang/jac/passes/main/tests/test_type_check_pass.py +42 -0
- jaclang/jac/passes/main/type_check_pass.py +103 -0
- jaclang/jac/passes/tool/fuse_comments_pass.py +57 -39
- jaclang/jac/passes/tool/jac_formatter_pass.py +419 -192
- jaclang/jac/passes/transform.py +0 -39
- jaclang/jac/passes/utils/__init__.py +1 -0
- jaclang/jac/passes/utils/mypy_ast_build.py +302 -0
- jaclang/jac/plugin/__init__.py +5 -2
- jaclang/jac/plugin/default.py +20 -4
- jaclang/jac/plugin/feature.py +15 -6
- jaclang/jac/plugin/spec.py +34 -6
- jaclang/jac/tests/test_workspace.py +45 -5
- jaclang/jac/transpiler.py +4 -9
- jaclang/utils/helpers.py +0 -33
- jaclang/utils/lang_tools.py +3 -0
- jaclang/utils/test.py +3 -1
- jaclang/vendor/lark/py.typed +0 -0
- jaclang/vendor/mypy/checker.py +19 -12
- jaclang/vendor/mypy/checkexpr.py +31 -10
- jaclang/vendor/mypy/constraints.py +56 -38
- jaclang/vendor/mypy/expandtype.py +1 -0
- jaclang/vendor/mypy/meet.py +10 -1
- jaclang/vendor/mypy/messages.py +16 -4
- jaclang/vendor/mypy/moduleinspect.py +10 -4
- jaclang/vendor/mypy/py.typed +1 -0
- jaclang/vendor/mypy/semanal.py +18 -17
- jaclang/vendor/mypy/semanal_enum.py +7 -4
- jaclang/vendor/mypy/semanal_namedtuple.py +11 -1
- jaclang/vendor/mypy/semanal_typeddict.py +25 -11
- jaclang/vendor/mypy/stubdoc.py +18 -4
- jaclang/vendor/mypy/stubgen.py +80 -1
- jaclang/vendor/mypy/stubgenc.py +47 -5
- jaclang/vendor/mypy/stubtest.py +53 -3
- jaclang/vendor/mypy/stubutil.py +9 -9
- jaclang/vendor/mypy/test/testipc.py +16 -7
- jaclang/vendor/mypy/test/teststubtest.py +20 -2
- jaclang/vendor/mypy/types.py +1 -1
- jaclang/vendor/mypyc/irbuild/prebuildvisitor.py +2 -1
- jaclang/vendor/mypyc/test/test_run.py +2 -4
- jaclang/vendor/pluggy/py.typed +0 -0
- {jaclang-0.2.5.dist-info → jaclang-0.3.1.dist-info}/METADATA +1 -1
- {jaclang-0.2.5.dist-info → jaclang-0.3.1.dist-info}/RECORD +67 -62
- {jaclang-0.2.5.dist-info → jaclang-0.3.1.dist-info}/WHEEL +1 -1
- {jaclang-0.2.5.dist-info → jaclang-0.3.1.dist-info}/entry_points.txt +3 -0
- jaclang/core/arch_impl.jac +0 -131
- jaclang/core/element_impl.jac +0 -109
- jaclang/core/exec_ctx_impl.jac +0 -14
- jaclang/core/memory_impl.jac +0 -57
- jaclang/jac/tests/fixtures/__jac_gen__/hello_world.py +0 -5
- /jaclang/{jac/tests/fixtures → core}/__jac_gen__/__init__.py +0 -0
- {jaclang-0.2.5.dist-info → jaclang-0.3.1.dist-info}/top_level.txt +0 -0
jaclang/jac/transpiler.py
CHANGED
|
@@ -4,11 +4,7 @@ from typing import Optional, Type
|
|
|
4
4
|
import jaclang.jac.absyntree as ast
|
|
5
5
|
from jaclang.jac.parser import JacParser
|
|
6
6
|
from jaclang.jac.passes import Pass
|
|
7
|
-
from jaclang.jac.passes.main import
|
|
8
|
-
PyOutPass,
|
|
9
|
-
PyastGenPass,
|
|
10
|
-
pass_schedule,
|
|
11
|
-
)
|
|
7
|
+
from jaclang.jac.passes.main import PyOutPass, pass_schedule
|
|
12
8
|
from jaclang.jac.passes.tool import JacFormatPass
|
|
13
9
|
from jaclang.jac.passes.tool.schedules import format_pass
|
|
14
10
|
from jaclang.jac.passes.transform import Alert
|
|
@@ -18,7 +14,6 @@ def transpile_jac(file_path: str) -> list[Alert]:
|
|
|
18
14
|
"""Transpiler Jac file and return python code as string."""
|
|
19
15
|
code = jac_file_to_pass(
|
|
20
16
|
file_path=file_path,
|
|
21
|
-
target=PyastGenPass,
|
|
22
17
|
schedule=pass_schedule,
|
|
23
18
|
)
|
|
24
19
|
if isinstance(code.ir, ast.Module) and not code.errors_had:
|
|
@@ -30,7 +25,7 @@ def transpile_jac(file_path: str) -> list[Alert]:
|
|
|
30
25
|
|
|
31
26
|
def jac_file_to_pass(
|
|
32
27
|
file_path: str,
|
|
33
|
-
target: Optional[Type[Pass]] =
|
|
28
|
+
target: Optional[Type[Pass]] = None,
|
|
34
29
|
schedule: list[Type[Pass]] = pass_schedule,
|
|
35
30
|
) -> Pass:
|
|
36
31
|
"""Convert a Jac file to an AST."""
|
|
@@ -46,7 +41,7 @@ def jac_file_to_pass(
|
|
|
46
41
|
def jac_str_to_pass(
|
|
47
42
|
jac_str: str,
|
|
48
43
|
file_path: str,
|
|
49
|
-
target: Optional[Type[Pass]] =
|
|
44
|
+
target: Optional[Type[Pass]] = None,
|
|
50
45
|
schedule: list[Type[Pass]] = pass_schedule,
|
|
51
46
|
) -> Pass:
|
|
52
47
|
"""Convert a Jac file to an AST."""
|
|
@@ -64,7 +59,7 @@ def jac_str_to_pass(
|
|
|
64
59
|
|
|
65
60
|
def jac_pass_to_pass(
|
|
66
61
|
in_pass: Pass,
|
|
67
|
-
target: Optional[Type[Pass]] =
|
|
62
|
+
target: Optional[Type[Pass]] = None,
|
|
68
63
|
schedule: list[Type[Pass]] = pass_schedule,
|
|
69
64
|
) -> Pass:
|
|
70
65
|
"""Convert a Jac file to an AST."""
|
jaclang/utils/helpers.py
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
"""Utility functions and classes for Jac compilation toolchain."""
|
|
2
2
|
import re
|
|
3
3
|
import textwrap
|
|
4
|
-
import traceback
|
|
5
4
|
|
|
6
5
|
|
|
7
6
|
import jaclang.jac.absyntree as ast
|
|
8
|
-
from jaclang.jac.constant import Constants as Con, Values as Val
|
|
9
7
|
|
|
10
8
|
|
|
11
9
|
def pascal_to_snake(pascal_string: str) -> str:
|
|
@@ -44,37 +42,6 @@ def dedent_code_block(code: str) -> str:
|
|
|
44
42
|
return textwrap.dedent(code)
|
|
45
43
|
|
|
46
44
|
|
|
47
|
-
def handle_jac_error(code_string: str, e: Exception, tb: traceback.StackSummary) -> str:
|
|
48
|
-
"""Handle Jac Error."""
|
|
49
|
-
except_line = e.end_lineno if isinstance(e, SyntaxError) else list(tb)[-1].lineno
|
|
50
|
-
if not isinstance(except_line, int) or except_line == 0:
|
|
51
|
-
return ""
|
|
52
|
-
py_error_region = clip_code_section(
|
|
53
|
-
add_line_numbers(code_string), except_line, Val.JAC_ERROR_LINE_RANGE
|
|
54
|
-
)
|
|
55
|
-
try:
|
|
56
|
-
jac_err_line = int(code_string.splitlines()[except_line - 1].split()[-1])
|
|
57
|
-
mod_index = int(code_string.splitlines()[except_line - 1].split()[-2])
|
|
58
|
-
mod_paths = code_string.split(Con.JAC_DEBUG_SPLITTER)[1].strip().splitlines()
|
|
59
|
-
target_mod = mod_paths[mod_index]
|
|
60
|
-
with open(target_mod, "r") as file:
|
|
61
|
-
jac_code_string = file.read()
|
|
62
|
-
jac_error_region = clip_code_section(
|
|
63
|
-
add_line_numbers(jac_code_string), jac_err_line, Val.JAC_ERROR_LINE_RANGE
|
|
64
|
-
)
|
|
65
|
-
target_mod = f"JacCode File: {target_mod}:{jac_err_line}"
|
|
66
|
-
except Exception as e:
|
|
67
|
-
jac_error_region = str(e)
|
|
68
|
-
target_mod = ""
|
|
69
|
-
snippet = (
|
|
70
|
-
f"{Con.JAC_ERROR_PREAMBLE}\n"
|
|
71
|
-
f"{target_mod}\n"
|
|
72
|
-
f"JacCode Snippet:\n{jac_error_region}\n"
|
|
73
|
-
f"PyCode Snippet:\n{py_error_region}\n"
|
|
74
|
-
)
|
|
75
|
-
return snippet
|
|
76
|
-
|
|
77
|
-
|
|
78
45
|
def get_ast_nodes_as_snake_case() -> list[str]:
|
|
79
46
|
"""Get all AST nodes as snake case."""
|
|
80
47
|
import inspect
|
jaclang/utils/lang_tools.py
CHANGED
|
@@ -191,6 +191,9 @@ class AstTool:
|
|
|
191
191
|
arrow = "-.->" if "Optional" in kid.typ else "-->"
|
|
192
192
|
typ = (
|
|
193
193
|
kid.typ.replace("Optional[", "")
|
|
194
|
+
.replace("SubNodeList[", "")
|
|
195
|
+
.replace("SubTag[", "")
|
|
196
|
+
.replace("Sequence[", "")
|
|
194
197
|
.replace("]", "")
|
|
195
198
|
.replace("|", ",")
|
|
196
199
|
.replace("list[", "list - ")
|
jaclang/utils/test.py
CHANGED
|
@@ -65,7 +65,9 @@ class TestCaseMicroSuite(ABC, TestCase):
|
|
|
65
65
|
"""Attach micro tests."""
|
|
66
66
|
for filename in [
|
|
67
67
|
os.path.normpath(os.path.join(root, name))
|
|
68
|
-
for root, _, files in os.walk(
|
|
68
|
+
for root, _, files in os.walk(
|
|
69
|
+
os.path.dirname(os.path.dirname(jaclang.__file__))
|
|
70
|
+
)
|
|
69
71
|
for name in files
|
|
70
72
|
if name.endswith(".jac") and not name.startswith("err")
|
|
71
73
|
]:
|
|
File without changes
|
jaclang/vendor/mypy/checker.py
CHANGED
|
@@ -6106,24 +6106,31 @@ class TypeChecker(NodeVisitor[None], CheckerPluginInterface):
|
|
|
6106
6106
|
if node.arg_kinds[0] != nodes.ARG_POS:
|
|
6107
6107
|
# the first argument might be used as a kwarg
|
|
6108
6108
|
called_type = get_proper_type(self.lookup_type(node.callee))
|
|
6109
|
-
|
|
6109
|
+
|
|
6110
|
+
# TODO: there are some more cases in check_call() to handle.
|
|
6111
|
+
if isinstance(called_type, Instance):
|
|
6112
|
+
call = find_member(
|
|
6113
|
+
"__call__", called_type, called_type, is_operator=True
|
|
6114
|
+
)
|
|
6115
|
+
if call is not None:
|
|
6116
|
+
called_type = get_proper_type(call)
|
|
6110
6117
|
|
|
6111
6118
|
# *assuming* the overloaded function is correct, there's a couple cases:
|
|
6112
6119
|
# 1) The first argument has different names, but is pos-only. We don't
|
|
6113
6120
|
# care about this case, the argument must be passed positionally.
|
|
6114
6121
|
# 2) The first argument allows keyword reference, therefore must be the
|
|
6115
6122
|
# same between overloads.
|
|
6116
|
-
|
|
6117
|
-
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
|
|
6121
|
-
|
|
6122
|
-
|
|
6123
|
-
|
|
6124
|
-
|
|
6125
|
-
|
|
6126
|
-
|
|
6123
|
+
if isinstance(called_type, (CallableType, Overloaded)):
|
|
6124
|
+
name = called_type.items[0].arg_names[0]
|
|
6125
|
+
if name in node.arg_names:
|
|
6126
|
+
idx = node.arg_names.index(name)
|
|
6127
|
+
# we want the idx-th variable to be narrowed
|
|
6128
|
+
expr = collapse_walrus(node.args[idx])
|
|
6129
|
+
else:
|
|
6130
|
+
self.fail(
|
|
6131
|
+
message_registry.TYPE_GUARD_POS_ARG_REQUIRED, node
|
|
6132
|
+
)
|
|
6133
|
+
return {}, {}
|
|
6127
6134
|
if literal(expr) == LITERAL_TYPE:
|
|
6128
6135
|
# Note: we wrap the target type, so that we can special case later.
|
|
6129
6136
|
# Namely, for isinstance() we use a normal meet, while TypeGuard is
|
jaclang/vendor/mypy/checkexpr.py
CHANGED
|
@@ -3870,8 +3870,9 @@ class ExpressionChecker(ExpressionVisitor[Type]):
|
|
|
3870
3870
|
self,
|
|
3871
3871
|
left: Type,
|
|
3872
3872
|
right: Type,
|
|
3873
|
-
original_container: Type | None = None,
|
|
3874
3873
|
*,
|
|
3874
|
+
original_container: Type | None = None,
|
|
3875
|
+
seen_types: set[tuple[Type, Type]] | None = None,
|
|
3875
3876
|
prefer_literal: bool = True,
|
|
3876
3877
|
) -> bool:
|
|
3877
3878
|
"""Check for dangerous non-overlapping comparisons like 42 == 'no'.
|
|
@@ -3892,6 +3893,12 @@ class ExpressionChecker(ExpressionVisitor[Type]):
|
|
|
3892
3893
|
if not self.chk.options.strict_equality:
|
|
3893
3894
|
return False
|
|
3894
3895
|
|
|
3896
|
+
if seen_types is None:
|
|
3897
|
+
seen_types = set()
|
|
3898
|
+
if (left, right) in seen_types:
|
|
3899
|
+
return False
|
|
3900
|
+
seen_types.add((left, right))
|
|
3901
|
+
|
|
3895
3902
|
left, right = get_proper_types((left, right))
|
|
3896
3903
|
|
|
3897
3904
|
# We suppress the error if there is a custom __eq__() method on either
|
|
@@ -3949,7 +3956,9 @@ class ExpressionChecker(ExpressionVisitor[Type]):
|
|
|
3949
3956
|
abstract_set = self.chk.lookup_typeinfo("typing.AbstractSet")
|
|
3950
3957
|
left = map_instance_to_supertype(left, abstract_set)
|
|
3951
3958
|
right = map_instance_to_supertype(right, abstract_set)
|
|
3952
|
-
return self.dangerous_comparison(
|
|
3959
|
+
return self.dangerous_comparison(
|
|
3960
|
+
left.args[0], right.args[0], seen_types=seen_types
|
|
3961
|
+
)
|
|
3953
3962
|
elif left.type.has_base("typing.Mapping") and right.type.has_base(
|
|
3954
3963
|
"typing.Mapping"
|
|
3955
3964
|
):
|
|
@@ -3958,13 +3967,17 @@ class ExpressionChecker(ExpressionVisitor[Type]):
|
|
|
3958
3967
|
left = map_instance_to_supertype(left, abstract_map)
|
|
3959
3968
|
right = map_instance_to_supertype(right, abstract_map)
|
|
3960
3969
|
return self.dangerous_comparison(
|
|
3961
|
-
left.args[0], right.args[0]
|
|
3962
|
-
) or self.dangerous_comparison(
|
|
3970
|
+
left.args[0], right.args[0], seen_types=seen_types
|
|
3971
|
+
) or self.dangerous_comparison(
|
|
3972
|
+
left.args[1], right.args[1], seen_types=seen_types
|
|
3973
|
+
)
|
|
3963
3974
|
elif (
|
|
3964
3975
|
left_name in ("builtins.list", "builtins.tuple")
|
|
3965
3976
|
and right_name == left_name
|
|
3966
3977
|
):
|
|
3967
|
-
return self.dangerous_comparison(
|
|
3978
|
+
return self.dangerous_comparison(
|
|
3979
|
+
left.args[0], right.args[0], seen_types=seen_types
|
|
3980
|
+
)
|
|
3968
3981
|
elif left_name in OVERLAPPING_BYTES_ALLOWLIST and right_name in (
|
|
3969
3982
|
OVERLAPPING_BYTES_ALLOWLIST
|
|
3970
3983
|
):
|
|
@@ -6624,11 +6637,16 @@ class PolyTranslator(TypeTranslator):
|
|
|
6624
6637
|
See docstring for apply_poly() for details.
|
|
6625
6638
|
"""
|
|
6626
6639
|
|
|
6627
|
-
def __init__(
|
|
6640
|
+
def __init__(
|
|
6641
|
+
self,
|
|
6642
|
+
poly_tvars: Iterable[TypeVarLikeType],
|
|
6643
|
+
bound_tvars: frozenset[TypeVarLikeType] = frozenset(),
|
|
6644
|
+
seen_aliases: frozenset[TypeInfo] = frozenset(),
|
|
6645
|
+
) -> None:
|
|
6628
6646
|
self.poly_tvars = set(poly_tvars)
|
|
6629
6647
|
# This is a simplified version of TypeVarScope used during semantic analysis.
|
|
6630
|
-
self.bound_tvars
|
|
6631
|
-
self.seen_aliases
|
|
6648
|
+
self.bound_tvars = bound_tvars
|
|
6649
|
+
self.seen_aliases = seen_aliases
|
|
6632
6650
|
|
|
6633
6651
|
def collect_vars(self, t: CallableType | Parameters) -> list[TypeVarLikeType]:
|
|
6634
6652
|
found_vars = []
|
|
@@ -6706,10 +6724,13 @@ class PolyTranslator(TypeTranslator):
|
|
|
6706
6724
|
if t.args and t.type.is_protocol and t.type.protocol_members == ["__call__"]:
|
|
6707
6725
|
if t.type in self.seen_aliases:
|
|
6708
6726
|
raise PolyTranslationError()
|
|
6709
|
-
self.seen_aliases.add(t.type)
|
|
6710
6727
|
call = find_member("__call__", t, t, is_operator=True)
|
|
6711
6728
|
assert call is not None
|
|
6712
|
-
return call.accept(
|
|
6729
|
+
return call.accept(
|
|
6730
|
+
PolyTranslator(
|
|
6731
|
+
self.poly_tvars, self.bound_tvars, self.seen_aliases | {t.type}
|
|
6732
|
+
)
|
|
6733
|
+
)
|
|
6713
6734
|
return super().visit_instance(t)
|
|
6714
6735
|
|
|
6715
6736
|
|
|
@@ -238,29 +238,29 @@ def infer_constraints_for_callable(
|
|
|
238
238
|
callee.arg_names[i],
|
|
239
239
|
callee.arg_kinds[i],
|
|
240
240
|
)
|
|
241
|
-
if (
|
|
242
|
-
param_spec
|
|
243
|
-
and callee.arg_kinds[i] in (ARG_STAR, ARG_STAR2)
|
|
244
|
-
and not incomplete_star_mapping
|
|
245
|
-
):
|
|
241
|
+
if param_spec and callee.arg_kinds[i] in (ARG_STAR, ARG_STAR2):
|
|
246
242
|
# If actual arguments are mapped to ParamSpec type, we can't infer individual
|
|
247
243
|
# constraints, instead store them and infer single constraint at the end.
|
|
248
244
|
# It is impossible to map actual kind to formal kind, so use some heuristic.
|
|
249
245
|
# This inference is used as a fallback, so relying on heuristic should be OK.
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
246
|
+
if not incomplete_star_mapping:
|
|
247
|
+
param_spec_arg_types.append(
|
|
248
|
+
mapper.expand_actual_type(
|
|
249
|
+
actual_arg_type,
|
|
250
|
+
arg_kinds[actual],
|
|
251
|
+
None,
|
|
252
|
+
arg_kinds[actual],
|
|
253
|
+
)
|
|
254
|
+
)
|
|
255
|
+
actual_kind = arg_kinds[actual]
|
|
256
|
+
param_spec_arg_kinds.append(
|
|
257
|
+
ARG_POS
|
|
258
|
+
if actual_kind not in (ARG_STAR, ARG_STAR2)
|
|
259
|
+
else actual_kind
|
|
260
|
+
)
|
|
261
|
+
param_spec_arg_names.append(
|
|
262
|
+
arg_names[actual] if arg_names else None
|
|
253
263
|
)
|
|
254
|
-
)
|
|
255
|
-
actual_kind = arg_kinds[actual]
|
|
256
|
-
param_spec_arg_kinds.append(
|
|
257
|
-
ARG_POS
|
|
258
|
-
if actual_kind not in (ARG_STAR, ARG_STAR2)
|
|
259
|
-
else actual_kind
|
|
260
|
-
)
|
|
261
|
-
param_spec_arg_names.append(
|
|
262
|
-
arg_names[actual] if arg_names else None
|
|
263
|
-
)
|
|
264
264
|
else:
|
|
265
265
|
c = infer_constraints(
|
|
266
266
|
callee.arg_types[i], actual_type, SUPERTYPE_OF
|
|
@@ -285,6 +285,9 @@ def infer_constraints_for_callable(
|
|
|
285
285
|
),
|
|
286
286
|
)
|
|
287
287
|
)
|
|
288
|
+
if any(isinstance(v, ParamSpecType) for v in callee.variables):
|
|
289
|
+
# As a perf optimization filter imprecise constraints only when we can have them.
|
|
290
|
+
constraints = filter_imprecise_kinds(constraints)
|
|
288
291
|
return constraints
|
|
289
292
|
|
|
290
293
|
|
|
@@ -1197,32 +1200,23 @@ class ConstraintBuilderVisitor(TypeVisitor[List[Constraint]]):
|
|
|
1197
1200
|
)
|
|
1198
1201
|
|
|
1199
1202
|
param_spec_target: Type | None = None
|
|
1200
|
-
skip_imprecise = (
|
|
1201
|
-
any(c.type_var == param_spec.id for c in res)
|
|
1202
|
-
and cactual.imprecise_arg_kinds
|
|
1203
|
-
)
|
|
1204
1203
|
if not cactual_ps:
|
|
1205
1204
|
max_prefix_len = len(
|
|
1206
1205
|
[k for k in cactual.arg_kinds if k in (ARG_POS, ARG_OPT)]
|
|
1207
1206
|
)
|
|
1208
1207
|
prefix_len = min(prefix_len, max_prefix_len)
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
else [],
|
|
1219
|
-
imprecise_arg_kinds=cactual.imprecise_arg_kinds,
|
|
1220
|
-
)
|
|
1208
|
+
param_spec_target = Parameters(
|
|
1209
|
+
arg_types=cactual.arg_types[prefix_len:],
|
|
1210
|
+
arg_kinds=cactual.arg_kinds[prefix_len:],
|
|
1211
|
+
arg_names=cactual.arg_names[prefix_len:],
|
|
1212
|
+
variables=cactual.variables
|
|
1213
|
+
if not type_state.infer_polymorphic
|
|
1214
|
+
else [],
|
|
1215
|
+
imprecise_arg_kinds=cactual.imprecise_arg_kinds,
|
|
1216
|
+
)
|
|
1221
1217
|
else:
|
|
1222
|
-
if (
|
|
1223
|
-
|
|
1224
|
-
<= len(cactual_ps.prefix.arg_types)
|
|
1225
|
-
and not skip_imprecise
|
|
1218
|
+
if len(param_spec.prefix.arg_types) <= len(
|
|
1219
|
+
cactual_ps.prefix.arg_types
|
|
1226
1220
|
):
|
|
1227
1221
|
param_spec_target = cactual_ps.copy_modified(
|
|
1228
1222
|
prefix=Parameters(
|
|
@@ -1770,3 +1764,27 @@ def infer_callable_arguments_constraints(
|
|
|
1770
1764
|
)
|
|
1771
1765
|
)
|
|
1772
1766
|
return res
|
|
1767
|
+
|
|
1768
|
+
|
|
1769
|
+
def filter_imprecise_kinds(cs: list[Constraint]) -> list[Constraint]:
|
|
1770
|
+
"""For each ParamSpec remove all imprecise constraints, if at least one precise available."""
|
|
1771
|
+
have_precise = set()
|
|
1772
|
+
for c in cs:
|
|
1773
|
+
if not isinstance(c.origin_type_var, ParamSpecType):
|
|
1774
|
+
continue
|
|
1775
|
+
if (
|
|
1776
|
+
isinstance(c.target, ParamSpecType)
|
|
1777
|
+
or isinstance(c.target, Parameters)
|
|
1778
|
+
and not c.target.imprecise_arg_kinds
|
|
1779
|
+
):
|
|
1780
|
+
have_precise.add(c.type_var)
|
|
1781
|
+
new_cs = []
|
|
1782
|
+
for c in cs:
|
|
1783
|
+
if (
|
|
1784
|
+
not isinstance(c.origin_type_var, ParamSpecType)
|
|
1785
|
+
or c.type_var not in have_precise
|
|
1786
|
+
):
|
|
1787
|
+
new_cs.append(c)
|
|
1788
|
+
if not isinstance(c.target, Parameters) or not c.target.imprecise_arg_kinds:
|
|
1789
|
+
new_cs.append(c)
|
|
1790
|
+
return new_cs
|
|
@@ -256,6 +256,7 @@ class ExpandTypeVisitor(TrivialSyntheticTypeTranslator):
|
|
|
256
256
|
t.prefix.arg_kinds + repl.arg_kinds,
|
|
257
257
|
t.prefix.arg_names + repl.arg_names,
|
|
258
258
|
variables=[*t.prefix.variables, *repl.variables],
|
|
259
|
+
imprecise_arg_kinds=repl.imprecise_arg_kinds,
|
|
259
260
|
)
|
|
260
261
|
else:
|
|
261
262
|
# We could encode Any as trivial parameters etc., but it would be too verbose.
|
jaclang/vendor/mypy/meet.py
CHANGED
|
@@ -268,6 +268,7 @@ def is_overlapping_types(
|
|
|
268
268
|
ignore_promotions: bool = False,
|
|
269
269
|
prohibit_none_typevar_overlap: bool = False,
|
|
270
270
|
ignore_uninhabited: bool = False,
|
|
271
|
+
seen_types: set[tuple[Type, Type]] | None = None,
|
|
271
272
|
) -> bool:
|
|
272
273
|
"""Can a value of type 'left' also be of type 'right' or vice-versa?
|
|
273
274
|
|
|
@@ -281,12 +282,19 @@ def is_overlapping_types(
|
|
|
281
282
|
# A type guard forces the new type even if it doesn't overlap the old.
|
|
282
283
|
return True
|
|
283
284
|
|
|
285
|
+
if seen_types is None:
|
|
286
|
+
seen_types = set()
|
|
287
|
+
if (left, right) in seen_types:
|
|
288
|
+
return True
|
|
289
|
+
if isinstance(left, TypeAliasType) and isinstance(right, TypeAliasType):
|
|
290
|
+
seen_types.add((left, right))
|
|
291
|
+
|
|
284
292
|
left, right = get_proper_types((left, right))
|
|
285
293
|
|
|
286
294
|
def _is_overlapping_types(left: Type, right: Type) -> bool:
|
|
287
295
|
"""Encode the kind of overlapping check to perform.
|
|
288
296
|
|
|
289
|
-
This function mostly exists so we don't have to repeat keyword arguments everywhere.
|
|
297
|
+
This function mostly exists, so we don't have to repeat keyword arguments everywhere.
|
|
290
298
|
"""
|
|
291
299
|
return is_overlapping_types(
|
|
292
300
|
left,
|
|
@@ -294,6 +302,7 @@ def is_overlapping_types(
|
|
|
294
302
|
ignore_promotions=ignore_promotions,
|
|
295
303
|
prohibit_none_typevar_overlap=prohibit_none_typevar_overlap,
|
|
296
304
|
ignore_uninhabited=ignore_uninhabited,
|
|
305
|
+
seen_types=seen_types.copy(),
|
|
297
306
|
)
|
|
298
307
|
|
|
299
308
|
# We should never encounter this type.
|
jaclang/vendor/mypy/messages.py
CHANGED
|
@@ -1052,10 +1052,22 @@ class MessageBuilder:
|
|
|
1052
1052
|
context,
|
|
1053
1053
|
)
|
|
1054
1054
|
|
|
1055
|
+
def unexpected_keyword_argument_for_function(
|
|
1056
|
+
self,
|
|
1057
|
+
for_func: str,
|
|
1058
|
+
name: str,
|
|
1059
|
+
context: Context,
|
|
1060
|
+
*,
|
|
1061
|
+
matches: list[str] | None = None,
|
|
1062
|
+
) -> None:
|
|
1063
|
+
msg = f'Unexpected keyword argument "{name}"' + for_func
|
|
1064
|
+
if matches:
|
|
1065
|
+
msg += f"; did you mean {pretty_seq(matches, 'or')}?"
|
|
1066
|
+
self.fail(msg, context, code=codes.CALL_ARG)
|
|
1067
|
+
|
|
1055
1068
|
def unexpected_keyword_argument(
|
|
1056
1069
|
self, callee: CallableType, name: str, arg_type: Type, context: Context
|
|
1057
1070
|
) -> None:
|
|
1058
|
-
msg = f'Unexpected keyword argument "{name}"' + for_function(callee)
|
|
1059
1071
|
# Suggest intended keyword, look for type match else fallback on any match.
|
|
1060
1072
|
matching_type_args = []
|
|
1061
1073
|
not_matching_type_args = []
|
|
@@ -1069,9 +1081,9 @@ class MessageBuilder:
|
|
|
1069
1081
|
matches = best_matches(name, matching_type_args, n=3)
|
|
1070
1082
|
if not matches:
|
|
1071
1083
|
matches = best_matches(name, not_matching_type_args, n=3)
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1084
|
+
self.unexpected_keyword_argument_for_function(
|
|
1085
|
+
for_function(callee), name, context, matches=matches
|
|
1086
|
+
)
|
|
1075
1087
|
module = find_defining_module(self.modules, callee)
|
|
1076
1088
|
if module:
|
|
1077
1089
|
assert callee.definition is not None
|
|
@@ -8,7 +8,7 @@ import os
|
|
|
8
8
|
import pkgutil
|
|
9
9
|
import queue
|
|
10
10
|
import sys
|
|
11
|
-
from multiprocessing import
|
|
11
|
+
from multiprocessing import Queue, get_context
|
|
12
12
|
from types import ModuleType
|
|
13
13
|
|
|
14
14
|
|
|
@@ -133,9 +133,15 @@ class ModuleInspect:
|
|
|
133
133
|
self._start()
|
|
134
134
|
|
|
135
135
|
def _start(self) -> None:
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
136
|
+
if sys.platform == "linux":
|
|
137
|
+
ctx = get_context("forkserver")
|
|
138
|
+
else:
|
|
139
|
+
ctx = get_context("spawn")
|
|
140
|
+
self.tasks: Queue[str] = ctx.Queue()
|
|
141
|
+
self.results: Queue[ModuleProperties | str] = ctx.Queue()
|
|
142
|
+
self.proc = ctx.Process(
|
|
143
|
+
target=worker, args=(self.tasks, self.results, sys.path)
|
|
144
|
+
)
|
|
139
145
|
self.proc.start()
|
|
140
146
|
self.counter = 0 # Number of successful roundtrips
|
|
141
147
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Marker file for PEP 561. The mypy package uses inline types.
|
jaclang/vendor/mypy/semanal.py
CHANGED
|
@@ -811,7 +811,7 @@ class SemanticAnalyzer(
|
|
|
811
811
|
self.globals = file_node.names
|
|
812
812
|
self.tvar_scope = TypeVarLikeScope()
|
|
813
813
|
|
|
814
|
-
self.named_tuple_analyzer = NamedTupleAnalyzer(options, self)
|
|
814
|
+
self.named_tuple_analyzer = NamedTupleAnalyzer(options, self, self.msg)
|
|
815
815
|
self.typed_dict_analyzer = TypedDictAnalyzer(options, self, self.msg)
|
|
816
816
|
self.enum_call_analyzer = EnumCallAnalyzer(options, self)
|
|
817
817
|
self.newtype_analyzer = NewTypeAnalyzer(options, self, self.msg)
|
|
@@ -3035,22 +3035,23 @@ class SemanticAnalyzer(
|
|
|
3035
3035
|
if self.check_and_set_up_type_alias(s):
|
|
3036
3036
|
s.is_alias_def = True
|
|
3037
3037
|
special_form = True
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3038
|
+
elif isinstance(s.rvalue, CallExpr):
|
|
3039
|
+
# * type variable definition
|
|
3040
|
+
if self.process_typevar_declaration(s):
|
|
3041
|
+
special_form = True
|
|
3042
|
+
elif self.process_paramspec_declaration(s):
|
|
3043
|
+
special_form = True
|
|
3044
|
+
elif self.process_typevartuple_declaration(s):
|
|
3045
|
+
special_form = True
|
|
3046
|
+
# * type constructors
|
|
3047
|
+
elif self.analyze_namedtuple_assign(s):
|
|
3048
|
+
special_form = True
|
|
3049
|
+
elif self.analyze_typeddict_assign(s):
|
|
3050
|
+
special_form = True
|
|
3051
|
+
elif self.newtype_analyzer.process_newtype_declaration(s):
|
|
3052
|
+
special_form = True
|
|
3053
|
+
elif self.analyze_enum_assign(s):
|
|
3054
|
+
special_form = True
|
|
3054
3055
|
|
|
3055
3056
|
if special_form:
|
|
3056
3057
|
self.record_special_form_lvalue(s)
|
|
@@ -106,16 +106,19 @@ class EnumCallAnalyzer:
|
|
|
106
106
|
items, values, ok = self.parse_enum_call_args(call, fullname.split(".")[-1])
|
|
107
107
|
if not ok:
|
|
108
108
|
# Error. Construct dummy return value.
|
|
109
|
-
|
|
109
|
+
name = var_name
|
|
110
|
+
if is_func_scope:
|
|
111
|
+
name += "@" + str(call.line)
|
|
112
|
+
info = self.build_enum_call_typeinfo(name, [], fullname, node.line)
|
|
110
113
|
else:
|
|
111
114
|
name = cast(StrExpr, call.args[0]).value
|
|
112
115
|
if name != var_name or is_func_scope:
|
|
113
116
|
# Give it a unique name derived from the line number.
|
|
114
117
|
name += "@" + str(call.line)
|
|
115
118
|
info = self.build_enum_call_typeinfo(name, items, fullname, call.line)
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
+
# Store generated TypeInfo under both names, see semanal_namedtuple for more details.
|
|
120
|
+
if name != var_name or is_func_scope:
|
|
121
|
+
self.api.add_symbol_skip_local(name, info)
|
|
119
122
|
call.analyzed = EnumCallExpr(info, items, values)
|
|
120
123
|
call.analyzed.set_line(call)
|
|
121
124
|
info.line = node.line
|
|
@@ -9,6 +9,7 @@ from contextlib import contextmanager
|
|
|
9
9
|
from typing import Final, Iterator, List, Mapping, cast
|
|
10
10
|
|
|
11
11
|
from mypy.exprtotype import TypeTranslationError, expr_to_unanalyzed_type
|
|
12
|
+
from mypy.messages import MessageBuilder
|
|
12
13
|
from mypy.nodes import (
|
|
13
14
|
ARG_NAMED_OPT,
|
|
14
15
|
ARG_OPT,
|
|
@@ -92,9 +93,12 @@ SELF_TVAR_NAME: Final = "_NT"
|
|
|
92
93
|
|
|
93
94
|
|
|
94
95
|
class NamedTupleAnalyzer:
|
|
95
|
-
def __init__(
|
|
96
|
+
def __init__(
|
|
97
|
+
self, options: Options, api: SemanticAnalyzerInterface, msg: MessageBuilder
|
|
98
|
+
) -> None:
|
|
96
99
|
self.options = options
|
|
97
100
|
self.api = api
|
|
101
|
+
self.msg = msg
|
|
98
102
|
|
|
99
103
|
def analyze_namedtuple_classdef(
|
|
100
104
|
self, defn: ClassDef, is_stub_file: bool, is_func_scope: bool
|
|
@@ -212,6 +216,12 @@ class NamedTupleAnalyzer:
|
|
|
212
216
|
)
|
|
213
217
|
else:
|
|
214
218
|
default_items[name] = stmt.rvalue
|
|
219
|
+
if defn.keywords:
|
|
220
|
+
for_function = ' for "__init_subclass__" of "NamedTuple"'
|
|
221
|
+
for key in defn.keywords:
|
|
222
|
+
self.msg.unexpected_keyword_argument_for_function(
|
|
223
|
+
for_function, key, defn
|
|
224
|
+
)
|
|
215
225
|
return items, types, default_items, statements
|
|
216
226
|
|
|
217
227
|
def check_namedtuple(
|