[Python-checkins] gh-73965: Move PYTHON_HISTORY into the correct usage section (#113798)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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]
