forked from python/mypy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcommon.py
134 lines (103 loc) · 4.25 KB
/
common.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
from __future__ import annotations
import sys
import sysconfig
from typing import Any, Final
from mypy.util import unnamed_function
PREFIX: Final = "CPyPy_" # Python wrappers
NATIVE_PREFIX: Final = "CPyDef_" # Native functions etc.
DUNDER_PREFIX: Final = "CPyDunder_" # Wrappers for exposing dunder methods to the API
REG_PREFIX: Final = "cpy_r_" # Registers
STATIC_PREFIX: Final = "CPyStatic_" # Static variables (for literals etc.)
TYPE_PREFIX: Final = "CPyType_" # Type object struct
MODULE_PREFIX: Final = "CPyModule_" # Cached modules
TYPE_VAR_PREFIX: Final = "CPyTypeVar_" # Type variables when using new-style Python 3.12 syntax
ATTR_PREFIX: Final = "_" # Attributes
ENV_ATTR_NAME: Final = "__mypyc_env__"
NEXT_LABEL_ATTR_NAME: Final = "__mypyc_next_label__"
TEMP_ATTR_NAME: Final = "__mypyc_temp__"
LAMBDA_NAME: Final = "__mypyc_lambda__"
PROPSET_PREFIX: Final = "__mypyc_setter__"
SELF_NAME: Final = "__mypyc_self__"
# Max short int we accept as a literal is based on 32-bit platforms,
# so that we can just always emit the same code.
TOP_LEVEL_NAME: Final = "__top_level__" # Special function representing module top level
# Maximal number of subclasses for a class to trigger fast path in isinstance() checks.
FAST_ISINSTANCE_MAX_SUBCLASSES: Final = 2
# Size of size_t, if configured.
SIZEOF_SIZE_T_SYSCONFIG: Final = sysconfig.get_config_var("SIZEOF_SIZE_T")
SIZEOF_SIZE_T: Final = (
int(SIZEOF_SIZE_T_SYSCONFIG)
if SIZEOF_SIZE_T_SYSCONFIG is not None
else (sys.maxsize + 1).bit_length() // 8
)
IS_32_BIT_PLATFORM: Final = int(SIZEOF_SIZE_T) == 4
PLATFORM_SIZE = 4 if IS_32_BIT_PLATFORM else 8
# Maximum value for a short tagged integer.
MAX_SHORT_INT: Final = 2 ** (8 * int(SIZEOF_SIZE_T) - 2) - 1
# Minimum value for a short tagged integer.
MIN_SHORT_INT: Final = -(MAX_SHORT_INT) - 1
# Maximum value for a short tagged integer represented as a C integer literal.
#
# Note: Assume that the compiled code uses the same bit width as mypyc
MAX_LITERAL_SHORT_INT: Final = MAX_SHORT_INT
MIN_LITERAL_SHORT_INT: Final = -MAX_LITERAL_SHORT_INT - 1
# Description of the C type used to track the definedness of attributes and
# the presence of argument default values that have types with overlapping
# error values. Each tracked attribute/argument has a dedicated bit in the
# relevant bitmap.
BITMAP_TYPE: Final = "uint32_t"
BITMAP_BITS: Final = 32
# Runtime C library files
RUNTIME_C_FILES: Final = [
"init.c",
"getargs.c",
"getargsfast.c",
"int_ops.c",
"float_ops.c",
"str_ops.c",
"bytes_ops.c",
"list_ops.c",
"dict_ops.c",
"set_ops.c",
"tuple_ops.c",
"exc_ops.c",
"misc_ops.c",
"generic_ops.c",
"pythonsupport.c",
]
# Python 3.12 introduced immortal objects, specified via a special reference count
# value. The reference counts of immortal objects are normally not modified, but it's
# not strictly wrong to modify them. See PEP 683 for more information, but note that
# some details in the PEP are out of date.
HAVE_IMMORTAL: Final = sys.version_info >= (3, 12)
JsonDict = dict[str, Any]
def shared_lib_name(group_name: str) -> str:
"""Given a group name, return the actual name of its extension module.
(This just adds a suffix to the final component.)
"""
return f"{group_name}__mypyc"
def short_name(name: str) -> str:
if name.startswith("builtins."):
return name[9:]
return name
def get_id_from_name(name: str, fullname: str, line: int) -> str:
"""Create a unique id for a function.
This creates an id that is unique for any given function definition, so that it can be used as
a dictionary key. This is usually the fullname of the function, but this is different in that
it handles the case where the function is named '_', in which case multiple different functions
could have the same name."""
if unnamed_function(name):
return f"{fullname}.{line}"
else:
return fullname
def short_id_from_name(func_name: str, shortname: str, line: int | None) -> str:
if unnamed_function(func_name):
assert line is not None
partial_name = f"{shortname}.{line}"
else:
partial_name = shortname
return partial_name
def bitmap_name(index: int) -> str:
if index == 0:
return "__bitmap"
return f"__bitmap{index + 1}"