Skip to content

Commit d33217b

Browse files
authored
Merge branch 'main' into main
2 parents 9e21b07 + 4b33308 commit d33217b

File tree

9 files changed

+64
-42
lines changed

9 files changed

+64
-42
lines changed

.github/workflows/mypy.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ on:
1919
- "Tools/build/consts_getter.py"
2020
- "Tools/build/deepfreeze.py"
2121
- "Tools/build/generate-build-details.py"
22+
- "Tools/build/generate_levenshtein_examples.py"
2223
- "Tools/build/generate_sbom.py"
2324
- "Tools/build/generate_stdlib_module_names.py"
2425
- "Tools/build/mypy.ini"

Include/internal/pycore_genobject.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ PyAPI_FUNC(int) _PyGen_FetchStopIterationValue(PyObject **);
3333
PyAPI_FUNC(PyObject *)_PyCoro_GetAwaitableIter(PyObject *o);
3434
PyAPI_FUNC(PyObject *)_PyAsyncGenValueWrapperNew(PyThreadState *state, PyObject *);
3535

36+
// Exported for external JIT support
37+
PyAPI_FUNC(PyObject *) _PyCoro_ComputeOrigin(int origin_depth, _PyInterpreterFrame *current_frame);
38+
3639
extern PyTypeObject _PyCoroWrapper_Type;
3740
extern PyTypeObject _PyAsyncGenWrappedValue_Type;
3841
extern PyTypeObject _PyAsyncGenAThrow_Type;

Include/internal/pycore_instruments.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,15 @@ typedef struct _PyCoMonitoringData {
122122
extern int
123123
_Py_Instrumentation_GetLine(PyCodeObject *code, _PyCoLineInstrumentationData *line_data, int index);
124124

125+
static inline uint8_t
126+
_PyCode_GetOriginalOpcode(_PyCoLineInstrumentationData *line_data, int index)
127+
{
128+
return line_data->data[index*line_data->bytes_per_entry];
129+
}
130+
131+
// Exported for external JIT support
132+
PyAPI_FUNC(uint8_t) _PyCode_Deinstrument(uint8_t opcode);
133+
125134
#ifdef __cplusplus
126135
}
127136
#endif

Lib/_colorize.py

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import builtins
12
import os
23
import sys
34

@@ -202,25 +203,25 @@ class Difflib(ThemeSection):
202203
@dataclass(frozen=True, kw_only=True)
203204
class FancyCompleter(ThemeSection):
204205
# functions and methods
205-
function: str = ANSIColors.BOLD_BLUE
206-
builtin_function_or_method: str = ANSIColors.BOLD_BLUE
207-
method: str = ANSIColors.BOLD_CYAN
208-
method_wrapper: str = ANSIColors.BOLD_CYAN
209-
wrapper_descriptor: str = ANSIColors.BOLD_CYAN
210-
method_descriptor: str = ANSIColors.BOLD_CYAN
206+
function: builtins.str = ANSIColors.BOLD_BLUE
207+
builtin_function_or_method: builtins.str = ANSIColors.BOLD_BLUE
208+
method: builtins.str = ANSIColors.BOLD_CYAN
209+
method_wrapper: builtins.str = ANSIColors.BOLD_CYAN
210+
wrapper_descriptor: builtins.str = ANSIColors.BOLD_CYAN
211+
method_descriptor: builtins.str = ANSIColors.BOLD_CYAN
211212

212213
# numbers
213-
int: str = ANSIColors.BOLD_YELLOW
214-
float: str = ANSIColors.BOLD_YELLOW
215-
complex: str = ANSIColors.BOLD_YELLOW
216-
bool: str = ANSIColors.BOLD_YELLOW
214+
int: builtins.str = ANSIColors.BOLD_YELLOW
215+
float: builtins.str = ANSIColors.BOLD_YELLOW
216+
complex: builtins.str = ANSIColors.BOLD_YELLOW
217+
bool: builtins.str = ANSIColors.BOLD_YELLOW
217218

218219
# others
219-
type: str = ANSIColors.BOLD_MAGENTA
220-
module: str = ANSIColors.CYAN
221-
NoneType: str = ANSIColors.GREY
222-
bytes: str = ANSIColors.BOLD_GREEN
223-
str: str = ANSIColors.BOLD_GREEN
220+
type: builtins.str = ANSIColors.BOLD_MAGENTA
221+
module: builtins.str = ANSIColors.CYAN
222+
NoneType: builtins.str = ANSIColors.GREY
223+
bytes: builtins.str = ANSIColors.BOLD_GREEN
224+
str: builtins.str = ANSIColors.BOLD_GREEN
224225

225226

226227
@dataclass(frozen=True, kw_only=True)

Lib/test/test__colorize.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import unittest
66
import unittest.mock
77
import _colorize
8+
from test.support import cpython_only, import_helper
89
from test.support.os_helper import EnvironmentVarGuard
910

1011

@@ -22,6 +23,15 @@ def supports_virtual_terminal():
2223
return contextlib.nullcontext()
2324

2425

26+
class TestImportTime(unittest.TestCase):
27+
28+
@cpython_only
29+
def test_lazy_import(self):
30+
import_helper.ensure_lazy_imports(
31+
"_colorize", {"copy", "re"}
32+
)
33+
34+
2535
class TestTheme(unittest.TestCase):
2636

2737
def test_attributes(self):

Objects/genobject.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,9 +1110,6 @@ make_gen(PyTypeObject *type, PyFunctionObject *func)
11101110
return (PyObject *)gen;
11111111
}
11121112

1113-
static PyObject *
1114-
compute_cr_origin(int origin_depth, _PyInterpreterFrame *current_frame);
1115-
11161113
PyObject *
11171114
_Py_MakeCoro(PyFunctionObject *func)
11181115
{
@@ -1150,7 +1147,7 @@ _Py_MakeCoro(PyFunctionObject *func)
11501147
assert(frame);
11511148
assert(_PyFrame_IsIncomplete(frame));
11521149
frame = _PyFrame_GetFirstComplete(frame->previous);
1153-
PyObject *cr_origin = compute_cr_origin(origin_depth, frame);
1150+
PyObject *cr_origin = _PyCoro_ComputeOrigin(origin_depth, frame);
11541151
((PyCoroObject *)coro)->cr_origin_or_finalizer = cr_origin;
11551152
if (!cr_origin) {
11561153
Py_DECREF(coro);
@@ -1535,8 +1532,8 @@ PyTypeObject _PyCoroWrapper_Type = {
15351532
0, /* tp_free */
15361533
};
15371534

1538-
static PyObject *
1539-
compute_cr_origin(int origin_depth, _PyInterpreterFrame *current_frame)
1535+
PyObject *
1536+
_PyCoro_ComputeOrigin(int origin_depth, _PyInterpreterFrame *current_frame)
15401537
{
15411538
_PyInterpreterFrame *frame = current_frame;
15421539
/* First count how many frames we have */
@@ -1581,7 +1578,7 @@ PyCoro_New(PyFrameObject *f, PyObject *name, PyObject *qualname)
15811578
if (origin_depth == 0) {
15821579
((PyCoroObject *)coro)->cr_origin_or_finalizer = NULL;
15831580
} else {
1584-
PyObject *cr_origin = compute_cr_origin(origin_depth, _PyEval_GetFrame());
1581+
PyObject *cr_origin = _PyCoro_ComputeOrigin(origin_depth, _PyEval_GetFrame());
15851582
((PyCoroObject *)coro)->cr_origin_or_finalizer = cr_origin;
15861583
if (!cr_origin) {
15871584
Py_DECREF(coro);

Python/instrumentation.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,12 @@ opcode_has_event(int opcode)
185185
);
186186
}
187187

188+
uint8_t
189+
_PyCode_Deinstrument(uint8_t opcode)
190+
{
191+
return DE_INSTRUMENT[opcode];
192+
}
193+
188194
static inline bool
189195
is_instrumented(int opcode)
190196
{
@@ -330,12 +336,6 @@ _PyInstruction_GetLength(PyCodeObject *code, int offset)
330336
return 1 + _PyOpcode_Caches[inst.op.code];
331337
}
332338

333-
static inline uint8_t
334-
get_original_opcode(_PyCoLineInstrumentationData *line_data, int index)
335-
{
336-
return line_data->data[index*line_data->bytes_per_entry];
337-
}
338-
339339
static inline uint8_t *
340340
get_original_opcode_ptr(_PyCoLineInstrumentationData *line_data, int index)
341341
{
@@ -401,7 +401,7 @@ dump_instrumentation_data_lines(PyCodeObject *code, _PyCoLineInstrumentationData
401401
fprintf(out, ", lines = NULL");
402402
}
403403
else {
404-
int opcode = get_original_opcode(lines, i);
404+
int opcode = _PyCode_GetOriginalOpcode(lines, i);
405405
int line_delta = get_line_delta(lines, i);
406406
if (opcode == 0) {
407407
fprintf(out, ", lines = {original_opcode = No LINE (0), line_delta = %d)", line_delta);
@@ -571,7 +571,7 @@ sanity_check_instrumentation(PyCodeObject *code)
571571
}
572572
if (opcode == INSTRUMENTED_LINE) {
573573
CHECK(data->lines);
574-
opcode = get_original_opcode(data->lines, i);
574+
opcode = _PyCode_GetOriginalOpcode(data->lines, i);
575575
CHECK(valid_opcode(opcode));
576576
CHECK(opcode != END_FOR);
577577
CHECK(opcode != RESUME);
@@ -588,7 +588,7 @@ sanity_check_instrumentation(PyCodeObject *code)
588588
* *and* we are executing a INSTRUMENTED_LINE instruction
589589
* that has de-instrumented itself, then we will execute
590590
* an invalid INSTRUMENTED_INSTRUCTION */
591-
CHECK(get_original_opcode(data->lines, i) != INSTRUMENTED_INSTRUCTION);
591+
CHECK(_PyCode_GetOriginalOpcode(data->lines, i) != INSTRUMENTED_INSTRUCTION);
592592
}
593593
if (opcode == INSTRUMENTED_INSTRUCTION) {
594594
CHECK(data->per_instruction_opcodes[i] != 0);
@@ -603,7 +603,7 @@ sanity_check_instrumentation(PyCodeObject *code)
603603
}
604604
CHECK(active_monitors.tools[event] != 0);
605605
}
606-
if (data->lines && get_original_opcode(data->lines, i)) {
606+
if (data->lines && _PyCode_GetOriginalOpcode(data->lines, i)) {
607607
int line1 = compute_line(code, get_line_delta(data->lines, i));
608608
int line2 = _PyCode_CheckLineNumber(i*sizeof(_Py_CODEUNIT), &range);
609609
CHECK(line1 == line2);
@@ -655,7 +655,7 @@ _Py_GetBaseCodeUnit(PyCodeObject *code, int i)
655655
return inst;
656656
}
657657
if (opcode == INSTRUMENTED_LINE) {
658-
opcode = get_original_opcode(code->_co_monitoring->lines, i);
658+
opcode = _PyCode_GetOriginalOpcode(code->_co_monitoring->lines, i);
659659
}
660660
if (opcode == INSTRUMENTED_INSTRUCTION) {
661661
opcode = code->_co_monitoring->per_instruction_opcodes[i];
@@ -714,7 +714,7 @@ de_instrument_line(PyCodeObject *code, _Py_CODEUNIT *bytecode, _PyCoMonitoringDa
714714
return;
715715
}
716716
_PyCoLineInstrumentationData *lines = monitoring->lines;
717-
int original_opcode = get_original_opcode(lines, i);
717+
int original_opcode = _PyCode_GetOriginalOpcode(lines, i);
718718
if (original_opcode == INSTRUMENTED_INSTRUCTION) {
719719
set_original_opcode(lines, i, monitoring->per_instruction_opcodes[i]);
720720
}
@@ -1391,7 +1391,7 @@ _Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame,
13911391
Py_DECREF(line_obj);
13921392
uint8_t original_opcode;
13931393
done:
1394-
original_opcode = get_original_opcode(line_data, i);
1394+
original_opcode = _PyCode_GetOriginalOpcode(line_data, i);
13951395
assert(original_opcode != 0);
13961396
assert(original_opcode != INSTRUMENTED_LINE);
13971397
assert(_PyOpcode_Deopt[original_opcode] == original_opcode);
@@ -1464,7 +1464,7 @@ initialize_tools(PyCodeObject *code)
14641464
int opcode = instr->op.code;
14651465
assert(opcode != ENTER_EXECUTOR);
14661466
if (opcode == INSTRUMENTED_LINE) {
1467-
opcode = get_original_opcode(code->_co_monitoring->lines, i);
1467+
opcode = _PyCode_GetOriginalOpcode(code->_co_monitoring->lines, i);
14681468
}
14691469
if (opcode == INSTRUMENTED_INSTRUCTION) {
14701470
opcode = code->_co_monitoring->per_instruction_opcodes[i];
@@ -1849,7 +1849,7 @@ force_instrument_lock_held(PyCodeObject *code, PyInterpreterState *interp)
18491849
if (removed_line_tools) {
18501850
_PyCoLineInstrumentationData *line_data = code->_co_monitoring->lines;
18511851
for (int i = code->_co_firsttraceable; i < code_len;) {
1852-
if (get_original_opcode(line_data, i)) {
1852+
if (_PyCode_GetOriginalOpcode(line_data, i)) {
18531853
remove_line_tools(code, i, removed_line_tools);
18541854
}
18551855
i += _PyInstruction_GetLength(code, i);
@@ -1876,7 +1876,7 @@ force_instrument_lock_held(PyCodeObject *code, PyInterpreterState *interp)
18761876
if (new_line_tools) {
18771877
_PyCoLineInstrumentationData *line_data = code->_co_monitoring->lines;
18781878
for (int i = code->_co_firsttraceable; i < code_len;) {
1879-
if (get_original_opcode(line_data, i)) {
1879+
if (_PyCode_GetOriginalOpcode(line_data, i)) {
18801880
add_line_tools(code, i, new_line_tools);
18811881
}
18821882
i += _PyInstruction_GetLength(code, i);

Tools/build/generate_levenshtein_examples.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
_CASE_COST = 1
1414

1515

16-
def _substitution_cost(ch_a, ch_b):
16+
def _substitution_cost(ch_a: str, ch_b: str) -> int:
1717
if ch_a == ch_b:
1818
return 0
1919
if ch_a.lower() == ch_b.lower():
@@ -22,7 +22,7 @@ def _substitution_cost(ch_a, ch_b):
2222

2323

2424
@lru_cache(None)
25-
def levenshtein(a, b):
25+
def levenshtein(a: str, b: str) -> int:
2626
if not a or not b:
2727
return (len(a) + len(b)) * _MOVE_COST
2828
option1 = levenshtein(a[:-1], b[:-1]) + _substitution_cost(a[-1], b[-1])
@@ -31,7 +31,7 @@ def levenshtein(a, b):
3131
return min(option1, option2, option3)
3232

3333

34-
def main():
34+
def main() -> None:
3535
parser = argparse.ArgumentParser(description=__doc__)
3636
parser.add_argument('output_path', metavar='FILE', type=str)
3737
parser.add_argument('--overwrite', dest='overwrite', action='store_const',
@@ -48,7 +48,7 @@ def main():
4848
)
4949
return
5050

51-
examples = set()
51+
examples: set[tuple[str, str, int]] = set()
5252
# Create a lot of non-empty examples, which should end up with a Gauss-like
5353
# distribution for even costs (moves) and odd costs (case substitutions).
5454
while len(examples) < 9990:

Tools/build/mypy.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ files =
99
Tools/build/consts_getter.py,
1010
Tools/build/deepfreeze.py,
1111
Tools/build/generate-build-details.py,
12+
Tools/build/generate_levenshtein_examples.py,
1213
Tools/build/generate_sbom.py,
1314
Tools/build/generate_stdlib_module_names.py,
1415
Tools/build/verify_ensurepip_wheels.py,

0 commit comments

Comments
 (0)