pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/python/cpython/commit/ebc24d54bcf554403e9bf4b590d5c1f49e648e0d

gh-117174: Fix reference leak and gdb tests (#131095) · python/cpython@ebc24d5 · GitHub
Skip to content

Commit ebc24d5

Browse files
authored
gh-117174: Fix reference leak and gdb tests (#131095)
1 parent c00ac57 commit ebc24d5

8 files changed

Lines changed: 88 additions & 83 deletions

File tree

Lib/linecache.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,11 @@ def _getline_from_code(filename, lineno):
5151
return lines[lineno - 1]
5252
return ''
5353

54+
def _make_key(code):
55+
return (code.co_filename, code.co_qualname, code.co_firstlineno)
5456

5557
def _getlines_from_code(code):
56-
code_id = id(code)
58+
code_id = _make_key(code)
5759
if code_id in _interactive_cache:
5860
entry = _interactive_cache[code_id]
5961
if len(entry) != 1:
@@ -215,7 +217,6 @@ def get_lines(name=name, *args, **kwargs):
215217
return True
216218
return False
217219

218-
219220
def _register_code(code, string, name):
220221
entry = (len(string),
221222
None,
@@ -227,4 +228,4 @@ def _register_code(code, string, name):
227228
for const in code.co_consts:
228229
if isinstance(const, type(code)):
229230
stack.append(const)
230-
_interactive_cache[id(code)] = entry
231+
_interactive_cache[_make_key(code)] = entry

Lib/test/libregrtest/refleak.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import warnings
44
from inspect import isabstract
55
from typing import Any
6+
import linecache
67

78
from test import support
89
from test.support import os_helper
@@ -73,6 +74,11 @@ def runtest_refleak(test_name, test_func,
7374
ps = copyreg.dispatch_table.copy()
7475
pic = sys.path_importer_cache.copy()
7576
zdc: dict[str, Any] | None
77+
# Linecache holds a cache with the source of interactive code snippets
78+
# (e.g. code typed in the REPL). This cache is not cleared by
79+
# linecache.clearcache(). We need to save and restore it to avoid false
80+
# positives.
81+
linecache_data = linecache.cache.copy(), linecache._interactive_cache.copy() # type: ignore[attr-defined]
7682
try:
7783
import zipimport
7884
except ImportError:
@@ -122,7 +128,7 @@ def get_pooled_int(value):
122128

123129
xml_filename = 'refleak-xml.tmp'
124130
result = None
125-
dash_R_cleanup(fs, ps, pic, zdc, abcs)
131+
dash_R_cleanup(fs, ps, pic, zdc, abcs, linecache_data)
126132

127133
for i in rep_range:
128134
support.gc_collect()
@@ -134,7 +140,7 @@ def get_pooled_int(value):
134140
refleak_helper._hunting_for_refleaks = current
135141

136142
save_support_xml(xml_filename)
137-
dash_R_cleanup(fs, ps, pic, zdc, abcs)
143+
dash_R_cleanup(fs, ps, pic, zdc, abcs, linecache_data)
138144
support.gc_collect()
139145

140146
# Read memory statistics immediately after the garbage collection.
@@ -223,7 +229,7 @@ def check_fd_deltas(deltas):
223229
return (failed, result)
224230

225231

226-
def dash_R_cleanup(fs, ps, pic, zdc, abcs):
232+
def dash_R_cleanup(fs, ps, pic, zdc, abcs, linecache_data):
227233
import copyreg
228234
import collections.abc
229235

@@ -233,6 +239,11 @@ def dash_R_cleanup(fs, ps, pic, zdc, abcs):
233239
copyreg.dispatch_table.update(ps)
234240
sys.path_importer_cache.clear()
235241
sys.path_importer_cache.update(pic)
242+
lcache, linteractive = linecache_data
243+
linecache._interactive_cache.clear()
244+
linecache._interactive_cache.update(linteractive)
245+
linecache.cache.clear()
246+
linecache.cache.update(lcache)
236247
try:
237248
import zipimport
238249
except ImportError:

Lib/test/test_gdb/gdb_sample.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
# Sample script for use by test_gdb
2-
from _typing import _idfunc
32

43
def foo(a, b, c):
54
bar(a=a, b=b, c=c)
@@ -8,6 +7,6 @@ def bar(a, b, c):
87
baz(a, b, c)
98

109
def baz(*args):
11-
_idfunc(42)
10+
id(42)
1211

1312
foo(1, 2, 3)

Lib/test/test_gdb/test_backtrace.py

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ def test_bt(self):
2020
self.assertMultilineMatches(bt,
2121
r'''^.*
2222
Traceback \(most recent call first\):
23-
<built-in method _idfunc of module object .*>
24-
File ".*gdb_sample.py", line 11, in baz
25-
_idfunc\(42\)
26-
File ".*gdb_sample.py", line 8, in bar
23+
<built-in method id of module object .*>
24+
File ".*gdb_sample.py", line 10, in baz
25+
id\(42\)
26+
File ".*gdb_sample.py", line 7, in bar
2727
baz\(a, b, c\)
28-
File ".*gdb_sample.py", line 5, in foo
28+
File ".*gdb_sample.py", line 4, in foo
2929
bar\(a=a, b=b, c=c\)
30-
File ".*gdb_sample.py", line 13, in <module>
30+
File ".*gdb_sample.py", line 12, in <module>
3131
foo\(1, 2, 3\)
3232
''')
3333

@@ -39,11 +39,11 @@ def test_bt_full(self):
3939
cmds_after_breakpoint=['py-bt-full'])
4040
self.assertMultilineMatches(bt,
4141
r'''^.*
42-
#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 8, in bar \(a=1, b=2, c=3\)
42+
#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 7, in bar \(a=1, b=2, c=3\)
4343
baz\(a, b, c\)
44-
#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 5, in foo \(a=1, b=2, c=3\)
44+
#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 4, in foo \(a=1, b=2, c=3\)
4545
bar\(a=a, b=b, c=c\)
46-
#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 13, in <module> \(\)
46+
#[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 12, in <module> \(\)
4747
foo\(1, 2, 3\)
4848
''')
4949

@@ -55,7 +55,6 @@ def test_threads(self):
5555
'Verify that "py-bt" indicates threads that are waiting for the GIL'
5656
cmd = '''
5757
from threading import Thread
58-
from _typing import _idfunc
5958
6059
class TestThread(Thread):
6160
# These threads would run forever, but we'll interrupt things with the
@@ -71,7 +70,7 @@ def run(self):
7170
t[i].start()
7271
7372
# Trigger a breakpoint on the main thread
74-
_idfunc(42)
73+
id(42)
7574
7675
'''
7776
# Verify with "py-bt":
@@ -91,8 +90,8 @@ def run(self):
9190
# unless we add LD_PRELOAD=PATH-TO-libpthread.so.1 as a workaround
9291
def test_gc(self):
9392
'Verify that "py-bt" indicates if a thread is garbage-collecting'
94-
cmd = ('from gc import collect; from _typing import _idfunc\n'
95-
'_idfunc(42)\n'
93+
cmd = ('from gc import collect\n'
94+
'id(42)\n'
9695
'def foo():\n'
9796
' collect()\n'
9897
'def bar():\n'
@@ -114,12 +113,11 @@ def test_gc(self):
114113
"Python was compiled with optimizations")
115114
def test_wrapper_call(self):
116115
cmd = textwrap.dedent('''
117-
from typing import _idfunc
118116
class MyList(list):
119117
def __init__(self):
120118
super(*[]).__init__() # wrapper_call()
121119
122-
_idfunc("first break point")
120+
id("first break point")
123121
l = MyList()
124122
''')
125123
cmds_after_breakpoint = ['break wrapper_call', 'continue']

Lib/test/test_gdb/test_misc.py

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -35,42 +35,40 @@ def test_basic_command(self):
3535
bt = self.get_stack_trace(script=SAMPLE_SCRIPT,
3636
cmds_after_breakpoint=['py-list'])
3737

38-
self.assertListing(' 6 \n'
39-
' 7 def bar(a, b, c):\n'
40-
' 8 baz(a, b, c)\n'
41-
' 9 \n'
42-
' 10 def baz(*args):\n'
43-
' >11 _idfunc(42)\n'
44-
' 12 \n'
45-
' 13 foo(1, 2, 3)\n',
38+
self.assertListing(' 5 \n'
39+
' 6 def bar(a, b, c):\n'
40+
' 7 baz(a, b, c)\n'
41+
' 8 \n'
42+
' 9 def baz(*args):\n'
43+
' >10 id(42)\n'
44+
' 11 \n'
45+
' 12 foo(1, 2, 3)\n',
4646
bt)
4747

4848
def test_one_abs_arg(self):
4949
'Verify the "py-list" command with one absolute argument'
5050
bt = self.get_stack_trace(script=SAMPLE_SCRIPT,
5151
cmds_after_breakpoint=['py-list 9'])
5252

53-
self.assertListing(' 10 def baz(*args):\n'
54-
' >11 _idfunc(42)\n'
55-
' 12 \n'
56-
' 13 foo(1, 2, 3)\n',
53+
self.assertListing(' 9 def baz(*args):\n'
54+
' >10 id(42)\n'
55+
' 11 \n'
56+
' 12 foo(1, 2, 3)\n',
5757
bt)
5858

5959
def test_two_abs_args(self):
6060
'Verify the "py-list" command with two absolute arguments'
6161
bt = self.get_stack_trace(script=SAMPLE_SCRIPT,
62-
cmds_after_breakpoint=['py-list 1,4'])
62+
cmds_after_breakpoint=['py-list 1,3'])
6363

6464
self.assertListing(' 1 # Sample script for use by test_gdb\n'
65-
' 2 from _typing import _idfunc\n'
66-
' 3 \n'
67-
' 4 def foo(a, b, c):\n',
65+
' 2 \n'
66+
' 3 def foo(a, b, c):\n',
6867
bt)
6968

7069
SAMPLE_WITH_C_CALL = """
7170
7271
from _testcapi import pyobject_vectorcall
73-
from _typing import _idfunc
7472
7573
def foo(a, b, c):
7674
bar(a, b, c)
@@ -79,7 +77,7 @@ def bar(a, b, c):
7977
pyobject_vectorcall(baz, (a, b, c), None)
8078
8179
def baz(*args):
82-
_idfunc(42)
80+
id(42)
8381
8482
foo(1, 2, 3)
8583
@@ -96,7 +94,7 @@ def test_pyup_command(self):
9694
cmds_after_breakpoint=['py-up', 'py-up'])
9795
self.assertMultilineMatches(bt,
9896
r'''^.*
99-
#[0-9]+ Frame 0x-?[0-9a-f]+, for file <string>, line 13, in baz \(args=\(1, 2, 3\)\)
97+
#[0-9]+ Frame 0x-?[0-9a-f]+, for file <string>, line 12, in baz \(args=\(1, 2, 3\)\)
10098
#[0-9]+ <built-in method pyobject_vectorcall of module object at remote 0x[0-9a-f]+>
10199
$''')
102100

@@ -125,9 +123,9 @@ def test_up_then_down(self):
125123
cmds_after_breakpoint=['py-up', 'py-up', 'py-down'])
126124
self.assertMultilineMatches(bt,
127125
r'''^.*
128-
#[0-9]+ Frame 0x-?[0-9a-f]+, for file <string>, line 13, in baz \(args=\(1, 2, 3\)\)
126+
#[0-9]+ Frame 0x-?[0-9a-f]+, for file <string>, line 12, in baz \(args=\(1, 2, 3\)\)
129127
#[0-9]+ <built-in method pyobject_vectorcall of module object at remote 0x[0-9a-f]+>
130-
#[0-9]+ Frame 0x-?[0-9a-f]+, for file <string>, line 13, in baz \(args=\(1, 2, 3\)\)
128+
#[0-9]+ Frame 0x-?[0-9a-f]+, for file <string>, line 12, in baz \(args=\(1, 2, 3\)\)
131129
$''')
132130

133131
class PyPrintTests(DebuggerTests):

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

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