File: common.py

package info (click to toggle)
mypy 1.15.0-5
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 20,576 kB
  • sloc: python: 105,159; cpp: 11,380; ansic: 6,629; makefile: 247; sh: 20
file content (138 lines) | stat: -rw-r--r-- 4,347 bytes parent folder | download
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
135
136
137
138
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",
]


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 use_vectorcall(capi_version: tuple[int, int]) -> bool:
    # We can use vectorcalls to make calls on Python 3.8+ (PEP 590).
    return capi_version >= (3, 8)


def use_method_vectorcall(capi_version: tuple[int, int]) -> bool:
    # We can use a dedicated vectorcall API to call methods on Python 3.9+.
    return capi_version >= (3, 9)


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}"