Skip to content

Commit 2d4588d

Browse files
Merge branch 'main' into capi-PySys_GetAttr
2 parents eb42b39 + cb1bf89 commit 2d4588d

40 files changed

+1275
-556
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ gmon.out
4242
.coverage
4343
.mypy_cache/
4444
.pytest_cache/
45+
.ruff_cache/
4546
.DS_Store
4647

4748
*.exe

Doc/requirements-oldest-sphinx.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ alabaster==0.7.13
1616
Babel==2.13.0
1717
certifi==2023.7.22
1818
charset-normalizer==3.3.0
19-
colorama==0.4.6
2019
docutils==0.17.1
2120
idna==3.4
2221
imagesize==1.4.1
@@ -33,4 +32,4 @@ sphinxcontrib-htmlhelp==2.0.1
3332
sphinxcontrib-jsmath==1.0.1
3433
sphinxcontrib-qthelp==1.0.3
3534
sphinxcontrib-serializinghtml==1.1.5
36-
urllib3==2.0.6
35+
urllib3==2.0.7

Doc/whatsnew/3.13.rst

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,12 @@ Summary -- Release highlights
6565
6666
.. PEP-sized items next.
6767
68+
* :pep:`602` ("Annual Release Cycle for Python") has been updated:
6869

70+
* Python 3.9 - 3.12 have one and a half years of full support,
71+
followed by three and a half years of security fixes.
72+
* Python 3.13 and later have two years of full support,
73+
followed by three years of security fixes.
6974

7075
New Features
7176
============
@@ -932,9 +937,9 @@ Build Changes
932937
* Building CPython now requires a compiler with support for the C11 atomic
933938
library, GCC built-in atomic functions, or MSVC interlocked intrinsics.
934939

935-
* The ``errno``, ``md5``, ``winsound``, ``_ctypes_test``, ``_stat`` and
936-
``_testimportmultiple`` C extensions are now built with the :ref:`limited C
937-
API <limited-c-api>`.
940+
* The ``errno``, ``md5``, ``resource``, ``winsound``, ``_ctypes_test``,
941+
``_scproxy``, ``_stat``, ``_testimportmultiple`` and ``_uuid`` C extensions
942+
are now built with the :ref:`limited C API <limited-c-api>`.
938943
(Contributed by Victor Stinner in :gh:`85283`.)
939944

940945

Include/cpython/pystate.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ struct _xid {
291291
// with deleted interpreters. Note that IDs are never re-used, so
292292
// each one will always correspond to a specific interpreter
293293
// (whether still alive or not).
294-
int64_t interp;
294+
int64_t interpid;
295295
// new_object is a function that returns a new object in the current
296296
// interpreter given the data. The resulting object (a new
297297
// reference) will be equivalent to the original object. This field

Include/internal/pycore_pythread.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,27 @@ extern int _PyThread_at_fork_reinit(PyThread_type_lock *lock);
8686
#endif /* HAVE_FORK */
8787

8888

89+
// unset: -1 seconds, in nanoseconds
90+
#define PyThread_UNSET_TIMEOUT ((_PyTime_t)(-1 * 1000 * 1000 * 1000))
91+
92+
// Exported for the _xxinterpchannels module.
93+
PyAPI_FUNC(int) PyThread_ParseTimeoutArg(
94+
PyObject *arg,
95+
int blocking,
96+
PY_TIMEOUT_T *timeout);
97+
98+
/* Helper to acquire an interruptible lock with a timeout. If the lock acquire
99+
* is interrupted, signal handlers are run, and if they raise an exception,
100+
* PY_LOCK_INTR is returned. Otherwise, PY_LOCK_ACQUIRED or PY_LOCK_FAILURE
101+
* are returned, depending on whether the lock can be acquired within the
102+
* timeout.
103+
*/
104+
// Exported for the _xxinterpchannels module.
105+
PyAPI_FUNC(PyLockStatus) PyThread_acquire_lock_timed_with_retries(
106+
PyThread_type_lock,
107+
PY_TIMEOUT_T microseconds);
108+
109+
89110
#ifdef __cplusplus
90111
}
91112
#endif

Lib/asyncio/tasks.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,8 +424,6 @@ async def wait(fs, *, timeout=None, return_when=ALL_COMPLETED):
424424
425425
The fs iterable must not be empty.
426426
427-
Coroutines will be wrapped in Tasks.
428-
429427
Returns two sets of Future: (done, pending).
430428
431429
Usage:

Lib/idlelib/config.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,9 @@ def GetCoreKeys(self, keySetName=None):
597597
problem getting any core binding there will be an 'ultimate last
598598
resort fallback' to the CUA-ish bindings defined here.
599599
"""
600+
# TODO: = dict(sorted([(v-event, keys), ...]))?
600601
keyBindings={
602+
# vitual-event: list of key events.
601603
'<<copy>>': ['<Control-c>', '<Control-C>'],
602604
'<<cut>>': ['<Control-x>', '<Control-X>'],
603605
'<<paste>>': ['<Control-v>', '<Control-V>'],
@@ -880,7 +882,7 @@ def _dump(): # htest # (not really, but ignore in coverage)
880882
line, crc = 0, 0
881883

882884
def sprint(obj):
883-
global line, crc
885+
nonlocal line, crc
884886
txt = str(obj)
885887
line += 1
886888
crc = crc32(txt.encode(encoding='utf-8'), crc)
@@ -889,7 +891,7 @@ def sprint(obj):
889891

890892
def dumpCfg(cfg):
891893
print('\n', cfg, '\n') # Cfg has variable '0xnnnnnnnn' address.
892-
for key in sorted(cfg.keys()):
894+
for key in sorted(cfg):
893895
sections = cfg[key].sections()
894896
sprint(key)
895897
sprint(sections)
@@ -908,4 +910,6 @@ def dumpCfg(cfg):
908910
from unittest import main
909911
main('idlelib.idle_test.test_config', verbosity=2, exit=False)
910912

911-
# Run revised _dump() as htest?
913+
_dump()
914+
# Run revised _dump() (700+ lines) as htest? More sorting.
915+
# Perhaps as window with tabs for textviews, making it config viewer.

Lib/idlelib/configdialog.py

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -211,14 +211,8 @@ def help(self):
211211
contents=help_common+help_pages.get(page, ''))
212212

213213
def deactivate_current_config(self):
214-
"""Remove current key bindings.
215-
Iterate over window instances defined in parent and remove
216-
the keybindings.
217-
"""
218-
# Before a config is saved, some cleanup of current
219-
# config must be done - remove the previous keybindings.
220-
win_instances = self.parent.instance_dict.keys()
221-
for instance in win_instances:
214+
"""Remove current key bindings in current windows."""
215+
for instance in self.parent.instance_dict:
222216
instance.RemoveKeybindings()
223217

224218
def activate_config_changes(self):
@@ -227,8 +221,7 @@ def activate_config_changes(self):
227221
Dynamically update the current parent window instances
228222
with some of the configuration changes.
229223
"""
230-
win_instances = self.parent.instance_dict.keys()
231-
for instance in win_instances:
224+
for instance in self.parent.instance_dict:
232225
instance.ResetColorizer()
233226
instance.ResetFont()
234227
instance.set_notabs_indentwidth()
@@ -583,6 +576,8 @@ def create_page_highlight(self):
583576
(*)theme_message: Label
584577
"""
585578
self.theme_elements = {
579+
# Display_name: ('internal_name, sort_number').
580+
# TODO: remove sort_number unneeded with dict ordering.
586581
'Normal Code or Text': ('normal', '00'),
587582
'Code Context': ('context', '01'),
588583
'Python Keywords': ('keyword', '02'),
@@ -765,7 +760,7 @@ def load_theme_cfg(self):
765760
self.builtinlist.SetMenu(item_list, item_list[0])
766761
self.set_theme_type()
767762
# Load theme element option menu.
768-
theme_names = list(self.theme_elements.keys())
763+
theme_names = list(self.theme_elements)
769764
theme_names.sort(key=lambda x: self.theme_elements[x][1])
770765
self.targetlist.SetMenu(theme_names, theme_names[0])
771766
self.paint_theme_sample()
@@ -1477,12 +1472,13 @@ def load_keys_list(self, keyset_name):
14771472
reselect = True
14781473
list_index = self.bindingslist.index(ANCHOR)
14791474
keyset = idleConf.GetKeySet(keyset_name)
1480-
bind_names = list(keyset.keys())
1475+
# 'set' is dict mapping virtual event to list of key events.
1476+
bind_names = list(keyset)
14811477
bind_names.sort()
14821478
self.bindingslist.delete(0, END)
14831479
for bind_name in bind_names:
14841480
key = ' '.join(keyset[bind_name])
1485-
bind_name = bind_name[2:-2] # Trim off the angle brackets.
1481+
bind_name = bind_name[2:-2] # Trim double angle brackets.
14861482
if keyset_name in changes['keys']:
14871483
# Handle any unsaved changes to this key set.
14881484
if bind_name in changes['keys'][keyset_name]:

Lib/idlelib/debugger.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ def load_dict(self, dict, force=0, rpc_client=None):
509509
# There is also an obscure bug in sorted(dict) where the
510510
# interpreter gets into a loop requesting non-existing dict[0],
511511
# dict[1], dict[2], etc from the debugger_r.DictProxy.
512-
###
512+
# TODO recheck above; see debugger_r 159ff, debugobj 60.
513513
keys_list = dict.keys()
514514
names = sorted(keys_list)
515515
###

Lib/idlelib/debugobj.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ def setfunction(value, key=key, object=self.object):
9393

9494
class DictTreeItem(SequenceTreeItem):
9595
def keys(self):
96-
keys = list(self.object.keys())
96+
# TODO return sorted(self.object)
97+
keys = list(self.object)
9798
try:
9899
keys.sort()
99100
except:

0 commit comments

Comments
 (0)