Skip to content

Commit 04af22b

Browse files
Merge branch 'main' into pythongh-94906
2 parents 61c7c6e + 678bf57 commit 04af22b

30 files changed

+2016
-1655
lines changed

Include/internal/pycore_pylifecycle.h

-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ PyAPI_FUNC(int) _Py_IsLocaleCoercionTarget(const char *ctype_loc);
3131

3232
extern void _Py_InitVersion(void);
3333
extern PyStatus _PyFaulthandler_Init(int enable);
34-
extern int _PyTraceMalloc_Init(int enable);
3534
extern PyObject * _PyBuiltin_Init(PyInterpreterState *interp);
3635
extern PyStatus _PySys_Create(
3736
PyThreadState *tstate,

Include/tracemalloc.h

+34
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,40 @@ PyAPI_FUNC(int) PyTraceMalloc_Untrack(
3333
PyAPI_FUNC(PyObject*) _PyTraceMalloc_GetTraceback(
3434
unsigned int domain,
3535
uintptr_t ptr);
36+
37+
/* Return non-zero if tracemalloc is tracing */
38+
PyAPI_FUNC(int) _PyTraceMalloc_IsTracing(void);
39+
40+
/* Clear the tracemalloc traces */
41+
PyAPI_FUNC(void) _PyTraceMalloc_ClearTraces(void);
42+
43+
/* Clear the tracemalloc traces */
44+
PyAPI_FUNC(PyObject *) _PyTraceMalloc_GetTraces(void);
45+
46+
/* Clear tracemalloc traceback for an object */
47+
PyAPI_FUNC(PyObject *) _PyTraceMalloc_GetObjectTraceback(PyObject *obj);
48+
49+
/* Initialize tracemalloc */
50+
PyAPI_FUNC(int) _PyTraceMalloc_Init(void);
51+
52+
/* Start tracemalloc */
53+
PyAPI_FUNC(int) _PyTraceMalloc_Start(int max_nframe);
54+
55+
/* Stop tracemalloc */
56+
PyAPI_FUNC(void) _PyTraceMalloc_Stop(void);
57+
58+
/* Get the tracemalloc traceback limit */
59+
PyAPI_FUNC(int) _PyTraceMalloc_GetTracebackLimit(void);
60+
61+
/* Get the memory usage of tracemalloc in bytes */
62+
PyAPI_FUNC(size_t) _PyTraceMalloc_GetMemory(void);
63+
64+
/* Get the current size and peak size of traced memory blocks as a 2-tuple */
65+
PyAPI_FUNC(PyObject *) _PyTraceMalloc_GetTracedMemory(void);
66+
67+
/* Set the peak size of traced memory blocks to the current size */
68+
PyAPI_FUNC(void) _PyTraceMalloc_ResetPeak(void);
69+
3670
#endif
3771

3872
#endif /* !Py_TRACEMALLOC_H */

Lib/asyncio/subprocess.py

+3
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ def pipe_connection_lost(self, fd, exc):
8181
self._stdin_closed.set_result(None)
8282
else:
8383
self._stdin_closed.set_exception(exc)
84+
# Since calling `wait_closed()` is not mandatory,
85+
# we shouldn't log the traceback if this is not awaited.
86+
self._stdin_closed._log_traceback = False
8487
return
8588
if fd == 1:
8689
reader = self.stdout

Lib/idlelib/NEWS.txt

+5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ Released on 2023-10-02
44
=========================
55

66

7+
gh-104499: Fix completions for Tk Aqua 8.7 (currently blank).
8+
9+
gh-104486: Make About print both tcl and tk versions if different,
10+
as is expected someday.
11+
712
gh-88496 Fix IDLE test hang on macOS.
813

914
gh-103314 Support sys.last_exc after exceptions in Shell.

Lib/idlelib/autocomplete_w.py

+3-7
Original file line numberDiff line numberDiff line change
@@ -182,16 +182,11 @@ def show_window(self, comp_lists, index, complete, mode, userWantsWin):
182182
self.userwantswindow = userWantsWin
183183
self.lasttypedstart = self.start
184184

185-
# Put widgets in place
186185
self.autocompletewindow = acw = Toplevel(self.widget)
187-
# Put it in a position so that it is not seen.
188-
acw.wm_geometry("+10000+10000")
189-
# Make it float
186+
acw.withdraw()
190187
acw.wm_overrideredirect(1)
191188
try:
192-
# This command is only needed and available on Tk >= 8.4.0 for OSX
193-
# Without it, call tips intrude on the typing process by grabbing
194-
# the focus.
189+
# Prevent grabbing focus on maxOS.
195190
acw.tk.call("::tk::unsupported::MacWindowStyle", "style", acw._w,
196191
"help", "noActivates")
197192
except TclError:
@@ -271,6 +266,7 @@ def winconfig_event(self, event):
271266
# place acw above current line
272267
new_y -= acw_height
273268
acw.wm_geometry("+%d+%d" % (new_x, new_y))
269+
acw.deiconify()
274270
acw.update_idletasks()
275271
except TclError:
276272
pass

Lib/idlelib/help_about.py

+16-21
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,12 @@
1111

1212
from idlelib import textview
1313

14-
version = python_version()
14+
pyver = python_version()
1515

16-
17-
def build_bits():
18-
"Return bits for platform."
19-
if sys.platform == 'darwin':
20-
return '64' if sys.maxsize > 2**32 else '32'
21-
else:
22-
return architecture()[0][:2]
16+
if sys.platform == 'darwin':
17+
bits = '64' if sys.maxsize > 2**32 else '32'
18+
else:
19+
bits = architecture()[0][:2]
2320

2421

2522
class AboutDialog(Toplevel):
@@ -45,7 +42,7 @@ def __init__(self, parent, title=None, *, _htest=False, _utest=False):
4542
self.create_widgets()
4643
self.resizable(height=False, width=False)
4744
self.title(title or
48-
f'About IDLE {version} ({build_bits()} bit)')
45+
f'About IDLE {pyver} ({bits} bit)')
4946
self.transient(parent)
5047
self.grab_set()
5148
self.protocol("WM_DELETE_WINDOW", self.ok)
@@ -76,8 +73,8 @@ def create_widgets(self):
7673
bg=self.bg, font=('courier', 24, 'bold'))
7774
header.grid(row=0, column=0, sticky=E, padx=10, pady=10)
7875

79-
tk_patchlevel = self.info_patchlevel()
80-
ext = '.png' if tk_patchlevel >= (8, 6) else '.gif'
76+
tkpatch = self._root().getvar('tk_patchLevel')
77+
ext = '.png' if tkpatch >= '8.6' else '.gif'
8178
icon = os.path.join(os.path.abspath(os.path.dirname(__file__)),
8279
'Icons', f'idle_48{ext}')
8380
self.icon_image = PhotoImage(master=self._root(), file=icon)
@@ -102,13 +99,11 @@ def create_widgets(self):
10299
height=2, bg=self.bg).grid(row=8, column=0, sticky=EW,
103100
columnspan=3, padx=5, pady=5)
104101

105-
pyver = Label(frame_background,
106-
text='Python version: ' + version,
107-
fg=self.fg, bg=self.bg)
108-
pyver.grid(row=9, column=0, sticky=W, padx=10, pady=0)
109-
tkver = Label(frame_background, text=f'Tk version: {tk_patchlevel}',
110-
fg=self.fg, bg=self.bg)
111-
tkver.grid(row=9, column=1, sticky=W, padx=2, pady=0)
102+
tclver = str(self.info_patchlevel())
103+
tkver = ' and ' + tkpatch if tkpatch != tclver else ''
104+
versions = f"Python {pyver} with tcl/tk {tclver}{tkver}"
105+
vers = Label(frame_background, text=versions, fg=self.fg, bg=self.bg)
106+
vers.grid(row=9, column=0, sticky=W, padx=10, pady=0)
112107
py_buttons = Frame(frame_background, bg=self.bg)
113108
py_buttons.grid(row=10, column=0, columnspan=2, sticky=NSEW)
114109
self.py_license = Button(py_buttons, text='License', width=8,
@@ -128,10 +123,10 @@ def create_widgets(self):
128123
height=2, bg=self.bg).grid(row=11, column=0, sticky=EW,
129124
columnspan=3, padx=5, pady=5)
130125

131-
idlever = Label(frame_background,
132-
text='IDLE version: ' + version,
126+
idle = Label(frame_background,
127+
text='IDLE',
133128
fg=self.fg, bg=self.bg)
134-
idlever.grid(row=12, column=0, sticky=W, padx=10, pady=0)
129+
idle.grid(row=12, column=0, sticky=W, padx=10, pady=0)
135130
idle_buttons = Frame(frame_background, bg=self.bg)
136131
idle_buttons.grid(row=13, column=0, columnspan=3, sticky=NSEW)
137132
self.readme = Button(idle_buttons, text='README', width=8,

Lib/idlelib/idle_test/test_help_about.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def tearDownClass(cls):
3636
del cls.root
3737

3838
def test_build_bits(self):
39-
self.assertIn(help_about.build_bits(), ('32', '64'))
39+
self.assertIn(help_about.bits, ('32', '64'))
4040

4141
def test_dialog_title(self):
4242
"""Test about dialog title"""
@@ -107,7 +107,7 @@ def test_dialog_title(self):
107107
"""Test about dialog title"""
108108
self.assertEqual(self.dialog.title(),
109109
f'About IDLE {python_version()}'
110-
f' ({help_about.build_bits()} bit)')
110+
f' ({help_about.bits} bit)')
111111

112112

113113
class CloseTest(unittest.TestCase):

Lib/test/test_syntax.py

+62
Original file line numberDiff line numberDiff line change
@@ -1877,6 +1877,68 @@ def f(x: *b)
18771877
^^^^^^^^^^^
18781878
SyntaxError: bytes can only contain ASCII literal characters
18791879
1880+
Invalid expressions in type scopes:
1881+
1882+
>>> type A[T: (x:=3)] = int
1883+
Traceback (most recent call last):
1884+
...
1885+
SyntaxError: named expression cannot be used within a TypeVar bound
1886+
1887+
>>> type A[T: (yield 3)] = int
1888+
Traceback (most recent call last):
1889+
...
1890+
SyntaxError: yield expression cannot be used within a TypeVar bound
1891+
1892+
>>> type A[T: (await 3)] = int
1893+
Traceback (most recent call last):
1894+
...
1895+
SyntaxError: await expression cannot be used within a TypeVar bound
1896+
1897+
>>> type A[T: (yield from [])] = int
1898+
Traceback (most recent call last):
1899+
...
1900+
SyntaxError: yield expression cannot be used within a TypeVar bound
1901+
1902+
>>> type A = (x := 3)
1903+
Traceback (most recent call last):
1904+
...
1905+
SyntaxError: named expression cannot be used within a type alias
1906+
1907+
>>> type A = (yield 3)
1908+
Traceback (most recent call last):
1909+
...
1910+
SyntaxError: yield expression cannot be used within a type alias
1911+
1912+
>>> type A = (await 3)
1913+
Traceback (most recent call last):
1914+
...
1915+
SyntaxError: await expression cannot be used within a type alias
1916+
1917+
>>> type A = (yield from [])
1918+
Traceback (most recent call last):
1919+
...
1920+
SyntaxError: yield expression cannot be used within a type alias
1921+
1922+
>>> class A[T]((x := 3)): ...
1923+
Traceback (most recent call last):
1924+
...
1925+
SyntaxError: named expression cannot be used within the definition of a generic
1926+
1927+
>>> class A[T]((yield 3)): ...
1928+
Traceback (most recent call last):
1929+
...
1930+
SyntaxError: yield expression cannot be used within the definition of a generic
1931+
1932+
>>> class A[T]((await 3)): ...
1933+
Traceback (most recent call last):
1934+
...
1935+
SyntaxError: await expression cannot be used within the definition of a generic
1936+
1937+
>>> class A[T]((yield from [])): ...
1938+
Traceback (most recent call last):
1939+
...
1940+
SyntaxError: yield expression cannot be used within the definition of a generic
1941+
18801942
"""
18811943

18821944
import re

Lib/test/test_type_params.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -425,11 +425,11 @@ class Foo[T: Foo, U: (Foo, Foo)]:
425425
type_params = Foo.__type_params__
426426
self.assertEqual(len(type_params), 2)
427427
self.assertEqual(type_params[0].__name__, "T")
428-
self.assertEqual(type_params[0].__bound__, Foo)
429-
self.assertEqual(type_params[0].__constraints__, None)
428+
self.assertIs(type_params[0].__bound__, Foo)
429+
self.assertEqual(type_params[0].__constraints__, ())
430430

431431
self.assertEqual(type_params[1].__name__, "U")
432-
self.assertEqual(type_params[1].__bound__, None)
432+
self.assertIs(type_params[1].__bound__, None)
433433
self.assertEqual(type_params[1].__constraints__, (Foo, Foo))
434434

435435
def test_evaluation_error(self):
@@ -439,16 +439,16 @@ class Foo[T: Undefined, U: (Undefined,)]:
439439
type_params = Foo.__type_params__
440440
with self.assertRaises(NameError):
441441
type_params[0].__bound__
442-
self.assertEqual(type_params[0].__constraints__, None)
443-
self.assertEqual(type_params[1].__bound__, None)
442+
self.assertEqual(type_params[0].__constraints__, ())
443+
self.assertIs(type_params[1].__bound__, None)
444444
with self.assertRaises(NameError):
445445
type_params[1].__constraints__
446446

447447
Undefined = "defined"
448448
self.assertEqual(type_params[0].__bound__, "defined")
449-
self.assertEqual(type_params[0].__constraints__, None)
449+
self.assertEqual(type_params[0].__constraints__, ())
450450

451-
self.assertEqual(type_params[1].__bound__, None)
451+
self.assertIs(type_params[1].__bound__, None)
452452
self.assertEqual(type_params[1].__constraints__, ("defined",))
453453

454454

0 commit comments

Comments
 (0)