Skip to content

Commit 0ff5841

Browse files
Merge branch 'master' into patch-3
2 parents a4bb497 + ed88d82 commit 0ff5841

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+921
-459
lines changed

docs/source/error_code_list2.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ Example:
616616
617617
.. _code-exhaustive-match:
618618

619-
Check that match statements match exhaustively [match-exhaustive]
619+
Check that match statements match exhaustively [exhaustive-match]
620620
-----------------------------------------------------------------------
621621

622622
If enabled with :option:`--enable-error-code exhaustive-match <mypy --enable-error-code>`,

docs/source/protocols.rst

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,53 @@ the parameters are positional-only. Example (using the legacy syntax for generic
352352
copy_a = copy_b # OK
353353
copy_b = copy_a # Also OK
354354
355+
Binding of types in protocol attributes
356+
***************************************
357+
358+
All protocol attributes annotations are treated as externally visible types
359+
of those attributes. This means that for example callables are not bound,
360+
and descriptors are not invoked:
361+
362+
.. code-block:: python
363+
364+
from typing import Callable, Protocol, overload
365+
366+
class Integer:
367+
@overload
368+
def __get__(self, instance: None, owner: object) -> Integer: ...
369+
@overload
370+
def __get__(self, instance: object, owner: object) -> int: ...
371+
# <some implementation>
372+
373+
class Example(Protocol):
374+
foo: Callable[[object], int]
375+
bar: Integer
376+
377+
ex: Example
378+
reveal_type(ex.foo) # Revealed type is Callable[[object], int]
379+
reveal_type(ex.bar) # Revealed type is Integer
380+
381+
In other words, protocol attribute types are handled as they would appear in a
382+
``self`` attribute annotation in a regular class. If you want some protocol
383+
attributes to be handled as though they were defined at class level, you should
384+
declare them explicitly using ``ClassVar[...]``. Continuing previous example:
385+
386+
.. code-block:: python
387+
388+
from typing import ClassVar
389+
390+
class OtherExample(Protocol):
391+
# This style is *not recommended*, but may be needed to reuse
392+
# some complex callable types. Otherwise use regular methods.
393+
foo: ClassVar[Callable[[object], int]]
394+
# This may be needed to mimic descriptor access on Type[...] types,
395+
# otherwise use a plain "bar: int" style.
396+
bar: ClassVar[Integer]
397+
398+
ex2: OtherExample
399+
reveal_type(ex2.foo) # Revealed type is Callable[[], int]
400+
reveal_type(ex2.bar) # Revealed type is int
401+
355402
.. _predefined_protocols_reference:
356403

357404
Predefined protocol reference

misc/self_compile_info.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
"""Print list of files compiled when compiling self (mypy and mypyc)."""
2+
3+
import argparse
4+
import sys
5+
from typing import Any
6+
7+
import setuptools
8+
9+
import mypyc.build
10+
11+
12+
class FakeExtension:
13+
def __init__(self, *args: Any, **kwargs: Any) -> None:
14+
pass
15+
16+
17+
def fake_mypycify(args: list[str], **kwargs: Any) -> list[FakeExtension]:
18+
for target in sorted(args):
19+
if not target.startswith("-"):
20+
print(target)
21+
return [FakeExtension()]
22+
23+
24+
def fake_setup(*args: Any, **kwargs: Any) -> Any:
25+
pass
26+
27+
28+
def main() -> None:
29+
parser = argparse.ArgumentParser(
30+
description="Print list of files compiled when compiling self. Run in repository root."
31+
)
32+
parser.parse_args()
33+
34+
# Prepare fake state for running setup.py.
35+
mypyc.build.mypycify = fake_mypycify # type: ignore[assignment]
36+
setuptools.Extension = FakeExtension # type: ignore[misc, assignment]
37+
setuptools.setup = fake_setup
38+
sys.argv = [sys.argv[0], "--use-mypyc"]
39+
40+
# Run setup.py at the root of the repository.
41+
import setup # noqa: F401
42+
43+
44+
if __name__ == "__main__":
45+
main()

misc/upload-pypi.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ def tmp_twine() -> Iterator[Path]:
108108
def upload_dist(dist: Path, dry_run: bool = True) -> None:
109109
with tmp_twine() as twine:
110110
files = [item for item in dist.iterdir() if item_ok_for_pypi(item.name)]
111-
cmd: list[Any] = [twine, "upload"]
111+
cmd: list[Any] = [twine, "upload", "--skip-existing"]
112112
cmd += files
113113
if dry_run:
114114
print("[dry run] " + " ".join(map(str, cmd)))

mypy/checker.py

Lines changed: 8 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from mypy.constraints import SUPERTYPE_OF
2626
from mypy.erasetype import erase_type, erase_typevars, remove_instance_last_known_values
2727
from mypy.errorcodes import TYPE_VAR, UNUSED_AWAITABLE, UNUSED_COROUTINE, ErrorCode
28-
from mypy.errors import Errors, ErrorWatcher, LoopErrorWatcher, report_internal_error
28+
from mypy.errors import ErrorInfo, Errors, ErrorWatcher, LoopErrorWatcher, report_internal_error
2929
from mypy.expandtype import expand_type
3030
from mypy.literals import Key, extract_var_from_literal_hash, literal, literal_hash
3131
from mypy.maptype import map_instance_to_supertype
@@ -117,7 +117,6 @@
117117
TypeAlias,
118118
TypeAliasStmt,
119119
TypeInfo,
120-
TypeVarExpr,
121120
UnaryExpr,
122121
Var,
123122
WhileStmt,
@@ -2858,29 +2857,6 @@ def check_multiple_inheritance(self, typ: TypeInfo) -> None:
28582857
if name in base2.names and base2 not in base.mro:
28592858
self.check_compatibility(name, base, base2, typ)
28602859

2861-
def determine_type_of_member(self, sym: SymbolTableNode) -> Type | None:
2862-
# TODO: this duplicates both checkmember.py and analyze_ref_expr(), delete.
2863-
if sym.type is not None:
2864-
return sym.type
2865-
if isinstance(sym.node, SYMBOL_FUNCBASE_TYPES):
2866-
return self.function_type(sym.node)
2867-
if isinstance(sym.node, TypeInfo):
2868-
if sym.node.typeddict_type:
2869-
# We special-case TypedDict, because they don't define any constructor.
2870-
return self.expr_checker.typeddict_callable(sym.node)
2871-
else:
2872-
return type_object_type(sym.node, self.named_type)
2873-
if isinstance(sym.node, TypeVarExpr):
2874-
# Use of TypeVars is rejected in an expression/runtime context, so
2875-
# we don't need to check supertype compatibility for them.
2876-
return AnyType(TypeOfAny.special_form)
2877-
if isinstance(sym.node, TypeAlias):
2878-
with self.msg.filter_errors():
2879-
# Suppress any errors, they will be given when analyzing the corresponding node.
2880-
# Here we may have incorrect options and location context.
2881-
return self.expr_checker.alias_type_in_runtime_context(sym.node, ctx=sym.node)
2882-
return None
2883-
28842860
def check_compatibility(
28852861
self, name: str, base1: TypeInfo, base2: TypeInfo, ctx: TypeInfo
28862862
) -> None:
@@ -3864,7 +3840,7 @@ def check_assignment_to_multiple_lvalues(
38643840
if rvalue_needed > 0:
38653841
rvalues = (
38663842
rvalues[0:iterable_start]
3867-
+ [TempNode(iterable_type) for i in range(rvalue_needed)]
3843+
+ [TempNode(iterable_type, context=rval) for _ in range(rvalue_needed)]
38683844
+ rvalues[iterable_end + 1 :]
38693845
)
38703846

@@ -7205,7 +7181,7 @@ def check_subtype(
72057181
if extra_info:
72067182
msg = msg.with_additional_msg(" (" + ", ".join(extra_info) + ")")
72077183

7208-
self.fail(msg, context)
7184+
error = self.fail(msg, context)
72097185
for note in notes:
72107186
self.msg.note(note, context, code=msg.code)
72117187
if note_msg:
@@ -7214,9 +7190,9 @@ def check_subtype(
72147190
if (
72157191
isinstance(supertype, Instance)
72167192
and supertype.type.is_protocol
7217-
and isinstance(subtype, (CallableType, Instance, TupleType, TypedDictType))
7193+
and isinstance(subtype, (CallableType, Instance, TupleType, TypedDictType, TypeType))
72187194
):
7219-
self.msg.report_protocol_problems(subtype, supertype, context, code=msg.code)
7195+
self.msg.report_protocol_problems(subtype, supertype, context, parent_error=error)
72207196
if isinstance(supertype, CallableType) and isinstance(subtype, Instance):
72217197
call = find_member("__call__", subtype, subtype, is_operator=True)
72227198
if call:
@@ -7545,12 +7521,11 @@ def temp_node(self, t: Type, context: Context | None = None) -> TempNode:
75457521

75467522
def fail(
75477523
self, msg: str | ErrorMessage, context: Context, *, code: ErrorCode | None = None
7548-
) -> None:
7524+
) -> ErrorInfo:
75497525
"""Produce an error message."""
75507526
if isinstance(msg, ErrorMessage):
7551-
self.msg.fail(msg.value, context, code=msg.code)
7552-
return
7553-
self.msg.fail(msg, context, code=code)
7527+
return self.msg.fail(msg.value, context, code=msg.code)
7528+
return self.msg.fail(msg, context, code=code)
75547529

75557530
def note(
75567531
self,

mypy/checker_shared.py

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
MypyFile,
2222
Node,
2323
RefExpr,
24-
TypeAlias,
24+
SymbolNode,
2525
TypeInfo,
2626
Var,
2727
)
@@ -64,10 +64,6 @@ def accept(
6464
def analyze_ref_expr(self, e: RefExpr, lvalue: bool = False) -> Type:
6565
raise NotImplementedError
6666

67-
@abstractmethod
68-
def module_type(self, node: MypyFile) -> Instance:
69-
raise NotImplementedError
70-
7167
@abstractmethod
7268
def check_call(
7369
self,
@@ -112,24 +108,26 @@ def check_method_call_by_name(
112108
) -> tuple[Type, Type]:
113109
raise NotImplementedError
114110

115-
@abstractmethod
116-
def alias_type_in_runtime_context(
117-
self, alias: TypeAlias, *, ctx: Context, alias_definition: bool = False
118-
) -> Type:
119-
raise NotImplementedError
120-
121111
@abstractmethod
122112
def visit_typeddict_index_expr(
123113
self, td_type: TypedDictType, index: Expression, setitem: bool = False
124114
) -> tuple[Type, set[str]]:
125115
raise NotImplementedError
126116

127117
@abstractmethod
128-
def typeddict_callable(self, info: TypeInfo) -> CallableType:
118+
def infer_literal_expr_type(self, value: LiteralValue, fallback_name: str) -> Type:
129119
raise NotImplementedError
130120

131121
@abstractmethod
132-
def infer_literal_expr_type(self, value: LiteralValue, fallback_name: str) -> Type:
122+
def analyze_static_reference(
123+
self,
124+
node: SymbolNode,
125+
ctx: Context,
126+
is_lvalue: bool,
127+
*,
128+
include_modules: bool = True,
129+
suppress_errors: bool = False,
130+
) -> Type:
133131
raise NotImplementedError
134132

135133

0 commit comments

Comments
 (0)