jaclang 0.4.7__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.
- jaclang/__init__.py +5 -2
- jaclang/cli/cli.py +56 -8
- jaclang/cli/cmdreg.py +16 -9
- jaclang/compiler/__jac_gen__/jac_parser.py +11 -15
- jaclang/compiler/absyntree.py +53 -19
- jaclang/compiler/codeloc.py +3 -1
- jaclang/compiler/{transpiler.py → compile.py} +3 -2
- jaclang/compiler/constant.py +4 -0
- jaclang/compiler/parser.py +156 -108
- jaclang/compiler/passes/ir_pass.py +1 -0
- jaclang/compiler/passes/main/__init__.py +2 -1
- jaclang/compiler/passes/main/def_impl_match_pass.py +1 -0
- jaclang/compiler/passes/main/def_use_pass.py +1 -0
- jaclang/compiler/passes/main/import_pass.py +18 -18
- jaclang/compiler/passes/main/pyast_gen_pass.py +1228 -853
- jaclang/compiler/passes/main/pyast_load_pass.py +3 -1
- jaclang/compiler/passes/main/pybc_gen_pass.py +46 -0
- jaclang/compiler/passes/main/pyout_pass.py +6 -7
- jaclang/compiler/passes/main/schedules.py +5 -9
- jaclang/compiler/passes/main/sub_node_tab_pass.py +1 -0
- jaclang/compiler/passes/main/sym_tab_build_pass.py +21 -9
- jaclang/compiler/passes/main/tests/test_decl_def_match_pass.py +2 -1
- jaclang/compiler/passes/main/tests/test_def_use_pass.py +2 -1
- jaclang/compiler/passes/main/tests/test_import_pass.py +2 -1
- jaclang/compiler/passes/main/tests/test_pyast_build_pass.py +1 -0
- jaclang/compiler/passes/main/tests/test_pyast_gen_pass.py +15 -38
- jaclang/compiler/passes/main/tests/test_pybc_gen_pass.py +25 -0
- jaclang/compiler/passes/main/tests/test_sub_node_pass.py +1 -1
- jaclang/compiler/passes/main/tests/test_sym_tab_build_pass.py +2 -1
- jaclang/compiler/passes/main/tests/test_type_check_pass.py +17 -1
- jaclang/compiler/passes/main/type_check_pass.py +9 -6
- jaclang/compiler/passes/tool/__init__.py +1 -0
- jaclang/compiler/passes/tool/ast_printer_pass.py +1 -0
- jaclang/compiler/passes/tool/fuse_comments_pass.py +1 -1
- jaclang/compiler/passes/tool/jac_formatter_pass.py +69 -32
- jaclang/compiler/passes/tool/schedules.py +1 -0
- jaclang/compiler/passes/tool/sym_tab_printer_pass.py +1 -0
- jaclang/compiler/passes/tool/tests/test_ast_print_pass.py +2 -1
- jaclang/compiler/passes/tool/tests/test_fuse_comments_pass.py +1 -0
- jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +4 -3
- jaclang/compiler/passes/tool/tests/test_symtab_print_pass.py +2 -1
- jaclang/compiler/passes/transform.py +1 -0
- jaclang/compiler/passes/utils/mypy_ast_build.py +203 -17
- jaclang/compiler/symtable.py +1 -0
- jaclang/compiler/tests/test_importer.py +3 -2
- jaclang/compiler/tests/test_parser.py +1 -0
- jaclang/compiler/tests/test_workspace.py +1 -0
- jaclang/compiler/workspace.py +18 -5
- jaclang/core/construct.py +9 -32
- jaclang/{compiler → core}/importer.py +95 -85
- jaclang/core/utils.py +17 -12
- jaclang/plugin/__init__.py +1 -0
- jaclang/plugin/default.py +145 -43
- jaclang/plugin/feature.py +65 -19
- jaclang/plugin/spec.py +56 -34
- jaclang/plugin/tests/test_features.py +9 -0
- jaclang/utils/helpers.py +1 -0
- jaclang/utils/lang_tools.py +13 -19
- jaclang/utils/tests/test_lang_tools.py +2 -1
- jaclang/utils/treeprinter.py +2 -1
- jaclang/vendor/lark/common.py +3 -1
- jaclang/vendor/lark/lexer.py +6 -12
- jaclang/vendor/lark/parsers/lalr_parser.py +1 -0
- jaclang/vendor/mypy/applytype.py +2 -1
- jaclang/vendor/mypy/binder.py +1 -1
- jaclang/vendor/mypy/build.py +7 -9
- jaclang/vendor/mypy/checker.py +57 -33
- jaclang/vendor/mypy/checkexpr.py +42 -29
- jaclang/vendor/mypy/checkmember.py +13 -1
- jaclang/vendor/mypy/checkpattern.py +1 -1
- jaclang/vendor/mypy/checkstrformat.py +2 -4
- jaclang/vendor/mypy/constraints.py +10 -5
- jaclang/vendor/mypy/dmypy_server.py +3 -3
- jaclang/vendor/mypy/dmypy_util.py +62 -3
- jaclang/vendor/mypy/errors.py +1 -1
- jaclang/vendor/mypy/evalexpr.py +1 -0
- jaclang/vendor/mypy/expandtype.py +29 -29
- jaclang/vendor/mypy/fastparse.py +51 -31
- jaclang/vendor/mypy/inspections.py +5 -3
- jaclang/vendor/mypy/join.py +4 -4
- jaclang/vendor/mypy/main.py +6 -6
- jaclang/vendor/mypy/message_registry.py +1 -2
- jaclang/vendor/mypy/messages.py +31 -23
- jaclang/vendor/mypy/metastore.py +1 -2
- jaclang/vendor/mypy/modulefinder.py +2 -22
- jaclang/vendor/mypy/nodes.py +22 -20
- jaclang/vendor/mypy/options.py +4 -0
- jaclang/vendor/mypy/parse.py +6 -2
- jaclang/vendor/mypy/patterns.py +6 -6
- jaclang/vendor/mypy/plugin.py +3 -1
- jaclang/vendor/mypy/plugins/attrs.py +52 -10
- jaclang/vendor/mypy/plugins/common.py +2 -1
- jaclang/vendor/mypy/plugins/enums.py +3 -2
- jaclang/vendor/mypy/plugins/functools.py +1 -0
- jaclang/vendor/mypy/renaming.py +1 -1
- jaclang/vendor/mypy/report.py +15 -15
- jaclang/vendor/mypy/semanal.py +22 -13
- jaclang/vendor/mypy/semanal_enum.py +1 -1
- jaclang/vendor/mypy/semanal_namedtuple.py +1 -2
- jaclang/vendor/mypy/semanal_shared.py +3 -6
- jaclang/vendor/mypy/semanal_typeddict.py +16 -5
- jaclang/vendor/mypy/server/astdiff.py +15 -9
- jaclang/vendor/mypy/server/astmerge.py +5 -5
- jaclang/vendor/mypy/stats.py +0 -5
- jaclang/vendor/mypy/stubdoc.py +1 -1
- jaclang/vendor/mypy/stubgen.py +12 -21
- jaclang/vendor/mypy/stubgenc.py +16 -8
- jaclang/vendor/mypy/stubtest.py +57 -48
- jaclang/vendor/mypy/stubutil.py +28 -15
- jaclang/vendor/mypy/subtypes.py +4 -4
- jaclang/vendor/mypy/test/helpers.py +2 -2
- jaclang/vendor/mypy/test/meta/test_parse_data.py +1 -0
- jaclang/vendor/mypy/test/meta/test_update_data.py +1 -0
- jaclang/vendor/mypy/test/testargs.py +1 -0
- jaclang/vendor/mypy/test/testcheck.py +4 -1
- jaclang/vendor/mypy/test/testconstraints.py +25 -7
- jaclang/vendor/mypy/test/testerrorstream.py +1 -0
- jaclang/vendor/mypy/test/testformatter.py +2 -2
- jaclang/vendor/mypy/test/testparse.py +6 -4
- jaclang/vendor/mypy/test/testpythoneval.py +1 -0
- jaclang/vendor/mypy/test/testreports.py +1 -0
- jaclang/vendor/mypy/test/teststubgen.py +1 -2
- jaclang/vendor/mypy/test/teststubtest.py +98 -4
- jaclang/vendor/mypy/test/testtypes.py +1 -1
- jaclang/vendor/mypy/test/testutil.py +22 -0
- jaclang/vendor/mypy/typeanal.py +302 -158
- jaclang/vendor/mypy/typeops.py +22 -13
- jaclang/vendor/mypy/types.py +33 -34
- jaclang/vendor/mypy/typestate.py +2 -2
- jaclang/vendor/mypy/util.py +7 -6
- jaclang/vendor/mypy/version.py +1 -1
- jaclang/vendor/mypyc/analysis/ircheck.py +1 -0
- jaclang/vendor/mypyc/codegen/emitfunc.py +5 -3
- jaclang/vendor/mypyc/codegen/emitmodule.py +12 -12
- jaclang/vendor/mypyc/codegen/emitwrapper.py +2 -2
- jaclang/vendor/mypyc/ir/class_ir.py +10 -6
- jaclang/vendor/mypyc/irbuild/builder.py +3 -4
- jaclang/vendor/mypyc/irbuild/function.py +5 -3
- jaclang/vendor/mypyc/irbuild/nonlocalcontrol.py +1 -2
- jaclang/vendor/mypyc/irbuild/prepare.py +6 -6
- jaclang/vendor/mypyc/primitives/registry.py +15 -5
- jaclang/vendor/mypyc/test/test_run.py +1 -2
- jaclang/vendor/mypyc/transform/uninit.py +3 -3
- jaclang/vendor/pluggy/_callers.py +1 -0
- jaclang/vendor/pluggy/_hooks.py +6 -10
- jaclang/vendor/pluggy/_result.py +1 -0
- jaclang/vendor/pluggy/_tracing.py +1 -0
- {jaclang-0.4.7.dist-info → jaclang-0.5.0.dist-info}/METADATA +1 -1
- {jaclang-0.4.7.dist-info → jaclang-0.5.0.dist-info}/RECORD +152 -150
- {jaclang-0.4.7.dist-info → jaclang-0.5.0.dist-info}/WHEEL +0 -0
- {jaclang-0.4.7.dist-info → jaclang-0.5.0.dist-info}/entry_points.txt +0 -0
- {jaclang-0.4.7.dist-info → jaclang-0.5.0.dist-info}/top_level.txt +0 -0
jaclang/vendor/mypy/typeanal.py
CHANGED
|
@@ -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
|
-
|
|
1735
|
-
|
|
1736
|
-
return
|
|
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
|
-
"""
|
|
1746
|
-
|
|
1747
|
-
|
|
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
|
-
|
|
1750
|
-
|
|
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
|
-
|
|
1758
|
-
|
|
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
|
-
|
|
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(
|
|
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, [
|
|
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
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
t.args = (
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
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
|
-
|
|
2128
|
+
max_tv_count = len(node.alias_tvars)
|
|
2120
2129
|
act_len = len(args)
|
|
2121
2130
|
if (
|
|
2122
|
-
|
|
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
|
|
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
|
-
|
|
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(
|
|
2158
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
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
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
2503
|
-
|
|
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: {
|
|
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
|
-
|
|
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
|
-
|
|
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)
|