Skip to content

Commit 6d49fbf

Browse files
authored
Avoid various NamedTuples (#21326)
1 parent bbe68d3 commit 6d49fbf

7 files changed

Lines changed: 48 additions & 34 deletions

File tree

mypy/binder.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from collections import defaultdict
44
from collections.abc import Iterator
55
from contextlib import contextmanager
6-
from typing import Literal, NamedTuple, TypeAlias as _TypeAlias
6+
from typing import Final, Literal, TypeAlias as _TypeAlias
77

88
from mypy.erasetype import remove_instance_last_known_values
99
from mypy.literals import Key, extract_var_from_literal_hash, literal, literal_hash, subkeys
@@ -42,9 +42,10 @@
4242
BindableExpression: _TypeAlias = IndexExpr | MemberExpr | NameExpr
4343

4444

45-
class CurrentType(NamedTuple):
46-
type: Type
47-
from_assignment: bool
45+
class CurrentType:
46+
def __init__(self, type: Type, from_assignment: bool) -> None:
47+
self.type: Final = type
48+
self.from_assignment: Final = from_assignment
4849

4950

5051
class Frame:

mypy/build_worker/worker.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
import platform
2424
import sys
2525
import time
26-
from typing import NamedTuple
26+
from typing import Final
2727

2828
from librt.internal import ReadBuffer, read_tag
2929

@@ -65,12 +65,20 @@
6565
CONNECTION_NAME = "build_worker"
6666

6767

68-
class ServerContext(NamedTuple):
69-
options: Options
70-
disable_error_code: list[str]
71-
enable_error_code: list[str]
72-
errors: Errors
73-
fscache: FileSystemCache
68+
class ServerContext:
69+
def __init__(
70+
self,
71+
options: Options,
72+
disable_error_code: list[str],
73+
enable_error_code: list[str],
74+
errors: Errors,
75+
fscache: FileSystemCache,
76+
) -> None:
77+
self.options: Final = options
78+
self.disable_error_code: Final = disable_error_code
79+
self.enable_error_code: Final = enable_error_code
80+
self.errors: Final = errors
81+
self.fscache: Final = fscache
7482

7583

7684
def main(argv: list[str]) -> None:

mypy/checker.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -353,10 +353,11 @@ class FineGrainedDeferredNode(NamedTuple):
353353
# Keeps track of partial types in a single scope. In fine-grained incremental
354354
# mode partial types initially defined at the top level cannot be completed in
355355
# a function, and we use the 'is_function' attribute to enforce this.
356-
class PartialTypeScope(NamedTuple):
357-
map: dict[Var, Context]
358-
is_function: bool
359-
is_local: bool
356+
class PartialTypeScope:
357+
def __init__(self, map: dict[Var, Context], is_function: bool, is_local: bool) -> None:
358+
self.map: Final = map
359+
self.is_function: Final = is_function
360+
self.is_local: Final = is_local
360361

361362

362363
class LocalTypeMap:
@@ -1617,14 +1618,14 @@ def check_func_def(
16171618
else:
16181619
msg = message_registry.MISSING_RETURN_STATEMENT
16191620
if body_is_trivial:
1620-
msg = msg._replace(code=codes.EMPTY_BODY)
1621+
msg = ErrorMessage(msg.value, code=codes.EMPTY_BODY)
16211622
self.fail(msg, defn)
16221623
if may_be_abstract:
16231624
self.note(message_registry.EMPTY_BODY_ABSTRACT, defn)
16241625
else:
16251626
msg = message_registry.INCOMPATIBLE_RETURN_VALUE_TYPE
16261627
if body_is_trivial:
1627-
msg = msg._replace(code=codes.EMPTY_BODY)
1628+
msg = ErrorMessage(msg.value, code=codes.EMPTY_BODY)
16281629
# similar to code in check_return_stmt
16291630
if (
16301631
not self.check_subtype(
@@ -7874,7 +7875,7 @@ def enter_partial_types(
78747875
self.options.check_untyped_defs and self.dynamic_funcs and self.dynamic_funcs[-1]
78757876
)
78767877

7877-
partial_types, _, _ = self.partial_types.pop()
7878+
partial_types = self.partial_types.pop().map
78787879
if not self.current_node_deferred:
78797880
for var, context in partial_types.items():
78807881
if isinstance(var.type, PartialType) and var.type.type is None and not permissive:

mypy/checker_shared.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from abc import abstractmethod
66
from collections.abc import Iterator, Sequence, Set as AbstractSet
77
from contextlib import contextmanager
8-
from typing import NamedTuple, overload
8+
from typing import Final, overload
99

1010
from mypy_extensions import trait
1111

@@ -42,9 +42,10 @@
4242

4343
# An object that represents either a precise type or a type with an upper bound;
4444
# it is important for correct type inference with isinstance.
45-
class TypeRange(NamedTuple):
46-
item: Type
47-
is_upper_bound: bool # False => precise type
45+
class TypeRange:
46+
def __init__(self, item: Type, is_upper_bound: bool) -> None:
47+
self.item: Final = item
48+
self.is_upper_bound: Final = is_upper_bound # False => precise type
4849

4950

5051
@trait

mypy/infer.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from __future__ import annotations
44

55
from collections.abc import Sequence
6-
from typing import NamedTuple
6+
from typing import Final
77

88
from mypy.constraints import (
99
SUBTYPE_OF,
@@ -16,7 +16,7 @@
1616
from mypy.types import CallableType, Instance, Type, TypeVarLikeType
1717

1818

19-
class ArgumentInferContext(NamedTuple):
19+
class ArgumentInferContext:
2020
"""Type argument inference context.
2121
2222
We need this because we pass around ``Mapping`` and ``Iterable`` types.
@@ -26,8 +26,9 @@ class ArgumentInferContext(NamedTuple):
2626
https://github.com/python/mypy/issues/11144
2727
"""
2828

29-
mapping_type: Instance
30-
iterable_type: Instance
29+
def __init__(self, mapping_type: Instance, iterable_type: Instance) -> None:
30+
self.mapping_type: Final = mapping_type
31+
self.iterable_type: Final = iterable_type
3132

3233

3334
def infer_function_type_arguments(

mypy/message_registry.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,16 @@
88

99
from __future__ import annotations
1010

11-
from typing import Final, NamedTuple
11+
from typing import Final
1212

1313
from mypy import errorcodes as codes
1414
from mypy.errorcodes import ErrorCode
1515

1616

17-
class ErrorMessage(NamedTuple):
18-
value: str
19-
code: ErrorCode | None = None
17+
class ErrorMessage:
18+
def __init__(self, value: str, code: ErrorCode | None = None) -> None:
19+
self.value: Final = value
20+
self.code: Final = code
2021

2122
def format(self, *args: object, **kwargs: object) -> ErrorMessage:
2223
return ErrorMessage(self.value.format(*args, **kwargs), code=self.code)

mypy/plugins/functools.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from __future__ import annotations
44

5-
from typing import Final, NamedTuple
5+
from typing import Final
66

77
import mypy.checker
88
import mypy.plugin
@@ -43,9 +43,10 @@
4343
PARTIAL: Final = "functools.partial"
4444

4545

46-
class _MethodInfo(NamedTuple):
47-
is_static: bool
48-
type: CallableType
46+
class _MethodInfo:
47+
def __init__(self, is_static: bool, type: CallableType) -> None:
48+
self.is_static: Final = is_static
49+
self.type: Final = type
4950

5051

5152
def functools_total_ordering_maker_callback(

0 commit comments

Comments
 (0)