[Python-checkins] gh-73965: Move PYTHON_HISTORY into the correct usage section (#113798)

2024-01-08 Thread hugovk
https://github.com/python/cpython/commit/e5d0316f35a62df05e1b196689f6998662631836
commit: e5d0316f35a62df05e1b196689f6998662631836
branch: main
author: Hugo van Kemenade <[email protected]>
committer: hugovk <[email protected]>
date: 2024-01-08T11:58:58+02:00
summary:

gh-73965: Move PYTHON_HISTORY into the correct usage section (#113798)

Co-authored-by: Serhiy Storchaka 

files:
M Python/initconfig.c

diff --git a/Python/initconfig.c b/Python/initconfig.c
index aad3b3d53ca787..a6d8c176156617 100644
--- a/Python/initconfig.c
+++ b/Python/initconfig.c
@@ -295,8 +295,8 @@ static const char usage_envvars[] =
 "   running a local build).\n"
 "PYTHON_COLORS   : If this variable is set to 1, the interpreter will"
 "   colorize various kinds of output. Setting it to 0 deactivates this 
behavior.\n"
+"PYTHON_HISTORY  : the location of a .python_history file.\n"
 "These variables have equivalent command-line parameters (see --help for 
details):\n"
-"PYTHON_HISTORY: the location of a .python_history file.\n"
 "PYTHONDEBUG : enable parser debug mode (-d)\n"
 "PYTHONDONTWRITEBYTECODE : don't write .pyc files (-B)\n"
 "PYTHONINSPECT   : inspect interactively after running script (-i)\n"

___
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]


[Python-checkins] gh-80109: Fix io.TextIOWrapper dropping the internal buffer during write() (GH-22535)

2024-01-08 Thread serhiy-storchaka
https://github.com/python/cpython/commit/73c93265634257b1488262097e024c1727260cfd
commit: 73c93265634257b1488262097e024c1727260cfd
branch: main
author: Zackery Spytz 
committer: serhiy-storchaka 
date: 2024-01-08T12:33:34+02:00
summary:

gh-80109: Fix io.TextIOWrapper dropping the internal buffer during write() 
(GH-22535)

io.TextIOWrapper was dropping the internal decoding buffer
during read() and write() calls.

files:
A Misc/NEWS.d/next/Library/2020-10-03-23-47-28.bpo-35928.E0iPAa.rst
M Lib/_pyio.py
M Lib/test/test_io.py
M Modules/_io/textio.c

diff --git a/Lib/_pyio.py b/Lib/_pyio.py
index 32698abac78d25..df2c29bfa9caee 100644
--- a/Lib/_pyio.py
+++ b/Lib/_pyio.py
@@ -2198,8 +2198,9 @@ def write(self, s):
 self.buffer.write(b)
 if self._line_buffering and (haslf or "\r" in s):
 self.flush()
-self._set_decoded_chars('')
-self._snapshot = None
+if self._snapshot is not None:
+self._set_decoded_chars('')
+self._snapshot = None
 if self._decoder:
 self._decoder.reset()
 return length
@@ -2513,8 +2514,9 @@ def read(self, size=None):
 # Read everything.
 result = (self._get_decoded_chars() +
   decoder.decode(self.buffer.read(), final=True))
-self._set_decoded_chars('')
-self._snapshot = None
+if self._snapshot is not None:
+self._set_decoded_chars('')
+self._snapshot = None
 return result
 else:
 # Keep reading chunks until we have size characters to return.
diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py
index 1d78876f2a1c84..ca31b9dad2631a 100644
--- a/Lib/test/test_io.py
+++ b/Lib/test/test_io.py
@@ -3880,6 +3880,14 @@ def test_issue25862(self):
 t.write('x')
 t.tell()
 
+def test_issue35928(self):
+p = self.BufferedRWPair(self.BytesIO(b'foo\nbar\n'), self.BytesIO())
+f = self.TextIOWrapper(p)
+res = f.readline()
+self.assertEqual(res, 'foo\n')
+f.write(res)
+self.assertEqual(res + f.readline(), 'foo\nbar\n')
+
 
 class MemviewBytesIO(io.BytesIO):
 '''A BytesIO object whose read method returns memoryviews
diff --git a/Misc/NEWS.d/next/Library/2020-10-03-23-47-28.bpo-35928.E0iPAa.rst 
b/Misc/NEWS.d/next/Library/2020-10-03-23-47-28.bpo-35928.E0iPAa.rst
new file mode 100644
index 00..c63e616458a356
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-10-03-23-47-28.bpo-35928.E0iPAa.rst
@@ -0,0 +1,2 @@
+:class:`io.TextIOWrapper` now correctly handles the decoding buffer after
+``read()`` and ``write()``.
diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c
index 4507930c14bb50..e93c3e091549db 100644
--- a/Modules/_io/textio.c
+++ b/Modules/_io/textio.c
@@ -1762,8 +1762,10 @@ _io_TextIOWrapper_write_impl(textio *self, PyObject 
*text)
 }
 }
 
-textiowrapper_set_decoded_chars(self, NULL);
-Py_CLEAR(self->snapshot);
+if (self->snapshot != NULL) {
+textiowrapper_set_decoded_chars(self, NULL);
+Py_CLEAR(self->snapshot);
+}
 
 if (self->decoder) {
 ret = PyObject_CallMethodNoArgs(self->decoder, &_Py_ID(reset));
@@ -1999,8 +2001,10 @@ _io_TextIOWrapper_read_impl(textio *self, Py_ssize_t n)
 if (result == NULL)
 goto fail;
 
-textiowrapper_set_decoded_chars(self, NULL);
-Py_CLEAR(self->snapshot);
+if (self->snapshot != NULL) {
+textiowrapper_set_decoded_chars(self, NULL);
+Py_CLEAR(self->snapshot);
+}
 return result;
 }
 else {

___
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]


[Python-checkins] [3.11] gh-80109: Fix io.TextIOWrapper dropping the internal buffer during write() (GH-22535) (GH-113809)

2024-01-08 Thread serhiy-storchaka
https://github.com/python/cpython/commit/4db8d3be49b3a229932a24f6271d3f062843d08f
commit: 4db8d3be49b3a229932a24f6271d3f062843d08f
branch: 3.11
author: Miss Islington (bot) <[email protected]>
committer: serhiy-storchaka 
date: 2024-01-08T10:47:50Z
summary:

[3.11] gh-80109: Fix io.TextIOWrapper dropping the internal buffer during 
write() (GH-22535) (GH-113809)

io.TextIOWrapper was dropping the internal decoding buffer
during read() and write() calls.
(cherry picked from commit 73c93265634257b1488262097e024c1727260cfd)

Co-authored-by: Zackery Spytz 

files:
A Misc/NEWS.d/next/Library/2020-10-03-23-47-28.bpo-35928.E0iPAa.rst
M Lib/_pyio.py
M Lib/test/test_io.py
M Modules/_io/textio.c

diff --git a/Lib/_pyio.py b/Lib/_pyio.py
index 0bfdeaafae274b..16d025b1703e4f 100644
--- a/Lib/_pyio.py
+++ b/Lib/_pyio.py
@@ -2224,8 +2224,9 @@ def write(self, s):
 self.buffer.write(b)
 if self._line_buffering and (haslf or "\r" in s):
 self.flush()
-self._set_decoded_chars('')
-self._snapshot = None
+if self._snapshot is not None:
+self._set_decoded_chars('')
+self._snapshot = None
 if self._decoder:
 self._decoder.reset()
 return length
@@ -2539,8 +2540,9 @@ def read(self, size=None):
 # Read everything.
 result = (self._get_decoded_chars() +
   decoder.decode(self.buffer.read(), final=True))
-self._set_decoded_chars('')
-self._snapshot = None
+if self._snapshot is not None:
+self._set_decoded_chars('')
+self._snapshot = None
 return result
 else:
 # Keep reading chunks until we have size characters to return.
diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py
index 78537057f32666..3dae7890ec3574 100644
--- a/Lib/test/test_io.py
+++ b/Lib/test/test_io.py
@@ -3788,6 +3788,14 @@ def test_issue25862(self):
 t.write('x')
 t.tell()
 
+def test_issue35928(self):
+p = self.BufferedRWPair(self.BytesIO(b'foo\nbar\n'), self.BytesIO())
+f = self.TextIOWrapper(p)
+res = f.readline()
+self.assertEqual(res, 'foo\n')
+f.write(res)
+self.assertEqual(res + f.readline(), 'foo\nbar\n')
+
 
 class MemviewBytesIO(io.BytesIO):
 '''A BytesIO object whose read method returns memoryviews
diff --git a/Misc/NEWS.d/next/Library/2020-10-03-23-47-28.bpo-35928.E0iPAa.rst 
b/Misc/NEWS.d/next/Library/2020-10-03-23-47-28.bpo-35928.E0iPAa.rst
new file mode 100644
index 00..c63e616458a356
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-10-03-23-47-28.bpo-35928.E0iPAa.rst
@@ -0,0 +1,2 @@
+:class:`io.TextIOWrapper` now correctly handles the decoding buffer after
+``read()`` and ``write()``.
diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c
index b994dc3d7c45b1..3de4c06704b8b9 100644
--- a/Modules/_io/textio.c
+++ b/Modules/_io/textio.c
@@ -1745,8 +1745,10 @@ _io_TextIOWrapper_write_impl(textio *self, PyObject 
*text)
 Py_DECREF(ret);
 }
 
-textiowrapper_set_decoded_chars(self, NULL);
-Py_CLEAR(self->snapshot);
+if (self->snapshot != NULL) {
+textiowrapper_set_decoded_chars(self, NULL);
+Py_CLEAR(self->snapshot);
+}
 
 if (self->decoder) {
 ret = PyObject_CallMethodNoArgs(self->decoder, &_Py_ID(reset));
@@ -1979,8 +1981,10 @@ _io_TextIOWrapper_read_impl(textio *self, Py_ssize_t n)
 if (result == NULL)
 goto fail;
 
-textiowrapper_set_decoded_chars(self, NULL);
-Py_CLEAR(self->snapshot);
+if (self->snapshot != NULL) {
+textiowrapper_set_decoded_chars(self, NULL);
+Py_CLEAR(self->snapshot);
+}
 return result;
 }
 else {

___
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]


[Python-checkins] [3.12] gh-80109: Fix io.TextIOWrapper dropping the internal buffer during write() (GH-22535) (GH-113808)

2024-01-08 Thread serhiy-storchaka
https://github.com/python/cpython/commit/ad2d5ec97e12063b7265faa8b0654bcf82a33545
commit: ad2d5ec97e12063b7265faa8b0654bcf82a33545
branch: 3.12
author: Miss Islington (bot) <[email protected]>
committer: serhiy-storchaka 
date: 2024-01-08T11:00:30Z
summary:

[3.12] gh-80109: Fix io.TextIOWrapper dropping the internal buffer during 
write() (GH-22535) (GH-113808)

io.TextIOWrapper was dropping the internal decoding buffer
during read() and write() calls.
(cherry picked from commit 73c93265634257b1488262097e024c1727260cfd)

Co-authored-by: Zackery Spytz 

files:
A Misc/NEWS.d/next/Library/2020-10-03-23-47-28.bpo-35928.E0iPAa.rst
M Lib/_pyio.py
M Lib/test/test_io.py
M Modules/_io/textio.c

diff --git a/Lib/_pyio.py b/Lib/_pyio.py
index 7f247ff47c9e61..9641d43101843f 100644
--- a/Lib/_pyio.py
+++ b/Lib/_pyio.py
@@ -2210,8 +2210,9 @@ def write(self, s):
 self.buffer.write(b)
 if self._line_buffering and (haslf or "\r" in s):
 self.flush()
-self._set_decoded_chars('')
-self._snapshot = None
+if self._snapshot is not None:
+self._set_decoded_chars('')
+self._snapshot = None
 if self._decoder:
 self._decoder.reset()
 return length
@@ -2525,8 +2526,9 @@ def read(self, size=None):
 # Read everything.
 result = (self._get_decoded_chars() +
   decoder.decode(self.buffer.read(), final=True))
-self._set_decoded_chars('')
-self._snapshot = None
+if self._snapshot is not None:
+self._set_decoded_chars('')
+self._snapshot = None
 return result
 else:
 # Keep reading chunks until we have size characters to return.
diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py
index 196b7d2b1429ab..cceaed8af59349 100644
--- a/Lib/test/test_io.py
+++ b/Lib/test/test_io.py
@@ -3891,6 +3891,14 @@ def test_issue25862(self):
 t.write('x')
 t.tell()
 
+def test_issue35928(self):
+p = self.BufferedRWPair(self.BytesIO(b'foo\nbar\n'), self.BytesIO())
+f = self.TextIOWrapper(p)
+res = f.readline()
+self.assertEqual(res, 'foo\n')
+f.write(res)
+self.assertEqual(res + f.readline(), 'foo\nbar\n')
+
 
 class MemviewBytesIO(io.BytesIO):
 '''A BytesIO object whose read method returns memoryviews
diff --git a/Misc/NEWS.d/next/Library/2020-10-03-23-47-28.bpo-35928.E0iPAa.rst 
b/Misc/NEWS.d/next/Library/2020-10-03-23-47-28.bpo-35928.E0iPAa.rst
new file mode 100644
index 00..c63e616458a356
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-10-03-23-47-28.bpo-35928.E0iPAa.rst
@@ -0,0 +1,2 @@
+:class:`io.TextIOWrapper` now correctly handles the decoding buffer after
+``read()`` and ``write()``.
diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c
index efada7f0495357..14dd19d95c2498 100644
--- a/Modules/_io/textio.c
+++ b/Modules/_io/textio.c
@@ -1767,8 +1767,10 @@ _io_TextIOWrapper_write_impl(textio *self, PyObject 
*text)
 Py_DECREF(ret);
 }
 
-textiowrapper_set_decoded_chars(self, NULL);
-Py_CLEAR(self->snapshot);
+if (self->snapshot != NULL) {
+textiowrapper_set_decoded_chars(self, NULL);
+Py_CLEAR(self->snapshot);
+}
 
 if (self->decoder) {
 ret = PyObject_CallMethodNoArgs(self->decoder, &_Py_ID(reset));
@@ -2003,8 +2005,10 @@ _io_TextIOWrapper_read_impl(textio *self, Py_ssize_t n)
 if (result == NULL)
 goto fail;
 
-textiowrapper_set_decoded_chars(self, NULL);
-Py_CLEAR(self->snapshot);
+if (self->snapshot != NULL) {
+textiowrapper_set_decoded_chars(self, NULL);
+Py_CLEAR(self->snapshot);
+}
 return result;
 }
 else {

___
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]


[Python-checkins] gh-74678: Increase base64 test coverage (GH-21913)

2024-01-08 Thread serhiy-storchaka
https://github.com/python/cpython/commit/802d4954f12541ba28dd7f18bf4a65054941a80d
commit: 802d4954f12541ba28dd7f18bf4a65054941a80d
branch: main
author: Zackery Spytz 
committer: serhiy-storchaka 
date: 2024-01-08T13:01:31+02:00
summary:

gh-74678: Increase base64 test coverage (GH-21913)

Ensure the character y is disallowed within an Ascii85 5-tuple.

Co-authored-by: Lee Cannon 

files:
M Lib/test/test_base64.py

diff --git a/Lib/test/test_base64.py b/Lib/test/test_base64.py
index fa03fa1d61ceab..f6171d3ed4efd7 100644
--- a/Lib/test/test_base64.py
+++ b/Lib/test/test_base64.py
@@ -586,6 +586,7 @@ def test_a85decode(self):
 eq(base64.a85decode(b'y+',
b"www.python.org")
@@ -689,6 +690,8 @@ def test_a85decode_errors(self):
 self.assertRaises(ValueError, base64.a85decode, b's8W', adobe=False)
 self.assertRaises(ValueError, base64.a85decode, b's8W-', adobe=False)
 self.assertRaises(ValueError, base64.a85decode, b's8W-"', adobe=False)
+self.assertRaises(ValueError, base64.a85decode, b'y',
+  foldspaces=True)
 
 def test_b85decode_errors(self):
 illegal = list(range(33)) + \

___
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]


[Python-checkins] [3.11] gh-74678: Increase base64 test coverage (GH-21913) (GH-113810)

2024-01-08 Thread serhiy-storchaka
https://github.com/python/cpython/commit/73573352fc4489ab3ded61f9a55965d9913de1f5
commit: 73573352fc4489ab3ded61f9a55965d9913de1f5
branch: 3.11
author: Miss Islington (bot) <[email protected]>
committer: serhiy-storchaka 
date: 2024-01-08T11:16:06Z
summary:

[3.11] gh-74678: Increase base64 test coverage (GH-21913) (GH-113810)

Ensure the character y is disallowed within an Ascii85 5-tuple.

(cherry picked from commit 802d4954f12541ba28dd7f18bf4a65054941a80d)

Co-authored-by: Zackery Spytz 
Co-authored-by: Lee Cannon 

files:
M Lib/test/test_base64.py

diff --git a/Lib/test/test_base64.py b/Lib/test/test_base64.py
index 217f2945468844..8582cdc409371c 100644
--- a/Lib/test/test_base64.py
+++ b/Lib/test/test_base64.py
@@ -582,6 +582,7 @@ def test_a85decode(self):
 eq(base64.a85decode(b'y+',
b"www.python.org")
@@ -685,6 +686,8 @@ def test_a85decode_errors(self):
 self.assertRaises(ValueError, base64.a85decode, b's8W', adobe=False)
 self.assertRaises(ValueError, base64.a85decode, b's8W-', adobe=False)
 self.assertRaises(ValueError, base64.a85decode, b's8W-"', adobe=False)
+self.assertRaises(ValueError, base64.a85decode, b'y',
+  foldspaces=True)
 
 def test_b85decode_errors(self):
 illegal = list(range(33)) + \

___
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]


[Python-checkins] [3.12] gh-74678: Increase base64 test coverage (GH-21913) (GH-113811)

2024-01-08 Thread serhiy-storchaka
https://github.com/python/cpython/commit/7390dffce0624f38f78441cf2b618f3ab98d3ce3
commit: 7390dffce0624f38f78441cf2b618f3ab98d3ce3
branch: 3.12
author: Miss Islington (bot) <[email protected]>
committer: serhiy-storchaka 
date: 2024-01-08T11:20:36Z
summary:

[3.12] gh-74678: Increase base64 test coverage (GH-21913) (GH-113811)

Ensure the character y is disallowed within an Ascii85 5-tuple.

(cherry picked from commit 802d4954f12541ba28dd7f18bf4a65054941a80d)

Co-authored-by: Zackery Spytz 
Co-authored-by: Lee Cannon 

files:
M Lib/test/test_base64.py

diff --git a/Lib/test/test_base64.py b/Lib/test/test_base64.py
index fa03fa1d61ceab..f6171d3ed4efd7 100644
--- a/Lib/test/test_base64.py
+++ b/Lib/test/test_base64.py
@@ -586,6 +586,7 @@ def test_a85decode(self):
 eq(base64.a85decode(b'y+',
b"www.python.org")
@@ -689,6 +690,8 @@ def test_a85decode_errors(self):
 self.assertRaises(ValueError, base64.a85decode, b's8W', adobe=False)
 self.assertRaises(ValueError, base64.a85decode, b's8W-', adobe=False)
 self.assertRaises(ValueError, base64.a85decode, b's8W-"', adobe=False)
+self.assertRaises(ValueError, base64.a85decode, b'y',
+  foldspaces=True)
 
 def test_b85decode_errors(self):
 illegal = list(range(33)) + \

___
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]


[Python-checkins] gh-110721: Remove unused code from suggestions.c after moving PyErr_Display to use the traceback module (#113712)

2024-01-08 Thread pablogsal
https://github.com/python/cpython/commit/a03ec20bcdf757138557127689405b3a525b3c44
commit: a03ec20bcdf757138557127689405b3a525b3c44
branch: main
author: Pablo Galindo Salgado 
committer: pablogsal 
date: 2024-01-08T15:10:45Z
summary:

gh-110721: Remove unused code from suggestions.c after moving PyErr_Display to 
use the traceback module (#113712)

files:
A Modules/_suggestions.c
A Modules/clinic/_suggestions.c.h
M Include/internal/pycore_global_objects_fini_generated.h
M Include/internal/pycore_global_strings.h
M Include/internal/pycore_runtime_init_generated.h
M Include/internal/pycore_unicodeobject_generated.h
M Lib/traceback.py
M Modules/Setup.bootstrap.in
M PCbuild/pythoncore.vcxproj
M PCbuild/pythoncore.vcxproj.filters
M Python/stdlib_module_names.h
M Python/suggestions.c

diff --git a/Include/internal/pycore_global_objects_fini_generated.h 
b/Include/internal/pycore_global_objects_fini_generated.h
index 89ec8cbbbcd649..8dbdc399d77f57 100644
--- a/Include/internal/pycore_global_objects_fini_generated.h
+++ b/Include/internal/pycore_global_objects_fini_generated.h
@@ -1164,7 +1164,6 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
 _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(seek));
 _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(seekable));
 _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(selectors));
-_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(self));
 _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(send));
 _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sep));
 _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sequence));
diff --git a/Include/internal/pycore_global_strings.h 
b/Include/internal/pycore_global_strings.h
index 62c3ee3ae2a0bd..1fa2d1d49cbb49 100644
--- a/Include/internal/pycore_global_strings.h
+++ b/Include/internal/pycore_global_strings.h
@@ -653,7 +653,6 @@ struct _Py_global_strings {
 STRUCT_FOR_ID(seek)
 STRUCT_FOR_ID(seekable)
 STRUCT_FOR_ID(selectors)
-STRUCT_FOR_ID(self)
 STRUCT_FOR_ID(send)
 STRUCT_FOR_ID(sep)
 STRUCT_FOR_ID(sequence)
diff --git a/Include/internal/pycore_runtime_init_generated.h 
b/Include/internal/pycore_runtime_init_generated.h
index 1defa39f816e78..8fd922af2654e0 100644
--- a/Include/internal/pycore_runtime_init_generated.h
+++ b/Include/internal/pycore_runtime_init_generated.h
@@ -1162,7 +1162,6 @@ extern "C" {
 INIT_ID(seek), \
 INIT_ID(seekable), \
 INIT_ID(selectors), \
-INIT_ID(self), \
 INIT_ID(send), \
 INIT_ID(sep), \
 INIT_ID(sequence), \
diff --git a/Include/internal/pycore_unicodeobject_generated.h 
b/Include/internal/pycore_unicodeobject_generated.h
index be9baa3eebecfc..0b5fb7363b4f4e 100644
--- a/Include/internal/pycore_unicodeobject_generated.h
+++ b/Include/internal/pycore_unicodeobject_generated.h
@@ -1800,9 +1800,6 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
 string = &_Py_ID(selectors);
 assert(_PyUnicode_CheckConsistency(string, 1));
 _PyUnicode_InternInPlace(interp, &string);
-string = &_Py_ID(self);
-assert(_PyUnicode_CheckConsistency(string, 1));
-_PyUnicode_InternInPlace(interp, &string);
 string = &_Py_ID(send);
 assert(_PyUnicode_CheckConsistency(string, 1));
 _PyUnicode_InternInPlace(interp, &string);
diff --git a/Lib/traceback.py b/Lib/traceback.py
index 1cf008c7e9da97..30b42a4f693d95 100644
--- a/Lib/traceback.py
+++ b/Lib/traceback.py
@@ -1497,6 +1497,13 @@ def _compute_suggestion_error(exc_value, tb, wrong_name):
 if hasattr(self, wrong_name):
 return f"self.{wrong_name}"
 
+try:
+import _suggestions
+except ImportError:
+pass
+else:
+return _suggestions._generate_suggestions(d, wrong_name)
+
 # Compute closest match
 
 if len(d) > _MAX_CANDIDATE_ITEMS:
diff --git a/Modules/Setup.bootstrap.in b/Modules/Setup.bootstrap.in
index cd12c1bd0df8f9..aa4e60e272653b 100644
--- a/Modules/Setup.bootstrap.in
+++ b/Modules/Setup.bootstrap.in
@@ -11,6 +11,7 @@ faulthandler faulthandler.c
 posix posixmodule.c
 _signal signalmodule.c
 _tracemalloc _tracemalloc.c
+_suggestions _suggestions.c
 
 # modules used by importlib, deepfreeze, freeze, runpy, and sysconfig
 _codecs _codecsmodule.c
diff --git a/Modules/_suggestions.c b/Modules/_suggestions.c
new file mode 100644
index 00..30b524d70c1211
--- /dev/null
+++ b/Modules/_suggestions.c
@@ -0,0 +1,63 @@
+#include "Python.h"
+#include "pycore_pyerrors.h"
+#include "clinic/_suggestions.c.h"
+
+/*[clinic input]
+module _suggestions
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e58d81fafad5637b]*/
+
+/*[clinic input]
+_suggestions._generate_suggestions
+candidates: object
+item: unicode
+/
+Returns the candidate in candidates that's closest to item
+[clinic start generated code]*/
+
+static PyObject *
+_suggestions__generate_suggestions_impl(PyObject *module,
+  

[Python-checkins] gh-113391: fix outdated PyObject_HasAttr docs (#113420)

2024-01-08 Thread encukou
https://github.com/python/cpython/commit/61dd77b04ea205f492498d30637f2d516d8e2a8b
commit: 61dd77b04ea205f492498d30637f2d516d8e2a8b
branch: main
author: Sergey B Kirpichev 
committer: encukou 
date: 2024-01-08T16:23:43+01:00
summary:

gh-113391: fix outdated PyObject_HasAttr docs (#113420)

After #53875: PyObject_HasAttr is not an equivalent of hasattr.
PyObject_HasAttrWithError is; it already has the note.

files:
M Doc/c-api/object.rst

diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst
index a4e3e74861a315..8a179690d048e3 100644
--- a/Doc/c-api/object.rst
+++ b/Doc/c-api/object.rst
@@ -47,9 +47,8 @@ Object Protocol
 
 .. c:function:: int PyObject_HasAttr(PyObject *o, PyObject *attr_name)
 
-   Returns ``1`` if *o* has the attribute *attr_name*, and ``0`` otherwise.  
This
-   is equivalent to the Python expression ``hasattr(o, attr_name)``.  This 
function
-   always succeeds.
+   Returns ``1`` if *o* has the attribute *attr_name*, and ``0`` otherwise.
+   This function always succeeds.
 
.. note::
 

___
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]


[Python-checkins] gh-113787: Fix refleaks in test_capi (gh-113816)

2024-01-08 Thread nascheme
https://github.com/python/cpython/commit/ace4d7ff9a247cbe7350719b996a1c7d88a57813
commit: ace4d7ff9a247cbe7350719b996a1c7d88a57813
branch: main
author: neonene <[email protected]>
committer: nascheme 
date: 2024-01-08T08:34:51-08:00
summary:

gh-113787: Fix refleaks in test_capi (gh-113816)

Fix refleaks and a typo.

files:
M Modules/_testcapi/vectorcall_limited.c
M Modules/_testcapimodule.c

diff --git a/Modules/_testcapi/vectorcall_limited.c 
b/Modules/_testcapi/vectorcall_limited.c
index d7b8d33b7f7162..d7070d37bb9e9b 100644
--- a/Modules/_testcapi/vectorcall_limited.c
+++ b/Modules/_testcapi/vectorcall_limited.c
@@ -195,6 +195,6 @@ _PyTestCapi_Init_VectorcallLimited(PyObject *m) {
 if (PyModule_AddType(m, (PyTypeObject *)LimitedVectorCallClass) < 0) {
 return -1;
 }
-
+Py_DECREF(LimitedVectorCallClass);
 return 0;
 }
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 6762c611fb12a2..398570ff8e05c6 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -49,7 +49,7 @@ get_testcapi_state(PyObject *module)
 
 static PyObject *
 get_testerror(PyObject *self) {
-testcapistate_t *state = get_testcapi_state((PyObject *)Py_TYPE(self));
+testcapistate_t *state = get_testcapi_state(self);
 return state->error;
 }
 
@@ -3947,7 +3947,6 @@ PyInit__testcapi(void)
 
 testcapistate_t *state = get_testcapi_state(m);
 state->error = PyErr_NewException("_testcapi.error", NULL, NULL);
-Py_INCREF(state->error);
 PyModule_AddObject(m, "error", state->error);
 
 if (PyType_Ready(&ContainerNoGC_type) < 0) {

___
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]


[Python-checkins] gh-113755: Fully adapt gcmodule.c to Argument Clinic (#113756)

2024-01-08 Thread erlend-aasland
https://github.com/python/cpython/commit/35fa13d48b3247ea5e83b17c05a98163904e5a0b
commit: 35fa13d48b3247ea5e83b17c05a98163904e5a0b
branch: main
author: Erlend E. Aasland 
committer: erlend-aasland 
date: 2024-01-08T18:32:34+01:00
summary:

gh-113755: Fully adapt gcmodule.c to Argument Clinic (#113756)

Adapt the following functions to Argument Clinic:

- gc.set_threshold
- gc.get_referrers
- gc.get_referents

files:
M Doc/library/gc.rst
M Modules/clinic/gcmodule.c.h
M Modules/gcmodule.c

diff --git a/Doc/library/gc.rst b/Doc/library/gc.rst
index 82277aa52aee01..e36a71af2b64ab 100644
--- a/Doc/library/gc.rst
+++ b/Doc/library/gc.rst
@@ -96,7 +96,7 @@ The :mod:`gc` module provides the following functions:
.. versionadded:: 3.4
 
 
-.. function:: set_threshold(threshold0[, threshold1[, threshold2]])
+.. function:: set_threshold(threshold0, [threshold1, [threshold2]])
 
Set the garbage collection thresholds (the collection frequency). Setting
*threshold0* to zero disables collection.
diff --git a/Modules/clinic/gcmodule.c.h b/Modules/clinic/gcmodule.c.h
index ad4469350447cb..d50d170589a2cd 100644
--- a/Modules/clinic/gcmodule.c.h
+++ b/Modules/clinic/gcmodule.c.h
@@ -214,6 +214,58 @@ gc_get_debug(PyObject *module, PyObject 
*Py_UNUSED(ignored))
 return return_value;
 }
 
+PyDoc_STRVAR(gc_set_threshold__doc__,
+"set_threshold(threshold0, [threshold1, [threshold2]])\n"
+"Set the collection thresholds (the collection frequency).\n"
+"\n"
+"Setting \'threshold0\' to zero disables collection.");
+
+#define GC_SET_THRESHOLD_METHODDEF\
+{"set_threshold", (PyCFunction)gc_set_threshold, METH_VARARGS, 
gc_set_threshold__doc__},
+
+static PyObject *
+gc_set_threshold_impl(PyObject *module, int threshold0, int group_right_1,
+  int threshold1, int group_right_2, int threshold2);
+
+static PyObject *
+gc_set_threshold(PyObject *module, PyObject *args)
+{
+PyObject *return_value = NULL;
+int threshold0;
+int group_right_1 = 0;
+int threshold1 = 0;
+int group_right_2 = 0;
+int threshold2 = 0;
+
+switch (PyTuple_GET_SIZE(args)) {
+case 1:
+if (!PyArg_ParseTuple(args, "i:set_threshold", &threshold0)) {
+goto exit;
+}
+break;
+case 2:
+if (!PyArg_ParseTuple(args, "ii:set_threshold", &threshold0, 
&threshold1)) {
+goto exit;
+}
+group_right_1 = 1;
+break;
+case 3:
+if (!PyArg_ParseTuple(args, "iii:set_threshold", &threshold0, 
&threshold1, &threshold2)) {
+goto exit;
+}
+group_right_1 = 1;
+group_right_2 = 1;
+break;
+default:
+PyErr_SetString(PyExc_TypeError, "gc.set_threshold requires 1 to 3 
arguments");
+goto exit;
+}
+return_value = gc_set_threshold_impl(module, threshold0, group_right_1, 
threshold1, group_right_2, threshold2);
+
+exit:
+return return_value;
+}
+
 PyDoc_STRVAR(gc_get_threshold__doc__,
 "get_threshold($module, /)\n"
 "--\n"
@@ -250,6 +302,76 @@ gc_get_count(PyObject *module, PyObject 
*Py_UNUSED(ignored))
 return gc_get_count_impl(module);
 }
 
+PyDoc_STRVAR(gc_get_referrers__doc__,
+"get_referrers($module, /, *objs)\n"
+"--\n"
+"\n"
+"Return the list of objects that directly refer to any of \'objs\'.");
+
+#define GC_GET_REFERRERS_METHODDEF\
+{"get_referrers", _PyCFunction_CAST(gc_get_referrers), METH_FASTCALL, 
gc_get_referrers__doc__},
+
+static PyObject *
+gc_get_referrers_impl(PyObject *module, PyObject *args);
+
+static PyObject *
+gc_get_referrers(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+PyObject *return_value = NULL;
+PyObject *__clinic_args = NULL;
+
+if (!_PyArg_CheckPositional("get_referrers", nargs, 0, PY_SSIZE_T_MAX)) {
+goto exit;
+}
+__clinic_args = PyTuple_New(nargs - 0);
+if (!__clinic_args) {
+goto exit;
+}
+for (Py_ssize_t i = 0; i < nargs - 0; ++i) {
+PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[0 + i]));
+}
+return_value = gc_get_referrers_impl(module, __clinic_args);
+
+exit:
+Py_XDECREF(__clinic_args);
+return return_value;
+}
+
+PyDoc_STRVAR(gc_get_referents__doc__,
+"get_referents($module, /, *objs)\n"
+"--\n"
+"\n"
+"Return the list of objects that are directly referred to by \'objs\'.");
+
+#define GC_GET_REFERENTS_METHODDEF\
+{"get_referents", _PyCFunction_CAST(gc_get_referents), METH_FASTCALL, 
gc_get_referents__doc__},
+
+static PyObject *
+gc_get_referents_impl(PyObject *module, PyObject *args);
+
+static PyObject *
+gc_get_referents(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+PyObject *return_value = NULL;
+PyObject *__clinic_args = NULL;
+
+if (!_PyArg_CheckPositional("get_referents", nargs, 0, PY_SSIZE_T_MAX)) {
+goto exit;
+}
+__clinic_args = PyTuple_New(nargs - 0);
+if (!__clinic

[Python-checkins] Minor algebraic simplification for the totient() recipe (gh-113822)

2024-01-08 Thread rhettinger
https://github.com/python/cpython/commit/aef375f56ec93740f0a9b5031c3d2063c553fc12
commit: aef375f56ec93740f0a9b5031c3d2063c553fc12
branch: main
author: Raymond Hettinger 
committer: rhettinger 
date: 2024-01-08T13:16:22-06:00
summary:

Minor algebraic simplification for the totient() recipe (gh-113822)

files:
M Doc/library/itertools.rst

diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst
index 5c8cc982a89a2c..338a5f9615aae3 100644
--- a/Doc/library/itertools.rst
+++ b/Doc/library/itertools.rst
@@ -1150,7 +1150,7 @@ The following recipes have a more mathematical flavor:
# https://mathworld.wolfram.com/TotientFunction.html
# totient(12) --> 4 because len([1, 5, 7, 11]) == 4
for p in unique_justseen(factor(n)):
-   n = n // p * (p - 1)
+   n -= n // p
return n
 
 

___
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]


[Python-checkins] GH-113528: Move a few misplaced pathlib tests (#113527)

2024-01-08 Thread barneygale
https://github.com/python/cpython/commit/a9df076d7d5e113aab4dfd32118a14b62537a8a2
commit: a9df076d7d5e113aab4dfd32118a14b62537a8a2
branch: main
author: Barney Gale 
committer: barneygale 
date: 2024-01-08T19:17:18Z
summary:

GH-113528: Move a few misplaced pathlib tests (#113527)

`PurePathBase` does not define `__eq__()`, and so we have no business checking 
path equality in `test_eq_common` and `test_equivalences`. The tests only pass 
at the moment because we define the test class's `__eq__()` for use elsewhere.

Also move `test_parse_path_common` into the main pathlib test suite. It 
exercises a private `_parse_path()` method that will be moved to `PurePath` 
soon.

Lastly move a couple more tests concerned with optimisations and path 
normalisation.

files:
M Lib/test/test_pathlib/test_pathlib.py
M Lib/test/test_pathlib/test_pathlib_abc.py

diff --git a/Lib/test/test_pathlib/test_pathlib.py 
b/Lib/test/test_pathlib/test_pathlib.py
index 93fe327a0d3c23..6e42122212632d 100644
--- a/Lib/test/test_pathlib/test_pathlib.py
+++ b/Lib/test/test_pathlib/test_pathlib.py
@@ -45,6 +45,22 @@ class PurePathTest(test_pathlib_abc.DummyPurePathTest):
 # Make sure any symbolic links in the base test path are resolved.
 base = os.path.realpath(TESTFN)
 
+# Keys are canonical paths, values are list of tuples of arguments
+# supposed to produce equal paths.
+equivalences = {
+'a/b': [
+('a', 'b'), ('a/', 'b'), ('a', 'b/'), ('a/', 'b/'),
+('a/b/',), ('a//b',), ('a//b//',),
+# Empty components get removed.
+('', 'a', 'b'), ('a', '', 'b'), ('a', 'b', ''),
+],
+'/b/c/d': [
+('a', '/b/c', 'd'), ('/a', '/b/c', 'd'),
+# Empty components get removed.
+('/', 'b', '', 'c/d'), ('/', '', 'b/c/d'), ('', '/b/c/d'),
+],
+}
+
 def test_concrete_class(self):
 if self.cls is pathlib.PurePath:
 expected = pathlib.PureWindowsPath if os.name == 'nt' else 
pathlib.PurePosixPath
@@ -95,6 +111,45 @@ def test_constructor_nested(self):
 self.assertEqual(P(P('a'), P('b'), P('c')), P(FakePath("a/b/c")))
 self.assertEqual(P(P('./a:b')), P('./a:b'))
 
+def _check_parse_path(self, raw_path, *expected):
+sep = self.pathmod.sep
+actual = self.cls._parse_path(raw_path.replace('/', sep))
+self.assertEqual(actual, expected)
+if altsep := self.pathmod.altsep:
+actual = self.cls._parse_path(raw_path.replace('/', altsep))
+self.assertEqual(actual, expected)
+
+def test_parse_path_common(self):
+check = self._check_parse_path
+sep = self.pathmod.sep
+check('', '', '', [])
+check('a','', '', ['a'])
+check('a/',   '', '', ['a'])
+check('a/b',  '', '', ['a', 'b'])
+check('a/b/', '', '', ['a', 'b'])
+check('a/b/c/d',  '', '', ['a', 'b', 'c', 'd'])
+check('a/b//c/d', '', '', ['a', 'b', 'c', 'd'])
+check('a/b/c/d',  '', '', ['a', 'b', 'c', 'd'])
+check('.','', '', [])
+check('././b','', '', ['b'])
+check('a/./b','', '', ['a', 'b'])
+check('a/./.','', '', ['a'])
+check('/a/b', '', sep, ['a', 'b'])
+
+def test_empty_path(self):
+# The empty path points to '.'
+p = self.cls('')
+self.assertEqual(str(p), '.')
+
+def test_parts_interning(self):
+P = self.cls
+p = P('/usr/bin/foo')
+q = P('/usr/local/bin')
+# 'usr'
+self.assertIs(p.parts[1], q.parts[1])
+# 'bin'
+self.assertIs(p.parts[2], q.parts[3])
+
 def test_join_nested(self):
 P = self.cls
 p = P('a/b').joinpath(P('c'))
@@ -168,6 +223,37 @@ def test_as_bytes_common(self):
 P = self.cls
 self.assertEqual(bytes(P('a/b')), b'a' + sep + b'b')
 
+def test_eq_common(self):
+P = self.cls
+self.assertEqual(P('a/b'), P('a/b'))
+self.assertEqual(P('a/b'), P('a', 'b'))
+self.assertNotEqual(P('a/b'), P('a'))
+self.assertNotEqual(P('a/b'), P('/a/b'))
+self.assertNotEqual(P('a/b'), P())
+self.assertNotEqual(P('/a/b'), P('/'))
+self.assertNotEqual(P(), P('/'))
+self.assertNotEqual(P(), "")
+self.assertNotEqual(P(), {})
+self.assertNotEqual(P(), int)
+
+def test_equivalences(self):
+for k, tuples in self.equivalences.items():
+canon = k.replace('/', self.sep)
+posix = k.replace(self.sep, '/')
+if canon != posix:
+tuples = tuples + [
+tuple(part.replace('/', self.sep) for part in t)
+for t in tuples
+]
+tuples.append((posix, ))
+pcanon = self.cls(canon)
+for t in tuples:
+p = self.cls(*t)
+self.assertEqual(p, pcano

[Python-checkins] [3.12] Minor algebraic simplification for the totient() recipe (gh-113822) (gh-113823)

2024-01-08 Thread rhettinger
https://github.com/python/cpython/commit/0b31a50ecd494d76e4254d4b2de18e5926683124
commit: 0b31a50ecd494d76e4254d4b2de18e5926683124
branch: 3.12
author: Miss Islington (bot) <[email protected]>
committer: rhettinger 
date: 2024-01-08T19:22:42Z
summary:

[3.12] Minor algebraic simplification for the totient() recipe (gh-113822) 
(gh-113823)

files:
M Doc/library/itertools.rst

diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst
index a0181612d5bb67..67dc8f6d875f68 100644
--- a/Doc/library/itertools.rst
+++ b/Doc/library/itertools.rst
@@ -1142,7 +1142,7 @@ The following recipes have a more mathematical flavor:
# https://mathworld.wolfram.com/TotientFunction.html
# totient(12) --> 4 because len([1, 5, 7, 11]) == 4
for p in unique_justseen(factor(n)):
-   n = n // p * (p - 1)
+   n -= n // p
return n
 
 

___
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]


[Python-checkins] gh-113688: fix dtrace build on Solaris (#113814)

2024-01-08 Thread gpshead
https://github.com/python/cpython/commit/bc71ae2b97bb59b1796be056fb821d9abdee840b
commit: bc71ae2b97bb59b1796be056fb821d9abdee840b
branch: main
author: Jakub Kulík 
committer: gpshead 
date: 2024-01-08T11:28:09-08:00
summary:

gh-113688: fix dtrace build on Solaris (#113814)

(the gcmodule -> gc refactoring broke it)

files:
M Makefile.pre.in

diff --git a/Makefile.pre.in b/Makefile.pre.in
index d3c43640fef5cd..abbd4b1b1fbd6c 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -547,7 +547,7 @@ LINK_PYTHON_OBJS=@LINK_PYTHON_OBJS@
 # On some systems, object files that reference DTrace probes need to be 
modified
 # in-place by dtrace(1).
 DTRACE_DEPS = \
-   Python/ceval.o Python/import.o Python/sysmodule.o Modules/gcmodule.o
+   Python/ceval.o Python/gc.o Python/import.o Python/sysmodule.o
 
 ##
 # decimal's libmpdec
@@ -1648,8 +1648,8 @@ Include/pydtrace_probes.h: $(srcdir)/Include/pydtrace.d
mv [email protected] $@
 
 Python/ceval.o: $(srcdir)/Include/pydtrace.h
+Python/gc.o: $(srcdir)/Include/pydtrace.h
 Python/import.o: $(srcdir)/Include/pydtrace.h
-Modules/gcmodule.o: $(srcdir)/Include/pydtrace.h
 
 Python/pydtrace.o: $(srcdir)/Include/pydtrace.d $(DTRACE_DEPS)
$(DTRACE) $(DFLAGS) -o $@ -G -s $< $(DTRACE_DEPS)

___
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]


[Python-checkins] GH-113528: Speed up pathlib ABC tests. (#113788)

2024-01-08 Thread barneygale
https://github.com/python/cpython/commit/b3dba18eab96dc95653031863bb2a222af912f2b
commit: b3dba18eab96dc95653031863bb2a222af912f2b
branch: main
author: Barney Gale 
committer: barneygale 
date: 2024-01-08T19:31:52Z
summary:

GH-113528: Speed up pathlib ABC tests. (#113788)

- Add `__slots__` to dummy path classes.
- Return namedtuple rather than `os.stat_result` from `DummyPath.stat()`.
- Reduce maximum symlink count in `DummyPathWithSymlinks.resolve()`.

files:
M Lib/pathlib/_abc.py
M Lib/test/test_pathlib/test_pathlib_abc.py

diff --git a/Lib/pathlib/_abc.py b/Lib/pathlib/_abc.py
index 97663b904c8915..be22ecef4d214e 100644
--- a/Lib/pathlib/_abc.py
+++ b/Lib/pathlib/_abc.py
@@ -10,9 +10,6 @@
 # Internals
 #
 
-# Maximum number of symlinks to follow in PathBase.resolve()
-_MAX_SYMLINKS = 40
-
 # Reference for Windows paths can be found at
 # https://learn.microsoft.com/en-gb/windows/win32/fileio/naming-a-file .
 _WIN_RESERVED_NAMES = frozenset(
@@ -500,6 +497,9 @@ class PathBase(PurePathBase):
 """
 __slots__ = ()
 
+# Maximum number of symlinks to follow in resolve()
+_max_symlinks = 40
+
 @classmethod
 def _unsupported(cls, method_name):
 msg = f"{cls.__name__}.{method_name}() is unsupported"
@@ -971,7 +971,7 @@ def resolve(self, strict=False):
 # Like Linux and macOS, raise OSError(errno.ELOOP) if 
too many symlinks are
 # encountered during resolution.
 link_count += 1
-if link_count >= _MAX_SYMLINKS:
+if link_count >= self._max_symlinks:
 raise OSError(ELOOP, "Too many symbolic links in 
path", str(self))
 target, target_parts = 
next_path.readlink()._split_stack()
 # If the symlink target is absolute (like 
'/etc/hosts'), set the current
diff --git a/Lib/test/test_pathlib/test_pathlib_abc.py 
b/Lib/test/test_pathlib/test_pathlib_abc.py
index f33d4973177fb2..b088be87141729 100644
--- a/Lib/test/test_pathlib/test_pathlib_abc.py
+++ b/Lib/test/test_pathlib/test_pathlib_abc.py
@@ -1,4 +1,4 @@
-import collections.abc
+import collections
 import io
 import os
 import errno
@@ -43,6 +43,8 @@ def test_pathmod(self):
 
 
 class DummyPurePath(PurePathBase):
+__slots__ = ()
+
 def __eq__(self, other):
 if not isinstance(other, DummyPurePath):
 return NotImplemented
@@ -660,11 +662,18 @@ def close(self):
 super().close()
 
 
+DummyPathStatResult = collections.namedtuple(
+'DummyPathStatResult',
+'st_mode st_ino st_dev st_nlink st_uid st_gid st_size st_atime st_mtime 
st_ctime')
+
+
 class DummyPath(PathBase):
 """
 Simple implementation of PathBase that keeps files and directories in
 memory.
 """
+__slots__ = ()
+
 _files = {}
 _directories = {}
 _symlinks = {}
@@ -693,7 +702,7 @@ def stat(self, *, follow_symlinks=True):
 st_mode = stat.S_IFLNK
 else:
 raise FileNotFoundError(errno.ENOENT, "Not found", str(self))
-return os.stat_result((st_mode, hash(str(self)), 0, 0, 0, 0, 0, 0, 0, 
0))
+return DummyPathStatResult(st_mode, hash(str(self)), 0, 0, 0, 0, 0, 0, 
0, 0)
 
 def open(self, mode='r', buffering=-1, encoding=None,
  errors=None, newline=None):
@@ -1728,6 +1737,11 @@ def test_walk_symlink_location(self):
 
 
 class DummyPathWithSymlinks(DummyPath):
+__slots__ = ()
+
+# Reduce symlink traversal limit to make tests run faster.
+_max_symlinks = 20
+
 def readlink(self):
 path = str(self.parent.resolve() / self.name)
 if path in self._symlinks:

___
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]


[Python-checkins] gh-113791: Expose CLOCK_MONOTONIC_RAW_APPROX and CLOCK_UPTIME_RAW_APROX on macOS in the time module (#113792)

2024-01-08 Thread ronaldoussoren
https://github.com/python/cpython/commit/c6ca562138a0916192f9c3100cae678c616aed29
commit: c6ca562138a0916192f9c3100cae678c616aed29
branch: main
author: Ronald Oussoren 
committer: ronaldoussoren 
date: 2024-01-08T20:44:00+01:00
summary:

gh-113791: Expose CLOCK_MONOTONIC_RAW_APPROX and CLOCK_UPTIME_RAW_APROX on 
macOS in the time module (#113792)

files:
A Misc/NEWS.d/next/Library/2024-01-07-11-45-56.gh-issue-113791.XF5xSW.rst
M Doc/library/time.rst
M Modules/timemodule.c

diff --git a/Doc/library/time.rst b/Doc/library/time.rst
index 577600881676b3..2782a961363666 100644
--- a/Doc/library/time.rst
+++ b/Doc/library/time.rst
@@ -840,6 +840,15 @@ These constants are used as parameters for 
:func:`clock_getres` and
 
.. versionadded:: 3.3
 
+.. data:: CLOCK_MONOTONIC_RAW_APPROX
+
+   Similar to :data:`CLOCK_MONOTONIC_RAW`, but reads a value cached by
+   the system at context switch and hence has less accuracy.
+
+   .. availability:: macOS >= 10.12.
+
+   .. versionadded:: 3.13
+
 
 .. data:: CLOCK_PROCESS_CPUTIME_ID
 
@@ -899,6 +908,15 @@ These constants are used as parameters for 
:func:`clock_getres` and
 
.. versionadded:: 3.8
 
+.. data:: CLOCK_UPTIME_RAW_APPROX
+
+   Like :data:`CLOCK_UPTIME_RAW`, but the value is cached by the system
+   at context switches and therefore has less accuracy.
+
+   .. availability:: macOS >= 10.12.
+
+   .. versionadded:: 3.13
+
 The following constant is the only parameter that can be sent to
 :func:`clock_settime`.
 
diff --git 
a/Misc/NEWS.d/next/Library/2024-01-07-11-45-56.gh-issue-113791.XF5xSW.rst 
b/Misc/NEWS.d/next/Library/2024-01-07-11-45-56.gh-issue-113791.XF5xSW.rst
new file mode 100644
index 00..16e77269813560
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-01-07-11-45-56.gh-issue-113791.XF5xSW.rst
@@ -0,0 +1,2 @@
+Add ``CLOCK_MONOTONIC_RAW_APPROX`` and ``CLOCK_UPTIME_RAW_APPROX`` to
+:mod:`time` on macOS. These are clocks available on macOS 10.12 or later.
diff --git a/Modules/timemodule.c b/Modules/timemodule.c
index b3fe175d9b184a..2b0d3900dbddd6 100644
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -1993,20 +1993,16 @@ time_exec(PyObject *module)
 return -1;
 }
 #endif
-
 #ifdef CLOCK_MONOTONIC
-
 if (PyModule_AddIntMacro(module, CLOCK_MONOTONIC) < 0) {
 return -1;
 }
-
 #endif
 #ifdef CLOCK_MONOTONIC_RAW
 if (PyModule_AddIntMacro(module, CLOCK_MONOTONIC_RAW) < 0) {
 return -1;
 }
 #endif
-
 #ifdef CLOCK_HIGHRES
 if (PyModule_AddIntMacro(module, CLOCK_HIGHRES) < 0) {
 return -1;
@@ -2017,7 +2013,6 @@ time_exec(PyObject *module)
 return -1;
 }
 #endif
-
 #ifdef CLOCK_THREAD_CPUTIME_ID
 if (PyModule_AddIntMacro(module, CLOCK_THREAD_CPUTIME_ID) < 0) {
 return -1;
@@ -2044,10 +2039,19 @@ time_exec(PyObject *module)
 }
 #endif
 #ifdef CLOCK_UPTIME_RAW
-
 if (PyModule_AddIntMacro(module, CLOCK_UPTIME_RAW) < 0) {
 return -1;
 }
+#endif
+#ifdef CLOCK_MONOTONIC_RAW_APPROX
+if (PyModule_AddIntMacro(module, CLOCK_MONOTONIC_RAW_APPROX) < 0) {
+return -1;
+}
+#endif
+#ifdef CLOCK_UPTIME_RAW_APPROX
+if (PyModule_AddIntMacro(module, CLOCK_UPTIME_RAW_APPROX) < 0) {
+return -1;
+}
 #endif
 }
 

___
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]


[Python-checkins] GH-111693: Propagate correct asyncio.CancelledError instance out of asyncio.Condition.wait() (#111694)

2024-01-08 Thread gvanrossum
https://github.com/python/cpython/commit/52161781a6134a4b846500ad68004fe9027a233c
commit: 52161781a6134a4b846500ad68004fe9027a233c
branch: main
author: Kristján Valur Jónsson 
committer: gvanrossum 
date: 2024-01-08T11:57:48-08:00
summary:

GH-111693: Propagate correct asyncio.CancelledError instance out of 
asyncio.Condition.wait() (#111694)

Also fix a race condition in `asyncio.Semaphore.acquire()` when cancelled.

files:
A Misc/NEWS.d/next/Library/2024-01-07-13-36-03.gh-issue-111693.xN2LuL.rst
M Lib/asyncio/futures.py
M Lib/asyncio/locks.py
M Lib/test/test_asyncio/test_locks.py

diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py
index 97fc4e3fcb60ee..d19e5d8c9194fd 100644
--- a/Lib/asyncio/futures.py
+++ b/Lib/asyncio/futures.py
@@ -138,9 +138,6 @@ def _make_cancelled_error(self):
 exc = exceptions.CancelledError()
 else:
 exc = exceptions.CancelledError(self._cancel_message)
-exc.__context__ = self._cancelled_exc
-# Remove the reference since we don't need this anymore.
-self._cancelled_exc = None
 return exc
 
 def cancel(self, msg=None):
diff --git a/Lib/asyncio/locks.py b/Lib/asyncio/locks.py
index ce5d8d5bfb2e81..04158e667a895f 100644
--- a/Lib/asyncio/locks.py
+++ b/Lib/asyncio/locks.py
@@ -95,6 +95,8 @@ async def acquire(self):
 This method blocks until the lock is unlocked, then sets it to
 locked and returns True.
 """
+# Implement fair scheduling, where thread always waits
+# its turn. Jumping the queue if all are cancelled is an optimization.
 if (not self._locked and (self._waiters is None or
 all(w.cancelled() for w in self._waiters))):
 self._locked = True
@@ -105,19 +107,22 @@ async def acquire(self):
 fut = self._get_loop().create_future()
 self._waiters.append(fut)
 
-# Finally block should be called before the CancelledError
-# handling as we don't want CancelledError to call
-# _wake_up_first() and attempt to wake up itself.
 try:
 try:
 await fut
 finally:
 self._waiters.remove(fut)
 except exceptions.CancelledError:
+# Currently the only exception designed be able to occur here.
+
+# Ensure the lock invariant: If lock is not claimed (or about
+# to be claimed by us) and there is a Task in waiters,
+# ensure that the Task at the head will run.
 if not self._locked:
 self._wake_up_first()
 raise
 
+# assert self._locked is False
 self._locked = True
 return True
 
@@ -139,7 +144,7 @@ def release(self):
 raise RuntimeError('Lock is not acquired.')
 
 def _wake_up_first(self):
-"""Wake up the first waiter if it isn't done."""
+"""Ensure that the first waiter will wake up."""
 if not self._waiters:
 return
 try:
@@ -147,9 +152,7 @@ def _wake_up_first(self):
 except StopIteration:
 return
 
-# .done() necessarily means that a waiter will wake up later on and
-# either take the lock, or, if it was cancelled and lock wasn't
-# taken already, will hit this again and wake up a new waiter.
+# .done() means that the waiter is already set to wake up.
 if not fut.done():
 fut.set_result(True)
 
@@ -269,17 +272,22 @@ async def wait(self):
 self._waiters.remove(fut)
 
 finally:
-# Must reacquire lock even if wait is cancelled
-cancelled = False
+# Must re-acquire lock even if wait is cancelled.
+# We only catch CancelledError here, since we don't want any
+# other (fatal) errors with the future to cause us to spin.
+err = None
 while True:
 try:
 await self.acquire()
 break
-except exceptions.CancelledError:
-cancelled = True
+except exceptions.CancelledError as e:
+err = e
 
-if cancelled:
-raise exceptions.CancelledError
+if err:
+try:
+raise err  # Re-raise most recent exception instance.
+finally:
+err = None  # Break reference cycles.
 
 async def wait_for(self, predicate):
 """Wait until a predicate becomes true.
@@ -357,6 +365,7 @@ def __repr__(self):
 
 def locked(self):
 """Returns True if semaphore cannot be acquired immediately."""
+# Due to state, or FIFO rules (must allow others to run first).
 return self._value == 0 or (
 any(not w.cancelled() for w in (self._waiters or (
 
@@ -370,6 +379,7 @@ async def acquire(self):
 True.
 """
 if not self.locked():
+ 

[Python-checkins] gh-113827: Move Windows frozen modules directory to allow PGO builds (GH-113828)

2024-01-08 Thread zooba
https://github.com/python/cpython/commit/92f96240d713a5a36c54515e5b3cd0947163
commit: 92f96240d713a5a36c54515e5b3cd0947163
branch: main
author: Steve Dower 
committer: zooba 
date: 2024-01-08T21:51:39Z
summary:

gh-113827: Move Windows frozen modules directory to allow PGO builds (GH-113828)

files:
M PCbuild/pyproject.props

diff --git a/PCbuild/pyproject.props b/PCbuild/pyproject.props
index d69b43b0406ce0..06c695783ced12 100644
--- a/PCbuild/pyproject.props
+++ b/PCbuild/pyproject.props
@@ -12,7 +12,7 @@
 $(IntDir.Replace(`\\`, `\`))
 
 
$(Py_IntDir)\$(MajorVersionNumber)$(MinorVersionNumber)$(ArchName)_$(Configuration)\pythoncore\
-
$(Py_IntDir)\$(MajorVersionNumber)$(MinorVersionNumber)_frozen_$(Configuration)\
+
$(Py_IntDir)\$(MajorVersionNumber)$(MinorVersionNumber)_frozen\
 $(ProjectName)
 $(TargetName)$(PyDebugExt)
 false

___
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]


[Python-checkins] gh-113027: Fix test_variable_tzname in test_email (#113821)

2024-01-08 Thread pablogsal
https://github.com/python/cpython/commit/931d7e052e22aa01e18fcc67ed71b6ea305aff71
commit: 931d7e052e22aa01e18fcc67ed71b6ea305aff71
branch: main
author: Serhiy Storchaka 
committer: pablogsal 
date: 2024-01-08T22:33:53Z
summary:

gh-113027: Fix test_variable_tzname in test_email (#113821)

Determine the support of the Kyiv timezone by checking the result of
astimezone() which uses the system tz database and not the one
populated by zoneinfo.

files:
M Lib/test/test_email/test_utils.py

diff --git a/Lib/test/test_email/test_utils.py 
b/Lib/test/test_email/test_utils.py
index c9d973df0a2192..0f1c3a84e61abd 100644
--- a/Lib/test/test_email/test_utils.py
+++ b/Lib/test/test_email/test_utils.py
@@ -143,12 +143,12 @@ def test_localtime_epoch_notz_daylight_false(self):
 t2 = utils.localtime(t0.replace(tzinfo=None))
 self.assertEqual(t1, t2)
 
[email protected]("Europe/Kyiv" in zoneinfo.available_timezones(),
- "Can't find a Kyiv timezone database")
 @test.support.run_with_tz('Europe/Kyiv')
 def test_variable_tzname(self):
 t0 = datetime.datetime(1984, 1, 1, tzinfo=datetime.timezone.utc)
 t1 = utils.localtime(t0)
+if t1.tzname() == 'Europe':
+self.skipTest("Can't find a Kyiv timezone database")
 self.assertEqual(t1.tzname(), 'MSK')
 t0 = datetime.datetime(1994, 1, 1, tzinfo=datetime.timezone.utc)
 t1 = utils.localtime(t0)

___
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]


[Python-checkins] readme: fix displaying issue of command (#113719)

2024-01-08 Thread willingc
https://github.com/python/cpython/commit/0b2340263172ad0fdd95aed6266496b7f4db4de3
commit: 0b2340263172ad0fdd95aed6266496b7f4db4de3
branch: main
author: mara004 
committer: willingc 
date: 2024-01-08T15:42:56-08:00
summary:

readme: fix displaying issue of command (#113719)

Avoid line break in command as this causes displaying issues on GH.

files:
M README.rst

diff --git a/README.rst b/README.rst
index 4c8602c97ac8ef..9343c830ce1f0f 100644
--- a/README.rst
+++ b/README.rst
@@ -206,8 +206,8 @@ directories installed using ``make altinstall`` contain the 
major and minor
 version and can thus live side-by-side.  ``make install`` also creates
 ``${prefix}/bin/python3`` which refers to ``${prefix}/bin/python3.X``.  If you
 intend to install multiple versions using the same prefix you must decide which
-version (if any) is your "primary" version.  Install that version using ``make
-install``.  Install all other versions using ``make altinstall``.
+version (if any) is your "primary" version.  Install that version using
+``make install``.  Install all other versions using ``make altinstall``.
 
 For example, if you want to install Python 2.7, 3.6, and 3.13 with 3.13 being 
the
 primary version, you would execute ``make install`` in your 3.13 build 
directory

___
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]


[Python-checkins] gh-112806: Remove unused function warnings during mimalloc build on Solaris (#112807)

2024-01-08 Thread DinoV
https://github.com/python/cpython/commit/ae968d10326165b1114568ab1ca0a7776ea9c234
commit: ae968d10326165b1114568ab1ca0a7776ea9c234
branch: main
author: Jakub Kulík 
committer: DinoV 
date: 2024-01-08T15:49:33-08:00
summary:

gh-112806: Remove unused function warnings during mimalloc build on Solaris 
(#112807)

files:
M Objects/mimalloc/prim/unix/prim.c

diff --git a/Objects/mimalloc/prim/unix/prim.c 
b/Objects/mimalloc/prim/unix/prim.c
index 2152017e01fb43..bf324e3f626679 100644
--- a/Objects/mimalloc/prim/unix/prim.c
+++ b/Objects/mimalloc/prim/unix/prim.c
@@ -50,7 +50,7 @@ terms of the MIT license. A copy of the license can be found 
in the file
   #include 
 #endif
 
-#if !defined(__HAIKU__) && !defined(__APPLE__) && !defined(__CYGWIN__) && 
!defined(_AIX) && !defined(__FreeBSD__)
+#if !defined(__HAIKU__) && !defined(__APPLE__) && !defined(__CYGWIN__) && 
!defined(_AIX) && !defined(__FreeBSD__) && !defined(__sun)
   #define MI_HAS_SYSCALL_H
   #include 
 #endif
@@ -76,7 +76,7 @@ static int mi_prim_access(const char *fpath, int mode) {
   return syscall(SYS_access,fpath,mode);
 }
 
-#elif !defined(__APPLE__) && !defined(_AIX) && !defined(__FreeBSD__) // avoid 
unused warnings
+#elif !defined(__APPLE__) && !defined(_AIX) && !defined(__FreeBSD__) && 
!defined(__sun) // avoid unused warnings
 
 static int mi_prim_open(const char* fpath, int open_flags) {
   return open(fpath,open_flags);

___
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]


[Python-checkins] gh-112808: Fix mimalloc build on Solaris (#112809)

2024-01-08 Thread DinoV
https://github.com/python/cpython/commit/10d3f04aec745c6676ef31611549b970a78338b3
commit: 10d3f04aec745c6676ef31611549b970a78338b3
branch: main
author: Jakub Kulík 
committer: DinoV 
date: 2024-01-08T15:50:56-08:00
summary:

gh-112808: Fix mimalloc build on Solaris (#112809)

files:
M Objects/mimalloc/prim/unix/prim.c

diff --git a/Objects/mimalloc/prim/unix/prim.c 
b/Objects/mimalloc/prim/unix/prim.c
index bf324e3f626679..ec8447ab40d70c 100644
--- a/Objects/mimalloc/prim/unix/prim.c
+++ b/Objects/mimalloc/prim/unix/prim.c
@@ -310,7 +310,7 @@ static void* unix_mmap(void* addr, size_t size, size_t 
try_alignment, int protec
   #elif defined(__sun)
   if (allow_large && _mi_os_use_large_page(size, try_alignment)) {
 struct memcntl_mha cmd = {0};
-cmd.mha_pagesize = large_os_page_size;
+cmd.mha_pagesize = 2*MI_MiB;
 cmd.mha_cmd = MHA_MAPSIZE_VA;
 if (memcntl((caddr_t)p, size, MC_HAT_ADVISE, (caddr_t)&cmd, 0, 0) == 
0) {
   *is_large = true;

___
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]


[Python-checkins] gh-112087: Update list.{pop,clear,reverse,remove} to use CS (gh-113764)

2024-01-08 Thread corona10
https://github.com/python/cpython/commit/a023bc252dc744736bd21897c5a23a25b800df92
commit: a023bc252dc744736bd21897c5a23a25b800df92
branch: main
author: Donghee Na 
committer: corona10 
date: 2024-01-09T09:00:55+09:00
summary:

gh-112087: Update list.{pop,clear,reverse,remove} to use CS (gh-113764)

files:
M Objects/clinic/listobject.c.h
M Objects/listobject.c

diff --git a/Objects/clinic/listobject.c.h b/Objects/clinic/listobject.c.h
index 54e6060451f3ff..cf6f7449df5e1d 100644
--- a/Objects/clinic/listobject.c.h
+++ b/Objects/clinic/listobject.c.h
@@ -7,6 +7,7 @@ preserve
 #  include "pycore_runtime.h" // _Py_ID()
 #endif
 #include "pycore_abstract.h"  // _PyNumber_Index()
+#include "pycore_critical_section.h"// Py_BEGIN_CRITICAL_SECTION()
 #include "pycore_modsupport.h"// _PyArg_CheckPositional()
 
 PyDoc_STRVAR(list_insert__doc__,
@@ -44,7 +45,9 @@ list_insert(PyListObject *self, PyObject *const *args, 
Py_ssize_t nargs)
 index = ival;
 }
 object = args[1];
+Py_BEGIN_CRITICAL_SECTION(self);
 return_value = list_insert_impl(self, index, object);
+Py_END_CRITICAL_SECTION();
 
 exit:
 return return_value;
@@ -65,7 +68,13 @@ py_list_clear_impl(PyListObject *self);
 static PyObject *
 py_list_clear(PyListObject *self, PyObject *Py_UNUSED(ignored))
 {
-return py_list_clear_impl(self);
+PyObject *return_value = NULL;
+
+Py_BEGIN_CRITICAL_SECTION(self);
+return_value = py_list_clear_impl(self);
+Py_END_CRITICAL_SECTION();
+
+return return_value;
 }
 
 PyDoc_STRVAR(list_copy__doc__,
@@ -143,7 +152,9 @@ list_pop(PyListObject *self, PyObject *const *args, 
Py_ssize_t nargs)
 index = ival;
 }
 skip_optional:
+Py_BEGIN_CRITICAL_SECTION(self);
 return_value = list_pop_impl(self, index);
+Py_END_CRITICAL_SECTION();
 
 exit:
 return return_value;
@@ -242,7 +253,13 @@ list_reverse_impl(PyListObject *self);
 static PyObject *
 list_reverse(PyListObject *self, PyObject *Py_UNUSED(ignored))
 {
-return list_reverse_impl(self);
+PyObject *return_value = NULL;
+
+Py_BEGIN_CRITICAL_SECTION(self);
+return_value = list_reverse_impl(self);
+Py_END_CRITICAL_SECTION();
+
+return return_value;
 }
 
 PyDoc_STRVAR(list_index__doc__,
@@ -311,6 +328,21 @@ PyDoc_STRVAR(list_remove__doc__,
 #define LIST_REMOVE_METHODDEF\
 {"remove", (PyCFunction)list_remove, METH_O, list_remove__doc__},
 
+static PyObject *
+list_remove_impl(PyListObject *self, PyObject *value);
+
+static PyObject *
+list_remove(PyListObject *self, PyObject *value)
+{
+PyObject *return_value = NULL;
+
+Py_BEGIN_CRITICAL_SECTION(self);
+return_value = list_remove_impl(self, value);
+Py_END_CRITICAL_SECTION();
+
+return return_value;
+}
+
 PyDoc_STRVAR(list___initdoc__,
 "list(iterable=(), /)\n"
 "--\n"
@@ -384,4 +416,4 @@ list___reversed__(PyListObject *self, PyObject 
*Py_UNUSED(ignored))
 {
 return list___reversed___impl(self);
 }
-/*[clinic end generated code: output=f2d7b63119464ff4 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=3c9f24fd3212b18b input=a9049054013a1b77]*/
diff --git a/Objects/listobject.c b/Objects/listobject.c
index dfb8cd2b106511..5cd4a059c668ba 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -798,6 +798,7 @@ list_ass_item(PyObject *aa, Py_ssize_t i, PyObject *v)
 }
 
 /*[clinic input]
+@critical_section
 list.insert
 
 index: Py_ssize_t
@@ -809,7 +810,7 @@ Insert object before index.
 
 static PyObject *
 list_insert_impl(PyListObject *self, Py_ssize_t index, PyObject *object)
-/*[clinic end generated code: output=7f35e32f60c8cb78 input=858514cf894c7eab]*/
+/*[clinic end generated code: output=7f35e32f60c8cb78 input=b1987ca998a4ae2d]*/
 {
 if (ins1(self, index, object) == 0)
 Py_RETURN_NONE;
@@ -817,6 +818,7 @@ list_insert_impl(PyListObject *self, Py_ssize_t index, 
PyObject *object)
 }
 
 /*[clinic input]
+@critical_section
 list.clear as py_list_clear
 
 Remove all items from list.
@@ -824,7 +826,7 @@ Remove all items from list.
 
 static PyObject *
 py_list_clear_impl(PyListObject *self)
-/*[clinic end generated code: output=83726743807e3518 input=378711e10f545c53]*/
+/*[clinic end generated code: output=83726743807e3518 input=e285b7f09051a9ba]*/
 {
 list_clear(self);
 Py_RETURN_NONE;
@@ -1062,6 +1064,7 @@ list_inplace_concat(PyObject *_self, PyObject *other)
 }
 
 /*[clinic input]
+@critical_section
 list.pop
 
 index: Py_ssize_t = -1
@@ -1074,7 +1077,7 @@ Raises IndexError if list is empty or index is out of 
range.
 
 static PyObject *
 list_pop_impl(PyListObject *self, Py_ssize_t index)
-/*[clinic end generated code: output=6bd69dcb3f17eca8 input=b83675976f329e6f]*/
+/*[clinic end generated code: output=6bd69dcb3f17eca8 input=c269141068ae4b8f]*/
 {
 PyObject *v;
 int status;
@@ -2593,6 +2596,7 @@ PyList_Sort(PyObject *v)
 }
 
 /*[clinic input]
+@critical_section
 list.reverse
 
 Reverse *IN PLACE*.
@@ -2600,7 +2604,7 @@ Rev

[Python-checkins] Docs: Link tokens in the format string grammars (#108184)

2024-01-08 Thread AA-Turner
https://github.com/python/cpython/commit/f3d5d4aa8f0388217aeff69e28d078bdda464b38
commit: f3d5d4aa8f0388217aeff69e28d078bdda464b38
branch: main
author: William Andrea 
committer: AA-Turner <[email protected]>
date: 2024-01-09T02:47:59Z
summary:

Docs: Link tokens in the format string grammars (#108184)

Co-authored-by: Adam Turner <[email protected]>
Co-authored-by: Sergey B Kirpichev 

files:
M Doc/library/string.rst
M Doc/tools/.nitignore
M Doc/tools/extensions/pyspecific.py

diff --git a/Doc/library/string.rst b/Doc/library/string.rst
index 262b785bbcbfc1..1867678b2077fc 100644
--- a/Doc/library/string.rst
+++ b/Doc/library/string.rst
@@ -208,13 +208,13 @@ The grammar for a replacement field is as follows:
 
 .. productionlist:: format-string
replacement_field: "{" [`field_name`] ["!" `conversion`] [":" 
`format_spec`] "}"
-   field_name: arg_name ("." `attribute_name` | "[" `element_index` "]")*
-   arg_name: [`identifier` | `digit`+]
-   attribute_name: `identifier`
-   element_index: `digit`+ | `index_string`
+   field_name: `arg_name` ("." `attribute_name` | "[" `element_index` "]")*
+   arg_name: [`~python-grammar:identifier` | `~python-grammar:digit`+]
+   attribute_name: `~python-grammar:identifier`
+   element_index: `~python-grammar:digit`+ | `index_string`
index_string:  +
conversion: "r" | "s" | "a"
-   format_spec: 
+   format_spec: `format-spec:format_spec`
 
 In less formal terms, the replacement field can start with a *field_name* that 
specifies
 the object whose value is to be formatted and inserted
@@ -316,9 +316,9 @@ The general form of a *standard format specifier* is:
fill: 
align: "<" | ">" | "=" | "^"
sign: "+" | "-" | " "
-   width: `digit`+
+   width: `~python-grammar:digit`+
grouping_option: "_" | ","
-   precision: `digit`+
+   precision: `~python-grammar:digit`+
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*
diff --git a/Doc/tools/.nitignore b/Doc/tools/.nitignore
index c4f9b07dc916c9..d80af40bbdca4c 100644
--- a/Doc/tools/.nitignore
+++ b/Doc/tools/.nitignore
@@ -77,7 +77,6 @@ Doc/library/smtplib.rst
 Doc/library/socket.rst
 Doc/library/ssl.rst
 Doc/library/stdtypes.rst
-Doc/library/string.rst
 Doc/library/subprocess.rst
 Doc/library/termios.rst
 Doc/library/test.rst
diff --git a/Doc/tools/extensions/pyspecific.py 
b/Doc/tools/extensions/pyspecific.py
index 31c2544caf601c..cd441836f62bde 100644
--- a/Doc/tools/extensions/pyspecific.py
+++ b/Doc/tools/extensions/pyspecific.py
@@ -48,6 +48,11 @@
 Body.enum.converters['lowerroman'] = \
 Body.enum.converters['upperroman'] = lambda x: None
 
+# monkey-patch the productionlist directive to allow hyphens in group names
+# https://github.com/sphinx-doc/sphinx/issues/11854
+from sphinx.domains import std
+
+std.token_re = re.compile(r'`((~?[\w-]*:)?\w+)`')
 
 # Support for marking up and linking to bugs.python.org issues
 

___
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]


[Python-checkins] [3.11] Docs: Link tokens in the format string grammars (GH-108184) (#113840)

2024-01-08 Thread AA-Turner
https://github.com/python/cpython/commit/3958c7d712b2cb32cb649eee7391d8a431a9cfa9
commit: 3958c7d712b2cb32cb649eee7391d8a431a9cfa9
branch: 3.11
author: Miss Islington (bot) <[email protected]>
committer: AA-Turner <[email protected]>
date: 2024-01-09T02:53:59Z
summary:

[3.11] Docs: Link tokens in the format string grammars (GH-108184) (#113840)

Docs: Link tokens in the format string grammars (GH-108184)
(cherry picked from commit f3d5d4aa8f0388217aeff69e28d078bdda464b38)

Co-authored-by: William Andrea 
Co-authored-by: Adam Turner <[email protected]>
Co-authored-by: Sergey B Kirpichev 

files:
M Doc/library/string.rst
M Doc/tools/.nitignore
M Doc/tools/extensions/pyspecific.py

diff --git a/Doc/library/string.rst b/Doc/library/string.rst
index 5fbd82a5ec852e..5fe9d920606f5a 100644
--- a/Doc/library/string.rst
+++ b/Doc/library/string.rst
@@ -208,13 +208,13 @@ The grammar for a replacement field is as follows:
 
 .. productionlist:: format-string
replacement_field: "{" [`field_name`] ["!" `conversion`] [":" 
`format_spec`] "}"
-   field_name: arg_name ("." `attribute_name` | "[" `element_index` "]")*
-   arg_name: [`identifier` | `digit`+]
-   attribute_name: `identifier`
-   element_index: `digit`+ | `index_string`
+   field_name: `arg_name` ("." `attribute_name` | "[" `element_index` "]")*
+   arg_name: [`~python-grammar:identifier` | `~python-grammar:digit`+]
+   attribute_name: `~python-grammar:identifier`
+   element_index: `~python-grammar:digit`+ | `index_string`
index_string:  +
conversion: "r" | "s" | "a"
-   format_spec: 
+   format_spec: `format-spec:format_spec`
 
 In less formal terms, the replacement field can start with a *field_name* that 
specifies
 the object whose value is to be formatted and inserted
@@ -316,9 +316,9 @@ The general form of a *standard format specifier* is:
fill: 
align: "<" | ">" | "=" | "^"
sign: "+" | "-" | " "
-   width: `digit`+
+   width: `~python-grammar:digit`+
grouping_option: "_" | ","
-   precision: `digit`+
+   precision: `~python-grammar:digit`+
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*
diff --git a/Doc/tools/.nitignore b/Doc/tools/.nitignore
index 69e00cb8770fa3..0d0d07011f551f 100644
--- a/Doc/tools/.nitignore
+++ b/Doc/tools/.nitignore
@@ -80,7 +80,6 @@ Doc/library/smtplib.rst
 Doc/library/socket.rst
 Doc/library/ssl.rst
 Doc/library/stdtypes.rst
-Doc/library/string.rst
 Doc/library/subprocess.rst
 Doc/library/syslog.rst
 Doc/library/termios.rst
diff --git a/Doc/tools/extensions/pyspecific.py 
b/Doc/tools/extensions/pyspecific.py
index 31c42e9d9d3a63..c849a4d3875029 100644
--- a/Doc/tools/extensions/pyspecific.py
+++ b/Doc/tools/extensions/pyspecific.py
@@ -53,6 +53,11 @@
 Body.enum.converters['lowerroman'] = \
 Body.enum.converters['upperroman'] = lambda x: None
 
+# monkey-patch the productionlist directive to allow hyphens in group names
+# https://github.com/sphinx-doc/sphinx/issues/11854
+from sphinx.domains import std
+
+std.token_re = re.compile(r'`((~?[\w-]*:)?\w+)`')
 
 # Support for marking up and linking to bugs.python.org issues
 

___
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]


[Python-checkins] [3.12] Docs: Link tokens in the format string grammars (GH-108184) (#113839)

2024-01-08 Thread AA-Turner
https://github.com/python/cpython/commit/cd87737a1de9a3b766358912985ffae511c3911d
commit: cd87737a1de9a3b766358912985ffae511c3911d
branch: 3.12
author: Miss Islington (bot) <[email protected]>
committer: AA-Turner <[email protected]>
date: 2024-01-09T02:54:07Z
summary:

[3.12] Docs: Link tokens in the format string grammars (GH-108184) (#113839)

Docs: Link tokens in the format string grammars (GH-108184)
(cherry picked from commit f3d5d4aa8f0388217aeff69e28d078bdda464b38)

Co-authored-by: William Andrea 
Co-authored-by: Adam Turner <[email protected]>
Co-authored-by: Sergey B Kirpichev 

files:
M Doc/library/string.rst
M Doc/tools/.nitignore
M Doc/tools/extensions/pyspecific.py

diff --git a/Doc/library/string.rst b/Doc/library/string.rst
index 262b785bbcbfc1..1867678b2077fc 100644
--- a/Doc/library/string.rst
+++ b/Doc/library/string.rst
@@ -208,13 +208,13 @@ The grammar for a replacement field is as follows:
 
 .. productionlist:: format-string
replacement_field: "{" [`field_name`] ["!" `conversion`] [":" 
`format_spec`] "}"
-   field_name: arg_name ("." `attribute_name` | "[" `element_index` "]")*
-   arg_name: [`identifier` | `digit`+]
-   attribute_name: `identifier`
-   element_index: `digit`+ | `index_string`
+   field_name: `arg_name` ("." `attribute_name` | "[" `element_index` "]")*
+   arg_name: [`~python-grammar:identifier` | `~python-grammar:digit`+]
+   attribute_name: `~python-grammar:identifier`
+   element_index: `~python-grammar:digit`+ | `index_string`
index_string:  +
conversion: "r" | "s" | "a"
-   format_spec: 
+   format_spec: `format-spec:format_spec`
 
 In less formal terms, the replacement field can start with a *field_name* that 
specifies
 the object whose value is to be formatted and inserted
@@ -316,9 +316,9 @@ The general form of a *standard format specifier* is:
fill: 
align: "<" | ">" | "=" | "^"
sign: "+" | "-" | " "
-   width: `digit`+
+   width: `~python-grammar:digit`+
grouping_option: "_" | ","
-   precision: `digit`+
+   precision: `~python-grammar:digit`+
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*
diff --git a/Doc/tools/.nitignore b/Doc/tools/.nitignore
index fe83c25a1c683f..1d9f4f348a9ed5 100644
--- a/Doc/tools/.nitignore
+++ b/Doc/tools/.nitignore
@@ -88,7 +88,6 @@ Doc/library/smtplib.rst
 Doc/library/socket.rst
 Doc/library/ssl.rst
 Doc/library/stdtypes.rst
-Doc/library/string.rst
 Doc/library/subprocess.rst
 Doc/library/sunau.rst
 Doc/library/syslog.rst
diff --git a/Doc/tools/extensions/pyspecific.py 
b/Doc/tools/extensions/pyspecific.py
index cdb8cf85e20af0..c29846e6e707f4 100644
--- a/Doc/tools/extensions/pyspecific.py
+++ b/Doc/tools/extensions/pyspecific.py
@@ -48,6 +48,11 @@
 Body.enum.converters['lowerroman'] = \
 Body.enum.converters['upperroman'] = lambda x: None
 
+# monkey-patch the productionlist directive to allow hyphens in group names
+# https://github.com/sphinx-doc/sphinx/issues/11854
+from sphinx.domains import std
+
+std.token_re = re.compile(r'`((~?[\w-]*:)?\w+)`')
 
 # Support for marking up and linking to bugs.python.org issues
 

___
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]


[Python-checkins] gh-113692: skip a test if multiprocessing isn't available. (GH-113704)

2024-01-08 Thread vsajip
https://github.com/python/cpython/commit/842b738129021f52293dc053e014ecb4fe095baa
commit: 842b738129021f52293dc053e014ecb4fe095baa
branch: main
author: Vinay Sajip 
committer: vsajip 
date: 2024-01-09T07:47:42Z
summary:

gh-113692: skip a test if multiprocessing isn't available. (GH-113704)

files:
M Lib/test/test_logging.py

diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py
index 33db5d6443f6fd..0be26981184213 100644
--- a/Lib/test/test_logging.py
+++ b/Lib/test/test_logging.py
@@ -43,6 +43,7 @@
 import tempfile
 from test.support.script_helper import assert_python_ok, assert_python_failure
 from test import support
+from test.support import import_helper
 from test.support import os_helper
 from test.support import socket_helper
 from test.support import threading_helper
@@ -3924,7 +3925,8 @@ def test_90195(self):
 
 def test_111615(self):
 # See gh-111615
-import multiprocessing as mp
+import_helper.import_module('_multiprocessing')  # see gh-113692
+mp = import_helper.import_module('multiprocessing')
 
 config = {
 'version': 1,

___
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]