| from __future__ import annotations |
| |
| import sys |
| import sysconfig |
| from typing import Any, Dict, 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 |
| 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", |
| ] |
| |
| |
| 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}" |