[Python-checkins] gh-111178: fix UBSan failures in `Objects/typeobject.c` (#129799)

2025-02-25 Thread picnixz
https://github.com/python/cpython/commit/3d40317ed24d03e9511ee96316bd204a8f041746
commit: 3d40317ed24d03e9511ee96316bd204a8f041746
branch: main
author: Bénédikt Tran <10796600+picn...@users.noreply.github.com>
committer: picnixz <10796600+picn...@users.noreply.github.com>
date: 2025-02-25T10:44:59Z
summary:

gh-78: fix UBSan failures in `Objects/typeobject.c` (#129799)

Fix UBSan failures for `PyTypeObject`.
Introduce a macro cast for `superobject` and remove redundant casts.
Rename the unused parameter in getter/setter methods  to `closure`
for semantic purposes.

files:
M Objects/typeobject.c

diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 1fa1220aeec648..458d78e0502723 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -84,6 +84,7 @@ class object "PyObject *" "&PyBaseObject_Type"
 
 #endif
 
+#define PyTypeObject_CAST(op)   ((PyTypeObject *)(op))
 
 typedef struct PySlot_Offset {
 short subslot_offset;
@@ -1334,11 +1335,11 @@ _PyType_Name(PyTypeObject *type)
 }
 
 static PyObject *
-type_name(PyTypeObject *type, void *context)
+type_name(PyObject *tp, void *Py_UNUSED(closure))
 {
+PyTypeObject *type = PyTypeObject_CAST(tp);
 if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
 PyHeapTypeObject* et = (PyHeapTypeObject*)type;
-
 return Py_NewRef(et->ht_name);
 }
 else {
@@ -1347,8 +1348,9 @@ type_name(PyTypeObject *type, void *context)
 }
 
 static PyObject *
-type_qualname(PyTypeObject *type, void *context)
+type_qualname(PyObject *tp, void *Py_UNUSED(closure))
 {
+PyTypeObject *type = PyTypeObject_CAST(tp);
 if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
 PyHeapTypeObject* et = (PyHeapTypeObject*)type;
 return Py_NewRef(et->ht_qualname);
@@ -1359,8 +1361,9 @@ type_qualname(PyTypeObject *type, void *context)
 }
 
 static int
-type_set_name(PyTypeObject *type, PyObject *value, void *context)
+type_set_name(PyObject *tp, PyObject *value, void *Py_UNUSED(closure))
 {
+PyTypeObject *type = PyTypeObject_CAST(tp);
 const char *tp_name;
 Py_ssize_t name_size;
 
@@ -1389,8 +1392,9 @@ type_set_name(PyTypeObject *type, PyObject *value, void 
*context)
 }
 
 static int
-type_set_qualname(PyTypeObject *type, PyObject *value, void *context)
+type_set_qualname(PyObject *tp, PyObject *value, void *context)
 {
+PyTypeObject *type = PyTypeObject_CAST(tp);
 PyHeapTypeObject* et;
 
 if (!check_set_special_type_attr(type, value, "__qualname__"))
@@ -1434,15 +1438,17 @@ type_module(PyTypeObject *type)
 return mod;
 }
 
-static PyObject *
-type_get_module(PyTypeObject *type, void *context)
+static inline PyObject *
+type_get_module(PyObject *tp, void *Py_UNUSED(closure))
 {
+PyTypeObject *type = PyTypeObject_CAST(tp);
 return type_module(type);
 }
 
 static int
-type_set_module(PyTypeObject *type, PyObject *value, void *context)
+type_set_module(PyObject *tp, PyObject *value, void *Py_UNUSED(closure))
 {
+PyTypeObject *type = PyTypeObject_CAST(tp);
 if (!check_set_special_type_attr(type, value, "__module__"))
 return -1;
 
@@ -1463,7 +1469,7 @@ _PyType_GetFullyQualifiedName(PyTypeObject *type, char 
sep)
 return PyUnicode_FromString(type->tp_name);
 }
 
-PyObject *qualname = type_qualname(type, NULL);
+PyObject *qualname = type_qualname((PyObject *)type, NULL);
 if (qualname == NULL) {
 return NULL;
 }
@@ -1495,11 +1501,11 @@ PyType_GetFullyQualifiedName(PyTypeObject *type)
 return _PyType_GetFullyQualifiedName(type, '.');
 }
 
-
 static PyObject *
-type_abstractmethods(PyTypeObject *type, void *context)
+type_abstractmethods(PyObject *tp, void *Py_UNUSED(closure))
 {
-PyObject *mod = NULL;
+PyTypeObject *type = PyTypeObject_CAST(tp);
+PyObject *res = NULL;
 /* type itself has an __abstractmethods__ descriptor (this). Don't return
that. */
 if (type == &PyType_Type) {
@@ -1507,16 +1513,17 @@ type_abstractmethods(PyTypeObject *type, void *context)
 }
 else {
 PyObject *dict = lookup_tp_dict(type);
-if (PyDict_GetItemRef(dict, &_Py_ID(__abstractmethods__), &mod) == 0) {
+if (PyDict_GetItemRef(dict, &_Py_ID(__abstractmethods__), &res) == 0) {
 PyErr_SetObject(PyExc_AttributeError, 
&_Py_ID(__abstractmethods__));
 }
 }
-return mod;
+return res;
 }
 
 static int
-type_set_abstractmethods(PyTypeObject *type, PyObject *value, void *context)
+type_set_abstractmethods(PyObject *tp, PyObject *value, void 
*Py_UNUSED(closure))
 {
+PyTypeObject *type = PyTypeObject_CAST(tp);
 /* __abstractmethods__ should only be set once on a type, in
abc.ABCMeta.__new__, so this function doesn't do anything
special to update subclasses.
@@ -1550,8 +1557,9 @@ type_set_abstractmethods(PyTypeObject *type, PyObject 
*value, void *context)
 }
 
 static PyObject *
-type_get_bases(PyTypeObject *type, void *context)
+type_get_bases(PyObject *tp, void *Py_UNUSED(closure))
 {
+

[Python-checkins] [3.12] Fix a typo in code module test (GH-130530) (GH-130533)

2025-02-25 Thread serhiy-storchaka
https://github.com/python/cpython/commit/def2ee1280fa1efcf75fdff6db6ce07530f4cc10
commit: def2ee1280fa1efcf75fdff6db6ce07530f4cc10
branch: 3.12
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: serhiy-storchaka 
date: 2025-02-25T09:54:15Z
summary:

[3.12] Fix a typo in code module test (GH-130530) (GH-130533)

(cherry picked from commit 56e337d32b88630f2c35458231cd61929f1be6d4)

Co-authored-by: Tian Gao 

files:
M Lib/test/test_code_module.py

diff --git a/Lib/test/test_code_module.py b/Lib/test/test_code_module.py
index 06a1ba494be131..a79dd73a5b65de 100644
--- a/Lib/test/test_code_module.py
+++ b/Lib/test/test_code_module.py
@@ -46,9 +46,9 @@ def test_ps2(self):
 self.infunc.side_effect = EOFError('Finished')
 self.console.interact()
 self.assertEqual(self.sysmod.ps2, '... ')
-self.sysmod.ps1 = 'custom2> '
+self.sysmod.ps2 = 'custom2> '
 self.console.interact()
-self.assertEqual(self.sysmod.ps1, 'custom2> ')
+self.assertEqual(self.sysmod.ps2, 'custom2> ')
 
 def test_console_stderr(self):
 self.infunc.side_effect = ["'antioch'", "", EOFError('Finished')]

___
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com


[Python-checkins] Fix a typo in `Py_DECREF` comment (#128387)

2025-02-25 Thread picnixz
https://github.com/python/cpython/commit/31ef8fd8e21141576796ef473c1fb7b4bffc5f0a
commit: 31ef8fd8e21141576796ef473c1fb7b4bffc5f0a
branch: main
author: Justine Krejcha 
committer: picnixz <10796600+picn...@users.noreply.github.com>
date: 2025-02-25T11:10:40+01:00
summary:

Fix a typo in `Py_DECREF` comment (#128387)

files:
M Include/refcount.h

diff --git a/Include/refcount.h b/Include/refcount.h
index d98b2dfcf37202..dbc69ee02b017d 100644
--- a/Include/refcount.h
+++ b/Include/refcount.h
@@ -313,7 +313,7 @@ PyAPI_FUNC(void) _Py_MergeZeroLocalRefcount(PyObject *);
 // Stable ABI implements Py_DECREF() as a function call on limited C API
 // version 3.12 and newer, and on Python built in debug mode. _Py_DecRef() was
 // added to Python 3.10.0a7, use Py_DecRef() on older Python versions.
-// Py_DecRef() accepts NULL whereas _Py_IncRef() doesn't.
+// Py_DecRef() accepts NULL whereas _Py_DecRef() doesn't.
 static inline void Py_DECREF(PyObject *op) {
 #  if Py_LIMITED_API+0 >= 0x030a00A7
 _Py_DecRef(op);

___
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com


[Python-checkins] gh-130453: pygettext: Extend support for specifying custom keywords (GH-130463)

2025-02-25 Thread serhiy-storchaka
https://github.com/python/cpython/commit/44213bc57c0a4b674463e170ad9d80896d866a64
commit: 44213bc57c0a4b674463e170ad9d80896d866a64
branch: main
author: Tomas R. 
committer: serhiy-storchaka 
date: 2025-02-25T12:10:54+02:00
summary:

gh-130453: pygettext: Extend support for specifying custom keywords (GH-130463)

files:
A Lib/test/test_tools/i18n_data/custom_keywords.pot
A Lib/test/test_tools/i18n_data/custom_keywords.py
A Misc/NEWS.d/next/Tools-Demos/2025-02-22-18-08-35.gh-issue-130453.njRXG8.rst
M Lib/test/test_tools/test_i18n.py
M Tools/i18n/pygettext.py

diff --git a/Lib/test/test_tools/i18n_data/custom_keywords.pot 
b/Lib/test/test_tools/i18n_data/custom_keywords.pot
new file mode 100644
index 00..48df2e7f579cc7
--- /dev/null
+++ b/Lib/test/test_tools/i18n_data/custom_keywords.pot
@@ -0,0 +1,45 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR ORGANIZATION
+# FIRST AUTHOR , YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 2000-01-01 00:00+\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: LANGUAGE \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: pygettext.py 1.5\n"
+
+
+#: custom_keywords.py:9 custom_keywords.py:10
+msgid "bar"
+msgstr ""
+
+#: custom_keywords.py:12
+msgid "cat"
+msgid_plural "cats"
+msgstr[0] ""
+msgstr[1] ""
+
+#: custom_keywords.py:13
+msgid "dog"
+msgid_plural "dogs"
+msgstr[0] ""
+msgstr[1] ""
+
+#: custom_keywords.py:15
+msgctxt "context"
+msgid "bar"
+msgstr ""
+
+#: custom_keywords.py:17
+msgctxt "context"
+msgid "cat"
+msgid_plural "cats"
+msgstr[0] ""
+msgstr[1] ""
+
diff --git a/Lib/test/test_tools/i18n_data/custom_keywords.py 
b/Lib/test/test_tools/i18n_data/custom_keywords.py
new file mode 100644
index 00..01ea56c348cb55
--- /dev/null
+++ b/Lib/test/test_tools/i18n_data/custom_keywords.py
@@ -0,0 +1,30 @@
+from gettext import (
+gettext as foo,
+ngettext as nfoo,
+pgettext as pfoo,
+npgettext as npfoo,
+gettext as bar,
+)
+
+foo('bar')
+foo('bar', 'baz')
+
+nfoo('cat', 'cats', 1)
+nfoo('dog', 'dogs')
+
+pfoo('context', 'bar')
+
+npfoo('context', 'cat', 'cats', 1)
+
+# This is an unknown keyword and should be ignored
+bar('baz')
+
+# 'nfoo' requires at least 2 arguments
+nfoo('dog')
+
+# 'pfoo' requires at least 2 arguments
+pfoo('context')
+
+# 'npfoo' requires at least 3 arguments
+npfoo('context')
+npfoo('context', 'cat')
diff --git a/Lib/test/test_tools/test_i18n.py b/Lib/test/test_tools/test_i18n.py
index d97fdb116fcd19..d73fcff4c9cb11 100644
--- a/Lib/test/test_tools/test_i18n.py
+++ b/Lib/test/test_tools/test_i18n.py
@@ -8,7 +8,7 @@
 from pathlib import Path
 
 from test.support.script_helper import assert_python_ok
-from test.test_tools import skip_if_missing, toolsdir
+from test.test_tools import imports_under_tool, skip_if_missing, toolsdir
 from test.support.os_helper import temp_cwd, temp_dir
 
 
@@ -17,6 +17,10 @@
 DATA_DIR = Path(__file__).resolve().parent / 'i18n_data'
 
 
+with imports_under_tool("i18n"):
+from pygettext import parse_spec
+
+
 def normalize_POT_file(pot):
 """Normalize the POT creation timestamp, charset and
 file locations to make the POT file easier to compare.
@@ -377,16 +381,8 @@ class _(object):
 
 def test_pygettext_output(self):
 """Test that the pygettext output exactly matches snapshots."""
-for input_file in DATA_DIR.glob('*.py'):
-output_file = input_file.with_suffix('.pot')
-with self.subTest(input_file=f'i18n_data/{input_file}'):
-contents = input_file.read_text(encoding='utf-8')
-with temp_cwd(None):
-Path(input_file.name).write_text(contents)
-assert_python_ok('-Xutf8', self.script, '--docstrings',
- '--add-comments=i18n:', input_file.name)
-output = Path('messages.pot').read_text(encoding='utf-8')
-
+for input_file, output_file, output in extract_from_snapshots():
+with self.subTest(input_file=input_file):
 expected = output_file.read_text(encoding='utf-8')
 self.assert_POT_equal(expected, output)
 
@@ -485,17 +481,67 @@ def test_comments_not_extracted_without_tags(self):
 '''), raw=True)
 self.assertNotIn('#.', data)
 
-
-def update_POT_snapshots():
-for input_file in DATA_DIR.glob('*.py'):
+def test_parse_keyword_spec(self):
+valid = (
+('foo', ('foo', {0: 'msgid'})),
+('foo:1', ('foo', {0: 'msgid'})),
+('foo:1,2', ('foo', {0: 'msgid', 1: 'msgid_plural'})),
+('foo:1, 2', ('foo', {0: 'msgid', 1: 'msgid_plural'})),
+('foo:1,2c', ('foo', {0: 'msgid', 1: 'msgctxt'})),
+('foo:2c,1', ('foo', {0: 'msgid', 1: 'msgctxt'})),
+('foo:2c ,1', ('foo', {0: 'msgid', 1: 'msgctxt'}))

[Python-checkins] [3.12] gh-108303: Fix and move `badsyntax_pep3120.py` (GH-109513) (#130540)

2025-02-25 Thread hugovk
https://github.com/python/cpython/commit/e28097682eb96550e30a66c65d929b412bf51d52
commit: e28097682eb96550e30a66c65d929b412bf51d52
branch: 3.12
author: Hugo van Kemenade <1324225+hug...@users.noreply.github.com>
committer: hugovk <1324225+hug...@users.noreply.github.com>
date: 2025-02-26T09:46:12+02:00
summary:

[3.12] gh-108303: Fix and move `badsyntax_pep3120.py` (GH-109513) (#130540)

(cherry picked from commit 4dd47c63a97b3c39cd964ad12431fcdaf76dc823)

Co-authored-by: Nikita Sobolev 
Co-authored-by: Alex Waygood 

files:
A Lib/test/tokenizedata/badsyntax_pep3120.py
D Lib/test/badsyntax_pep3120.py
M Lib/test/.ruff.toml
M Lib/test/test_utf8source.py

diff --git a/Lib/test/.ruff.toml b/Lib/test/.ruff.toml
index 1632900057cd74..79ee34362644a2 100644
--- a/Lib/test/.ruff.toml
+++ b/Lib/test/.ruff.toml
@@ -2,12 +2,12 @@ fix = true
 extend-exclude = [
 # Excluded (run with the other AC files in its own separate ruff job in 
pre-commit)
 "test_clinic.py",
+# Excluded (these aren't actually executed, they're just "data files")
+"tokenizedata/*.py",
 # Failed to lint
-"badsyntax_pep3120.py",
 "encoded_modules/module_iso_8859_1.py",
 "encoded_modules/module_koi8_r.py",
 # Failed to parse
-"badsyntax_3131.py",
 "test_lib2to3/data/bom.py",
 "test_lib2to3/data/crlf.py",
 "test_lib2to3/data/different_encoding.py",
diff --git a/Lib/test/test_utf8source.py b/Lib/test/test_utf8source.py
index 97dced8a622889..c42b6b579d 100644
--- a/Lib/test/test_utf8source.py
+++ b/Lib/test/test_utf8source.py
@@ -1,5 +1,3 @@
-# This file is marked as binary in the CVS, to prevent MacCVS from recoding it.
-
 import unittest
 
 class PEP3120Test(unittest.TestCase):
@@ -16,7 +14,7 @@ def test_pep3120(self):
 
 def test_badsyntax(self):
 try:
-import test.badsyntax_pep3120
+import test.tokenizedata.badsyntax_pep3120
 except SyntaxError as msg:
 msg = str(msg).lower()
 self.assertTrue('utf-8' in msg)
diff --git a/Lib/test/badsyntax_pep3120.py 
b/Lib/test/tokenizedata/badsyntax_pep3120.py
similarity index 100%
rename from Lib/test/badsyntax_pep3120.py
rename to Lib/test/tokenizedata/badsyntax_pep3120.py

___
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com


[Python-checkins] gh-117657: Use an atomic store to set type flags. (gh-127588)

2025-02-25 Thread nascheme
https://github.com/python/cpython/commit/baae9cb159e240ee9474ce7c02f88c233390777a
commit: baae9cb159e240ee9474ce7c02f88c233390777a
branch: main
author: Neil Schemenauer 
committer: nascheme 
date: 2025-02-25T21:24:20-08:00
summary:

gh-117657: Use an atomic store to set type flags. (gh-127588)

The `PyType_HasFeature()` function reads the flags with a relaxed atomic
load and without holding the type lock.  To avoid data races, use atomic
stores if `PyType_Ready()` has already been called.

files:
M Objects/typeobject.c

diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 458d78e0502723..f667e56afbbf8b 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -13,6 +13,7 @@
 #include "pycore_moduleobject.h"  // _PyModule_GetDef()
 #include "pycore_object.h"// _PyType_HasFeature()
 #include "pycore_object_alloc.h"  // _PyObject_MallocWithType()
+#include "pycore_pyatomic_ft_wrappers.h"
 #include "pycore_pyerrors.h"  // _PyErr_Occurred()
 #include "pycore_pystate.h"   // _PyThreadState_GET()
 #include "pycore_symtable.h"  // _Py_Mangle()
@@ -344,6 +345,39 @@ _PyStaticType_GetBuiltins(void)
 
 /* end static builtin helpers */
 
+static void
+type_set_flags(PyTypeObject *tp, unsigned long flags)
+{
+if (tp->tp_flags & Py_TPFLAGS_READY) {
+// It's possible the type object has been exposed to other threads
+// if it's been marked ready.  In that case, the type lock should be
+// held when flags are modified.
+ASSERT_TYPE_LOCK_HELD();
+}
+// Since PyType_HasFeature() reads the flags without holding the type
+// lock, we need an atomic store here.
+FT_ATOMIC_STORE_ULONG_RELAXED(tp->tp_flags, flags);
+}
+
+static void
+type_set_flags_with_mask(PyTypeObject *tp, unsigned long mask, unsigned long 
flags)
+{
+ASSERT_TYPE_LOCK_HELD();
+unsigned long new_flags = (tp->tp_flags & ~mask) | flags;
+type_set_flags(tp, new_flags);
+}
+
+static void
+type_add_flags(PyTypeObject *tp, unsigned long flag)
+{
+type_set_flags(tp, tp->tp_flags | flag);
+}
+
+static void
+type_clear_flags(PyTypeObject *tp, unsigned long flag)
+{
+type_set_flags(tp, tp->tp_flags & ~flag);
+}
 
 static inline void
 start_readying(PyTypeObject *type)
@@ -357,7 +391,7 @@ start_readying(PyTypeObject *type)
 return;
 }
 assert((type->tp_flags & Py_TPFLAGS_READYING) == 0);
-type->tp_flags |= Py_TPFLAGS_READYING;
+type_add_flags(type, Py_TPFLAGS_READYING);
 }
 
 static inline void
@@ -372,7 +406,7 @@ stop_readying(PyTypeObject *type)
 return;
 }
 assert(type->tp_flags & Py_TPFLAGS_READYING);
-type->tp_flags &= ~Py_TPFLAGS_READYING;
+type_clear_flags(type, Py_TPFLAGS_READYING);
 }
 
 static inline int
@@ -1548,11 +1582,14 @@ type_set_abstractmethods(PyObject *tp, PyObject *value, 
void *Py_UNUSED(closure)
 return -1;
 }
 
-PyType_Modified(type);
+BEGIN_TYPE_LOCK();
+type_modified_unlocked(type);
 if (abstract)
-type->tp_flags |= Py_TPFLAGS_IS_ABSTRACT;
+type_add_flags(type, Py_TPFLAGS_IS_ABSTRACT);
 else
-type->tp_flags &= ~Py_TPFLAGS_IS_ABSTRACT;
+type_clear_flags(type, Py_TPFLAGS_IS_ABSTRACT);
+END_TYPE_LOCK();
+
 return 0;
 }
 
@@ -3335,7 +3372,7 @@ mro_internal_unlocked(PyTypeObject *type, int initial, 
PyObject **p_old_mro)
 
 // XXX Expand this to Py_TPFLAGS_IMMUTABLETYPE?
 if (!(type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN)) {
-PyType_Modified(type);
+type_modified_unlocked(type);
 }
 else {
 /* For static builtin types, this is only called during init
@@ -3941,8 +3978,8 @@ type_new_alloc(type_new_ctx *ctx)
 // Initialize tp_flags.
 // All heap types need GC, since we can create a reference cycle by storing
 // an instance on one of its parents.
-type->tp_flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE |
-  Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC);
+type_set_flags(type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE |
+   Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC);
 
 // Initialize essential fields
 type->tp_as_async = &et->as_async;
@@ -4175,12 +4212,12 @@ type_new_descriptors(const type_new_ctx *ctx, 
PyTypeObject *type)
 
 if (ctx->add_weak) {
 assert((type->tp_flags & Py_TPFLAGS_MANAGED_WEAKREF) == 0);
-type->tp_flags |= Py_TPFLAGS_MANAGED_WEAKREF;
+type_add_flags(type, Py_TPFLAGS_MANAGED_WEAKREF);
 type->tp_weaklistoffset = MANAGED_WEAKREF_OFFSET;
 }
 if (ctx->add_dict) {
 assert((type->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0);
-type->tp_flags |= Py_TPFLAGS_MANAGED_DICT;
+type_add_flags(type, Py_TPFLAGS_MANAGED_DICT);
 type->tp_dictoffset = -1;
 }
 
@@ -4978,7 +5015,7 @@ PyType_FromMetaclass(
 
 type = &res->ht_type;
 /* The flags must be initialized early, before the GC traverses us */
-type->tp_flags = spec->flags | Py_TPFLAGS_HEAPTY

[Python-checkins] [3.13] gh-130163: Fix crashes related to PySys_GetObject() (GH-130503) (GH-130556)

2025-02-25 Thread serhiy-storchaka
https://github.com/python/cpython/commit/7c1b76fce8c8df00da38830f72dbdde6881a33be
commit: 7c1b76fce8c8df00da38830f72dbdde6881a33be
branch: 3.13
author: Serhiy Storchaka 
committer: serhiy-storchaka 
date: 2025-02-25T22:50:26Z
summary:

[3.13] gh-130163: Fix crashes related to PySys_GetObject() (GH-130503) 
(GH-130556)

The use of PySys_GetObject() and _PySys_GetAttr(), which return a borrowed
reference, has been replaced by using one of the following functions, which
return a strong reference and distinguish a missing attribute from an error:
_PySys_GetOptionalAttr(), _PySys_GetOptionalAttrString(),
_PySys_GetRequiredAttr(), and _PySys_GetRequiredAttrString().
(cherry picked from commit 0ef4ffeefd1737c18dc9326133c7894d58108c2e)

files:
A Misc/NEWS.d/next/Core and 
Builtins/2025-02-24-14-25-36.gh-issue-130163.rGpc9v.rst
M Include/internal/pycore_sysmodule.h
M Lib/test/test_builtin.py
M Lib/test/test_print.py
M Lib/test/test_sys.py
M Modules/_cursesmodule.c
M Modules/_pickle.c
M Modules/_threadmodule.c
M Modules/_tkinter.c
M Modules/faulthandler.c
M Modules/syslogmodule.c
M Objects/moduleobject.c
M Python/_warnings.c
M Python/bltinmodule.c
M Python/ceval.c
M Python/errors.c
M Python/import.c
M Python/initconfig.c
M Python/intrinsics.c
M Python/pylifecycle.c
M Python/pythonrun.c
M Python/sysmodule.c
M Python/traceback.c

diff --git a/Include/internal/pycore_sysmodule.h 
b/Include/internal/pycore_sysmodule.h
index 9b8eafd3d6cfd3..6df574487bcd1b 100644
--- a/Include/internal/pycore_sysmodule.h
+++ b/Include/internal/pycore_sysmodule.h
@@ -8,8 +8,11 @@ extern "C" {
 #  error "this header requires Py_BUILD_CORE define"
 #endif
 
-// Export for '_pickle' shared extension
-PyAPI_FUNC(PyObject*) _PySys_GetAttr(PyThreadState *tstate, PyObject *name);
+PyAPI_FUNC(PyObject *) _PySys_GetAttr(PyThreadState *, PyObject *); /* unused 
*/
+PyAPI_FUNC(int) _PySys_GetOptionalAttr(PyObject *, PyObject **);
+PyAPI_FUNC(int) _PySys_GetOptionalAttrString(const char *, PyObject **);
+PyAPI_FUNC(PyObject *) _PySys_GetRequiredAttr(PyObject *);
+PyAPI_FUNC(PyObject *) _PySys_GetRequiredAttrString(const char *);
 
 // Export for '_pickle' shared extension
 PyAPI_FUNC(size_t) _PySys_GetSizeOf(PyObject *);
diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py
index 3a5531924976f7..d4da29150d5fed 100644
--- a/Lib/test/test_builtin.py
+++ b/Lib/test/test_builtin.py
@@ -1576,6 +1576,29 @@ def test_input(self):
 sys.stdout = savestdout
 fp.close()
 
+def test_input_gh130163(self):
+class X(io.StringIO):
+def __getattribute__(self, name):
+nonlocal patch
+if patch:
+patch = False
+sys.stdout = X()
+sys.stderr = X()
+sys.stdin = X('input\n')
+support.gc_collect()
+return io.StringIO.__getattribute__(self, name)
+
+with (support.swap_attr(sys, 'stdout', None),
+  support.swap_attr(sys, 'stderr', None),
+  support.swap_attr(sys, 'stdin', None)):
+patch = False
+# the only references:
+sys.stdout = X()
+sys.stderr = X()
+sys.stdin = X('input\n')
+patch = True
+input()  # should not crash
+
 # test_int(): see test_int.py for tests of built-in function int().
 
 def test_repr(self):
diff --git a/Lib/test/test_print.py b/Lib/test/test_print.py
index 5f1bfd9e30db98..a782225ce99971 100644
--- a/Lib/test/test_print.py
+++ b/Lib/test/test_print.py
@@ -129,6 +129,17 @@ def flush(self):
 raise RuntimeError
 self.assertRaises(RuntimeError, print, 1, file=noflush(), flush=True)
 
+def test_gh130163(self):
+class X:
+def __str__(self):
+sys.stdout = StringIO()
+support.gc_collect()
+return 'foo'
+
+with support.swap_attr(sys, 'stdout', None):
+sys.stdout = StringIO()  # the only reference
+print(X())  # should not crash
+
 
 class TestPy2MigrationHint(unittest.TestCase):
 """Test that correct hint is produced analogous to Python3 syntax,
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index 01ce0118651b75..19597eb75f9168 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -2,6 +2,7 @@
 import codecs
 import _datetime
 import gc
+import io
 import locale
 import operator
 import os
@@ -80,6 +81,18 @@ def baddisplayhook(obj):
 code = compile("42", "", "single")
 self.assertRaises(ValueError, eval, code)
 
+def test_gh130163(self):
+class X:
+def __repr__(self):
+sys.stdout = io.StringIO()
+support.gc_collect()
+return 'foo'
+
+with support.swap_attr(sys, 'stdout', None):
+sys.stdout = io.StringIO()  # the only reference
+sys.displayhook(X())  # should not cra

[Python-checkins] gh-129824: Temporarily skip InterpreterPoolMixin tests under TSAN (gh-129826)

2025-02-25 Thread colesbury
https://github.com/python/cpython/commit/3774d9f7b56871372ac278e2c2d8ff33460d7eb0
commit: 3774d9f7b56871372ac278e2c2d8ff33460d7eb0
branch: main
author: Sam Gross 
committer: colesbury 
date: 2025-02-25T10:33:04-05:00
summary:

gh-129824: Temporarily skip InterpreterPoolMixin tests under TSAN (gh-129826)

There are multiple data races reported when running the
InterpreterPoolMixin tests, but it's still useful to run the other
test_concurrent_futures tests under TSAN.

Add test_concurrent_futures to the TSAN test suite.

files:
M Lib/test/libregrtest/tsan.py
M Lib/test/test_concurrent_futures/util.py

diff --git a/Lib/test/libregrtest/tsan.py b/Lib/test/libregrtest/tsan.py
index 2a656705d7b508..37d2983837fb78 100644
--- a/Lib/test/libregrtest/tsan.py
+++ b/Lib/test/libregrtest/tsan.py
@@ -6,6 +6,7 @@
 'test_capi.test_mem',
 'test_capi.test_pyatomic',
 'test_code',
+'test_concurrent_futures',
 'test_enum',
 'test_functools',
 'test_httpservers',
diff --git a/Lib/test/test_concurrent_futures/util.py 
b/Lib/test/test_concurrent_futures/util.py
index 52baab51340fc9..44086217f9dbcb 100644
--- a/Lib/test/test_concurrent_futures/util.py
+++ b/Lib/test/test_concurrent_futures/util.py
@@ -74,6 +74,7 @@ class ThreadPoolMixin(ExecutorMixin):
 executor_type = futures.ThreadPoolExecutor
 
 
+@support.skip_if_sanitizer("gh-129824: data races in InterpreterPool tests", 
thread=True)
 class InterpreterPoolMixin(ExecutorMixin):
 executor_type = futures.InterpreterPoolExecutor
 

___
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com


[Python-checkins] [3.13] Fix a typo in code module test (GH-130530) (#130534)

2025-02-25 Thread gaogaotiantian
https://github.com/python/cpython/commit/b0d3f4919579cb02c46918f47ea4faa2e5d304fc
commit: b0d3f4919579cb02c46918f47ea4faa2e5d304fc
branch: 3.13
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: gaogaotiantian 
date: 2025-02-25T17:38:40Z
summary:

[3.13] Fix a typo in code module test (GH-130530) (#130534)

Fix a typo in code module test (GH-130530)
(cherry picked from commit 56e337d32b88630f2c35458231cd61929f1be6d4)

Co-authored-by: Tian Gao 

files:
M Lib/test/test_code_module.py

diff --git a/Lib/test/test_code_module.py b/Lib/test/test_code_module.py
index 20b960ce8d1e02..faa0b38f8373e3 100644
--- a/Lib/test/test_code_module.py
+++ b/Lib/test/test_code_module.py
@@ -50,9 +50,9 @@ def test_ps2(self):
 self.infunc.side_effect = EOFError('Finished')
 self.console.interact()
 self.assertEqual(self.sysmod.ps2, '... ')
-self.sysmod.ps1 = 'custom2> '
+self.sysmod.ps2 = 'custom2> '
 self.console.interact()
-self.assertEqual(self.sysmod.ps1, 'custom2> ')
+self.assertEqual(self.sysmod.ps2, 'custom2> ')
 
 def test_console_stderr(self):
 self.infunc.side_effect = ["'antioch'", "", EOFError('Finished')]

___
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com


[Python-checkins] GH-130396: Include stack margin for debug windows builds (GH-130554)

2025-02-25 Thread markshannon
https://github.com/python/cpython/commit/2dad1e08ec9d5ddc798a313900613b3d1eeaff6b
commit: 2dad1e08ec9d5ddc798a313900613b3d1eeaff6b
branch: main
author: Mark Shannon 
committer: markshannon 
date: 2025-02-25T19:26:21Z
summary:

GH-130396: Include stack margin for debug windows builds (GH-130554)

files:
M Include/pythonrun.h

diff --git a/Include/pythonrun.h b/Include/pythonrun.h
index ef4b727442a935..4d459cb92e36ea 100644
--- a/Include/pythonrun.h
+++ b/Include/pythonrun.h
@@ -28,7 +28,7 @@ PyAPI_DATA(int) (*PyOS_InputHook)(void);
 #if defined(_Py_ADDRESS_SANITIZER) || defined(_Py_THREAD_SANITIZER)
 #  define PYOS_STACK_MARGIN 4096
 #elif defined(Py_DEBUG) && defined(WIN32)
-#  define PYOS_STACK_MARGIN 3072
+#  define PYOS_STACK_MARGIN 4096
 #elif defined(__wasi__)
/* Web assembly has two stacks, so this isn't really a size */
 #  define PYOS_STACK_MARGIN 500

___
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com


[Python-checkins] gh-130202: Fix bug in `_PyObject_ResurrectEnd` in free threaded build (gh-130281)

2025-02-25 Thread colesbury
https://github.com/python/cpython/commit/f963239ff1f986742d4c6bab2ab7b73f5a4047f6
commit: f963239ff1f986742d4c6bab2ab7b73f5a4047f6
branch: main
author: Sam Gross 
committer: colesbury 
date: 2025-02-25T12:03:28-05:00
summary:

gh-130202: Fix bug in `_PyObject_ResurrectEnd` in free threaded build 
(gh-130281)

This fixes a fairly subtle bug involving finalizers and resurrection in
debug free threaded builds: if `_PyObject_ResurrectEnd` returns `1`
(i.e., the object was resurrected by a finalizer), it's not safe to
access the object because it might still be deallocated. For example:

 * The finalizer may have exposed the object to another thread. That
   thread may hold the last reference and concurrently deallocate it any
   time after `_PyObject_ResurrectEnd()` returns `1`.
 * `_PyObject_ResurrectEnd()` may call `_Py_brc_queue_object()`, which
   may internally deallocate the object immediately if the owning thread
   is dead.

Therefore, it's important not to access the object after it's
resurrected. We only violate this in two cases, and only in debug
builds:

 * We assert that the object is tracked appropriately. This is now moved
   up betewen the finalizer and the `_PyObject_ResurrectEnd()` call.

 * The `--with-trace-refs` builds may need to remember the object if
   it's resurrected. This is now handled by `_PyObject_ResurrectStart()`
   and `_PyObject_ResurrectEnd()`.

Note that `--with-trace-refs` is currently disabled in `--disable-gil`
builds because the refchain hash table isn't thread-safe, but this
refactoring avoids an additional thread-safety issue.

files:
M Include/cpython/object.h
M Include/internal/pycore_object.h
M Objects/object.c

diff --git a/Include/cpython/object.h b/Include/cpython/object.h
index 260b90da24c18b..f466091e07e465 100644
--- a/Include/cpython/object.h
+++ b/Include/cpython/object.h
@@ -5,6 +5,7 @@
 PyAPI_FUNC(void) _Py_NewReference(PyObject *op);
 PyAPI_FUNC(void) _Py_NewReferenceNoTotal(PyObject *op);
 PyAPI_FUNC(void) _Py_ResurrectReference(PyObject *op);
+PyAPI_FUNC(void) _Py_ForgetReference(PyObject *op);
 
 #ifdef Py_REF_DEBUG
 /* These are useful as debugging aids when chasing down refleaks. */
diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h
index ffd31bd4a27f49..53403ebcfc0043 100644
--- a/Include/internal/pycore_object.h
+++ b/Include/internal/pycore_object.h
@@ -730,6 +730,9 @@ _PyObject_ResurrectStart(PyObject *op)
 #else
 Py_SET_REFCNT(op, 1);
 #endif
+#ifdef Py_TRACE_REFS
+_Py_ResurrectReference(op);
+#endif
 }
 
 // Undoes an object resurrection by decrementing the refcount without calling
@@ -743,13 +746,22 @@ _PyObject_ResurrectEnd(PyObject *op)
 #endif
 #ifndef Py_GIL_DISABLED
 Py_SET_REFCNT(op, Py_REFCNT(op) - 1);
-return Py_REFCNT(op) != 0;
+if (Py_REFCNT(op) == 0) {
+# ifdef Py_TRACE_REFS
+_Py_ForgetReference(op);
+# endif
+return 0;
+}
+return 1;
 #else
 uint32_t local = _Py_atomic_load_uint32_relaxed(&op->ob_ref_local);
 Py_ssize_t shared = _Py_atomic_load_ssize_acquire(&op->ob_ref_shared);
 if (_Py_IsOwnedByCurrentThread(op) && local == 1 && shared == 0) {
 // Fast-path: object has a single refcount and is owned by this thread
 _Py_atomic_store_uint32_relaxed(&op->ob_ref_local, 0);
+# ifdef Py_TRACE_REFS
+_Py_ForgetReference(op);
+# endif
 return 0;
 }
 // Slow-path: object has a shared refcount or is not owned by this thread
diff --git a/Objects/object.c b/Objects/object.c
index d342549b6ffecc..b3309bac7afdee 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -496,10 +496,22 @@ _PyObject_ResurrectEndSlow(PyObject *op)
 // merge the refcount. This isn't necessary in all cases, but it
 // simplifies the implementation.
 Py_ssize_t refcount = _Py_ExplicitMergeRefcount(op, -1);
-return refcount != 0;
+if (refcount == 0) {
+#ifdef Py_TRACE_REFS
+_Py_ForgetReference(op);
+#endif
+return 0;
+}
+return 1;
 }
 int is_dead = _Py_DecRefSharedIsDead(op, NULL, 0);
-return !is_dead;
+if (is_dead) {
+#ifdef Py_TRACE_REFS
+_Py_ForgetReference(op);
+#endif
+return 0;
+}
+return 1;
 }
 
 
@@ -589,20 +601,24 @@ PyObject_CallFinalizerFromDealloc(PyObject *self)
   Py_REFCNT(self) > 0,
   "refcount is too small");
 
+_PyObject_ASSERT(self,
+(!_PyType_IS_GC(Py_TYPE(self))
+|| _PyObject_GC_IS_TRACKED(self)));
+
 /* Undo the temporary resurrection; can't use DECREF here, it would
  * cause a recursive call. */
-if (!_PyObject_ResurrectEnd(self)) {
-return 0; /* this is the normal path out */
+if (_PyObject_ResurrectEnd(self)) {
+/* tp_finalize resurrected it!
+   gh-130202: Note that the object may still be dead in the free
+   threaded build in some circumstances,

[Python-checkins] [3.12] gh-130461: Remove unnecessary usages of `.. index::` directives in Doc/library/uuid.rst (#130526) (#130546)

2025-02-25 Thread hugovk
https://github.com/python/cpython/commit/ca9e52dac15d0da4d4ef57fb408565338da0bb40
commit: ca9e52dac15d0da4d4ef57fb408565338da0bb40
branch: 3.12
author: Kanishk Pachauri 
committer: hugovk <1324225+hug...@users.noreply.github.com>
date: 2025-02-25T15:25:20+02:00
summary:

[3.12] gh-130461: Remove unnecessary usages of `.. index::` directives in 
Doc/library/uuid.rst (#130526) (#130546)

Co-authored-by: Bénédikt Tran <10796600+picn...@users.noreply.github.com>
Co-authored-by: Hugo van Kemenade <1324225+hug...@users.noreply.github.com>

files:
A Misc/NEWS.d/next/Library/2025-02-25-03-53-00.gh-issue-130461.asr2dg.rst
M Doc/library/uuid.rst

diff --git a/Doc/library/uuid.rst b/Doc/library/uuid.rst
index 0f2d7820cb25c8..95f1176e7512b8 100644
--- a/Doc/library/uuid.rst
+++ b/Doc/library/uuid.rst
@@ -179,8 +179,6 @@ The :mod:`uuid` module defines the following functions:
   administered MAC addresses, since the former are guaranteed to be
   globally unique, while the latter are not.
 
-.. index:: single: getnode
-
 
 .. function:: uuid1(node=None, clock_seq=None)
 
@@ -189,8 +187,6 @@ The :mod:`uuid` module defines the following functions:
*clock_seq* is given, it is used as the sequence number; otherwise a random
14-bit sequence number is chosen.
 
-.. index:: single: uuid1
-
 
 .. function:: uuid3(namespace, name)
 
@@ -198,15 +194,11 @@ The :mod:`uuid` module defines the following functions:
UUID) and a name (which is a :class:`bytes` object or a string
that will be encoded using UTF-8).
 
-.. index:: single: uuid3
-
 
 .. function:: uuid4()
 
Generate a random UUID.
 
-.. index:: single: uuid4
-
 
 .. function:: uuid5(namespace, name)
 
@@ -214,7 +206,6 @@ The :mod:`uuid` module defines the following functions:
UUID) and a name (which is a :class:`bytes` object or a string
that will be encoded using UTF-8).
 
-.. index:: single: uuid5
 
 The :mod:`uuid` module defines the following namespace identifiers for use with
 :func:`uuid3` or :func:`uuid5`.
diff --git 
a/Misc/NEWS.d/next/Library/2025-02-25-03-53-00.gh-issue-130461.asr2dg.rst 
b/Misc/NEWS.d/next/Library/2025-02-25-03-53-00.gh-issue-130461.asr2dg.rst
new file mode 100644
index 00..d28f71fc1b1019
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-02-25-03-53-00.gh-issue-130461.asr2dg.rst
@@ -0,0 +1,4 @@
+Remove ``.. index::`` directives from the :mod:`uuid` module documentation. 
These directives
+previously created entries in the general index for :func:`~uuid.getnode` as 
well as the
+:func:`~uuid.uuid1`, :func:`~uuid.uuid3`, :func:`~uuid.uuid4`, and 
:func:`~uuid.uuid5`
+constructor functions.

___
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com


[Python-checkins] gh-130163: Fix crashes related to PySys_GetObject() (GH-130503)

2025-02-25 Thread serhiy-storchaka
https://github.com/python/cpython/commit/0ef4ffeefd1737c18dc9326133c7894d58108c2e
commit: 0ef4ffeefd1737c18dc9326133c7894d58108c2e
branch: main
author: Serhiy Storchaka 
committer: serhiy-storchaka 
date: 2025-02-25T23:04:27+02:00
summary:

gh-130163: Fix crashes related to PySys_GetObject() (GH-130503)

The use of PySys_GetObject() and _PySys_GetAttr(), which return a borrowed
reference, has been replaced by using one of the following functions, which
return a strong reference and distinguish a missing attribute from an error:
_PySys_GetOptionalAttr(), _PySys_GetOptionalAttrString(),
_PySys_GetRequiredAttr(), and _PySys_GetRequiredAttrString().

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2025-02-24-14-25-36.gh-issue-130163.rGpc9v.rst
M Include/internal/pycore_sysmodule.h
M Lib/test/test_builtin.py
M Lib/test/test_print.py
M Lib/test/test_sys.py
M Modules/_cursesmodule.c
M Modules/_pickle.c
M Modules/_threadmodule.c
M Modules/_tkinter.c
M Modules/faulthandler.c
M Modules/syslogmodule.c
M Objects/moduleobject.c
M Python/_warnings.c
M Python/bltinmodule.c
M Python/ceval.c
M Python/errors.c
M Python/import.c
M Python/initconfig.c
M Python/intrinsics.c
M Python/pylifecycle.c
M Python/pythonrun.c
M Python/sysmodule.c
M Python/traceback.c

diff --git a/Include/internal/pycore_sysmodule.h 
b/Include/internal/pycore_sysmodule.h
index 99968df54a45f6..9536579e965f7b 100644
--- a/Include/internal/pycore_sysmodule.h
+++ b/Include/internal/pycore_sysmodule.h
@@ -8,8 +8,10 @@ extern "C" {
 #  error "this header requires Py_BUILD_CORE define"
 #endif
 
-// Export for '_pickle' shared extension
-PyAPI_FUNC(PyObject*) _PySys_GetAttr(PyThreadState *tstate, PyObject *name);
+PyAPI_FUNC(int) _PySys_GetOptionalAttr(PyObject *, PyObject **);
+PyAPI_FUNC(int) _PySys_GetOptionalAttrString(const char *, PyObject **);
+PyAPI_FUNC(PyObject *) _PySys_GetRequiredAttr(PyObject *);
+PyAPI_FUNC(PyObject *) _PySys_GetRequiredAttrString(const char *);
 
 // Export for '_pickle' shared extension
 PyAPI_FUNC(size_t) _PySys_GetSizeOf(PyObject *);
diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py
index d707d9d2f20049..c3cc13614250f0 100644
--- a/Lib/test/test_builtin.py
+++ b/Lib/test/test_builtin.py
@@ -1710,6 +1710,29 @@ def test_input(self):
 sys.stdout = savestdout
 fp.close()
 
+def test_input_gh130163(self):
+class X(io.StringIO):
+def __getattribute__(self, name):
+nonlocal patch
+if patch:
+patch = False
+sys.stdout = X()
+sys.stderr = X()
+sys.stdin = X('input\n')
+support.gc_collect()
+return io.StringIO.__getattribute__(self, name)
+
+with (support.swap_attr(sys, 'stdout', None),
+  support.swap_attr(sys, 'stderr', None),
+  support.swap_attr(sys, 'stdin', None)):
+patch = False
+# the only references:
+sys.stdout = X()
+sys.stderr = X()
+sys.stdin = X('input\n')
+patch = True
+input()  # should not crash
+
 # test_int(): see test_int.py for tests of built-in function int().
 
 def test_repr(self):
diff --git a/Lib/test/test_print.py b/Lib/test/test_print.py
index f4805a1d6c6602..12256b3b562637 100644
--- a/Lib/test/test_print.py
+++ b/Lib/test/test_print.py
@@ -129,6 +129,17 @@ def flush(self):
 raise RuntimeError
 self.assertRaises(RuntimeError, print, 1, file=noflush(), flush=True)
 
+def test_gh130163(self):
+class X:
+def __str__(self):
+sys.stdout = StringIO()
+support.gc_collect()
+return 'foo'
+
+with support.swap_attr(sys, 'stdout', None):
+sys.stdout = StringIO()  # the only reference
+print(X())  # should not crash
+
 
 class TestPy2MigrationHint(unittest.TestCase):
 """Test that correct hint is produced analogous to Python3 syntax,
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index 4a95fee7efb95c..87c0106ad30840 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -2,6 +2,7 @@
 import codecs
 import _datetime
 import gc
+import io
 import locale
 import operator
 import os
@@ -80,6 +81,18 @@ def baddisplayhook(obj):
 code = compile("42", "", "single")
 self.assertRaises(ValueError, eval, code)
 
+def test_gh130163(self):
+class X:
+def __repr__(self):
+sys.stdout = io.StringIO()
+support.gc_collect()
+return 'foo'
+
+with support.swap_attr(sys, 'stdout', None):
+sys.stdout = io.StringIO()  # the only reference
+sys.displayhook(X())  # should not crash
+
+
 class ActiveExceptionTests(unittest.TestCase):
 def test_exc_info_no_exception(self):
 self.assertEqual(sys.exc_info(), (None, None, None))
diff --

[Python-checkins] [3.12] gh-130151: Fix reference leaks in `_hashlib.hmac_{new,digest}` (GH-130152) (#130539)

2025-02-25 Thread picnixz
https://github.com/python/cpython/commit/b1a188a7faa76949ef621a5ecac38b9fccae05cc
commit: b1a188a7faa76949ef621a5ecac38b9fccae05cc
branch: 3.12
author: Bénédikt Tran <10796600+picn...@users.noreply.github.com>
committer: picnixz <10796600+picn...@users.noreply.github.com>
date: 2025-02-25T12:38:47+01:00
summary:

[3.12] gh-130151: Fix reference leaks in `_hashlib.hmac_{new,digest}` 
(GH-130152) (#130539)

gh-130151: Fix reference leaks in `_hashlib.hmac_{new,digest}` (GH-130152)

* fix leak in `_hashlib.hmac_new`
* fix leak in `hmac_digest`
* fix exception type in `_hashlib.HMAC.copy`
(cherry picked from commit 071820113f11b8f6a21f98652d0840e10268114c)

files:
A Misc/NEWS.d/next/Library/2025-02-15-12-36-49.gh-issue-130151.3IFumF.rst
M Modules/_hashopenssl.c

diff --git 
a/Misc/NEWS.d/next/Library/2025-02-15-12-36-49.gh-issue-130151.3IFumF.rst 
b/Misc/NEWS.d/next/Library/2025-02-15-12-36-49.gh-issue-130151.3IFumF.rst
new file mode 100644
index 00..4638f138bc43ba
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-02-15-12-36-49.gh-issue-130151.3IFumF.rst
@@ -0,0 +1,2 @@
+Fix reference leaks in :func:`!_hashlib.hmac_new` and
+:func:`!_hashlib.hmac_digest`. Patch by Bénédikt Tran.
diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c
index 3cc7d6f50e896f..84afb743ab8c3b 100644
--- a/Modules/_hashopenssl.c
+++ b/Modules/_hashopenssl.c
@@ -1544,7 +1544,6 @@ _hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, 
PyObject *msg_obj,
PyObject *digestmod)
 /*[clinic end generated code: output=c20d9e4d9ed6d219 input=5f4071dcc7f34362]*/
 {
-PyTypeObject *type = get_hashlib_state(module)->HMACtype;
 PY_EVP_MD *digest;
 HMAC_CTX *ctx = NULL;
 HMACobject *self = NULL;
@@ -1557,8 +1556,8 @@ _hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, 
PyObject *msg_obj,
 }
 
 if (digestmod == NULL) {
-PyErr_SetString(
-PyExc_TypeError, "Missing required parameter 'digestmod'.");
+PyErr_SetString(PyExc_TypeError,
+"Missing required parameter 'digestmod'.");
 return NULL;
 }
 
@@ -1569,40 +1568,37 @@ _hashlib_hmac_new_impl(PyObject *module, Py_buffer 
*key, PyObject *msg_obj,
 
 ctx = HMAC_CTX_new();
 if (ctx == NULL) {
-_setException(PyExc_ValueError, NULL);
+PyErr_NoMemory();
 goto error;
 }
 
-r = HMAC_Init_ex(
-ctx,
-(const char*)key->buf,
-(int)key->len,
-digest,
-NULL /*impl*/);
+r = HMAC_Init_ex(ctx, key->buf, (int)key->len, digest, NULL /* impl */);
 PY_EVP_MD_free(digest);
 if (r == 0) {
 _setException(PyExc_ValueError, NULL);
 goto error;
 }
 
-self = (HMACobject *)PyObject_New(HMACobject, type);
+_hashlibstate *state = get_hashlib_state(module);
+self = PyObject_New(HMACobject, state->HMACtype);
 if (self == NULL) {
 goto error;
 }
 
 self->ctx = ctx;
 self->lock = NULL;
+ctx = NULL;  // 'ctx' is now owned by 'self'
 
 if ((msg_obj != NULL) && (msg_obj != Py_None)) {
-if (!_hmac_update(self, msg_obj))
+if (!_hmac_update(self, msg_obj)) {
 goto error;
+}
 }
-
-return (PyObject*)self;
+return (PyObject *)self;
 
 error:
 if (ctx) HMAC_CTX_free(ctx);
-if (self) PyObject_Free(self);
+Py_XDECREF(self);
 return NULL;
 }
 
@@ -1671,14 +1667,14 @@ _hashlib_HMAC_copy_impl(HMACobject *self)
 
 HMAC_CTX *ctx = HMAC_CTX_new();
 if (ctx == NULL) {
-return _setException(PyExc_ValueError, NULL);
+return PyErr_NoMemory();
 }
 if (!locked_HMAC_CTX_copy(ctx, self)) {
 HMAC_CTX_free(ctx);
 return _setException(PyExc_ValueError, NULL);
 }
 
-retval = (HMACobject *)PyObject_New(HMACobject, Py_TYPE(self));
+retval = PyObject_New(HMACobject, Py_TYPE(self));
 if (retval == NULL) {
 HMAC_CTX_free(ctx);
 return NULL;
@@ -1696,7 +1692,10 @@ _hmac_dealloc(HMACobject *self)
 if (self->lock != NULL) {
 PyThread_free_lock(self->lock);
 }
-HMAC_CTX_free(self->ctx);
+if (self->ctx != NULL) {
+HMAC_CTX_free(self->ctx);
+self->ctx = NULL;
+}
 PyObject_Free(self);
 Py_DECREF(tp);
 }
@@ -1741,6 +1740,7 @@ _hmac_digest(HMACobject *self, unsigned char *buf, 
unsigned int len)
 return 0;
 }
 if (!locked_HMAC_CTX_copy(temp_ctx, self)) {
+HMAC_CTX_free(temp_ctx);
 _setException(PyExc_ValueError, NULL);
 return 0;
 }

___
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com


[Python-checkins] gh-87790: support thousands separators for formatting fractional part of floats (#125304)

2025-02-25 Thread vstinner
https://github.com/python/cpython/commit/f39a07be47cd9219eaf0e538ae32ad8239c88e66
commit: f39a07be47cd9219eaf0e538ae32ad8239c88e66
branch: main
author: Sergey B Kirpichev 
committer: vstinner 
date: 2025-02-25T16:27:07+01:00
summary:

gh-87790: support thousands separators for formatting fractional part of floats 
(#125304)

```pycon
>>> f"{123_456.123_456:_._f}"  # Whole and fractional
'123_456.123_456'
>>> f"{123_456.123_456:_f}"# Integer component only
'123_456.123456'
>>> f"{123_456.123_456:._f}"   # Fractional component only
'123456.123_456'
>>> f"{123_456.123_456:.4_f}"  # with precision
'123456.1_235'
```

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2024-10-11-10-41-05.gh-issue-87790.mlfEGl.rst
M Doc/library/string.rst
M Doc/whatsnew/3.14.rst
M Include/internal/pycore_unicodeobject.h
M Lib/test/test_float.py
M Lib/test/test_format.py
M Objects/stringlib/localeutil.h
M Objects/unicodeobject.c
M Python/formatter_unicode.c

diff --git a/Doc/library/string.rst b/Doc/library/string.rst
index 09165c481b246e..721c5c8d334674 100644
--- a/Doc/library/string.rst
+++ b/Doc/library/string.rst
@@ -319,14 +319,19 @@ non-empty format specification typically modifies the 
result.
 The general form of a *standard format specifier* is:
 
 .. productionlist:: format-spec
-   format_spec: 
[[`fill`]`align`][`sign`]["z"]["#"]["0"][`width`][`grouping_option`]["." 
`precision`][`type`]
+   format_spec: [`options`][`width_and_precision`][`type`]
+   options: [[`fill`]`align`][`sign`]["z"]["#"]["0"]
fill: 
align: "<" | ">" | "=" | "^"
sign: "+" | "-" | " "
+   width_and_precision: [`width_with_grouping`][`precision_with_grouping`]
+   width_with_grouping: [`width`][`grouping_option`]
+   precision_with_grouping: "." [`precision`]`grouping_option`
width: `~python-grammar:digit`+
grouping_option: "_" | ","
precision: `~python-grammar:digit`+
-   type: "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" 
| "x" | "X" | "%"
+   type: "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g"
+   : | "G" | "n" | "o" | "s" | "x" | "X" | "%"
 
 If a valid *align* value is specified, it can be preceded by a *fill*
 character that can be any character and defaults to a space if omitted.
@@ -458,6 +463,13 @@ indicates the maximum field size - in other words, how 
many characters will be
 used from the field content.  The *precision* is not allowed for integer
 presentation types.
 
+The ``'_'`` or ``','`` option after *precision* means the use of an underscore
+or a comma for a thousands separator of the fractional part for floating-point
+presentation types.
+
+.. versionchanged:: 3.14
+   Support thousands separators for the fractional part.
+
 Finally, the *type* determines how the data should be presented.
 
 The available string presentation types are:
@@ -704,10 +716,18 @@ Replacing ``%x`` and ``%o`` and converting the value to 
different bases::
>>> "int: {0:d};  hex: {0:#x};  oct: {0:#o};  bin: {0:#b}".format(42)
'int: 42;  hex: 0x2a;  oct: 0o52;  bin: 0b101010'
 
-Using the comma as a thousands separator::
+Using the comma or the underscore as a thousands separator::
 
>>> '{:,}'.format(1234567890)
'1,234,567,890'
+   >>> '{:_}'.format(1234567890)
+   '1_234_567_890'
+   >>> '{:_}'.format(123456789.123456789)
+   '123_456_789.12345679'
+   >>> '{:._}'.format(123456789.123456789)
+   '123456789.123_456_79'
+   >>> '{:_._}'.format(123456789.123456789)
+   '123_456_789.123_456_79'
 
 Expressing a percentage::
 
diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst
index 1cd8da46a2bb7e..dbd59a9d7be150 100644
--- a/Doc/whatsnew/3.14.rst
+++ b/Doc/whatsnew/3.14.rst
@@ -336,6 +336,11 @@ Other language changes
   making it a :term:`generic type`.
   (Contributed by Brian Schubert in :gh:`126012`.)
 
+* Support underscore and comma as thousands separators in the fractional part
+  for floating-point presentation types of the new-style string formatting
+  (with :func:`format` or :ref:`f-strings`).
+  (Contrubuted by Sergey B Kirpichev in :gh:`87790`.)
+
 * ``\B`` in :mod:`regular expression ` now matches empty input string.
   Now it is always the opposite of ``\b``.
   (Contributed by Serhiy Storchaka in :gh:`124130`.)
diff --git a/Include/internal/pycore_unicodeobject.h 
b/Include/internal/pycore_unicodeobject.h
index a60372f58295a9..13c3213132568b 100644
--- a/Include/internal/pycore_unicodeobject.h
+++ b/Include/internal/pycore_unicodeobject.h
@@ -246,7 +246,8 @@ extern Py_ssize_t _PyUnicode_InsertThousandsGrouping(
 Py_ssize_t min_width,
 const char *grouping,
 PyObject *thousands_sep,
-Py_UCS4 *maxchar);
+Py_UCS4 *maxchar,
+int forward);
 
 /* --- Misc functions - */
 
diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py
index f588e16b70123a..231b1047f72b39 100644
--- a/Lib/test/test_float.py
+++ b/Lib/test/test_float.py
@@ -754,6 +754,28 @@ def test_format(self):
 self.assertEqua

[Python-checkins] gh-122029: Move monitoring after method expand for CALL_KW (GH-130488)

2025-02-25 Thread markshannon
https://github.com/python/cpython/commit/c5f925c8c948736bd64652918b4e0186b91abbb5
commit: c5f925c8c948736bd64652918b4e0186b91abbb5
branch: main
author: Tian Gao 
committer: markshannon 
date: 2025-02-25T15:43:49Z
summary:

gh-122029: Move monitoring after method expand for CALL_KW (GH-130488)

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2025-02-23-20-48-31.gh-issue-122029.iW8GvA.rst
M Lib/test/test_sys_setprofile.py
M Python/bytecodes.c
M Python/generated_cases.c.h

diff --git a/Lib/test/test_sys_setprofile.py b/Lib/test/test_sys_setprofile.py
index 311a4d2cafe88d..0753a9d8b8e0ee 100644
--- a/Lib/test/test_sys_setprofile.py
+++ b/Lib/test/test_sys_setprofile.py
@@ -493,6 +493,24 @@ class A:
 # The last c_call is the call to sys.setprofile
 self.assertEqual(events, ['c_call', 'c_return', 'c_call'])
 
+class B:
+f = classmethod(max)
+events = []
+sys.setprofile(lambda frame, event, args: events.append(event))
+# Not important, we only want to trigger INSTRUMENTED_CALL_KW
+B().f(1, key=lambda x: 0)
+sys.setprofile(None)
+# The last c_call is the call to sys.setprofile
+self.assertEqual(
+events,
+['c_call',
+ 'call', 'return',
+ 'call', 'return',
+ 'c_return',
+ 'c_call'
+]
+)
+
 
 if __name__ == "__main__":
 unittest.main()
diff --git 
a/Misc/NEWS.d/next/Core_and_Builtins/2025-02-23-20-48-31.gh-issue-122029.iW8GvA.rst
 
b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-23-20-48-31.gh-issue-122029.iW8GvA.rst
new file mode 100644
index 00..ec7d774a16fdb0
--- /dev/null
+++ 
b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-23-20-48-31.gh-issue-122029.iW8GvA.rst
@@ -0,0 +1 @@
+``INSTRUMENTED_CALL_KW`` will expand the method before monitoring to reflect 
the actual behavior more accurately.
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index 3c5cb07709d66c..6f91b10b8b8a9b 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -4509,8 +4509,8 @@ dummy_func(
 macro(INSTRUMENTED_CALL_KW) =
 counter/1 +
 unused/2 +
-_MONITOR_CALL_KW +
 _MAYBE_EXPAND_METHOD_KW +
+_MONITOR_CALL_KW +
 _DO_CALL_KW;
 
 op(_CHECK_IS_NOT_PY_CALLABLE_KW, (callable[1], unused[1], 
unused[oparg], kwnames -- callable[1], unused[1], unused[oparg], kwnames)) {
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index 268e8836994bc4..377be6fb6d6390 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -6413,14 +6413,37 @@
 _PyStackRef *callable;
 _PyStackRef *self_or_null;
 _PyStackRef *args;
-_PyStackRef kwnames;
 _PyStackRef kwnames_in;
 _PyStackRef *func;
 _PyStackRef *maybe_self;
 _PyStackRef kwnames_out;
+_PyStackRef kwnames;
 _PyStackRef res;
 /* Skip 1 cache entry */
 /* Skip 2 cache entries */
+// _MAYBE_EXPAND_METHOD_KW
+{
+kwnames_in = stack_pointer[-1];
+args = &stack_pointer[-1 - oparg];
+self_or_null = &stack_pointer[-2 - oparg];
+callable = &stack_pointer[-3 - oparg];
+func = &stack_pointer[-3 - oparg];
+maybe_self = &stack_pointer[-2 - oparg];
+args = &stack_pointer[-1 - oparg];
+(void)args;
+if (PyStackRef_TYPE(callable[0]) == &PyMethod_Type && 
PyStackRef_IsNull(self_or_null[0])) {
+PyObject *callable_o = 
PyStackRef_AsPyObjectBorrow(callable[0]);
+PyObject *self = ((PyMethodObject *)callable_o)->im_self;
+maybe_self[0] = PyStackRef_FromPyObjectNew(self);
+PyObject *method = ((PyMethodObject *)callable_o)->im_func;
+_PyStackRef temp = callable[0];
+func[0] = PyStackRef_FromPyObjectNew(method);
+_PyFrame_SetStackPointer(frame, stack_pointer);
+PyStackRef_CLOSE(temp);
+stack_pointer = _PyFrame_GetStackPointer(frame);
+}
+kwnames_out = kwnames_in;
+}
 // _MONITOR_CALL_KW
 {
 args = &stack_pointer[-1 - oparg];
@@ -6440,6 +6463,7 @@
 }
 }
 PyObject *function = PyStackRef_AsPyObjectBorrow(callable[0]);
+stack_pointer[-1] = kwnames_out;
 _PyFrame_SetStackPointer(frame, stack_pointer);
 int err = _Py_call_instrumentation_2args(
 tstate, PY_MONITORING_EVENT_CALL,
@@ -6449,32 +6473,9 @@
 JUMP_TO_LABEL(error);
 }
 }
-// _MAYBE_EXPAND_METHOD_KW
-{
-k

[Python-checkins] gh-130461: Remove unnecessary usages of `.. index::` directives in Doc/library/uuid.rst (#130526)

2025-02-25 Thread hugovk
https://github.com/python/cpython/commit/85f1cc8d60b06d5b2af3e4da8e4f98171420dd91
commit: 85f1cc8d60b06d5b2af3e4da8e4f98171420dd91
branch: main
author: Kanishk Pachauri 
committer: hugovk <1324225+hug...@users.noreply.github.com>
date: 2025-02-25T14:27:50+02:00
summary:

gh-130461: Remove unnecessary usages of `.. index::` directives in 
Doc/library/uuid.rst (#130526)

Co-authored-by: Bénédikt Tran <10796600+picn...@users.noreply.github.com>

files:
A Misc/NEWS.d/next/Library/2025-02-25-03-53-00.gh-issue-130461.asr2dg.rst
M Doc/library/uuid.rst

diff --git a/Doc/library/uuid.rst b/Doc/library/uuid.rst
index bff6b9dcdc57ca..c661fa2e52565c 100644
--- a/Doc/library/uuid.rst
+++ b/Doc/library/uuid.rst
@@ -184,8 +184,6 @@ The :mod:`uuid` module defines the following functions:
   administered MAC addresses, since the former are guaranteed to be
   globally unique, while the latter are not.
 
-.. index:: single: getnode
-
 
 .. function:: uuid1(node=None, clock_seq=None)
 
@@ -194,8 +192,6 @@ The :mod:`uuid` module defines the following functions:
*clock_seq* is given, it is used as the sequence number; otherwise a random
14-bit sequence number is chosen.
 
-.. index:: single: uuid1
-
 
 .. function:: uuid3(namespace, name)
 
@@ -203,15 +199,11 @@ The :mod:`uuid` module defines the following functions:
UUID) and a name (which is a :class:`bytes` object or a string
that will be encoded using UTF-8).
 
-.. index:: single: uuid3
-
 
 .. function:: uuid4()
 
Generate a random UUID.
 
-.. index:: single: uuid4
-
 
 .. function:: uuid5(namespace, name)
 
@@ -219,8 +211,6 @@ The :mod:`uuid` module defines the following functions:
UUID) and a name (which is a :class:`bytes` object or a string
that will be encoded using UTF-8).
 
-.. index:: single: uuid5
-
 
 .. function:: uuid8(a=None, b=None, c=None)
 
@@ -235,8 +225,6 @@ The :mod:`uuid` module defines the following functions:
 
.. versionadded:: 3.14
 
-.. index:: single: uuid8
-
 
 The :mod:`uuid` module defines the following namespace identifiers for use with
 :func:`uuid3` or :func:`uuid5`.
diff --git 
a/Misc/NEWS.d/next/Library/2025-02-25-03-53-00.gh-issue-130461.asr2dg.rst 
b/Misc/NEWS.d/next/Library/2025-02-25-03-53-00.gh-issue-130461.asr2dg.rst
new file mode 100644
index 00..9e7e0373ea43a4
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-02-25-03-53-00.gh-issue-130461.asr2dg.rst
@@ -0,0 +1,4 @@
+Remove ``.. index::`` directives from the :mod:`uuid` module documentation. 
These directives
+previously created entries in the general index for :func:`~uuid.getnode` as 
well as the
+:func:`~uuid.uuid1`, :func:`~uuid.uuid3`, :func:`~uuid.uuid4`, 
:func:`~uuid.uuid5`, and
+:func:`~uuid.uuid8` constructor functions.

___
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com


[Python-checkins] gh-111178: fix UBSan failures in `Modules/xx*.c` (GH-129797)

2025-02-25 Thread encukou
https://github.com/python/cpython/commit/ead091357d67bc8144a73fcb7cb367602d21ecdd
commit: ead091357d67bc8144a73fcb7cb367602d21ecdd
branch: main
author: Bénédikt Tran <10796600+picn...@users.noreply.github.com>
committer: encukou 
date: 2025-02-25T13:02:32+01:00
summary:

gh-78: fix UBSan failures in `Modules/xx*.c` (GH-129797)

Fix UBSan failures in `Modules/xxlimited.c`, `Modules/xxlimited_35.c`, 
`Modules/xxsubtype.c`, `Modules/xxmodule.c`

files:
M Modules/xxlimited.c
M Modules/xxlimited_35.c
M Modules/xxmodule.c
M Modules/xxsubtype.c

diff --git a/Modules/xxlimited.c b/Modules/xxlimited.c
index d86741e1dfc18c..26ac35734fb060 100644
--- a/Modules/xxlimited.c
+++ b/Modules/xxlimited.c
@@ -90,6 +90,7 @@ typedef struct {
 Py_ssize_t  x_exports; /* how many buffer are exported */
 } XxoObject;
 
+#define XxoObject_CAST(op)  ((XxoObject *)(op))
 // XXX: no good way to do this yet
 // #define XxoObject_Check(v)  Py_IS_TYPE(v, Xxo_Type)
 
@@ -114,28 +115,29 @@ newXxoObject(PyObject *module)
 /* Xxo finalization */
 
 static int
-Xxo_traverse(PyObject *self_obj, visitproc visit, void *arg)
+Xxo_traverse(PyObject *op, visitproc visit, void *arg)
 {
 // Visit the type
-Py_VISIT(Py_TYPE(self_obj));
+Py_VISIT(Py_TYPE(op));
 
 // Visit the attribute dict
-XxoObject *self = (XxoObject *)self_obj;
+XxoObject *self = XxoObject_CAST(op);
 Py_VISIT(self->x_attr);
 return 0;
 }
 
 static int
-Xxo_clear(XxoObject *self)
+Xxo_clear(PyObject *op)
 {
+XxoObject *self = XxoObject_CAST(op);
 Py_CLEAR(self->x_attr);
 return 0;
 }
 
 static void
-Xxo_finalize(PyObject *self_obj)
+Xxo_finalize(PyObject *op)
 {
-XxoObject *self = (XxoObject *)self_obj;
+XxoObject *self = XxoObject_CAST(op);
 Py_CLEAR(self->x_attr);
 }
 
@@ -154,8 +156,9 @@ Xxo_dealloc(PyObject *self)
 /* Xxo attribute handling */
 
 static PyObject *
-Xxo_getattro(XxoObject *self, PyObject *name)
+Xxo_getattro(PyObject *op, PyObject *name)
 {
+XxoObject *self = XxoObject_CAST(op);
 if (self->x_attr != NULL) {
 PyObject *v = PyDict_GetItemWithError(self->x_attr, name);
 if (v != NULL) {
@@ -165,12 +168,13 @@ Xxo_getattro(XxoObject *self, PyObject *name)
 return NULL;
 }
 }
-return PyObject_GenericGetAttr((PyObject *)self, name);
+return PyObject_GenericGetAttr(op, name);
 }
 
 static int
-Xxo_setattro(XxoObject *self, PyObject *name, PyObject *v)
+Xxo_setattro(PyObject *op, PyObject *name, PyObject *v)
 {
+XxoObject *self = XxoObject_CAST(op);
 if (self->x_attr == NULL) {
 // prepare the attribute dict
 self->x_attr = PyDict_New();
@@ -197,8 +201,8 @@ Xxo_setattro(XxoObject *self, PyObject *name, PyObject *v)
 /* Xxo methods */
 
 static PyObject *
-Xxo_demo(XxoObject *self, PyTypeObject *defining_class,
- PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
+Xxo_demo(PyObject *op, PyTypeObject *defining_class,
+ PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
 if (kwnames != NULL && PyObject_Length(kwnames)) {
 PyErr_SetString(PyExc_TypeError, "demo() takes no keyword arguments");
@@ -233,9 +237,10 @@ static PyMethodDef Xxo_methods[] = {
 /* Xxo buffer interface */
 
 static int
-Xxo_getbuffer(XxoObject *self, Py_buffer *view, int flags)
+Xxo_getbuffer(PyObject *op, Py_buffer *view, int flags)
 {
-int res = PyBuffer_FillInfo(view, (PyObject*)self,
+XxoObject *self = XxoObject_CAST(op);
+int res = PyBuffer_FillInfo(view, op,
(void *)self->x_buffer, BUFSIZE,
0, flags);
 if (res == 0) {
@@ -245,14 +250,16 @@ Xxo_getbuffer(XxoObject *self, Py_buffer *view, int flags)
 }
 
 static void
-Xxo_releasebuffer(XxoObject *self, Py_buffer *view)
+Xxo_releasebuffer(PyObject *op, Py_buffer *Py_UNUSED(view))
 {
+XxoObject *self = XxoObject_CAST(op);
 self->x_exports--;
 }
 
 static PyObject *
-Xxo_get_x_exports(XxoObject *self, void *c)
+Xxo_get_x_exports(PyObject *op, void *Py_UNUSED(closure))
 {
+XxoObject *self = XxoObject_CAST(op);
 return PyLong_FromSsize_t(self->x_exports);
 }
 
@@ -262,7 +269,7 @@ PyDoc_STRVAR(Xxo_doc,
  "A class that explicitly stores attributes in an internal dict");
 
 static PyGetSetDef Xxo_getsetlist[] = {
-{"x_exports", (getter) Xxo_get_x_exports, NULL, NULL},
+{"x_exports", Xxo_get_x_exports, NULL, NULL},
 {NULL},
 };
 
diff --git a/Modules/xxlimited_35.c b/Modules/xxlimited_35.c
index 1063e54217b746..48fd1aac3f0f8d 100644
--- a/Modules/xxlimited_35.c
+++ b/Modules/xxlimited_35.c
@@ -24,7 +24,8 @@ typedef struct {
 
 static PyObject *Xxo_Type;
 
-#define XxoObject_Check(v)  Py_IS_TYPE(v, Xxo_Type)
+#define XxoObject_CAST(op)  ((XxoObject *)(op))
+#define XxoObject_Check(v)  Py_IS_TYPE(v, Xxo_Type)
 
 static XxoObject *
 newXxoObject(PyObject *arg)
@@ -40,32 +41,36 @@ newXxoObject(PyObject *arg)
 /* Xxo methods */
 
 static i

[Python-checkins] gh-111178: fix UBSan failures in `Objects/typevarobject.c` (GH-129800)

2025-02-25 Thread encukou
https://github.com/python/cpython/commit/ecde9400254eabf0ebcdbb04cb266e50f126e8ec
commit: ecde9400254eabf0ebcdbb04cb266e50f126e8ec
branch: main
author: Bénédikt Tran <10796600+picn...@users.noreply.github.com>
committer: encukou 
date: 2025-02-25T13:12:47+01:00
summary:

gh-78: fix UBSan failures in `Objects/typevarobject.c` (GH-129800)

Fix UBSan failures for `typealiasobject`, `paramspecobject`, `typevarobject`, 
`typevartupleobject`, `paramspecattrobject`

Use _PyCFunction_CAST macros

Use macro for `constevaluatorobject` casts

files:
M Objects/typevarobject.c

diff --git a/Objects/typevarobject.c b/Objects/typevarobject.c
index 4ed40aa71a595e..d8158293acaabd 100644
--- a/Objects/typevarobject.c
+++ b/Objects/typevarobject.c
@@ -57,6 +57,11 @@ typedef struct {
 PyObject *module;
 } typealiasobject;
 
+#define typevarobject_CAST(op)  ((typevarobject *)(op))
+#define typevartupleobject_CAST(op) ((typevartupleobject *)(op))
+#define paramspecobject_CAST(op)((paramspecobject *)(op))
+#define typealiasobject_CAST(op)((typealiasobject *)(op))
+
 #include "clinic/typevarobject.c.h"
 
 /* NoDefault is a marker object to indicate that a parameter has no default. */
@@ -121,11 +126,13 @@ typedef struct {
 PyObject *value;
 } constevaluatorobject;
 
+#define constevaluatorobject_CAST(op)   ((constevaluatorobject *)(op))
+
 static void
 constevaluator_dealloc(PyObject *self)
 {
 PyTypeObject *tp = Py_TYPE(self);
-constevaluatorobject *ce = (constevaluatorobject *)self;
+constevaluatorobject *ce = constevaluatorobject_CAST(self);
 
 _PyObject_GC_UNTRACK(self);
 
@@ -138,7 +145,7 @@ constevaluator_dealloc(PyObject *self)
 static int
 constevaluator_traverse(PyObject *self, visitproc visit, void *arg)
 {
-constevaluatorobject *ce = (constevaluatorobject *)self;
+constevaluatorobject *ce = constevaluatorobject_CAST(self);
 Py_VISIT(ce->value);
 return 0;
 }
@@ -146,20 +153,22 @@ constevaluator_traverse(PyObject *self, visitproc visit, 
void *arg)
 static int
 constevaluator_clear(PyObject *self)
 {
-Py_CLEAR(((constevaluatorobject *)self)->value);
+constevaluatorobject *ce = constevaluatorobject_CAST(self);
+Py_CLEAR(ce->value);
 return 0;
 }
 
 static PyObject *
 constevaluator_repr(PyObject *self)
 {
-PyObject *value = ((constevaluatorobject *)self)->value;
-return PyUnicode_FromFormat("", value);
+constevaluatorobject *ce = constevaluatorobject_CAST(self);
+return PyUnicode_FromFormat("", ce->value);
 }
 
 static PyObject *
 constevaluator_call(PyObject *self, PyObject *args, PyObject *kwargs)
 {
+constevaluatorobject *ce = constevaluatorobject_CAST(self);
 if (!_PyArg_NoKeywords("constevaluator.__call__", kwargs)) {
 return NULL;
 }
@@ -167,7 +176,7 @@ constevaluator_call(PyObject *self, PyObject *args, 
PyObject *kwargs)
 if (!PyArg_ParseTuple(args, "i:constevaluator.__call__", &format)) {
 return NULL;
 }
-PyObject *value = ((constevaluatorobject *)self)->value;
+PyObject *value = ce->value;
 if (format == _Py_ANNOTATE_FORMAT_STRING) {
 PyUnicodeWriter *writer = PyUnicodeWriter_Create(5);  // cannot be <5
 if (writer == NULL) {
@@ -453,7 +462,7 @@ static void
 typevar_dealloc(PyObject *self)
 {
 PyTypeObject *tp = Py_TYPE(self);
-typevarobject *tv = (typevarobject *)self;
+typevarobject *tv = typevarobject_CAST(self);
 
 _PyObject_GC_UNTRACK(self);
 
@@ -475,7 +484,7 @@ static int
 typevar_traverse(PyObject *self, visitproc visit, void *arg)
 {
 Py_VISIT(Py_TYPE(self));
-typevarobject *tv = (typevarobject *)self;
+typevarobject *tv = typevarobject_CAST(self);
 Py_VISIT(tv->bound);
 Py_VISIT(tv->evaluate_bound);
 Py_VISIT(tv->constraints);
@@ -487,22 +496,23 @@ typevar_traverse(PyObject *self, visitproc visit, void 
*arg)
 }
 
 static int
-typevar_clear(typevarobject *self)
+typevar_clear(PyObject *op)
 {
+typevarobject *self = typevarobject_CAST(op);
 Py_CLEAR(self->bound);
 Py_CLEAR(self->evaluate_bound);
 Py_CLEAR(self->constraints);
 Py_CLEAR(self->evaluate_constraints);
 Py_CLEAR(self->default_value);
 Py_CLEAR(self->evaluate_default);
-PyObject_ClearManagedDict((PyObject *)self);
+PyObject_ClearManagedDict(op);
 return 0;
 }
 
 static PyObject *
 typevar_repr(PyObject *self)
 {
-typevarobject *tv = (typevarobject *)self;
+typevarobject *tv = typevarobject_CAST(self);
 
 if (tv->infer_variance) {
 return Py_NewRef(tv->name);
@@ -521,8 +531,9 @@ static PyMemberDef typevar_members[] = {
 };
 
 static PyObject *
-typevar_bound(typevarobject *self, void *Py_UNUSED(ignored))
+typevar_bound(PyObject *op, void *Py_UNUSED(closure))
 {
+typevarobject *self = typevarobject_CAST(op);
 if (self->bound != NULL) {
 return Py_NewRef(self->bound);
 }
@@ -535,8 +546,9 @@ typevar_bound(typevarobject *self, void *Py_UNUSED(ignored))
 }
 
 static PyObject *
-ty

[Python-checkins] gh-111178: fix UBSan failures in `Modules/unicodedata.c` (GH-129801)

2025-02-25 Thread encukou
https://github.com/python/cpython/commit/c1478d1ebb7a6331d06939a27618dafb7fce91f1
commit: c1478d1ebb7a6331d06939a27618dafb7fce91f1
branch: main
author: Bénédikt Tran <10796600+picn...@users.noreply.github.com>
committer: encukou 
date: 2025-02-25T13:13:47+01:00
summary:

gh-78: fix UBSan failures in `Modules/unicodedata.c` (GH-129801)

fix UBSan failures for `PreviousDBVersion`

files:
M Modules/unicodedata.c

diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c
index 79be7674fc8ab5..f1ff7bd3eba232 100644
--- a/Modules/unicodedata.c
+++ b/Modules/unicodedata.c
@@ -77,9 +77,11 @@ typedef struct previous_version {
 Py_UCS4 (*normalization)(Py_UCS4);
 } PreviousDBVersion;
 
+#define PreviousDBVersion_CAST(op)  ((PreviousDBVersion *)(op))
+
 #include "clinic/unicodedata.c.h"
 
-#define get_old_record(self, v)PreviousDBVersion*)self)->getrecord)(v))
+#define get_old_record(self, v)(PreviousDBVersion_CAST(self)->getrecord(v))
 
 static PyMemberDef DB_members[] = {
 {"unidata_version", Py_T_STRING, offsetof(PreviousDBVersion, name), 
Py_READONLY},
@@ -1591,14 +1593,14 @@ static PyMethodDef unicodedata_functions[] = {
 };
 
 static int
-ucd_traverse(PreviousDBVersion *self, visitproc visit, void *arg)
+ucd_traverse(PyObject *self, visitproc visit, void *arg)
 {
 Py_VISIT(Py_TYPE(self));
 return 0;
 }
 
 static void
-ucd_dealloc(PreviousDBVersion *self)
+ucd_dealloc(PyObject *self)
 {
 PyTypeObject *tp = Py_TYPE(self);
 PyObject_GC_UnTrack(self);

___
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com


[Python-checkins] [3.13] gh-130461: Remove unnecessary usages of `.. index::` directives in Doc/library/uuid.rst (#130526) (#130548)

2025-02-25 Thread hugovk
https://github.com/python/cpython/commit/28bfc1c99698cb36491ffa146d478b05da8467ce
commit: 28bfc1c99698cb36491ffa146d478b05da8467ce
branch: 3.13
author: Kanishk Pachauri 
committer: hugovk <1324225+hug...@users.noreply.github.com>
date: 2025-02-25T15:24:46+02:00
summary:

[3.13] gh-130461: Remove unnecessary usages of `.. index::` directives in 
Doc/library/uuid.rst (#130526) (#130548)

Co-authored-by: Bénédikt Tran <10796600+picn...@users.noreply.github.com>

files:
A Misc/NEWS.d/next/Library/2025-02-25-03-53-00.gh-issue-130461.asr2dg.rst
M Doc/library/uuid.rst

diff --git a/Doc/library/uuid.rst b/Doc/library/uuid.rst
index 0f2d7820cb25c8..95f1176e7512b8 100644
--- a/Doc/library/uuid.rst
+++ b/Doc/library/uuid.rst
@@ -179,8 +179,6 @@ The :mod:`uuid` module defines the following functions:
   administered MAC addresses, since the former are guaranteed to be
   globally unique, while the latter are not.
 
-.. index:: single: getnode
-
 
 .. function:: uuid1(node=None, clock_seq=None)
 
@@ -189,8 +187,6 @@ The :mod:`uuid` module defines the following functions:
*clock_seq* is given, it is used as the sequence number; otherwise a random
14-bit sequence number is chosen.
 
-.. index:: single: uuid1
-
 
 .. function:: uuid3(namespace, name)
 
@@ -198,15 +194,11 @@ The :mod:`uuid` module defines the following functions:
UUID) and a name (which is a :class:`bytes` object or a string
that will be encoded using UTF-8).
 
-.. index:: single: uuid3
-
 
 .. function:: uuid4()
 
Generate a random UUID.
 
-.. index:: single: uuid4
-
 
 .. function:: uuid5(namespace, name)
 
@@ -214,7 +206,6 @@ The :mod:`uuid` module defines the following functions:
UUID) and a name (which is a :class:`bytes` object or a string
that will be encoded using UTF-8).
 
-.. index:: single: uuid5
 
 The :mod:`uuid` module defines the following namespace identifiers for use with
 :func:`uuid3` or :func:`uuid5`.
diff --git 
a/Misc/NEWS.d/next/Library/2025-02-25-03-53-00.gh-issue-130461.asr2dg.rst 
b/Misc/NEWS.d/next/Library/2025-02-25-03-53-00.gh-issue-130461.asr2dg.rst
new file mode 100644
index 00..d28f71fc1b1019
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-02-25-03-53-00.gh-issue-130461.asr2dg.rst
@@ -0,0 +1,4 @@
+Remove ``.. index::`` directives from the :mod:`uuid` module documentation. 
These directives
+previously created entries in the general index for :func:`~uuid.getnode` as 
well as the
+:func:`~uuid.uuid1`, :func:`~uuid.uuid3`, :func:`~uuid.uuid4`, and 
:func:`~uuid.uuid5`
+constructor functions.

___
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com


[Python-checkins] gh-129173: refactor `PyCodec_ReplaceErrors` into separate functions (#129893)

2025-02-25 Thread picnixz
https://github.com/python/cpython/commit/fa6a8140dd2a72da6df2a7dfafbf07045debf64d
commit: fa6a8140dd2a72da6df2a7dfafbf07045debf64d
branch: main
author: Bénédikt Tran <10796600+picn...@users.noreply.github.com>
committer: picnixz <10796600+picn...@users.noreply.github.com>
date: 2025-02-25T14:24:46+01:00
summary:

gh-129173: refactor `PyCodec_ReplaceErrors` into separate functions (#129893)

The logic of `PyCodec_ReplaceErrors` is now split into separate functions,
each of which handling a specific exception type.

files:
M Python/codecs.c

diff --git a/Python/codecs.c b/Python/codecs.c
index be019d6cda52a7..b876b816f688a0 100644
--- a/Python/codecs.c
+++ b/Python/codecs.c
@@ -730,6 +730,27 @@ codec_handler_write_unicode_hex(Py_UCS1 **p, Py_UCS4 ch)
 }
 
 
+/*
+ * Create a Unicode string containing 'count' copies of the official
+ * Unicode REPLACEMENT CHARACTER (0xFFFD).
+ */
+static PyObject *
+codec_handler_unicode_replacement_character(Py_ssize_t count)
+{
+PyObject *res = PyUnicode_New(count, Py_UNICODE_REPLACEMENT_CHARACTER);
+if (res == NULL) {
+return NULL;
+}
+assert(count == 0 || PyUnicode_KIND(res) == PyUnicode_2BYTE_KIND);
+Py_UCS2 *outp = PyUnicode_2BYTE_DATA(res);
+for (Py_ssize_t i = 0; i < count; ++i) {
+outp[i] = Py_UNICODE_REPLACEMENT_CHARACTER;
+}
+assert(_PyUnicode_CheckConsistency(res, 1));
+return res;
+}
+
+
 // --- handler: 'strict' --
 
 PyObject *PyCodec_StrictErrors(PyObject *exc)
@@ -774,50 +795,71 @@ PyObject *PyCodec_IgnoreErrors(PyObject *exc)
 }
 
 
-PyObject *PyCodec_ReplaceErrors(PyObject *exc)
+// --- handler: 'replace' -
+
+static PyObject *
+_PyCodec_ReplaceUnicodeEncodeError(PyObject *exc)
 {
 Py_ssize_t start, end, slen;
+if (_PyUnicodeError_GetParams(exc, NULL, NULL,
+  &start, &end, &slen, false) < 0)
+{
+return NULL;
+}
+PyObject *res = PyUnicode_New(slen, '?');
+if (res == NULL) {
+return NULL;
+}
+assert(PyUnicode_KIND(res) == PyUnicode_1BYTE_KIND);
+Py_UCS1 *outp = PyUnicode_1BYTE_DATA(res);
+memset(outp, '?', sizeof(Py_UCS1) * slen);
+assert(_PyUnicode_CheckConsistency(res, 1));
+return Py_BuildValue("(Nn)", res, end);
+}
 
-if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) {
-if (_PyUnicodeError_GetParams(exc, NULL, NULL,
-  &start, &end, &slen, false) < 0) {
-return NULL;
-}
-PyObject *res = PyUnicode_New(slen, '?');
-if (res == NULL) {
-return NULL;
-}
-assert(PyUnicode_KIND(res) == PyUnicode_1BYTE_KIND);
-Py_UCS1 *outp = PyUnicode_1BYTE_DATA(res);
-memset(outp, '?', sizeof(Py_UCS1) * slen);
-assert(_PyUnicode_CheckConsistency(res, 1));
-return Py_BuildValue("(Nn)", res, end);
+
+static PyObject *
+_PyCodec_ReplaceUnicodeDecodeError(PyObject *exc)
+{
+Py_ssize_t end;
+if (PyUnicodeDecodeError_GetEnd(exc, &end) < 0) {
+return NULL;
 }
-else if (PyObject_TypeCheck(exc, (PyTypeObject 
*)PyExc_UnicodeDecodeError)) {
-if (_PyUnicodeError_GetParams(exc, NULL, NULL,
-  NULL, &end, NULL, true) < 0) {
-return NULL;
-}
-return Py_BuildValue("(Cn)",
- (int)Py_UNICODE_REPLACEMENT_CHARACTER,
- end);
+PyObject *res = codec_handler_unicode_replacement_character(1);
+if (res == NULL) {
+return NULL;
 }
-else if (PyObject_TypeCheck(exc, (PyTypeObject 
*)PyExc_UnicodeTranslateError)) {
-if (_PyUnicodeError_GetParams(exc, NULL, NULL,
-  &start, &end, &slen, false) < 0) {
-return NULL;
-}
-PyObject *res = PyUnicode_New(slen, Py_UNICODE_REPLACEMENT_CHARACTER);
-if (res == NULL) {
-return NULL;
-}
-assert(slen == 0 || PyUnicode_KIND(res) == PyUnicode_2BYTE_KIND);
-Py_UCS2 *outp = PyUnicode_2BYTE_DATA(res);
-for (Py_ssize_t i = 0; i < slen; ++i) {
-outp[i] = Py_UNICODE_REPLACEMENT_CHARACTER;
-}
-assert(_PyUnicode_CheckConsistency(res, 1));
-return Py_BuildValue("(Nn)", res, end);
+return Py_BuildValue("(Nn)", res, end);
+}
+
+
+static PyObject *
+_PyCodec_ReplaceUnicodeTranslateError(PyObject *exc)
+{
+Py_ssize_t start, end, slen;
+if (_PyUnicodeError_GetParams(exc, NULL, NULL,
+  &start, &end, &slen, false) < 0)
+{
+return NULL;
+}
+PyObject *res = codec_handler_unicode_replacement_character(slen);
+if (res == NULL) {
+return NULL;
+}
+return Py_BuildValue("(Nn)", res, end);
+}
+
+
+PyObject *PyCodec_ReplaceErrors(PyObject *exc)
+{
+if (_PyIsUnicodeEncodeE

[Python-checkins] Docs: Fix some semantic usages of `iterator.__iter__` (GH-130172)

2025-02-25 Thread encukou
https://github.com/python/cpython/commit/4d3a7ea354a8ca7a9978f48e54399526d1b83f42
commit: 4d3a7ea354a8ca7a9978f48e54399526d1b83f42
branch: main
author: Yuki Kobayashi 
committer: encukou 
date: 2025-02-25T13:38:47+01:00
summary:

Docs: Fix some semantic usages of `iterator.__iter__` (GH-130172)

These references to an `__iter__` method mean `object.__iter__`, not 
`iterator.__iter__`.

files:
M Doc/glossary.rst
M Doc/library/abc.rst
M Doc/library/stdtypes.rst

diff --git a/Doc/glossary.rst b/Doc/glossary.rst
index 7670bd859e282e..a6b94b564db177 100644
--- a/Doc/glossary.rst
+++ b/Doc/glossary.rst
@@ -719,7 +719,7 @@ Glossary
   iterables include all sequence types (such as :class:`list`, 
:class:`str`,
   and :class:`tuple`) and some non-sequence types like :class:`dict`,
   :term:`file objects `, and objects of any classes you define
-  with an :meth:`~iterator.__iter__` method or with a
+  with an :meth:`~object.__iter__` method or with a
   :meth:`~object.__getitem__` method
   that implements :term:`sequence` semantics.
 
diff --git a/Doc/library/abc.rst b/Doc/library/abc.rst
index 38d744e97d087d..49e541a9d9b1cb 100644
--- a/Doc/library/abc.rst
+++ b/Doc/library/abc.rst
@@ -141,18 +141,18 @@ a helper class :class:`ABC` to alternatively define ABCs 
through inheritance:
   MyIterable.register(Foo)
 
The ABC ``MyIterable`` defines the standard iterable method,
-   :meth:`~iterator.__iter__`, as an abstract method.  The implementation given
+   :meth:`~object.__iter__`, as an abstract method.  The implementation given
here can still be called from subclasses.  The :meth:`!get_iterator` method
is also part of the ``MyIterable`` abstract base class, but it does not have
to be overridden in non-abstract derived classes.
 
The :meth:`__subclasshook__` class method defined here says that any class
-   that has an :meth:`~iterator.__iter__` method in its
+   that has an :meth:`~object.__iter__` method in its
:attr:`~object.__dict__` (or in that of one of its base classes, accessed
via the :attr:`~type.__mro__` list) is considered a ``MyIterable`` too.
 
Finally, the last line makes ``Foo`` a virtual subclass of ``MyIterable``,
-   even though it does not define an :meth:`~iterator.__iter__` method (it uses
+   even though it does not define an :meth:`~object.__iter__` method (it uses
the old-style iterable protocol, defined in terms of 
:meth:`~object.__len__` and
:meth:`~object.__getitem__`).  Note that this will not make ``get_iterator``
available as a method of ``Foo``, so it is provided separately.
diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst
index 143fc6508ebc42..0564981b52e4f0 100644
--- a/Doc/library/stdtypes.rst
+++ b/Doc/library/stdtypes.rst
@@ -949,9 +949,9 @@ Generator Types
 ---
 
 Python's :term:`generator`\s provide a convenient way to implement the iterator
-protocol.  If a container object's :meth:`~iterator.__iter__` method is 
implemented as a
+protocol.  If a container object's :meth:`~object.__iter__` method is 
implemented as a
 generator, it will automatically return an iterator object (technically, a
-generator object) supplying the :meth:`!__iter__` and 
:meth:`~generator.__next__`
+generator object) supplying the :meth:`~iterator.__iter__` and 
:meth:`~generator.__next__`
 methods.
 More information about generators can be found in :ref:`the documentation for
 the yield expression `.

___
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com