mirror of
https://github.com/python/cpython.git
synced 2025-10-19 16:03:42 +00:00
Compare commits
5 commits
9a87ce8b57
...
fbf0843e39
Author | SHA1 | Date | |
---|---|---|---|
![]() |
fbf0843e39 | ||
![]() |
67c98ad8ef | ||
![]() |
f1883852ed | ||
![]() |
999ab8926b | ||
![]() |
869bb6948e |
14 changed files with 208 additions and 25 deletions
1
.github/workflows/mypy.yml
vendored
1
.github/workflows/mypy.yml
vendored
|
@ -16,6 +16,7 @@ on:
|
|||
- "Tools/build/check_extension_modules.py"
|
||||
- "Tools/build/check_warnings.py"
|
||||
- "Tools/build/compute-changes.py"
|
||||
- "Tools/build/consts_getter.py"
|
||||
- "Tools/build/deepfreeze.py"
|
||||
- "Tools/build/generate-build-details.py"
|
||||
- "Tools/build/generate_sbom.py"
|
||||
|
|
|
@ -19,6 +19,12 @@ If you find a bug in this documentation or would like to propose an improvement,
|
|||
please submit a bug report on the :ref:`issue tracker <using-the-tracker>`. If you
|
||||
have a suggestion on how to fix it, include that as well.
|
||||
|
||||
.. only:: translation
|
||||
|
||||
If the bug or suggested improvement concerns the translation of this
|
||||
documentation, submit the report to the
|
||||
`translation’s repository <TRANSLATION_REPO_>`_ instead.
|
||||
|
||||
You can also open a discussion item on our
|
||||
`Documentation Discourse forum <https://discuss.python.org/c/documentation/26>`_.
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
|
|||
.. impl-detail::
|
||||
|
||||
CPython keeps an array of integer objects for all integers
|
||||
between ``-5`` and ``256``. When you create an int in that range
|
||||
between ``-5`` and ``1024``. When you create an int in that range
|
||||
you actually just get back a reference to the existing object.
|
||||
|
||||
|
||||
|
|
19
Doc/conf.py
19
Doc/conf.py
|
@ -444,6 +444,25 @@
|
|||
# https://github.com/sphinx-doc/sphinx/issues/12359
|
||||
epub_use_index = False
|
||||
|
||||
# translation tag
|
||||
# ---------------
|
||||
|
||||
language_code = None
|
||||
for arg in sys.argv:
|
||||
if arg.startswith('language='):
|
||||
language_code = arg.split('=', 1)[1]
|
||||
|
||||
if language_code:
|
||||
tags.add('translation') # noqa: F821
|
||||
|
||||
rst_epilog += f"""\
|
||||
.. _TRANSLATION_REPO: https://github.com/python/python-docs-{language_code.replace("_", "-").lower()}
|
||||
""" # noqa: F821
|
||||
else:
|
||||
rst_epilog += """\
|
||||
.. _TRANSLATION_REPO: https://github.com/python
|
||||
"""
|
||||
|
||||
# Options for the coverage checker
|
||||
# --------------------------------
|
||||
|
||||
|
|
|
@ -241,6 +241,85 @@ def test_once(self):
|
|||
42)
|
||||
self.assertEqual(len(w), 0)
|
||||
|
||||
def test_filter_module(self):
|
||||
MS_WINDOWS = (sys.platform == 'win32')
|
||||
with self.module.catch_warnings(record=True) as w:
|
||||
self.module.simplefilter('error')
|
||||
self.module.filterwarnings('always', module=r'package\.module\z')
|
||||
self.module.warn_explicit('msg', UserWarning, 'filename', 42,
|
||||
module='package.module')
|
||||
self.assertEqual(len(w), 1)
|
||||
with self.assertRaises(UserWarning):
|
||||
self.module.warn_explicit('msg', UserWarning, '/path/to/package/module', 42)
|
||||
with self.assertRaises(UserWarning):
|
||||
self.module.warn_explicit('msg', UserWarning, '/path/to/package/module.py', 42)
|
||||
|
||||
with self.module.catch_warnings(record=True) as w:
|
||||
self.module.simplefilter('error')
|
||||
self.module.filterwarnings('always', module='package')
|
||||
self.module.warn_explicit('msg', UserWarning, 'filename', 42,
|
||||
module='package.module')
|
||||
self.assertEqual(len(w), 1)
|
||||
with self.assertRaises(UserWarning):
|
||||
self.module.warn_explicit('msg', UserWarning, 'filename', 42,
|
||||
module='other.package.module')
|
||||
with self.assertRaises(UserWarning):
|
||||
self.module.warn_explicit('msg', UserWarning, '/path/to/otherpackage/module.py', 42)
|
||||
|
||||
with self.module.catch_warnings(record=True) as w:
|
||||
self.module.simplefilter('error')
|
||||
self.module.filterwarnings('always', module=r'/path/to/package/module\z')
|
||||
self.module.warn_explicit('msg', UserWarning, '/path/to/package/module', 42)
|
||||
self.assertEqual(len(w), 1)
|
||||
self.module.warn_explicit('msg', UserWarning, '/path/to/package/module.py', 42)
|
||||
self.assertEqual(len(w), 2)
|
||||
with self.assertRaises(UserWarning):
|
||||
self.module.warn_explicit('msg', UserWarning, '/PATH/TO/PACKAGE/MODULE', 42)
|
||||
if MS_WINDOWS:
|
||||
if self.module is py_warnings:
|
||||
self.module.warn_explicit('msg', UserWarning, r'/path/to/package/module.PY', 42)
|
||||
self.assertEqual(len(w), 3)
|
||||
with self.assertRaises(UserWarning):
|
||||
self.module.warn_explicit('msg', UserWarning, r'/path/to/package/module/__init__.py', 42)
|
||||
with self.assertRaises(UserWarning):
|
||||
self.module.warn_explicit('msg', UserWarning, r'/path/to/package/module.pyw', 42)
|
||||
with self.assertRaises(UserWarning):
|
||||
self.module.warn_explicit('msg', UserWarning, r'\path\to\package\module', 42)
|
||||
|
||||
with self.module.catch_warnings(record=True) as w:
|
||||
self.module.simplefilter('error')
|
||||
self.module.filterwarnings('always', module=r'/path/to/package/__init__\z')
|
||||
self.module.warn_explicit('msg', UserWarning, '/path/to/package/__init__.py', 42)
|
||||
self.assertEqual(len(w), 1)
|
||||
self.module.warn_explicit('msg', UserWarning, '/path/to/package/__init__', 42)
|
||||
self.assertEqual(len(w), 2)
|
||||
|
||||
if MS_WINDOWS:
|
||||
with self.module.catch_warnings(record=True) as w:
|
||||
self.module.simplefilter('error')
|
||||
self.module.filterwarnings('always', module=r'C:\\path\\to\\package\\module\z')
|
||||
self.module.warn_explicit('msg', UserWarning, r'C:\path\to\package\module', 42)
|
||||
self.assertEqual(len(w), 1)
|
||||
self.module.warn_explicit('msg', UserWarning, r'C:\path\to\package\module.py', 42)
|
||||
self.assertEqual(len(w), 2)
|
||||
if self.module is py_warnings:
|
||||
self.module.warn_explicit('msg', UserWarning, r'C:\path\to\package\module.PY', 42)
|
||||
self.assertEqual(len(w), 3)
|
||||
with self.assertRaises(UserWarning):
|
||||
self.module.warn_explicit('msg', UserWarning, r'C:\path\to\package\module.pyw', 42)
|
||||
with self.assertRaises(UserWarning):
|
||||
self.module.warn_explicit('msg', UserWarning, r'C:\PATH\TO\PACKAGE\MODULE', 42)
|
||||
with self.assertRaises(UserWarning):
|
||||
self.module.warn_explicit('msg', UserWarning, r'C:/path/to/package/module', 42)
|
||||
with self.assertRaises(UserWarning):
|
||||
self.module.warn_explicit('msg', UserWarning, r'C:\path\to\package\module\__init__.py', 42)
|
||||
|
||||
with self.module.catch_warnings(record=True) as w:
|
||||
self.module.simplefilter('error')
|
||||
self.module.filterwarnings('always', module=r'<unknown>\z')
|
||||
self.module.warn_explicit('msg', UserWarning, '', 42)
|
||||
self.assertEqual(len(w), 1)
|
||||
|
||||
def test_module_globals(self):
|
||||
with self.module.catch_warnings(record=True) as w:
|
||||
self.module.simplefilter("always", UserWarning)
|
||||
|
|
17
Python/jit.c
17
Python/jit.c
|
@ -170,6 +170,8 @@ set_bits(uint32_t *loc, uint8_t loc_start, uint64_t value, uint8_t value_start,
|
|||
#define IS_AARCH64_ADD_OR_SUB(I) (((I) & 0x11C00000) == 0x11000000)
|
||||
#define IS_AARCH64_ADRP(I) (((I) & 0x9F000000) == 0x90000000)
|
||||
#define IS_AARCH64_BRANCH(I) (((I) & 0x7C000000) == 0x14000000)
|
||||
#define IS_AARCH64_BRANCH_COND(I) (((I) & 0x7C000000) == 0x54000000)
|
||||
#define IS_AARCH64_TEST_AND_BRANCH(I) (((I) & 0x7E000000) == 0x36000000)
|
||||
#define IS_AARCH64_LDR_OR_STR(I) (((I) & 0x3B000000) == 0x39000000)
|
||||
#define IS_AARCH64_MOV(I) (((I) & 0x9F800000) == 0x92800000)
|
||||
|
||||
|
@ -332,6 +334,21 @@ patch_aarch64_21rx(unsigned char *location, uint64_t value)
|
|||
patch_aarch64_21r(location, value);
|
||||
}
|
||||
|
||||
// 21-bit relative branch.
|
||||
void
|
||||
patch_aarch64_19r(unsigned char *location, uint64_t value)
|
||||
{
|
||||
uint32_t *loc32 = (uint32_t *)location;
|
||||
assert(IS_AARCH64_BRANCH_COND(*loc32));
|
||||
value -= (uintptr_t)location;
|
||||
// Check that we're not out of range of 21 signed bits:
|
||||
assert((int64_t)value >= -(1 << 20));
|
||||
assert((int64_t)value < (1 << 20));
|
||||
// Since instructions are 4-byte aligned, only use 19 bits:
|
||||
assert(get_bits(value, 0, 2) == 0);
|
||||
set_bits(loc32, 5, value, 2, 19);
|
||||
}
|
||||
|
||||
// 28-bit relative branch.
|
||||
void
|
||||
patch_aarch64_26r(unsigned char *location, uint64_t value)
|
||||
|
|
20
Tools/build/consts_getter.py
Normal file
20
Tools/build/consts_getter.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
INTERNAL = ROOT / "Include" / "internal"
|
||||
|
||||
def get_nsmallnegints_and_nsmallposints() -> tuple[int, int]:
|
||||
nsmallposints = None
|
||||
nsmallnegints = None
|
||||
with open(INTERNAL / "pycore_runtime_structs.h") as infile:
|
||||
for line in infile:
|
||||
if line.startswith("#define _PY_NSMALLPOSINTS"):
|
||||
nsmallposints = int(line.split()[-1])
|
||||
elif line.startswith("#define _PY_NSMALLNEGINTS"):
|
||||
nsmallnegints = int(line.split()[-1])
|
||||
break
|
||||
else:
|
||||
raise NotImplementedError
|
||||
assert nsmallposints
|
||||
assert nsmallnegints
|
||||
return nsmallnegints, nsmallposints
|
|
@ -17,6 +17,7 @@
|
|||
import time
|
||||
import types
|
||||
|
||||
import consts_getter
|
||||
import umarshal
|
||||
|
||||
TYPE_CHECKING = False
|
||||
|
@ -362,7 +363,9 @@ def _generate_int_for_bits(self, name: str, i: int, digit: int) -> None:
|
|||
self.write(f".ob_digit = {{ {ds} }},")
|
||||
|
||||
def generate_int(self, name: str, i: int) -> str:
|
||||
if -5 <= i <= 256:
|
||||
nsmallnegints, nsmallposints = consts_getter.get_nsmallnegints_and_nsmallposints()
|
||||
|
||||
if -nsmallnegints <= i <= nsmallposints:
|
||||
return f"(PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + {i}]"
|
||||
if i >= 0:
|
||||
name = f"const_int_{i}"
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
import os.path
|
||||
import re
|
||||
|
||||
import consts_getter
|
||||
|
||||
SCRIPT_NAME = 'Tools/build/generate_global_objects.py'
|
||||
__file__ = os.path.abspath(__file__)
|
||||
ROOT = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
|
||||
|
@ -274,20 +276,7 @@ def generate_global_strings(identifiers, strings):
|
|||
|
||||
|
||||
def generate_runtime_init(identifiers, strings):
|
||||
# First get some info from the declarations.
|
||||
nsmallposints = None
|
||||
nsmallnegints = None
|
||||
with open(os.path.join(INTERNAL, 'pycore_runtime_structs.h')) as infile:
|
||||
for line in infile:
|
||||
if line.startswith('#define _PY_NSMALLPOSINTS'):
|
||||
nsmallposints = int(line.split()[-1])
|
||||
elif line.startswith('#define _PY_NSMALLNEGINTS'):
|
||||
nsmallnegints = int(line.split()[-1])
|
||||
break
|
||||
else:
|
||||
raise NotImplementedError
|
||||
assert nsmallposints
|
||||
assert nsmallnegints
|
||||
nsmallnegints, nsmallposints = consts_getter.get_nsmallnegints_and_nsmallposints()
|
||||
|
||||
# Then target the runtime initializer.
|
||||
filename = os.path.join(INTERNAL, 'pycore_runtime_init_generated.h')
|
||||
|
|
|
@ -6,6 +6,7 @@ files =
|
|||
Tools/build/check_extension_modules.py,
|
||||
Tools/build/check_warnings.py,
|
||||
Tools/build/compute-changes.py,
|
||||
Tools/build/consts_getter.py,
|
||||
Tools/build/deepfreeze.py,
|
||||
Tools/build/generate-build-details.py,
|
||||
Tools/build/generate_sbom.py,
|
||||
|
|
|
@ -39,6 +39,34 @@
|
|||
# Update with all of the inverted branches, too:
|
||||
_X86_BRANCHES |= {v: k for k, v in _X86_BRANCHES.items() if v}
|
||||
|
||||
_AARCH64_COND_CODES = {
|
||||
# https://developer.arm.com/documentation/dui0801/b/CJAJIHAD?lang=en
|
||||
"eq": "ne",
|
||||
"ne": "eq",
|
||||
"lt": "ge",
|
||||
"ge": "lt",
|
||||
"gt": "le",
|
||||
"le": "gt",
|
||||
"vs": "vc",
|
||||
"vc": "vs",
|
||||
"mi": "pl",
|
||||
"pl": "mi",
|
||||
"cs": "cc",
|
||||
"cc": "cs",
|
||||
"hs": "lo",
|
||||
"lo": "hs",
|
||||
"hi": "ls",
|
||||
"ls": "hi",
|
||||
}
|
||||
# Branches are either b.{cond} or bc.{cond}
|
||||
_AARCH64_BRANCHES = {
|
||||
"b." + cond: ("b." + inverse if inverse else None)
|
||||
for (cond, inverse) in _AARCH64_COND_CODES.items()
|
||||
} | {
|
||||
"bc." + cond: ("bc." + inverse if inverse else None)
|
||||
for (cond, inverse) in _AARCH64_COND_CODES.items()
|
||||
}
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class _Block:
|
||||
|
@ -283,13 +311,28 @@ def run(self) -> None:
|
|||
self.path.write_text(self._body())
|
||||
|
||||
|
||||
class OptimizerAArch64(Optimizer): # pylint: disable = too-few-public-methods
|
||||
"""aarch64-apple-darwin/aarch64-pc-windows-msvc/aarch64-unknown-linux-gnu"""
|
||||
# Mach-O does not support the 19 bit branch locations needed for branch reordering
|
||||
class OptimizerAArch64_MachO(Optimizer): # pylint: disable = too-few-public-methods
|
||||
"""aarch64-apple-darwin"""
|
||||
|
||||
# https://developer.arm.com/documentation/ddi0602/2025-03/Base-Instructions/B--Branch-
|
||||
_re_jump = re.compile(r"\s*b\s+(?P<target>[\w.]+)")
|
||||
|
||||
|
||||
class OptimizerAArch64(Optimizer): # pylint: disable = too-few-public-methods
|
||||
"""aarch64-pc-windows-msvc/aarch64-unknown-linux-gnu"""
|
||||
|
||||
_branches = _AARCH64_BRANCHES
|
||||
_re_branch = re.compile(
|
||||
rf"\s*(?P<instruction>{'|'.join(_AARCH64_BRANCHES)})\s+(.+,\s+)*(?P<target>[\w.]+)"
|
||||
)
|
||||
|
||||
# https://developer.arm.com/documentation/ddi0602/2025-03/Base-Instructions/B--Branch-
|
||||
_re_jump = re.compile(r"\s*b\s+(?P<target>[\w.]+)")
|
||||
# https://developer.arm.com/documentation/ddi0602/2025-09/Base-Instructions/RET--Return-from-subroutine-
|
||||
_re_return = re.compile(r"\s*ret\b")
|
||||
|
||||
|
||||
class OptimizerX86(Optimizer): # pylint: disable = too-few-public-methods
|
||||
"""i686-pc-windows-msvc/x86_64-apple-darwin/x86_64-unknown-linux-gnu"""
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
"ARM64_RELOC_PAGEOFF12",
|
||||
"ARM64_RELOC_UNSIGNED",
|
||||
"IMAGE_REL_AMD64_REL32",
|
||||
"IMAGE_REL_ARM64_BRANCH19",
|
||||
"IMAGE_REL_ARM64_BRANCH26",
|
||||
"IMAGE_REL_ARM64_PAGEBASE_REL21",
|
||||
"IMAGE_REL_ARM64_PAGEOFFSET_12A",
|
||||
|
@ -20,6 +21,7 @@
|
|||
"R_AARCH64_ADR_GOT_PAGE",
|
||||
"R_AARCH64_ADR_PREL_PG_HI21",
|
||||
"R_AARCH64_CALL26",
|
||||
"R_AARCH64_CONDBR19",
|
||||
"R_AARCH64_JUMP26",
|
||||
"R_AARCH64_ADD_ABS_LO12_NC",
|
||||
"R_AARCH64_LD64_GOT_LO12_NC",
|
||||
|
|
|
@ -61,6 +61,7 @@ class HoleValue(enum.Enum):
|
|||
# x86_64-pc-windows-msvc:
|
||||
"IMAGE_REL_AMD64_REL32": "patch_x86_64_32rx",
|
||||
# aarch64-pc-windows-msvc:
|
||||
"IMAGE_REL_ARM64_BRANCH19": "patch_aarch64_19r",
|
||||
"IMAGE_REL_ARM64_BRANCH26": "patch_aarch64_26r",
|
||||
"IMAGE_REL_ARM64_PAGEBASE_REL21": "patch_aarch64_21rx",
|
||||
"IMAGE_REL_ARM64_PAGEOFFSET_12A": "patch_aarch64_12",
|
||||
|
@ -74,6 +75,7 @@ class HoleValue(enum.Enum):
|
|||
"R_AARCH64_ADR_GOT_PAGE": "patch_aarch64_21rx",
|
||||
"R_AARCH64_ADR_PREL_PG_HI21": "patch_aarch64_21r",
|
||||
"R_AARCH64_CALL26": "patch_aarch64_26r",
|
||||
"R_AARCH64_CONDBR19": "patch_aarch64_19r",
|
||||
"R_AARCH64_JUMP26": "patch_aarch64_26r",
|
||||
"R_AARCH64_LD64_GOT_LO12_NC": "patch_aarch64_12x",
|
||||
"R_AARCH64_MOVW_UABS_G0_NC": "patch_aarch64_16a",
|
||||
|
|
|
@ -335,7 +335,8 @@ def _handle_relocation(
|
|||
"Offset": offset,
|
||||
"Symbol": s,
|
||||
"Type": {
|
||||
"Name": "IMAGE_REL_ARM64_BRANCH26"
|
||||
"Name": "IMAGE_REL_ARM64_BRANCH19"
|
||||
| "IMAGE_REL_ARM64_BRANCH26"
|
||||
| "IMAGE_REL_ARM64_PAGEBASE_REL21"
|
||||
| "IMAGE_REL_ARM64_PAGEOFFSET_12A"
|
||||
| "IMAGE_REL_ARM64_PAGEOFFSET_12L" as kind
|
||||
|
@ -564,7 +565,7 @@ def get_target(host: str) -> _COFF32 | _COFF64 | _ELF | _MachO:
|
|||
if re.fullmatch(r"aarch64-apple-darwin.*", host):
|
||||
host = "aarch64-apple-darwin"
|
||||
condition = "defined(__aarch64__) && defined(__APPLE__)"
|
||||
optimizer = _optimizers.OptimizerAArch64
|
||||
optimizer = _optimizers.OptimizerAArch64_MachO
|
||||
target = _MachO(host, condition, optimizer=optimizer)
|
||||
elif re.fullmatch(r"aarch64-pc-windows-msvc", host):
|
||||
host = "aarch64-pc-windows-msvc"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue