Skip to content

Commit d6b3068

Browse files
committed
Move closer to the real deal
1 parent 1865600 commit d6b3068

File tree

19 files changed

+338
-245
lines changed

19 files changed

+338
-245
lines changed

mypy/build.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
from typing_extensions import TypeAlias as _TypeAlias
4141

4242
import mypy.semanal_main
43-
from mypy.cache import BytesIO
43+
from mypy.cache import Buffer
4444
from mypy.checker import TypeChecker
4545
from mypy.error_formatter import OUTPUT_CHOICES, ErrorFormatter
4646
from mypy.errors import CompileError, ErrorInfo, Errors, report_internal_error
@@ -1576,7 +1576,7 @@ def write_cache(
15761576

15771577
# Serialize data and analyze interface
15781578
if manager.options.fixed_format_cache:
1579-
data_io = BytesIO()
1579+
data_io = Buffer()
15801580
tree.write(data_io)
15811581
data_bytes = data_io.getvalue()
15821582
else:
@@ -2119,7 +2119,7 @@ def load_tree(self, temporary: bool = False) -> None:
21192119
t0 = time.time()
21202120
# TODO: Assert data file wasn't changed.
21212121
if isinstance(data, bytes):
2122-
data_io = BytesIO(data)
2122+
data_io = Buffer(data)
21232123
self.tree = MypyFile.read(data_io)
21242124
else:
21252125
self.tree = MypyFile.deserialize(data)
@@ -2511,7 +2511,7 @@ def write_cache(self) -> None:
25112511
if self.options.debug_serialize:
25122512
try:
25132513
if self.manager.options.fixed_format_cache:
2514-
data = BytesIO()
2514+
data = Buffer()
25152515
self.tree.write(data)
25162516
else:
25172517
self.tree.serialize()

mypy/cache.py

Lines changed: 49 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,54 @@
11
from __future__ import annotations
22

33
from collections.abc import Sequence
4-
from typing import Final
4+
from typing import TYPE_CHECKING, Final
55

6+
try:
7+
from native_internal import (
8+
Buffer as Buffer,
9+
read_bool as read_bool,
10+
read_float as read_float,
11+
read_int as read_int,
12+
read_str as read_str,
13+
write_bool as write_bool,
14+
write_float as write_float,
15+
write_int as write_int,
16+
write_str as write_str,
17+
)
18+
except ImportError:
19+
# TODO: temporary, remove this after we publish mypy-native on PyPI.
20+
if not TYPE_CHECKING:
621

7-
class BytesIO:
8-
def __init__(self, buffer: bytes | None = None) -> None:
9-
if buffer is None:
10-
self.write_buffer: bytearray | None = bytearray()
11-
self.read_buffer = None
12-
else:
13-
self.read_buffer = buffer
14-
self.write_buffer = None
15-
self.pos = 0
22+
class Buffer:
23+
def __init__(self, source: bytes = b"") -> None:
24+
raise NotImplementedError
1625

17-
def read(self, size: int) -> bytes:
18-
assert self.read_buffer is not None
19-
pos = self.pos
20-
self.pos += size
21-
return self.read_buffer[pos : self.pos]
26+
def getvalue(self) -> bytes:
27+
raise NotImplementedError
2228

23-
def write(self, chunk: bytes) -> None:
24-
assert self.write_buffer is not None
25-
self.write_buffer += chunk
29+
def read_int(data: Buffer) -> int:
30+
raise NotImplementedError
2631

27-
def getvalue(self) -> bytes:
28-
assert self.write_buffer is not None
29-
return bytes(self.write_buffer)
32+
def write_int(data: Buffer, value: int) -> None:
33+
raise NotImplementedError
3034

35+
def read_str(data: Buffer) -> str:
36+
raise NotImplementedError
3137

32-
INT_LEN: Final = 10
33-
FLOAT_LEN: Final = 24
38+
def write_str(data: Buffer, value: str) -> None:
39+
raise NotImplementedError
3440

41+
def read_bool(data: Buffer) -> bool:
42+
raise NotImplementedError
3543

36-
def read_int(data: BytesIO) -> int:
37-
return int(data.read(INT_LEN).decode())
44+
def write_bool(data: Buffer, value: bool) -> None:
45+
raise NotImplementedError
3846

47+
def read_float(data: Buffer) -> float:
48+
raise NotImplementedError
3949

40-
def write_int(data: BytesIO, value: int) -> None:
41-
str_val = str(value)
42-
str_val = " " * (INT_LEN - len(str_val)) + str_val
43-
data.write(str_val.encode())
44-
45-
46-
def read_str(data: BytesIO) -> str:
47-
size = read_int(data)
48-
encoded = data.read(size)
49-
return encoded.decode()
50-
51-
52-
def write_str(data: BytesIO, value: str) -> None:
53-
encoded = value.encode()
54-
size = len(encoded)
55-
write_int(data, size)
56-
data.write(encoded)
57-
58-
59-
def read_bool(data: BytesIO) -> bool:
60-
return data.read(1) == b"\xff"
61-
62-
63-
def write_bool(data: BytesIO, value: bool) -> None:
64-
data.write(b"\xff" if value else b"\x00")
65-
66-
67-
def read_float(data: BytesIO) -> float:
68-
value_str = data.read(FLOAT_LEN).decode()
69-
return float(value_str)
70-
71-
72-
def write_float(data: BytesIO, value: float) -> None:
73-
value_str = str(value)
74-
value_str = "0" * (FLOAT_LEN - len(value_str)) + value_str
75-
data.write(value_str.encode())
50+
def write_float(data: Buffer, value: float) -> None:
51+
raise NotImplementedError
7652

7753

7854
LITERAL_INT: Final = 1
@@ -83,7 +59,7 @@ def write_float(data: BytesIO, value: float) -> None:
8359
LITERAL_NONE: Final = 6
8460

8561

86-
def read_literal(data: BytesIO, marker: int) -> int | str | bool | float:
62+
def read_literal(data: Buffer, marker: int) -> int | str | bool | float:
8763
if marker == LITERAL_INT:
8864
return read_int(data)
8965
elif marker == LITERAL_STR:
@@ -95,7 +71,7 @@ def read_literal(data: BytesIO, marker: int) -> int | str | bool | float:
9571
assert False, f"Unknown literal marker {marker}"
9672

9773

98-
def write_literal(data: BytesIO, value: int | str | bool | float | complex | None) -> None:
74+
def write_literal(data: Buffer, value: int | str | bool | float | complex | None) -> None:
9975
if isinstance(value, bool):
10076
write_int(data, LITERAL_BOOL)
10177
write_bool(data, value)
@@ -116,62 +92,62 @@ def write_literal(data: BytesIO, value: int | str | bool | float | complex | Non
11692
write_int(data, LITERAL_NONE)
11793

11894

119-
def read_int_opt(data: BytesIO) -> int | None:
95+
def read_int_opt(data: Buffer) -> int | None:
12096
if read_bool(data):
12197
return read_int(data)
12298
return None
12399

124100

125-
def write_int_opt(data: BytesIO, value: int | None) -> None:
101+
def write_int_opt(data: Buffer, value: int | None) -> None:
126102
if value is not None:
127103
write_bool(data, True)
128104
write_int(data, value)
129105
else:
130106
write_bool(data, False)
131107

132108

133-
def read_str_opt(data: BytesIO) -> str | None:
109+
def read_str_opt(data: Buffer) -> str | None:
134110
if read_bool(data):
135111
return read_str(data)
136112
return None
137113

138114

139-
def write_str_opt(data: BytesIO, value: str | None) -> None:
115+
def write_str_opt(data: Buffer, value: str | None) -> None:
140116
if value is not None:
141117
write_bool(data, True)
142118
write_str(data, value)
143119
else:
144120
write_bool(data, False)
145121

146122

147-
def read_int_list(data: BytesIO) -> list[int]:
123+
def read_int_list(data: Buffer) -> list[int]:
148124
size = read_int(data)
149125
return [read_int(data) for _ in range(size)]
150126

151127

152-
def write_int_list(data: BytesIO, value: list[int]) -> None:
128+
def write_int_list(data: Buffer, value: list[int]) -> None:
153129
write_int(data, len(value))
154130
for item in value:
155131
write_int(data, item)
156132

157133

158-
def read_str_list(data: BytesIO) -> list[str]:
134+
def read_str_list(data: Buffer) -> list[str]:
159135
size = read_int(data)
160136
return [read_str(data) for _ in range(size)]
161137

162138

163-
def write_str_list(data: BytesIO, value: Sequence[str]) -> None:
139+
def write_str_list(data: Buffer, value: Sequence[str]) -> None:
164140
write_int(data, len(value))
165141
for item in value:
166142
write_str(data, item)
167143

168144

169-
def read_str_opt_list(data: BytesIO) -> list[str | None]:
145+
def read_str_opt_list(data: Buffer) -> list[str | None]:
170146
size = read_int(data)
171147
return [read_str_opt(data) for _ in range(size)]
172148

173149

174-
def write_str_opt_list(data: BytesIO, value: list[str | None]) -> None:
150+
def write_str_opt_list(data: Buffer, value: list[str | None]) -> None:
175151
write_int(data, len(value))
176152
for item in value:
177153
write_str_opt(data, item)

mypy/modulefinder.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,7 @@ def default_lib_path(
796796
custom_typeshed_dir = os.path.abspath(custom_typeshed_dir)
797797
typeshed_dir = os.path.join(custom_typeshed_dir, "stdlib")
798798
mypy_extensions_dir = os.path.join(custom_typeshed_dir, "stubs", "mypy-extensions")
799+
mypy_native_dir = os.path.join(custom_typeshed_dir, "stubs", "mypy-native")
799800
versions_file = os.path.join(typeshed_dir, "VERSIONS")
800801
if not os.path.isdir(typeshed_dir) or not os.path.isfile(versions_file):
801802
print(
@@ -811,11 +812,13 @@ def default_lib_path(
811812
data_dir = auto
812813
typeshed_dir = os.path.join(data_dir, "typeshed", "stdlib")
813814
mypy_extensions_dir = os.path.join(data_dir, "typeshed", "stubs", "mypy-extensions")
815+
mypy_native_dir = os.path.join(data_dir, "typeshed", "stubs", "mypy-native")
814816
path.append(typeshed_dir)
815817

816-
# Get mypy-extensions stubs from typeshed, since we treat it as an
817-
# "internal" library, similar to typing and typing-extensions.
818+
# Get mypy-extensions and mypy-native stubs from typeshed, since we treat them as
819+
# "internal" libraries, similar to typing and typing-extensions.
818820
path.append(mypy_extensions_dir)
821+
path.append(mypy_native_dir)
819822

820823
# Add fallback path that can be used if we have a broken installation.
821824
if sys.platform != "win32":

0 commit comments

Comments
 (0)