common.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. from __future__ import annotations
  2. import sys
  3. import sysconfig
  4. from typing import Any, Dict
  5. from typing_extensions import Final
  6. from mypy.util import unnamed_function
  7. PREFIX: Final = "CPyPy_" # Python wrappers
  8. NATIVE_PREFIX: Final = "CPyDef_" # Native functions etc.
  9. DUNDER_PREFIX: Final = "CPyDunder_" # Wrappers for exposing dunder methods to the API
  10. REG_PREFIX: Final = "cpy_r_" # Registers
  11. STATIC_PREFIX: Final = "CPyStatic_" # Static variables (for literals etc.)
  12. TYPE_PREFIX: Final = "CPyType_" # Type object struct
  13. MODULE_PREFIX: Final = "CPyModule_" # Cached modules
  14. ATTR_PREFIX: Final = "_" # Attributes
  15. ENV_ATTR_NAME: Final = "__mypyc_env__"
  16. NEXT_LABEL_ATTR_NAME: Final = "__mypyc_next_label__"
  17. TEMP_ATTR_NAME: Final = "__mypyc_temp__"
  18. LAMBDA_NAME: Final = "__mypyc_lambda__"
  19. PROPSET_PREFIX: Final = "__mypyc_setter__"
  20. SELF_NAME: Final = "__mypyc_self__"
  21. # Max short int we accept as a literal is based on 32-bit platforms,
  22. # so that we can just always emit the same code.
  23. TOP_LEVEL_NAME: Final = "__top_level__" # Special function representing module top level
  24. # Maximal number of subclasses for a class to trigger fast path in isinstance() checks.
  25. FAST_ISINSTANCE_MAX_SUBCLASSES: Final = 2
  26. # Size of size_t, if configured.
  27. SIZEOF_SIZE_T_SYSCONFIG: Final = sysconfig.get_config_var("SIZEOF_SIZE_T")
  28. SIZEOF_SIZE_T: Final = (
  29. int(SIZEOF_SIZE_T_SYSCONFIG)
  30. if SIZEOF_SIZE_T_SYSCONFIG is not None
  31. else (sys.maxsize + 1).bit_length() // 8
  32. )
  33. IS_32_BIT_PLATFORM: Final = int(SIZEOF_SIZE_T) == 4
  34. PLATFORM_SIZE = 4 if IS_32_BIT_PLATFORM else 8
  35. # Maximum value for a short tagged integer.
  36. MAX_SHORT_INT: Final = 2 ** (8 * int(SIZEOF_SIZE_T) - 2) - 1
  37. # Minimum value for a short tagged integer.
  38. MIN_SHORT_INT: Final = -(MAX_SHORT_INT) - 1
  39. # Maximum value for a short tagged integer represented as a C integer literal.
  40. #
  41. # Note: Assume that the compiled code uses the same bit width as mypyc
  42. MAX_LITERAL_SHORT_INT: Final = MAX_SHORT_INT
  43. MIN_LITERAL_SHORT_INT: Final = -MAX_LITERAL_SHORT_INT - 1
  44. # Description of the C type used to track the definedness of attributes and
  45. # the presence of argument default values that have types with overlapping
  46. # error values. Each tracked attribute/argument has a dedicated bit in the
  47. # relevant bitmap.
  48. BITMAP_TYPE: Final = "uint32_t"
  49. BITMAP_BITS: Final = 32
  50. # Runtime C library files
  51. RUNTIME_C_FILES: Final = [
  52. "init.c",
  53. "getargs.c",
  54. "getargsfast.c",
  55. "int_ops.c",
  56. "float_ops.c",
  57. "str_ops.c",
  58. "bytes_ops.c",
  59. "list_ops.c",
  60. "dict_ops.c",
  61. "set_ops.c",
  62. "tuple_ops.c",
  63. "exc_ops.c",
  64. "misc_ops.c",
  65. "generic_ops.c",
  66. ]
  67. JsonDict = Dict[str, Any]
  68. def shared_lib_name(group_name: str) -> str:
  69. """Given a group name, return the actual name of its extension module.
  70. (This just adds a suffix to the final component.)
  71. """
  72. return f"{group_name}__mypyc"
  73. def short_name(name: str) -> str:
  74. if name.startswith("builtins."):
  75. return name[9:]
  76. return name
  77. def use_fastcall(capi_version: tuple[int, int]) -> bool:
  78. # We can use METH_FASTCALL for faster wrapper functions on Python 3.7+.
  79. return capi_version >= (3, 7)
  80. def use_vectorcall(capi_version: tuple[int, int]) -> bool:
  81. # We can use vectorcalls to make calls on Python 3.8+ (PEP 590).
  82. return capi_version >= (3, 8)
  83. def use_method_vectorcall(capi_version: tuple[int, int]) -> bool:
  84. # We can use a dedicated vectorcall API to call methods on Python 3.9+.
  85. return capi_version >= (3, 9)
  86. def get_id_from_name(name: str, fullname: str, line: int) -> str:
  87. """Create a unique id for a function.
  88. This creates an id that is unique for any given function definition, so that it can be used as
  89. a dictionary key. This is usually the fullname of the function, but this is different in that
  90. it handles the case where the function is named '_', in which case multiple different functions
  91. could have the same name."""
  92. if unnamed_function(name):
  93. return f"{fullname}.{line}"
  94. else:
  95. return fullname
  96. def short_id_from_name(func_name: str, shortname: str, line: int | None) -> str:
  97. if unnamed_function(func_name):
  98. assert line is not None
  99. partial_name = f"{shortname}.{line}"
  100. else:
  101. partial_name = shortname
  102. return partial_name
  103. def bitmap_name(index: int) -> str:
  104. if index == 0:
  105. return "__bitmap"
  106. return f"__bitmap{index + 1}"