Skip to content

Commit 4468bcd

Browse files
committed
Use u8 for type/symbol tags
1 parent dcb4d69 commit 4468bcd

File tree

10 files changed

+93
-74
lines changed

10 files changed

+93
-74
lines changed

mypy/cache.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
from collections.abc import Sequence
44
from typing import TYPE_CHECKING, Final
55

6+
from mypy_extensions import u8
7+
68
try:
79
from native_internal import (
810
Buffer as Buffer,
@@ -34,10 +36,10 @@ def read_int(data: Buffer) -> int:
3436
def write_int(data: Buffer, value: int) -> None:
3537
raise NotImplementedError
3638

37-
def read_tag(data: Buffer) -> int:
39+
def read_tag(data: Buffer) -> u8:
3840
raise NotImplementedError
3941

40-
def write_tag(data: Buffer, value: int) -> None:
42+
def write_tag(data: Buffer, value: u8) -> None:
4143
raise NotImplementedError
4244

4345
def read_str(data: Buffer) -> str:
@@ -59,15 +61,18 @@ def write_float(data: Buffer, value: float) -> None:
5961
raise NotImplementedError
6062

6163

62-
LITERAL_INT: Final = 1
63-
LITERAL_STR: Final = 2
64-
LITERAL_BOOL: Final = 3
65-
LITERAL_FLOAT: Final = 4
66-
LITERAL_COMPLEX: Final = 5
67-
LITERAL_NONE: Final = 6
64+
# Always use this type alias to refer to type tags.
65+
Tag = u8
66+
67+
LITERAL_INT: Final[Tag] = 1
68+
LITERAL_STR: Final[Tag] = 2
69+
LITERAL_BOOL: Final[Tag] = 3
70+
LITERAL_FLOAT: Final[Tag] = 4
71+
LITERAL_COMPLEX: Final[Tag] = 5
72+
LITERAL_NONE: Final[Tag] = 6
6873

6974

70-
def read_literal(data: Buffer, tag: int) -> int | str | bool | float:
75+
def read_literal(data: Buffer, tag: Tag) -> int | str | bool | float:
7176
if tag == LITERAL_INT:
7277
return read_int(data)
7378
elif tag == LITERAL_STR:

mypy/nodes.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
LITERAL_COMPLEX,
1919
LITERAL_NONE,
2020
Buffer,
21+
Tag,
2122
read_bool,
2223
read_float,
2324
read_int,
@@ -4877,17 +4878,17 @@ def local_definitions(
48774878
yield from local_definitions(node.names, fullname, node)
48784879

48794880

4880-
MYPY_FILE: Final = 0
4881-
OVERLOADED_FUNC_DEF: Final = 1
4882-
FUNC_DEF: Final = 2
4883-
DECORATOR: Final = 3
4884-
VAR: Final = 4
4885-
TYPE_VAR_EXPR: Final = 5
4886-
PARAM_SPEC_EXPR: Final = 6
4887-
TYPE_VAR_TUPLE_EXPR: Final = 7
4888-
TYPE_INFO: Final = 8
4889-
TYPE_ALIAS: Final = 9
4890-
CLASS_DEF: Final = 10
4881+
MYPY_FILE: Final[Tag] = 0
4882+
OVERLOADED_FUNC_DEF: Final[Tag] = 1
4883+
FUNC_DEF: Final[Tag] = 2
4884+
DECORATOR: Final[Tag] = 3
4885+
VAR: Final[Tag] = 4
4886+
TYPE_VAR_EXPR: Final[Tag] = 5
4887+
PARAM_SPEC_EXPR: Final[Tag] = 6
4888+
TYPE_VAR_TUPLE_EXPR: Final[Tag] = 7
4889+
TYPE_INFO: Final[Tag] = 8
4890+
TYPE_ALIAS: Final[Tag] = 9
4891+
CLASS_DEF: Final[Tag] = 10
48914892

48924893

48934894
def read_symbol(data: Buffer) -> mypy.nodes.SymbolNode:

mypy/types.py

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from mypy.bogus_type import Bogus
1313
from mypy.cache import (
1414
Buffer,
15+
Tag,
1516
read_bool,
1617
read_int,
1718
read_int_list,
@@ -4120,25 +4121,25 @@ def type_vars_as_args(type_vars: Sequence[TypeVarLikeType]) -> tuple[Type, ...]:
41204121
return tuple(args)
41214122

41224123

4123-
TYPE_ALIAS_TYPE: Final = 1
4124-
TYPE_VAR_TYPE: Final = 2
4125-
PARAM_SPEC_TYPE: Final = 3
4126-
TYPE_VAR_TUPLE_TYPE: Final = 4
4127-
UNBOUND_TYPE: Final = 5
4128-
UNPACK_TYPE: Final = 6
4129-
ANY_TYPE: Final = 7
4130-
UNINHABITED_TYPE: Final = 8
4131-
NONE_TYPE: Final = 9
4132-
DELETED_TYPE: Final = 10
4133-
INSTANCE: Final = 11
4134-
CALLABLE_TYPE: Final = 12
4135-
OVERLOADED: Final = 13
4136-
TUPLE_TYPE: Final = 14
4137-
TYPED_DICT_TYPE: Final = 15
4138-
LITERAL_TYPE: Final = 16
4139-
UNION_TYPE: Final = 17
4140-
TYPE_TYPE: Final = 18
4141-
PARAMETERS: Final = 19
4124+
TYPE_ALIAS_TYPE: Final[Tag] = 1
4125+
TYPE_VAR_TYPE: Final[Tag] = 2
4126+
PARAM_SPEC_TYPE: Final[Tag] = 3
4127+
TYPE_VAR_TUPLE_TYPE: Final[Tag] = 4
4128+
UNBOUND_TYPE: Final[Tag] = 5
4129+
UNPACK_TYPE: Final[Tag] = 6
4130+
ANY_TYPE: Final[Tag] = 7
4131+
UNINHABITED_TYPE: Final[Tag] = 8
4132+
NONE_TYPE: Final[Tag] = 9
4133+
DELETED_TYPE: Final[Tag] = 10
4134+
INSTANCE: Final[Tag] = 11
4135+
CALLABLE_TYPE: Final[Tag] = 12
4136+
OVERLOADED: Final[Tag] = 13
4137+
TUPLE_TYPE: Final[Tag] = 14
4138+
TYPED_DICT_TYPE: Final[Tag] = 15
4139+
LITERAL_TYPE: Final[Tag] = 16
4140+
UNION_TYPE: Final[Tag] = 17
4141+
TYPE_TYPE: Final[Tag] = 18
4142+
PARAMETERS: Final[Tag] = 19
41424143

41434144

41444145
def read_type(data: Buffer) -> Type:

mypy/typeshed/stubs/mypy-native/native_internal.pyi

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from mypy_extensions import u8
2+
13
class Buffer:
24
def __init__(self, source: bytes = ...) -> None: ...
35
def getvalue(self) -> bytes: ...
@@ -10,5 +12,5 @@ def write_float(data: Buffer, value: float) -> None: ...
1012
def read_float(data: Buffer) -> float: ...
1113
def write_int(data: Buffer, value: int) -> None: ...
1214
def read_int(data: Buffer) -> int: ...
13-
def write_tag(data: Buffer, value: int) -> None: ...
14-
def read_tag(data: Buffer) -> int: ...
15+
def write_tag(data: Buffer, value: u8) -> None: ...
16+
def read_tag(data: Buffer) -> u8: ...

mypyc/lib-rt/native_internal.c

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -438,18 +438,18 @@ write_int(PyObject *self, PyObject *args, PyObject *kwds) {
438438
return Py_None;
439439
}
440440

441-
static CPyTagged
441+
static uint8_t
442442
read_tag_internal(PyObject *data) {
443443
if (_check_buffer(data) == 2)
444-
return CPY_INT_TAG;
444+
return CPY_LL_UINT_ERROR;
445445

446446
if (_check_read((BufferObject *)data, 1) == 2)
447-
return CPY_INT_TAG;
447+
return CPY_LL_UINT_ERROR;
448448
char *buf = ((BufferObject *)data)->buf;
449449

450450
uint8_t ret = *(uint8_t *)(buf + ((BufferObject *)data)->pos);
451451
((BufferObject *)data)->pos += 1;
452-
return ((CPyTagged)ret) << 1;
452+
return ret;
453453
}
454454

455455
static PyObject*
@@ -458,27 +458,22 @@ read_tag(PyObject *self, PyObject *args, PyObject *kwds) {
458458
PyObject *data = NULL;
459459
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &data))
460460
return NULL;
461-
CPyTagged retval = read_tag_internal(data);
462-
if (retval == CPY_INT_TAG) {
461+
uint8_t retval = read_tag_internal(data);
462+
if (retval == CPY_LL_UINT_ERROR && PyErr_Occurred()) {
463463
return NULL;
464464
}
465-
return CPyTagged_StealAsObject(retval);
465+
return PyLong_FromLong(retval);
466466
}
467467

468468
static char
469-
write_tag_internal(PyObject *data, CPyTagged value) {
469+
write_tag_internal(PyObject *data, uint8_t value) {
470470
if (_check_buffer(data) == 2)
471471
return 2;
472472

473-
if (value > MAX_SHORT_INT_TAGGED) {
474-
PyErr_SetString(PyExc_OverflowError, "value must fit in single byte");
475-
return 2;
476-
}
477-
478473
if (_check_size((BufferObject *)data, 1) == 2)
479474
return 2;
480475
uint8_t *buf = (uint8_t *)((BufferObject *)data)->buf;
481-
*(buf + ((BufferObject *)data)->pos) = (uint8_t)(value >> 1);
476+
*(buf + ((BufferObject *)data)->pos) = value;
482477
((BufferObject *)data)->pos += 1;
483478
((BufferObject *)data)->end += 1;
484479
return 1;
@@ -491,12 +486,12 @@ write_tag(PyObject *self, PyObject *args, PyObject *kwds) {
491486
PyObject *value = NULL;
492487
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist, &data, &value))
493488
return NULL;
494-
if (!PyLong_Check(value)) {
495-
PyErr_SetString(PyExc_TypeError, "value must be an int");
489+
uint8_t unboxed = CPyLong_AsUInt8(value);
490+
if (unboxed == CPY_LL_UINT_ERROR && PyErr_Occurred()) {
491+
CPy_TypeError("u8", value);
496492
return NULL;
497493
}
498-
CPyTagged tagged_value = CPyTagged_BorrowFromObject(value);
499-
if (write_tag_internal(data, tagged_value) == 2) {
494+
if (write_tag_internal(data, unboxed) == 2) {
500495
return NULL;
501496
}
502497
Py_INCREF(Py_None);

mypyc/lib-rt/native_internal.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ static char write_float_internal(PyObject *data, double value);
1616
static double read_float_internal(PyObject *data);
1717
static char write_int_internal(PyObject *data, CPyTagged value);
1818
static CPyTagged read_int_internal(PyObject *data);
19-
static char write_tag_internal(PyObject *data, CPyTagged value);
20-
static CPyTagged read_tag_internal(PyObject *data);
19+
static char write_tag_internal(PyObject *data, uint8_t value);
20+
static uint8_t read_tag_internal(PyObject *data);
2121
static int NativeInternal_ABI_Version(void);
2222

2323
#else
@@ -35,8 +35,8 @@ static void **NativeInternal_API;
3535
#define read_float_internal (*(double (*)(PyObject *source)) NativeInternal_API[8])
3636
#define write_int_internal (*(char (*)(PyObject *source, CPyTagged value)) NativeInternal_API[9])
3737
#define read_int_internal (*(CPyTagged (*)(PyObject *source)) NativeInternal_API[10])
38-
#define write_tag_internal (*(char (*)(PyObject *source, CPyTagged value)) NativeInternal_API[11])
39-
#define read_tag_internal (*(CPyTagged (*)(PyObject *source)) NativeInternal_API[12])
38+
#define write_tag_internal (*(char (*)(PyObject *source, uint8_t value)) NativeInternal_API[11])
39+
#define read_tag_internal (*(uint8_t (*)(PyObject *source)) NativeInternal_API[12])
4040
#define NativeInternal_ABI_Version (*(int (*)(void)) NativeInternal_API[13])
4141

4242
static int

mypyc/primitives/misc_ops.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
object_rprimitive,
2121
pointer_rprimitive,
2222
str_rprimitive,
23+
uint8_rprimitive,
2324
void_rtype,
2425
)
2526
from mypyc.primitives.registry import (
@@ -426,7 +427,7 @@
426427

427428
function_op(
428429
name="native_internal.write_tag",
429-
arg_types=[object_rprimitive, int_rprimitive],
430+
arg_types=[object_rprimitive, uint8_rprimitive],
430431
return_type=none_rprimitive,
431432
c_function_name="write_tag_internal",
432433
error_kind=ERR_MAGIC,
@@ -435,7 +436,7 @@
435436
function_op(
436437
name="native_internal.read_tag",
437438
arg_types=[object_rprimitive],
438-
return_type=int_rprimitive,
439+
return_type=uint8_rprimitive,
439440
c_function_name="read_tag_internal",
440441
error_kind=ERR_MAGIC,
441442
)

mypyc/test-data/irbuild-classes.test

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1410,18 +1410,23 @@ class TestOverload:
14101410
return x
14111411

14121412
[case testNativeBufferFastPath]
1413+
from typing import Final
1414+
from mypy_extensions import u8
14131415
from native_internal import (
14141416
Buffer, write_bool, read_bool, write_str, read_str, write_float, read_float,
14151417
write_int, read_int, write_tag, read_tag
14161418
)
14171419

1420+
Tag = u8
1421+
TAG: Final[Tag] = 1
1422+
14181423
def foo() -> None:
14191424
b = Buffer()
14201425
write_str(b, "foo")
14211426
write_bool(b, True)
14221427
write_float(b, 0.1)
14231428
write_int(b, 1)
1424-
write_tag(b, 1)
1429+
write_tag(b, TAG)
14251430

14261431
b = Buffer(b.getvalue())
14271432
x = read_str(b)
@@ -1439,7 +1444,8 @@ def foo():
14391444
r9, x :: str
14401445
r10, y :: bool
14411446
r11, z :: float
1442-
r12, t, r13, u :: int
1447+
r12, t :: int
1448+
r13, u :: u8
14431449
L0:
14441450
r0 = Buffer_internal_empty()
14451451
b = r0
@@ -1448,7 +1454,7 @@ L0:
14481454
r3 = write_bool_internal(b, 1)
14491455
r4 = write_float_internal(b, 0.1)
14501456
r5 = write_int_internal(b, 2)
1451-
r6 = write_tag_internal(b, 2)
1457+
r6 = write_tag_internal(b, 1)
14521458
r7 = Buffer_getvalue_internal(b)
14531459
r8 = Buffer_internal(r7)
14541460
b = r8

mypyc/test-data/run-classes.test

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2711,11 +2711,17 @@ from native import Player
27112711
Player.MIN = <Player.MIN: 1>
27122712

27132713
[case testBufferRoundTrip_native_libs]
2714+
from typing import Final
2715+
from mypy_extensions import u8
27142716
from native_internal import (
27152717
Buffer, write_bool, read_bool, write_str, read_str, write_float, read_float,
27162718
write_int, read_int, write_tag, read_tag
27172719
)
27182720

2721+
Tag = u8
2722+
TAG_A: Final[Tag] = 33
2723+
TAG_B: Final[Tag] = 255
2724+
27192725
def test_buffer_basic() -> None:
27202726
b = Buffer(b"foo")
27212727
assert b.getvalue() == b"foo"
@@ -2729,8 +2735,8 @@ def test_buffer_roundtrip() -> None:
27292735
write_float(b, 0.1)
27302736
write_int(b, 0)
27312737
write_int(b, 1)
2732-
write_tag(b, 33)
2733-
write_tag(b, 255)
2738+
write_tag(b, TAG_A)
2739+
write_tag(b, TAG_B)
27342740
write_int(b, 2)
27352741
write_int(b, 2 ** 85)
27362742
write_int(b, -1)
@@ -2743,8 +2749,8 @@ def test_buffer_roundtrip() -> None:
27432749
assert read_float(b) == 0.1
27442750
assert read_int(b) == 0
27452751
assert read_int(b) == 1
2746-
assert read_tag(b) == 33
2747-
assert read_tag(b) == 255
2752+
assert read_tag(b) == TAG_A
2753+
assert read_tag(b) == TAG_B
27482754
assert read_int(b) == 2
27492755
assert read_int(b) == 2 ** 85
27502756
assert read_int(b) == -1

test-data/unit/lib-stub/native_internal.pyi

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from mypy_extensions import u8
2+
13
class Buffer:
24
def __init__(self, source: bytes = ...) -> None: ...
35
def getvalue(self) -> bytes: ...
@@ -10,5 +12,5 @@ def write_float(data: Buffer, value: float) -> None: ...
1012
def read_float(data: Buffer) -> float: ...
1113
def write_int(data: Buffer, value: int) -> None: ...
1214
def read_int(data: Buffer) -> int: ...
13-
def write_tag(data: Buffer, value: int) -> None: ...
14-
def read_tag(data: Buffer) -> int: ...
15+
def write_tag(data: Buffer, value: u8) -> None: ...
16+
def read_tag(data: Buffer) -> u8: ...

0 commit comments

Comments
 (0)