Skip to content

Commit fd26207

Browse files
Merge branch 'master' into bit-length
2 parents 5b58d41 + 4301be1 commit fd26207

File tree

18 files changed

+145
-81
lines changed

18 files changed

+145
-81
lines changed

.github/workflows/docs.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ on:
1212
# so it's important to do the docs build on all PRs touching mypy/errorcodes.py
1313
# in case somebody's adding a new error code without any docs
1414
- 'mypy/errorcodes.py'
15+
# Part of the documentation is automatically generated from the options
16+
# definitions in mypy/main.py
17+
- 'mypy/main.py'
1518
- 'mypyc/doc/**'
1619
- '**/*.rst'
1720
- '**/*.md'

CHANGELOG.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
## Next Release
44

5-
## Mypy 1.18
5+
## Mypy 1.18.1
66

7-
We’ve just uploaded mypy 1.18 to the Python Package Index ([PyPI](https://pypi.org/project/mypy/)).
7+
We’ve just uploaded mypy 1.18.1 to the Python Package Index ([PyPI](https://pypi.org/project/mypy/)).
88
Mypy is a static type checker for Python. This release includes new features, performance
99
improvements and bug fixes. You can install it as follows:
1010

@@ -14,7 +14,7 @@ You can read the full documentation for this release on [Read the Docs](http://m
1414

1515
### Mypy Performance Improvements
1616

17-
Mypy 1.18 includes numerous performance improvements, resulting in about 40% speedup
17+
Mypy 1.18.1 includes numerous performance improvements, resulting in about 40% speedup
1818
compared to 1.17 when type checking mypy itself. In extreme cases, the improvement
1919
can be 10x or higher. The list below is an overview of the various mypy optimizations.
2020
Many mypyc improvements (discussed in a separate section below) also improve performance.
@@ -283,6 +283,12 @@ Related PRs:
283283

284284
Please see [git log](https://github.com/python/typeshed/commits/main?after=2480d7e7c74493a024eaf254c5d2c6f452c80ee2+0&branch=main&path=stdlib) for full list of standard library typeshed stub changes.
285285

286+
### Mypy 1.18.2
287+
288+
- Fix crash on recursive alias (Ivan Levkivskyi, PR [19845](https://github.com/python/mypy/pull/19845))
289+
- Add additional guidance for stubtest errors when runtime is `object.__init__` (Stephen Morton, PR [19733](https://github.com/python/mypy/pull/19733))
290+
- Fix handling of None values in f-string expressions in mypyc (BobTheBuidler, PR [19846](https://github.com/python/mypy/pull/19846))
291+
286292
### Acknowledgements
287293

288294
Thanks to all mypy contributors who contributed to this release:

mypy/main.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,22 +1163,22 @@ def add_invertible_flag(
11631163
"--skip-c-gen", dest="mypyc_skip_c_generation", action="store_true", help=argparse.SUPPRESS
11641164
)
11651165

1166-
other_group = parser.add_argument_group(title="Miscellaneous")
1167-
other_group.add_argument("--quickstart-file", help=argparse.SUPPRESS)
1168-
other_group.add_argument("--junit-xml", help="Write junit.xml to the given file")
1166+
misc_group = parser.add_argument_group(title="Miscellaneous")
1167+
misc_group.add_argument("--quickstart-file", help=argparse.SUPPRESS)
1168+
misc_group.add_argument("--junit-xml", help="Write junit.xml to the given file")
11691169
imports_group.add_argument(
11701170
"--junit-format",
11711171
choices=["global", "per_file"],
11721172
default="global",
11731173
help="If --junit-xml is set, specifies format. global: single test with all errors; per_file: one test entry per file with failures",
11741174
)
1175-
other_group.add_argument(
1175+
misc_group.add_argument(
11761176
"--find-occurrences",
11771177
metavar="CLASS.MEMBER",
11781178
dest="special-opts:find_occurrences",
11791179
help="Print out all usages of a class member (experimental)",
11801180
)
1181-
other_group.add_argument(
1181+
misc_group.add_argument(
11821182
"--scripts-are-modules",
11831183
action="store_true",
11841184
help="Script x becomes module x instead of __main__",
@@ -1189,7 +1189,7 @@ def add_invertible_flag(
11891189
default=False,
11901190
strict_flag=False,
11911191
help="Install detected missing library stub packages using pip",
1192-
group=other_group,
1192+
group=misc_group,
11931193
)
11941194
add_invertible_flag(
11951195
"--non-interactive",
@@ -1199,12 +1199,12 @@ def add_invertible_flag(
11991199
"Install stubs without asking for confirmation and hide "
12001200
+ "errors, with --install-types"
12011201
),
1202-
group=other_group,
1202+
group=misc_group,
12031203
inverse="--interactive",
12041204
)
12051205

12061206
if server_options:
1207-
other_group.add_argument(
1207+
misc_group.add_argument(
12081208
"--use-fine-grained-cache",
12091209
action="store_true",
12101210
help="Use the cache in fine-grained incremental mode",

mypy/stubtest.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,7 +1053,10 @@ def get_kind(arg_name: str) -> nodes.ArgKind:
10531053

10541054

10551055
def _verify_signature(
1056-
stub: Signature[nodes.Argument], runtime: Signature[inspect.Parameter], function_name: str
1056+
stub: Signature[nodes.Argument],
1057+
runtime: Signature[inspect.Parameter],
1058+
function_name: str,
1059+
warn_runtime_is_object_init: bool = False,
10571060
) -> Iterator[str]:
10581061
# Check positional arguments match up
10591062
for stub_arg, runtime_arg in zip(stub.pos, runtime.pos):
@@ -1098,6 +1101,8 @@ def _verify_signature(
10981101
msg = f'runtime does not have parameter "{stub_arg.variable.name}"'
10991102
if runtime.varkw is not None:
11001103
msg += ". Maybe you forgot to make it keyword-only in the stub?"
1104+
elif warn_runtime_is_object_init:
1105+
msg += ". You may need to write stubs for __new__ instead of __init__."
11011106
yield msg
11021107
else:
11031108
yield f'stub parameter "{stub_arg.variable.name}" is not keyword-only'
@@ -1137,7 +1142,11 @@ def _verify_signature(
11371142
if arg not in {runtime_arg.name for runtime_arg in runtime.pos[len(stub.pos) :]}:
11381143
yield f'runtime parameter "{arg}" is not keyword-only'
11391144
else:
1140-
yield f'runtime does not have parameter "{arg}"'
1145+
msg = f'runtime does not have parameter "{arg}"'
1146+
if warn_runtime_is_object_init:
1147+
msg += ". You may need to write stubs for __new__ instead of __init__."
1148+
yield msg
1149+
11411150
for arg in sorted(set(runtime.kwonly) - set(stub.kwonly)):
11421151
if arg in {stub_arg.variable.name for stub_arg in stub.pos}:
11431152
# Don't report this if we've reported it before
@@ -1223,7 +1232,12 @@ def verify_funcitem(
12231232
if not signature:
12241233
return
12251234

1226-
for message in _verify_signature(stub_sig, runtime_sig, function_name=stub.name):
1235+
for message in _verify_signature(
1236+
stub_sig,
1237+
runtime_sig,
1238+
function_name=stub.name,
1239+
warn_runtime_is_object_init=runtime is object.__init__,
1240+
):
12271241
yield Error(
12281242
object_path,
12291243
"is inconsistent, " + message,
@@ -1333,7 +1347,12 @@ def verify_overloadedfuncdef(
13331347
stub_sig = Signature.from_overloadedfuncdef(stub)
13341348
runtime_sig = Signature.from_inspect_signature(signature)
13351349

1336-
for message in _verify_signature(stub_sig, runtime_sig, function_name=stub.name):
1350+
for message in _verify_signature(
1351+
stub_sig,
1352+
runtime_sig,
1353+
function_name=stub.name,
1354+
warn_runtime_is_object_init=runtime is object.__init__,
1355+
):
13371356
# TODO: This is a little hacky, but the addition here is super useful
13381357
if "has a default value of type" in message:
13391358
message += (

mypy/typeshed/stdlib/asyncio/events.pyi

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -602,18 +602,25 @@ class AbstractEventLoop:
602602
@abstractmethod
603603
async def shutdown_default_executor(self) -> None: ...
604604

605-
# This class does not exist at runtime, but stubtest complains if it's marked as
606-
# @type_check_only because it has an alias that does exist at runtime. See mypy#19568.
607-
# @type_check_only
608-
class _AbstractEventLoopPolicy:
609-
@abstractmethod
610-
def get_event_loop(self) -> AbstractEventLoop: ...
611-
@abstractmethod
612-
def set_event_loop(self, loop: AbstractEventLoop | None) -> None: ...
613-
@abstractmethod
614-
def new_event_loop(self) -> AbstractEventLoop: ...
615-
# Child processes handling (Unix only).
616-
if sys.version_info < (3, 14):
605+
if sys.version_info >= (3, 14):
606+
class _AbstractEventLoopPolicy:
607+
@abstractmethod
608+
def get_event_loop(self) -> AbstractEventLoop: ...
609+
@abstractmethod
610+
def set_event_loop(self, loop: AbstractEventLoop | None) -> None: ...
611+
@abstractmethod
612+
def new_event_loop(self) -> AbstractEventLoop: ...
613+
614+
else:
615+
@type_check_only
616+
class _AbstractEventLoopPolicy:
617+
@abstractmethod
618+
def get_event_loop(self) -> AbstractEventLoop: ...
619+
@abstractmethod
620+
def set_event_loop(self, loop: AbstractEventLoop | None) -> None: ...
621+
@abstractmethod
622+
def new_event_loop(self) -> AbstractEventLoop: ...
623+
# Child processes handling (Unix only).
617624
if sys.version_info >= (3, 12):
618625
@abstractmethod
619626
@deprecated("Deprecated since Python 3.12; removed in Python 3.14.")
@@ -627,7 +634,6 @@ class _AbstractEventLoopPolicy:
627634
@abstractmethod
628635
def set_child_watcher(self, watcher: AbstractChildWatcher) -> None: ...
629636

630-
if sys.version_info < (3, 14):
631637
AbstractEventLoopPolicy = _AbstractEventLoopPolicy
632638

633639
if sys.version_info >= (3, 14):

mypy/typeshed/stdlib/builtins.pyi

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -923,8 +923,7 @@ class slice(Generic[_StartT_co, _StopT_co, _StepT_co]):
923923

924924
def indices(self, len: SupportsIndex, /) -> tuple[int, int, int]: ...
925925

926-
# Making this a disjoint_base upsets pyright
927-
# @disjoint_base
926+
@disjoint_base
928927
class tuple(Sequence[_T_co]):
929928
def __new__(cls, iterable: Iterable[_T_co] = ..., /) -> Self: ...
930929
def __len__(self) -> int: ...
@@ -1266,10 +1265,8 @@ class property:
12661265
def __set__(self, instance: Any, value: Any, /) -> None: ...
12671266
def __delete__(self, instance: Any, /) -> None: ...
12681267

1269-
# This class does not exist at runtime, but stubtest complains if it's marked as
1270-
# @type_check_only because it has an alias that does exist at runtime. See mypy#19568.
1271-
# @type_check_only
12721268
@final
1269+
@type_check_only
12731270
class _NotImplementedType(Any):
12741271
__call__: None
12751272

mypy/typeshed/stdlib/turtle.pyi

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,12 @@ class RawTurtle(TPen, TNavigator): # type: ignore[misc] # Conflicting methods
463463

464464
def begin_fill(self) -> None: ...
465465
def end_fill(self) -> None: ...
466-
def dot(self, size: int | None = None, *color: _Color) -> None: ...
466+
@overload
467+
def dot(self, size: int | _Color | None = None) -> None: ...
468+
@overload
469+
def dot(self, size: int | None, color: _Color, /) -> None: ...
470+
@overload
471+
def dot(self, size: int | None, r: float, g: float, b: float, /) -> None: ...
467472
def write(
468473
self, arg: object, move: bool = False, align: str = "left", font: tuple[str, int, str] = ("Arial", 8, "normal")
469474
) -> None: ...
@@ -747,7 +752,12 @@ if sys.version_info >= (3, 14):
747752

748753
def begin_fill() -> None: ...
749754
def end_fill() -> None: ...
750-
def dot(size: int | None = None, *color: _Color) -> None: ...
755+
@overload
756+
def dot(size: int | _Color | None = None) -> None: ...
757+
@overload
758+
def dot(size: int | None, color: _Color, /) -> None: ...
759+
@overload
760+
def dot(size: int | None, r: float, g: float, b: float, /) -> None: ...
751761
def write(arg: object, move: bool = False, align: str = "left", font: tuple[str, int, str] = ("Arial", 8, "normal")) -> None: ...
752762

753763
if sys.version_info >= (3, 14):

mypy/typeshed/stdlib/unittest/mock.pyi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,8 @@ class MagicProxy(Base):
508508
def create_mock(self) -> Any: ...
509509
def __get__(self, obj: Any, _type: Any | None = None) -> Any: ...
510510

511-
class _ANY:
511+
# See https://github.com/python/typeshed/issues/14701
512+
class _ANY(Any):
512513
def __eq__(self, other: object) -> Literal[True]: ...
513514
def __ne__(self, other: object) -> Literal[False]: ...
514515
__hash__: ClassVar[None] # type: ignore[assignment]

mypyc/irbuild/specialize.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -719,7 +719,9 @@ def get_literal_str(expr: Expression) -> str | None:
719719
if isinstance(expr, StrExpr):
720720
return expr.value
721721
elif isinstance(expr, RefExpr) and isinstance(expr.node, Var) and expr.node.is_final:
722-
return str(expr.node.final_value)
722+
final_value = expr.node.final_value
723+
if final_value is not None:
724+
return str(final_value)
723725
return None
724726

725727
for i in range(len(exprs) - 1):

mypyc/test-data/run-strings.test

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,9 +412,16 @@ def test_basics() -> None:
412412
[case testFStrings]
413413
import decimal
414414
from datetime import datetime
415+
from typing import Final
415416

416417
var = 'mypyc'
417418
num = 20
419+
final_known_at_compile_time: Final = 'hello'
420+
421+
def final_value_setter() -> str:
422+
return 'goodbye'
423+
424+
final_unknown_at_compile_time: Final = final_value_setter()
418425

419426
def test_fstring_basics() -> None:
420427
assert f'Hello {var}, this is a test' == "Hello mypyc, this is a test"
@@ -451,6 +458,8 @@ def test_fstring_basics() -> None:
451458
inf_num = float('inf')
452459
assert f'{nan_num}, {inf_num}' == 'nan, inf'
453460

461+
assert f'{final_known_at_compile_time} {final_unknown_at_compile_time}' == 'hello goodbye'
462+
454463
# F-strings would be translated into ''.join[string literals, format method call, ...] in mypy AST.
455464
# Currently we are using a str.join specializer for f-string speed up. We might not cover all cases
456465
# and the rest ones should fall back to a normal str.join method call.

0 commit comments

Comments
 (0)