Skip to content

Commit 5340e87

Browse files
committed
Merge branch 'main' into pyfunctionobject-set-vectorcall-field
2 parents 56ffc70 + 6744490 commit 5340e87

14 files changed

+70
-63
lines changed

Doc/library/traceback.rst

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -429,9 +429,9 @@ exception and traceback:
429429
import sys, traceback
430430

431431
def lumberjack():
432-
bright_side_of_death()
432+
bright_side_of_life()
433433

434-
def bright_side_of_death():
434+
def bright_side_of_life():
435435
return tuple()[0]
436436

437437
try:
@@ -441,19 +441,15 @@ exception and traceback:
441441
print("*** print_tb:")
442442
traceback.print_tb(exc_traceback, limit=1, file=sys.stdout)
443443
print("*** print_exception:")
444-
# exc_type below is ignored on 3.5 and later
445-
traceback.print_exception(exc_type, exc_value, exc_traceback,
446-
limit=2, file=sys.stdout)
444+
traceback.print_exception(exc_value, limit=2, file=sys.stdout)
447445
print("*** print_exc:")
448446
traceback.print_exc(limit=2, file=sys.stdout)
449447
print("*** format_exc, first and last line:")
450448
formatted_lines = traceback.format_exc().splitlines()
451449
print(formatted_lines[0])
452450
print(formatted_lines[-1])
453451
print("*** format_exception:")
454-
# exc_type below is ignored on 3.5 and later
455-
print(repr(traceback.format_exception(exc_type, exc_value,
456-
exc_traceback)))
452+
print(repr(traceback.format_exception(exc_value)))
457453
print("*** extract_tb:")
458454
print(repr(traceback.extract_tb(exc_traceback)))
459455
print("*** format_tb:")
@@ -473,32 +469,32 @@ The output for the example would look similar to this:
473469
File "<doctest...>", line 10, in <module>
474470
lumberjack()
475471
File "<doctest...>", line 4, in lumberjack
476-
bright_side_of_death()
472+
bright_side_of_life()
477473
IndexError: tuple index out of range
478474
*** print_exc:
479475
Traceback (most recent call last):
480476
File "<doctest...>", line 10, in <module>
481477
lumberjack()
482478
File "<doctest...>", line 4, in lumberjack
483-
bright_side_of_death()
479+
bright_side_of_life()
484480
IndexError: tuple index out of range
485481
*** format_exc, first and last line:
486482
Traceback (most recent call last):
487483
IndexError: tuple index out of range
488484
*** format_exception:
489485
['Traceback (most recent call last):\n',
490486
' File "<doctest default[0]>", line 10, in <module>\n lumberjack()\n',
491-
' File "<doctest default[0]>", line 4, in lumberjack\n bright_side_of_death()\n',
492-
' File "<doctest default[0]>", line 7, in bright_side_of_death\n return tuple()[0]\n ~~~~~~~^^^\n',
487+
' File "<doctest default[0]>", line 4, in lumberjack\n bright_side_of_life()\n',
488+
' File "<doctest default[0]>", line 7, in bright_side_of_life\n return tuple()[0]\n ~~~~~~~^^^\n',
493489
'IndexError: tuple index out of range\n']
494490
*** extract_tb:
495491
[<FrameSummary file <doctest...>, line 10 in <module>>,
496492
<FrameSummary file <doctest...>, line 4 in lumberjack>,
497-
<FrameSummary file <doctest...>, line 7 in bright_side_of_death>]
493+
<FrameSummary file <doctest...>, line 7 in bright_side_of_life>]
498494
*** format_tb:
499495
[' File "<doctest default[0]>", line 10, in <module>\n lumberjack()\n',
500-
' File "<doctest default[0]>", line 4, in lumberjack\n bright_side_of_death()\n',
501-
' File "<doctest default[0]>", line 7, in bright_side_of_death\n return tuple()[0]\n ~~~~~~~^^^\n']
496+
' File "<doctest default[0]>", line 4, in lumberjack\n bright_side_of_life()\n',
497+
' File "<doctest default[0]>", line 7, in bright_side_of_life\n return tuple()[0]\n ~~~~~~~^^^\n']
502498
*** tb_lineno: 10
503499

504500

Include/internal/pycore_frame.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,11 +190,16 @@ _PyFrame_FastToLocalsWithError(_PyInterpreterFrame *frame);
190190
void
191191
_PyFrame_LocalsToFast(_PyInterpreterFrame *frame, int clear);
192192

193-
194193
static inline bool
195194
_PyThreadState_HasStackSpace(PyThreadState *tstate, int size)
196195
{
197-
return tstate->datastack_top + size < tstate->datastack_limit;
196+
assert(
197+
(tstate->datastack_top == NULL && tstate->datastack_limit == NULL)
198+
||
199+
(tstate->datastack_top != NULL && tstate->datastack_limit != NULL)
200+
);
201+
return tstate->datastack_top != NULL &&
202+
size < tstate->datastack_limit - tstate->datastack_top;
198203
}
199204

200205
extern _PyInterpreterFrame *

Lib/argparse.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2523,7 +2523,6 @@ def _get_value(self, action, arg_string):
25232523

25242524
# ArgumentTypeErrors indicate errors
25252525
except ArgumentTypeError as err:
2526-
name = getattr(action.type, '__name__', repr(action.type))
25272526
msg = str(err)
25282527
raise ArgumentError(action, msg)
25292528

Lib/test/test_importlib/test_abc.py

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -320,34 +320,6 @@ def contents(self, *args, **kwargs):
320320
return super().contents(*args, **kwargs)
321321

322322

323-
class ResourceReaderDefaultsTests(ABCTestHarness):
324-
325-
with warnings.catch_warnings():
326-
warnings.simplefilter('ignore', DeprecationWarning)
327-
SPLIT = make_abc_subclasses(ResourceReader)
328-
329-
def test_open_resource(self):
330-
with self.assertRaises(FileNotFoundError):
331-
self.ins.open_resource('dummy_file')
332-
333-
def test_resource_path(self):
334-
with self.assertRaises(FileNotFoundError):
335-
self.ins.resource_path('dummy_file')
336-
337-
def test_is_resource(self):
338-
with self.assertRaises(FileNotFoundError):
339-
self.ins.is_resource('dummy_file')
340-
341-
def test_contents(self):
342-
with self.assertRaises(FileNotFoundError):
343-
self.ins.contents()
344-
345-
346-
(Frozen_RRDefaultTests,
347-
Source_RRDefaultsTests
348-
) = test_util.test_both(ResourceReaderDefaultsTests)
349-
350-
351323
##### MetaPathFinder concrete methods ##########################################
352324
class MetaPathFinderFindModuleTests:
353325

Lib/test/test_tracemalloc.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,20 @@ def test_fork(self):
360360
else:
361361
support.wait_process(pid, exitcode=0)
362362

363+
def test_no_incomplete_frames(self):
364+
tracemalloc.stop()
365+
tracemalloc.start(8)
366+
367+
def f(x):
368+
def g():
369+
return x
370+
return g
371+
372+
obj = f(0).__closure__[0]
373+
traceback = tracemalloc.get_object_traceback(obj)
374+
self.assertIn("test_tracemalloc", traceback[-1].filename)
375+
self.assertNotIn("test_tracemalloc", traceback[-2].filename)
376+
363377

364378
class TestSnapshot(unittest.TestCase):
365379
maxDiff = 4000

Lib/test/test_typing.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4391,6 +4391,20 @@ def blah():
43914391

43924392
blah()
43934393

4394+
def test_overload_on_compiled_functions(self):
4395+
with patch("typing._overload_registry",
4396+
defaultdict(lambda: defaultdict(dict))):
4397+
# The registry starts out empty:
4398+
self.assertEqual(typing._overload_registry, {})
4399+
4400+
# This should just not fail:
4401+
overload(sum)
4402+
overload(print)
4403+
4404+
# No overloads are recorded (but, it still has a side-effect):
4405+
self.assertEqual(typing.get_overloads(sum), [])
4406+
self.assertEqual(typing.get_overloads(print), [])
4407+
43944408
def set_up_overloads(self):
43954409
def blah():
43964410
pass
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix an issue that could prevent :opcode:`LOAD_ATTR` from specializing
2+
properly when accessing properties.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Remove two cases of undefined behavoir, by adding NULL checks.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Make sure that incomplete frames do not show up in tracemalloc traces.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix use after free in trace refs build mode. Patch by Kumar Aditya.

Modules/_tracemalloc.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,13 @@ traceback_get_frames(traceback_t *traceback)
400400
}
401401

402402
_PyInterpreterFrame *pyframe = tstate->cframe->current_frame;
403-
for (; pyframe != NULL;) {
403+
for (;;) {
404+
while (pyframe && _PyFrame_IsIncomplete(pyframe)) {
405+
pyframe = pyframe->previous;
406+
}
407+
if (pyframe == NULL) {
408+
break;
409+
}
404410
if (traceback->nframe < _Py_tracemalloc_config.max_nframe) {
405411
tracemalloc_get_frame(pyframe, &traceback->frames[traceback->nframe]);
406412
assert(traceback->frames[traceback->nframe].filename != NULL);
@@ -410,8 +416,7 @@ traceback_get_frames(traceback_t *traceback)
410416
traceback->total_nframe++;
411417
}
412418

413-
_PyInterpreterFrame *back = pyframe->previous;
414-
pyframe = back;
419+
pyframe = pyframe->previous;
415420
}
416421
}
417422

Python/ceval.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
# error "ceval.c must be build with Py_BUILD_CORE define for best performance"
4747
#endif
4848

49-
#ifndef Py_DEBUG
49+
#if !defined(Py_DEBUG) && !defined(Py_TRACE_REFS)
5050
// GH-89279: The MSVC compiler does not inline these static inline functions
5151
// in PGO build in _PyEval_EvalFrameDefault(), because this function is over
5252
// the limit of PGO, and that limit cannot be configured.

Python/pystate.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2195,15 +2195,12 @@ _PyInterpreterFrame *
21952195
_PyThreadState_PushFrame(PyThreadState *tstate, size_t size)
21962196
{
21972197
assert(size < INT_MAX/sizeof(PyObject *));
2198-
PyObject **base = tstate->datastack_top;
2199-
PyObject **top = base + size;
2200-
if (top >= tstate->datastack_limit) {
2201-
base = push_chunk(tstate, (int)size);
2198+
if (_PyThreadState_HasStackSpace(tstate, (int)size)) {
2199+
_PyInterpreterFrame *res = (_PyInterpreterFrame *)tstate->datastack_top;
2200+
tstate->datastack_top += size;
2201+
return res;
22022202
}
2203-
else {
2204-
tstate->datastack_top = top;
2205-
}
2206-
return (_PyInterpreterFrame *)base;
2203+
return (_PyInterpreterFrame *)push_chunk(tstate, (int)size);
22072204
}
22082205

22092206
void

Python/specialize.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -775,8 +775,10 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name)
775775
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_PROPERTY_NOT_PY_FUNCTION);
776776
goto fail;
777777
}
778-
uint32_t version = function_check_args(fget, 1, LOAD_ATTR) &&
779-
function_get_version(fget, LOAD_ATTR);
778+
if (!function_check_args(fget, 1, LOAD_ATTR)) {
779+
goto fail;
780+
}
781+
uint32_t version = function_get_version(fget, LOAD_ATTR);
780782
if (version == 0) {
781783
goto fail;
782784
}
@@ -831,9 +833,7 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name)
831833
assert(type->tp_getattro == _Py_slot_tp_getattro);
832834
assert(Py_IS_TYPE(descr, &PyFunction_Type));
833835
_PyLoadMethodCache *lm_cache = (_PyLoadMethodCache *)(instr + 1);
834-
uint32_t func_version = function_check_args(descr, 2, LOAD_ATTR) &&
835-
function_get_version(descr, LOAD_ATTR);
836-
if (func_version == 0) {
836+
if (!function_check_args(descr, 2, LOAD_ATTR)) {
837837
goto fail;
838838
}
839839
write_u32(lm_cache->keys_version, func_version);

0 commit comments

Comments
 (0)