Skip to content

Commit b5310db

Browse files
Merge branch 'main' into reduce-sleep
2 parents c966e5f + 65dd745 commit b5310db

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+1409
-1503
lines changed

Doc/using/configure.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,13 @@ Compiler flags
767767

768768
.. versionadded:: 3.5
769769

770+
.. envvar:: COMPILEALL_OPTS
771+
772+
Options passed to the :mod:`compileall` command line when building PYC files
773+
in ``make install``. Default: ``-j0``.
774+
775+
.. versionadded:: 3.12
776+
770777
.. envvar:: EXTRA_CFLAGS
771778

772779
Extra C compiler flags.

Doc/whatsnew/3.12.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,12 @@ Build Changes
675675
if the Clang compiler accepts the flag.
676676
(Contributed by Dong-hee Na in :gh:`89536`.)
677677

678+
* Add ``COMPILEALL_OPTS`` variable in Makefile to override :mod:`compileall`
679+
options (default: ``-j0``) in ``make install``. Also merged the 3
680+
``compileall`` commands into a single command to build .pyc files for all
681+
optimization levels (0, 1, 2) at once.
682+
(Contributed by Victor Stinner in :gh:`99289`.)
683+
678684

679685
C API Changes
680686
=============

Include/internal/pycore_compile.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ extern int _PyAST_Optimize(
4040
_PyASTOptimizeState *state);
4141

4242
/* Access compiler internals for unit testing */
43+
44+
PyAPI_FUNC(PyObject*) _PyCompile_CodeGen(
45+
PyObject *ast,
46+
PyObject *filename,
47+
PyCompilerFlags *flags,
48+
int optimize);
49+
4350
PyAPI_FUNC(PyObject*) _PyCompile_OptimizeCfg(
4451
PyObject *instructions,
4552
PyObject *consts);

Include/internal/pycore_global_objects_fini_generated.h

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_global_strings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ struct _Py_global_strings {
267267
STRUCT_FOR_ID(arguments)
268268
STRUCT_FOR_ID(argv)
269269
STRUCT_FOR_ID(as_integer_ratio)
270+
STRUCT_FOR_ID(ast)
270271
STRUCT_FOR_ID(attribute)
271272
STRUCT_FOR_ID(authorizer_callback)
272273
STRUCT_FOR_ID(autocommit)

Include/internal/pycore_runtime_init_generated.h

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_unicodeobject_generated.h

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/test/support/bytecode_helper.py

Lines changed: 52 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import unittest
44
import dis
55
import io
6-
from _testinternalcapi import optimize_cfg
6+
from _testinternalcapi import compiler_codegen, optimize_cfg
77

88
_UNSPECIFIED = object()
99

@@ -44,8 +44,7 @@ def assertNotInBytecode(self, x, opname, argval=_UNSPECIFIED):
4444
msg = msg % (opname, argval, disassembly)
4545
self.fail(msg)
4646

47-
48-
class CfgOptimizationTestCase(unittest.TestCase):
47+
class CompilationStepTestCase(unittest.TestCase):
4948

5049
HAS_ARG = set(dis.hasarg)
5150
HAS_TARGET = set(dis.hasjrel + dis.hasjabs + dis.hasexc)
@@ -58,24 +57,35 @@ def Label(self):
5857
self.last_label += 1
5958
return self.last_label
6059

61-
def complete_insts_info(self, insts):
62-
# fill in omitted fields in location, and oparg 0 for ops with no arg.
63-
instructions = []
64-
for item in insts:
65-
if isinstance(item, int):
66-
instructions.append(item)
67-
else:
68-
assert isinstance(item, tuple)
69-
inst = list(reversed(item))
70-
opcode = dis.opmap[inst.pop()]
71-
oparg = inst.pop() if opcode in self.HAS_ARG_OR_TARGET else 0
72-
loc = inst + [-1] * (4 - len(inst))
73-
instructions.append((opcode, oparg, *loc))
74-
return instructions
60+
def assertInstructionsMatch(self, actual_, expected_):
61+
# get two lists where each entry is a label or
62+
# an instruction tuple. Compare them, while mapping
63+
# each actual label to a corresponding expected label
64+
# based on their locations.
65+
66+
self.assertIsInstance(actual_, list)
67+
self.assertIsInstance(expected_, list)
68+
69+
actual = self.normalize_insts(actual_)
70+
expected = self.normalize_insts(expected_)
71+
self.assertEqual(len(actual), len(expected))
72+
73+
# compare instructions
74+
for act, exp in zip(actual, expected):
75+
if isinstance(act, int):
76+
self.assertEqual(exp, act)
77+
continue
78+
self.assertIsInstance(exp, tuple)
79+
self.assertIsInstance(act, tuple)
80+
# crop comparison to the provided expected values
81+
if len(act) > len(exp):
82+
act = act[:len(exp)]
83+
self.assertEqual(exp, act)
7584

7685
def normalize_insts(self, insts):
7786
""" Map labels to instruction index.
7887
Remove labels which are not used as jump targets.
88+
Map opcodes to opnames.
7989
"""
8090
labels_map = {}
8191
targets = set()
@@ -107,31 +117,32 @@ def normalize_insts(self, insts):
107117
res.append((opcode, arg, *loc))
108118
return res
109119

110-
def get_optimized(self, insts, consts):
111-
insts = self.complete_insts_info(insts)
112-
insts = optimize_cfg(insts, consts)
113-
return insts, consts
114120

115-
def compareInstructions(self, actual_, expected_):
116-
# get two lists where each entry is a label or
117-
# an instruction tuple. Compare them, while mapping
118-
# each actual label to a corresponding expected label
119-
# based on their locations.
121+
class CodegenTestCase(CompilationStepTestCase):
120122

121-
self.assertIsInstance(actual_, list)
122-
self.assertIsInstance(expected_, list)
123+
def generate_code(self, ast):
124+
insts = compiler_codegen(ast, "my_file.py", 0)
125+
return insts
123126

124-
actual = self.normalize_insts(actual_)
125-
expected = self.normalize_insts(expected_)
126-
self.assertEqual(len(actual), len(expected))
127127

128-
# compare instructions
129-
for act, exp in zip(actual, expected):
130-
if isinstance(act, int):
131-
self.assertEqual(exp, act)
132-
continue
133-
self.assertIsInstance(exp, tuple)
134-
self.assertIsInstance(act, tuple)
135-
# pad exp with -1's (if location info is incomplete)
136-
exp += (-1,) * (len(act) - len(exp))
137-
self.assertEqual(exp, act)
128+
class CfgOptimizationTestCase(CompilationStepTestCase):
129+
130+
def complete_insts_info(self, insts):
131+
# fill in omitted fields in location, and oparg 0 for ops with no arg.
132+
instructions = []
133+
for item in insts:
134+
if isinstance(item, int):
135+
instructions.append(item)
136+
else:
137+
assert isinstance(item, tuple)
138+
inst = list(reversed(item))
139+
opcode = dis.opmap[inst.pop()]
140+
oparg = inst.pop() if opcode in self.HAS_ARG_OR_TARGET else 0
141+
loc = inst + [-1] * (4 - len(inst))
142+
instructions.append((opcode, oparg, *loc))
143+
return instructions
144+
145+
def get_optimized(self, insts, consts):
146+
insts = self.complete_insts_info(insts)
147+
insts = optimize_cfg(insts, consts)
148+
return insts, consts

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy