Skip to content

Commit 50bb05f

Browse files
committed
Merge master into pkgdata
2 parents 7c48b4a + 2b15be3 commit 50bb05f

30 files changed

+1612
-583
lines changed

docs/source/builtin_types.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ The type ``Any`` and type constructors such as ``List``, ``Dict``,
2727

2828
The type ``Dict`` is a *generic* class, signified by type arguments within
2929
``[...]``. For example, ``Dict[int, str]`` is a dictionary from integers to
30-
strings and and ``Dict[Any, Any]`` is a dictionary of dynamically typed
30+
strings and ``Dict[Any, Any]`` is a dictionary of dynamically typed
3131
(arbitrary) values and keys. ``List`` is another generic class. ``Dict`` and
3232
``List`` are aliases for the built-ins ``dict`` and ``list``, respectively.
3333

mypy/bogus_type.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,16 @@
1010
For those cases some other technique should be used.
1111
"""
1212

13+
import sys
14+
1315
from mypy_extensions import FlexibleAlias
1416
from typing import TypeVar, Any
1517

1618
T = TypeVar('T')
1719

18-
SUPPRESS_BOGUS_TYPES = False
19-
if SUPPRESS_BOGUS_TYPES:
20+
# This won't ever be true at runtime, but we consider it true during
21+
# mypyc compilations.
22+
if sys.platform == 'mypyc':
2023
Bogus = FlexibleAlias[T, Any]
2124
else:
2225
Bogus = FlexibleAlias[T, T]

mypy/checker.py

Lines changed: 144 additions & 125 deletions
Large diffs are not rendered by default.

mypy/checkexpr.py

Lines changed: 52 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -720,8 +720,8 @@ def analyze_type_type_callee(self, item: Type, context: Context) -> Type:
720720
res = res.copy_modified(from_type_type=True)
721721
return expand_type_by_instance(res, item)
722722
if isinstance(item, UnionType):
723-
return UnionType([self.analyze_type_type_callee(item, context)
724-
for item in item.relevant_items()], item.line)
723+
return UnionType([self.analyze_type_type_callee(tp, context)
724+
for tp in item.relevant_items()], item.line)
725725
if isinstance(item, TypeVarType):
726726
# Pretend we're calling the typevar's upper bound,
727727
# i.e. its constructor (a poor approximation for reality,
@@ -1575,12 +1575,9 @@ def union_overload_matches(self, types: Sequence[Type]) -> Union[AnyType, Callab
15751575
def erased_signature_similarity(self, arg_types: List[Type], arg_kinds: List[int],
15761576
arg_names: Optional[Sequence[Optional[str]]],
15771577
callee: CallableType,
1578-
context: Context) -> int:
1579-
"""Determine whether arguments could match the signature at runtime.
1580-
1581-
Return similarity level (0 = no match, 1 = can match, 2 = non-promotion match). See
1582-
overload_arg_similarity for a discussion of similarity levels.
1583-
"""
1578+
context: Context) -> bool:
1579+
"""Determine whether arguments could match the signature at runtime, after
1580+
erasing types."""
15841581
formal_to_actual = map_actuals_to_formals(arg_kinds,
15851582
arg_names,
15861583
callee.arg_kinds,
@@ -1590,55 +1587,22 @@ def erased_signature_similarity(self, arg_types: List[Type], arg_kinds: List[int
15901587
if not self.check_argument_count(callee, arg_types, arg_kinds, arg_names,
15911588
formal_to_actual, None, None):
15921589
# Too few or many arguments -> no match.
1593-
return 0
1594-
1595-
similarity = 2
1590+
return False
15961591

15971592
def check_arg(caller_type: Type, original_caller_type: Type, caller_kind: int,
15981593
callee_type: Type, n: int, m: int, callee: CallableType,
15991594
context: Context, messages: MessageBuilder) -> None:
1600-
nonlocal similarity
1601-
similarity = min(similarity,
1602-
overload_arg_similarity(caller_type, callee_type))
1603-
if similarity == 0:
1595+
if not arg_approximate_similarity(caller_type, callee_type):
16041596
# No match -- exit early since none of the remaining work can change
16051597
# the result.
16061598
raise Finished
16071599

16081600
try:
16091601
self.check_argument_types(arg_types, arg_kinds, callee, formal_to_actual,
16101602
context=context, check_arg=check_arg)
1603+
return True
16111604
except Finished:
1612-
pass
1613-
1614-
return similarity
1615-
1616-
def match_signature_types(self, arg_types: List[Type], arg_kinds: List[int],
1617-
arg_names: Optional[Sequence[Optional[str]]], callee: CallableType,
1618-
context: Context) -> bool:
1619-
"""Determine whether arguments types match the signature.
1620-
1621-
Assume that argument counts are compatible.
1622-
1623-
Return True if arguments match.
1624-
"""
1625-
formal_to_actual = map_actuals_to_formals(arg_kinds,
1626-
arg_names,
1627-
callee.arg_kinds,
1628-
callee.arg_names,
1629-
lambda i: arg_types[i])
1630-
ok = True
1631-
1632-
def check_arg(caller_type: Type, original_caller_type: Type, caller_kind: int,
1633-
callee_type: Type, n: int, m: int, callee: CallableType,
1634-
context: Context, messages: MessageBuilder) -> None:
1635-
nonlocal ok
1636-
if not is_subtype(caller_type, callee_type):
1637-
ok = False
1638-
1639-
self.check_argument_types(arg_types, arg_kinds, callee, formal_to_actual,
1640-
context=context, check_arg=check_arg)
1641-
return ok
1605+
return False
16421606

16431607
def apply_generic_arguments(self, callable: CallableType, types: Sequence[Optional[Type]],
16441608
context: Context) -> CallableType:
@@ -3399,101 +3363,68 @@ def visit_uninhabited_type(self, t: UninhabitedType) -> bool:
33993363
return True
34003364

34013365

3402-
def overload_arg_similarity(actual: Type, formal: Type) -> int:
3403-
"""Return if caller argument (actual) is compatible with overloaded signature arg (formal).
3366+
def arg_approximate_similarity(actual: Type, formal: Type) -> bool:
3367+
"""Return if caller argument (actual) is roughly compatible with signature arg (formal).
34043368
3405-
Return a similarity level:
3406-
0: no match
3407-
1: actual is compatible, but only using type promotions (e.g. int vs float)
3408-
2: actual is compatible without type promotions (e.g. int vs object)
3369+
This function is deliberately loose and will report two types are similar
3370+
as long as their "shapes" are plausibly the same.
34093371
3410-
The distinction is important in cases where multiple overload items match. We want
3411-
give priority to higher similarity matches.
3372+
This is useful when we're doing error reporting: for example, if we're trying
3373+
to select an overload alternative and there's no exact match, we can use
3374+
this function to help us identify which alternative the user might have
3375+
*meant* to match.
34123376
"""
3413-
# Replace type variables with their upper bounds. Overloading
3414-
# resolution is based on runtime behavior which erases type
3415-
# parameters, so no need to handle type variables occurring within
3416-
# a type.
3377+
3378+
# Erase typevars: we'll consider them all to have the same "shape".
3379+
34173380
if isinstance(actual, TypeVarType):
34183381
actual = actual.erase_to_union_or_bound()
34193382
if isinstance(formal, TypeVarType):
34203383
formal = formal.erase_to_union_or_bound()
3421-
if (isinstance(actual, UninhabitedType) or isinstance(actual, AnyType) or
3422-
isinstance(formal, AnyType) or
3423-
(isinstance(actual, Instance) and actual.type.fallback_to_any)):
3424-
# These could match anything at runtime.
3425-
return 2
3384+
3385+
# Callable or Type[...]-ish types
3386+
3387+
def is_typetype_like(typ: Type) -> bool:
3388+
return (isinstance(typ, TypeType)
3389+
or (isinstance(typ, FunctionLike) and typ.is_type_obj())
3390+
or (isinstance(typ, Instance) and typ.type.fullname() == "builtins.type"))
3391+
34263392
if isinstance(formal, CallableType):
3427-
if isinstance(actual, (CallableType, Overloaded)):
3428-
# TODO: do more sophisticated callable matching
3429-
return 2
3430-
if isinstance(actual, TypeType):
3431-
return 2 if is_subtype(actual, formal) else 0
3432-
if isinstance(actual, NoneTyp):
3433-
if not experiments.STRICT_OPTIONAL:
3434-
# NoneTyp matches anything if we're not doing strict Optional checking
3435-
return 2
3436-
else:
3437-
# NoneType is a subtype of object
3438-
if isinstance(formal, Instance) and formal.type.fullname() == "builtins.object":
3439-
return 2
3393+
if isinstance(actual, (CallableType, Overloaded, TypeType)):
3394+
return True
3395+
if is_typetype_like(actual) and is_typetype_like(formal):
3396+
return True
3397+
3398+
# Unions
3399+
34403400
if isinstance(actual, UnionType):
3441-
return max(overload_arg_similarity(item, formal)
3442-
for item in actual.relevant_items())
3401+
return any(arg_approximate_similarity(item, formal) for item in actual.relevant_items())
34433402
if isinstance(formal, UnionType):
3444-
return max(overload_arg_similarity(actual, item)
3445-
for item in formal.relevant_items())
3446-
if isinstance(formal, TypeType):
3447-
if isinstance(actual, TypeType):
3448-
# Since Type[T] is covariant, check if actual = Type[A] is
3449-
# a subtype of formal = Type[F].
3450-
return overload_arg_similarity(actual.item, formal.item)
3451-
elif isinstance(actual, FunctionLike) and actual.is_type_obj():
3452-
# Check if the actual is a constructor of some sort.
3453-
# Note that this is this unsound, since we don't check the __init__ signature.
3454-
return overload_arg_similarity(actual.items()[0].ret_type, formal.item)
3455-
else:
3456-
return 0
3403+
return any(arg_approximate_similarity(actual, item) for item in formal.relevant_items())
3404+
3405+
# TypedDicts
3406+
34573407
if isinstance(actual, TypedDictType):
34583408
if isinstance(formal, TypedDictType):
3459-
# Don't support overloading based on the keys or value types of a TypedDict since
3460-
# that would be complicated and probably only marginally useful.
3461-
return 2
3462-
return overload_arg_similarity(actual.fallback, formal)
3409+
return True
3410+
return arg_approximate_similarity(actual.fallback, formal)
3411+
3412+
# Instances
3413+
# For instances, we mostly defer to the existing is_subtype check.
3414+
34633415
if isinstance(formal, Instance):
34643416
if isinstance(actual, CallableType):
34653417
actual = actual.fallback
34663418
if isinstance(actual, Overloaded):
34673419
actual = actual.items()[0].fallback
34683420
if isinstance(actual, TupleType):
34693421
actual = actual.fallback
3470-
if isinstance(actual, Instance):
3471-
# First perform a quick check (as an optimization) and fall back to generic
3472-
# subtyping algorithm if type promotions are possible (e.g., int vs. float).
3473-
if formal.type in actual.type.mro:
3474-
return 2
3475-
elif formal.type.is_protocol and is_subtype(actual, erasetype.erase_type(formal)):
3476-
return 2
3477-
elif actual.type._promote and is_subtype(actual, formal):
3478-
return 1
3479-
else:
3480-
return 0
3481-
elif isinstance(actual, TypeType):
3482-
item = actual.item
3483-
if formal.type.fullname() in {"builtins.object", "builtins.type"}:
3484-
return 2
3485-
elif isinstance(item, Instance) and item.type.metaclass_type:
3486-
# FIX: this does not handle e.g. Union of instances
3487-
return overload_arg_similarity(item.type.metaclass_type, formal)
3488-
else:
3489-
return 0
3490-
else:
3491-
return 0
3492-
if isinstance(actual, UnboundType) or isinstance(formal, UnboundType):
3493-
# Either actual or formal is the result of an error; shut up.
3494-
return 2
3495-
# Fall back to a conservative equality check for the remaining kinds of type.
3496-
return 2 if is_same_type(erasetype.erase_type(actual), erasetype.erase_type(formal)) else 0
3422+
if isinstance(actual, Instance) and formal.type in actual.type.mro:
3423+
# Try performing a quick check as an optimization
3424+
return True
3425+
3426+
# Fall back to a standard subtype check for the remaining kinds of type.
3427+
return is_subtype(erasetype.erase_type(actual), erasetype.erase_type(formal))
34973428

34983429

34993430
def any_causes_overload_ambiguity(items: List[CallableType],

mypy/fastparse2.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@
1717
from functools import wraps
1818
import sys
1919

20-
from typing import Tuple, Union, TypeVar, Callable, Sequence, Optional, Any, cast, List
20+
from typing import Tuple, Union, TypeVar, Callable, Sequence, Optional, Any, Dict, cast, List
21+
MYPY = False
22+
if MYPY:
23+
import typing # for typing.Type, which conflicts with types.Type
24+
from typing import ClassVar
25+
2126
from mypy.sharedparse import (
2227
special_function_elide_names, argument_elide_name,
2328
)
@@ -193,7 +198,7 @@ def translate_stmt_list(self, l: Sequence[ast27.AST]) -> List[Statement]:
193198
ast27.BitXor: '^',
194199
ast27.BitAnd: '&',
195200
ast27.FloorDiv: '//'
196-
}
201+
} # type: ClassVar[Dict[typing.Type[ast27.AST], str]]
197202

198203
def from_operator(self, op: ast27.operator) -> str:
199204
op_name = ASTConverter.op_map.get(type(op))
@@ -215,7 +220,7 @@ def from_operator(self, op: ast27.operator) -> str:
215220
ast27.IsNot: 'is not',
216221
ast27.In: 'in',
217222
ast27.NotIn: 'not in'
218-
}
223+
} # type: ClassVar[Dict[typing.Type[ast27.AST], str]]
219224

220225
def from_comp_operator(self, op: ast27.cmpop) -> str:
221226
op_name = ASTConverter.comp_op_map.get(type(op))
@@ -240,7 +245,7 @@ def as_required_block(self, stmts: List[ast27.stmt], lineno: int) -> Block:
240245
def fix_function_overloads(self, stmts: List[Statement]) -> List[Statement]:
241246
ret = [] # type: List[Statement]
242247
current_overload = [] # type: List[OverloadPart]
243-
current_overload_name = None
248+
current_overload_name = None # type: Optional[str]
244249
for stmt in stmts:
245250
if (current_overload_name is not None
246251
and isinstance(stmt, (Decorator, FuncDef))

mypy/main.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from mypy.find_sources import create_source_list, InvalidSourceList
2020
from mypy.fscache import FileSystemCache
2121
from mypy.errors import CompileError
22-
from mypy.options import Options, BuildType
22+
from mypy.options import Options, BuildType, PER_MODULE_OPTIONS
2323
from mypy.report import reporter_classes
2424

2525
from mypy.version import __version__
@@ -1014,11 +1014,11 @@ def parse_config_file(options: Options, filename: Optional[str]) -> None:
10141014
print("%s: Per-module sections should not specify reports (%s)" %
10151015
(prefix, ', '.join(s + '_report' for s in sorted(report_dirs))),
10161016
file=sys.stderr)
1017-
if set(updates) - Options.PER_MODULE_OPTIONS:
1017+
if set(updates) - PER_MODULE_OPTIONS:
10181018
print("%s: Per-module sections should only specify per-module flags (%s)" %
1019-
(prefix, ', '.join(sorted(set(updates) - Options.PER_MODULE_OPTIONS))),
1019+
(prefix, ', '.join(sorted(set(updates) - PER_MODULE_OPTIONS))),
10201020
file=sys.stderr)
1021-
updates = {k: v for k, v in updates.items() if k in Options.PER_MODULE_OPTIONS}
1021+
updates = {k: v for k, v in updates.items() if k in PER_MODULE_OPTIONS}
10221022
globs = name[5:]
10231023
for glob in globs.split(','):
10241024
# For backwards compatibility, replace (back)slashes with dots.

0 commit comments

Comments
 (0)