[Python-checkins] [3.12] gh-72284: Revise lists in IDLE doc (GH-114174) (#114175)

2024-01-17 Thread terryjreedy
https://github.com/python/cpython/commit/5af161ffe629dc142d46a48489259ca4a0166ac0
commit: 5af161ffe629dc142d46a48489259ca4a0166ac0
branch: 3.12
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: terryjreedy 
date: 2024-01-17T03:35:19-05:00
summary:

[3.12] gh-72284: Revise lists in IDLE doc  (GH-114174) (#114175)

Tkinter is a fact, not necessarily a feature.

Reorganize editor key bindings in a logical order
and remove those that do not work, at least on Windows.

Improve shell bindings list.
(cherry picked from commit 4a32275389d94ba41f8881c32ad4b232effb1c6f)

Co-authored-by: Terry Jan Reedy 

files:
A Misc/NEWS.d/next/IDLE/2024-01-17-02-15-33.gh-issue-72284.cAQiYO.rst
M Doc/library/idle.rst
M Lib/idlelib/News3.txt
M Lib/idlelib/help.html

diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst
index e710d0bacf3fee..249dc0ea6ba735 100644
--- a/Doc/library/idle.rst
+++ b/Doc/library/idle.rst
@@ -18,8 +18,6 @@ IDLE is Python's Integrated Development and Learning 
Environment.
 
 IDLE has the following features:
 
-* coded in 100% pure Python, using the :mod:`tkinter` GUI toolkit
-
 * cross-platform: works mostly the same on Windows, Unix, and macOS
 
 * Python shell window (interactive interpreter) with colorizing
@@ -422,41 +420,34 @@ and that other files do not.  Run Python code with the 
Run menu.
 Key bindings
 
 
-In this section, 'C' refers to the :kbd:`Control` key on Windows and Unix and
-the :kbd:`Command` key on macOS.
-
-* :kbd:`Backspace` deletes to the left; :kbd:`Del` deletes to the right
-
-* :kbd:`C-Backspace` delete word left; :kbd:`C-Del` delete word to the right
-
-* Arrow keys and :kbd:`Page Up`/:kbd:`Page Down` to move around
-
-* :kbd:`C-LeftArrow` and :kbd:`C-RightArrow` moves by words
+The IDLE insertion cursor is a thin vertical bar between character
+positions.  When characters are entered, the insertion cursor and
+everything to its right moves right one character and
+the new character is entered in the new space.
 
-* :kbd:`Home`/:kbd:`End` go to begin/end of line
+Several non-character keys move the cursor and possibly
+delete characters.  Deletion does not puts text on the clipboard,
+but IDLE has an undo list.  Wherever this doc discusses keys,
+'C' refers to the :kbd:`Control` key on Windows and
+Unix and the :kbd:`Command` key on macOS.  (And all such dicussions
+assume that the keys have not been re-bound to something else.)
 
-* :kbd:`C-Home`/:kbd:`C-End` go to begin/end of file
+* Arrow keys move the cursor one character or line.
 
-* Some useful Emacs bindings are inherited from Tcl/Tk:
+* :kbd:`C-LeftArrow` and :kbd:`C-RightArrow` moves left or right one word.
 
-  * :kbd:`C-a` beginning of line
+* :kbd:`Home` and :kbd:`End` go to the beginning or end of the line.
 
-  * :kbd:`C-e` end of line
+* :kbd:`Page Up` and :kbd:`Page Down` go up or down one screen.
 
-  * :kbd:`C-k` kill line (but doesn't put it in clipboard)
+* :kbd:`C-Home` and :kbd:`C-End` go to beginning or end of the file.
 
-  * :kbd:`C-l` center window around the insertion point
+* :kbd:`Backspace` and :kbd:`Del` (or :kbd:`C-d`) delete the previous
+  or next character.
 
-  * :kbd:`C-b` go backward one character without deleting (usually you can
-also use the cursor key for this)
+* :kbd:`C-Backspace` and :kbd:`C-Del` delete one word left or right.
 
-  * :kbd:`C-f` go forward one character without deleting (usually you can
-also use the cursor key for this)
-
-  * :kbd:`C-p` go up one line (usually you can also use the cursor key for
-this)
-
-  * :kbd:`C-d` delete next character
+* :kbd:`C-k` deletes ('kills') everything to the right.
 
 Standard keybindings (like :kbd:`C-c` to copy and :kbd:`C-v` to paste)
 may work.  Keybindings are selected in the Configure IDLE dialog.
@@ -611,23 +602,18 @@ when one requests a restart on the Shell menu, or when 
one runs code
 in an editor window.
 
 The editing features described in previous subsections work when entering
-code interactively.  IDLE's Shell window also responds to the following keys.
-
-* :kbd:`C-c` interrupts executing command
-
-* :kbd:`C-d` sends end-of-file; closes window if typed at a ``>>>`` prompt
-
-* :kbd:`Alt-/` (Expand word) is also useful to reduce typing
+code interactively.  IDLE's Shell window also responds to the following:
 
-  Command history
+* :kbd:`C-c` attemps to interrupt statement execution (but may fail).
 
-  * :kbd:`Alt-p` retrieves previous command matching what you have typed. On
-macOS use :kbd:`C-p`.
+* :kbd:`C-d` closes Shell if typed at a ``>>>`` prompt.
 
-  * :kbd:`Alt-n` retrieves next. On macOS use :kbd:`C-n`.
+* :kbd:`Alt-p` and :kbd:`Alt-n` (:kbd:`C-p` and :kbd:`C-n` on macOS)
+  retrieve to the current prompt the previous or next previously
+  entered statement that matches anything already typed.
 
-  * :kbd:`Return` while the cursor is on any previous command
-retrieves that command
+* :kbd:`Return` while the cursor is on any previo

[Python-checkins] [3.11] gh-72284: Revise lists in IDLE doc (GH-114174) (#114176)

2024-01-17 Thread terryjreedy
https://github.com/python/cpython/commit/8cb1b797fb78865b7b0fb26a6883f3251f1b0190
commit: 8cb1b797fb78865b7b0fb26a6883f3251f1b0190
branch: 3.11
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: terryjreedy 
date: 2024-01-17T03:35:35-05:00
summary:

[3.11] gh-72284: Revise lists in IDLE doc  (GH-114174) (#114176)

Tkinter is a fact, not necessarily a feature.

Reorganize editor key bindings in a logical order
and remove those that do not work, at least on Windows.

Improve shell bindings list.
(cherry picked from commit 4a32275389d94ba41f8881c32ad4b232effb1c6f)

Co-authored-by: Terry Jan Reedy 

files:
A Misc/NEWS.d/next/IDLE/2024-01-17-02-15-33.gh-issue-72284.cAQiYO.rst
M Doc/library/idle.rst
M Lib/idlelib/News3.txt
M Lib/idlelib/help.html

diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst
index e710d0bacf3fee..249dc0ea6ba735 100644
--- a/Doc/library/idle.rst
+++ b/Doc/library/idle.rst
@@ -18,8 +18,6 @@ IDLE is Python's Integrated Development and Learning 
Environment.
 
 IDLE has the following features:
 
-* coded in 100% pure Python, using the :mod:`tkinter` GUI toolkit
-
 * cross-platform: works mostly the same on Windows, Unix, and macOS
 
 * Python shell window (interactive interpreter) with colorizing
@@ -422,41 +420,34 @@ and that other files do not.  Run Python code with the 
Run menu.
 Key bindings
 
 
-In this section, 'C' refers to the :kbd:`Control` key on Windows and Unix and
-the :kbd:`Command` key on macOS.
-
-* :kbd:`Backspace` deletes to the left; :kbd:`Del` deletes to the right
-
-* :kbd:`C-Backspace` delete word left; :kbd:`C-Del` delete word to the right
-
-* Arrow keys and :kbd:`Page Up`/:kbd:`Page Down` to move around
-
-* :kbd:`C-LeftArrow` and :kbd:`C-RightArrow` moves by words
+The IDLE insertion cursor is a thin vertical bar between character
+positions.  When characters are entered, the insertion cursor and
+everything to its right moves right one character and
+the new character is entered in the new space.
 
-* :kbd:`Home`/:kbd:`End` go to begin/end of line
+Several non-character keys move the cursor and possibly
+delete characters.  Deletion does not puts text on the clipboard,
+but IDLE has an undo list.  Wherever this doc discusses keys,
+'C' refers to the :kbd:`Control` key on Windows and
+Unix and the :kbd:`Command` key on macOS.  (And all such dicussions
+assume that the keys have not been re-bound to something else.)
 
-* :kbd:`C-Home`/:kbd:`C-End` go to begin/end of file
+* Arrow keys move the cursor one character or line.
 
-* Some useful Emacs bindings are inherited from Tcl/Tk:
+* :kbd:`C-LeftArrow` and :kbd:`C-RightArrow` moves left or right one word.
 
-  * :kbd:`C-a` beginning of line
+* :kbd:`Home` and :kbd:`End` go to the beginning or end of the line.
 
-  * :kbd:`C-e` end of line
+* :kbd:`Page Up` and :kbd:`Page Down` go up or down one screen.
 
-  * :kbd:`C-k` kill line (but doesn't put it in clipboard)
+* :kbd:`C-Home` and :kbd:`C-End` go to beginning or end of the file.
 
-  * :kbd:`C-l` center window around the insertion point
+* :kbd:`Backspace` and :kbd:`Del` (or :kbd:`C-d`) delete the previous
+  or next character.
 
-  * :kbd:`C-b` go backward one character without deleting (usually you can
-also use the cursor key for this)
+* :kbd:`C-Backspace` and :kbd:`C-Del` delete one word left or right.
 
-  * :kbd:`C-f` go forward one character without deleting (usually you can
-also use the cursor key for this)
-
-  * :kbd:`C-p` go up one line (usually you can also use the cursor key for
-this)
-
-  * :kbd:`C-d` delete next character
+* :kbd:`C-k` deletes ('kills') everything to the right.
 
 Standard keybindings (like :kbd:`C-c` to copy and :kbd:`C-v` to paste)
 may work.  Keybindings are selected in the Configure IDLE dialog.
@@ -611,23 +602,18 @@ when one requests a restart on the Shell menu, or when 
one runs code
 in an editor window.
 
 The editing features described in previous subsections work when entering
-code interactively.  IDLE's Shell window also responds to the following keys.
-
-* :kbd:`C-c` interrupts executing command
-
-* :kbd:`C-d` sends end-of-file; closes window if typed at a ``>>>`` prompt
-
-* :kbd:`Alt-/` (Expand word) is also useful to reduce typing
+code interactively.  IDLE's Shell window also responds to the following:
 
-  Command history
+* :kbd:`C-c` attemps to interrupt statement execution (but may fail).
 
-  * :kbd:`Alt-p` retrieves previous command matching what you have typed. On
-macOS use :kbd:`C-p`.
+* :kbd:`C-d` closes Shell if typed at a ``>>>`` prompt.
 
-  * :kbd:`Alt-n` retrieves next. On macOS use :kbd:`C-n`.
+* :kbd:`Alt-p` and :kbd:`Alt-n` (:kbd:`C-p` and :kbd:`C-n` on macOS)
+  retrieve to the current prompt the previous or next previously
+  entered statement that matches anything already typed.
 
-  * :kbd:`Return` while the cursor is on any previous command
-retrieves that command
+* :kbd:`Return` while the cursor is on any previo

[Python-checkins] [3.12] gh-102468: Document `PyCFunction_New*` and `PyCMethod_New` (GH-112557) (GH-114119)

2024-01-17 Thread encukou
https://github.com/python/cpython/commit/27941b14ab9ecdb88fe2ced68b50fa428c2ea8f2
commit: 27941b14ab9ecdb88fe2ced68b50fa428c2ea8f2
branch: 3.12
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: encukou 
date: 2024-01-17T10:21:08+01:00
summary:

[3.12] gh-102468: Document `PyCFunction_New*` and `PyCMethod_New` (GH-112557) 
(GH-114119)

gh-102468: Document `PyCFunction_New*` and `PyCMethod_New` (GH-112557)
(cherry picked from commit a482bc67ee786e60937a547776fcf9528810e1ce)

Co-authored-by: AN Long 
Co-authored-by: Erlend E. Aasland 

files:
M Doc/c-api/structures.rst
M Doc/data/refcounts.dat

diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst
index 7d82f7839dfcd7..86c779472fd244 100644
--- a/Doc/c-api/structures.rst
+++ b/Doc/c-api/structures.rst
@@ -399,6 +399,40 @@ definition with the same method name.
slot.  This is helpful because calls to PyCFunctions are optimized more
than wrapper object calls.
 
+.. c:function:: PyObject * PyCMethod_New(PyMethodDef *ml, PyObject *self, 
PyObject *module, PyTypeObject *cls)
+
+   Turn *ml* into a Python :term:`callable` object.
+   The caller must ensure that *ml* outlives the :term:`callable`.
+   Typically, *ml* is defined as a static variable.
+
+   The *self* parameter will be passed as the *self* argument
+   to the C function in ``ml->ml_meth`` when invoked.
+   *self* can be ``NULL``.
+
+   The :term:`callable` object's ``__module__`` attribute
+   can be set from the given *module* argument.
+   *module* should be a Python string,
+   which will be used as name of the module the function is defined in.
+   If unavailable, it can be set to :const:`None` or ``NULL``.
+
+   .. seealso:: :attr:`function.__module__`
+
+   The *cls* parameter will be passed as the *defining_class*
+   argument to the C function.
+   Must be set if :c:macro:`METH_METHOD` is set on ``ml->ml_flags``.
+
+   .. versionadded:: 3.9
+
+
+.. c:function:: PyObject * PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, 
PyObject *module)
+
+   Equivalent to ``PyCMethod_New(ml, self, module, NULL)``.
+
+
+.. c:function:: PyObject * PyCFunction_New(PyMethodDef *ml, PyObject *self)
+
+   Equivalent to ``PyCMethod_New(ml, self, NULL, NULL)``.
+
 
 Accessing attributes of extension types
 ---
diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat
index 1571a33e3bfec2..b5d953247f3c46 100644
--- a/Doc/data/refcounts.dat
+++ b/Doc/data/refcounts.dat
@@ -402,6 +402,21 @@ PyContextVar_Reset:int:::
 PyContextVar_Reset:PyObject*:var:0:
 PyContextVar_Reset:PyObject*:token:-1:
 
+PyCFunction_New:PyObject*::+1:
+PyCFunction_New:PyMethodDef*:ml::
+PyCFunction_New:PyObject*:self:+1:
+
+PyCFunction_NewEx:PyObject*::+1:
+PyCFunction_NewEx:PyMethodDef*:ml::
+PyCFunction_NewEx:PyObject*:self:+1:
+PyCFunction_NewEx:PyObject*:module:+1:
+
+PyCMethod_New:PyObject*::+1:
+PyCMethod_New:PyMethodDef*:ml::
+PyCMethod_New:PyObject*:self:+1:
+PyCMethod_New:PyObject*:module:+1:
+PyCMethod_New:PyObject*:cls:+1:
+
 PyDate_Check:int:::
 PyDate_Check:PyObject*:ob:0:
 

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


[Python-checkins] [3.11] gh-102468: Document `PyCFunction_New*` and `PyCMethod_New` (GH-112557) (GH-114120)

2024-01-17 Thread encukou
https://github.com/python/cpython/commit/bda62c0b22f8266b515e9ebb64a6115947b9dd43
commit: bda62c0b22f8266b515e9ebb64a6115947b9dd43
branch: 3.11
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: encukou 
date: 2024-01-17T10:21:16+01:00
summary:

[3.11] gh-102468: Document `PyCFunction_New*` and `PyCMethod_New` (GH-112557) 
(GH-114120)

gh-102468: Document `PyCFunction_New*` and `PyCMethod_New` (GH-112557)
(cherry picked from commit a482bc67ee786e60937a547776fcf9528810e1ce)

Co-authored-by: AN Long 
Co-authored-by: Erlend E. Aasland 

files:
M Doc/c-api/structures.rst
M Doc/data/refcounts.dat

diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst
index 304cc31575b1dc..1d313545fc57be 100644
--- a/Doc/c-api/structures.rst
+++ b/Doc/c-api/structures.rst
@@ -418,6 +418,40 @@ definition with the same method name.
slot.  This is helpful because calls to PyCFunctions are optimized more
than wrapper object calls.
 
+.. c:function:: PyObject * PyCMethod_New(PyMethodDef *ml, PyObject *self, 
PyObject *module, PyTypeObject *cls)
+
+   Turn *ml* into a Python :term:`callable` object.
+   The caller must ensure that *ml* outlives the :term:`callable`.
+   Typically, *ml* is defined as a static variable.
+
+   The *self* parameter will be passed as the *self* argument
+   to the C function in ``ml->ml_meth`` when invoked.
+   *self* can be ``NULL``.
+
+   The :term:`callable` object's ``__module__`` attribute
+   can be set from the given *module* argument.
+   *module* should be a Python string,
+   which will be used as name of the module the function is defined in.
+   If unavailable, it can be set to :const:`None` or ``NULL``.
+
+   .. seealso:: :attr:`function.__module__`
+
+   The *cls* parameter will be passed as the *defining_class*
+   argument to the C function.
+   Must be set if :c:macro:`METH_METHOD` is set on ``ml->ml_flags``.
+
+   .. versionadded:: 3.9
+
+
+.. c:function:: PyObject * PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, 
PyObject *module)
+
+   Equivalent to ``PyCMethod_New(ml, self, module, NULL)``.
+
+
+.. c:function:: PyObject * PyCFunction_New(PyMethodDef *ml, PyObject *self)
+
+   Equivalent to ``PyCMethod_New(ml, self, NULL, NULL)``.
+
 
 Accessing attributes of extension types
 ---
diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat
index 3ba39fa00c3a00..0465668e8764e7 100644
--- a/Doc/data/refcounts.dat
+++ b/Doc/data/refcounts.dat
@@ -402,6 +402,21 @@ PyContextVar_Reset:int:::
 PyContextVar_Reset:PyObject*:var:0:
 PyContextVar_Reset:PyObject*:token:-1:
 
+PyCFunction_New:PyObject*::+1:
+PyCFunction_New:PyMethodDef*:ml::
+PyCFunction_New:PyObject*:self:+1:
+
+PyCFunction_NewEx:PyObject*::+1:
+PyCFunction_NewEx:PyMethodDef*:ml::
+PyCFunction_NewEx:PyObject*:self:+1:
+PyCFunction_NewEx:PyObject*:module:+1:
+
+PyCMethod_New:PyObject*::+1:
+PyCMethod_New:PyMethodDef*:ml::
+PyCMethod_New:PyObject*:self:+1:
+PyCMethod_New:PyObject*:module:+1:
+PyCMethod_New:PyObject*:cls:+1:
+
 PyDate_Check:int:::
 PyDate_Check:PyObject*:ob:0:
 

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


[Python-checkins] gh-86179: Skip test case that fails on POSIX with unversioned binary (GH-114136)

2024-01-17 Thread zooba
https://github.com/python/cpython/commit/b204c4beb44c1a9013f8da16984c9129374ed8c5
commit: b204c4beb44c1a9013f8da16984c9129374ed8c5
branch: main
author: Steve Dower 
committer: zooba 
date: 2024-01-17T11:33:59Z
summary:

gh-86179: Skip test case that fails on POSIX with unversioned binary (GH-114136)

files:
M Lib/test/test_venv.py

diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py
index 8ecb23ff384362..218e7560cff3f5 100644
--- a/Lib/test/test_venv.py
+++ b/Lib/test/test_venv.py
@@ -324,7 +324,8 @@ def test_sysconfig_symlinks(self):
 ('executable', self.envpy()),
 # Usually compare to sys.executable, but if we're running in our 
own
 # venv then we really need to compare to our base executable
-('_base_executable', sys._base_executable),
+# HACK: Test fails on POSIX with unversioned binary (PR gh-113033)
+#('_base_executable', sys._base_executable),
 ):
 with self.subTest(attr):
 cmd[2] = f'import sys; print(sys.{attr})'

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


[Python-checkins] gh-104282: Fix null pointer dereference in `lzma._decode_filter_properties` (GH-104283)

2024-01-17 Thread serhiy-storchaka
https://github.com/python/cpython/commit/0154405350c272833bd51f68138223655e142a37
commit: 0154405350c272833bd51f68138223655e142a37
branch: main
author: Radislav Chugunov <52372310+chgn...@users.noreply.github.com>
committer: serhiy-storchaka 
date: 2024-01-17T13:15:44Z
summary:

gh-104282: Fix null pointer dereference in `lzma._decode_filter_properties` 
(GH-104283)

files:
A Misc/NEWS.d/next/Library/2023-05-08-09-30-00.gh-issue-104282.h4c6Eb.rst
M Lib/test/test_lzma.py
M Modules/_lzmamodule.c

diff --git a/Lib/test/test_lzma.py b/Lib/test/test_lzma.py
index 13b200912f6abd..65e6488c5d7b10 100644
--- a/Lib/test/test_lzma.py
+++ b/Lib/test/test_lzma.py
@@ -1401,6 +1401,14 @@ def test__decode_filter_properties(self):
 self.assertEqual(filterspec["lc"], 3)
 self.assertEqual(filterspec["dict_size"], 8 << 20)
 
+# see gh-104282
+filters = [lzma.FILTER_X86, lzma.FILTER_POWERPC,
+   lzma.FILTER_IA64, lzma.FILTER_ARM,
+   lzma.FILTER_ARMTHUMB, lzma.FILTER_SPARC]
+for f in filters:
+filterspec = lzma._decode_filter_properties(f, b"")
+self.assertEqual(filterspec, {"id": f})
+
 def test_filter_properties_roundtrip(self):
 spec1 = lzma._decode_filter_properties(
 lzma.FILTER_LZMA1, b"]\x00\x00\x80\x00")
diff --git 
a/Misc/NEWS.d/next/Library/2023-05-08-09-30-00.gh-issue-104282.h4c6Eb.rst 
b/Misc/NEWS.d/next/Library/2023-05-08-09-30-00.gh-issue-104282.h4c6Eb.rst
new file mode 100644
index 00..569ce66a5b9d5f
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-05-08-09-30-00.gh-issue-104282.h4c6Eb.rst
@@ -0,0 +1,3 @@
+Fix null pointer dereference in :func:`lzma._decode_filter_properties`
+due to improper handling of BCJ filters with properties of zero length.
+Patch by Radislav Chugunov.
diff --git a/Modules/_lzmamodule.c b/Modules/_lzmamodule.c
index eb90c308d16d19..f6bfbfa62687b8 100644
--- a/Modules/_lzmamodule.c
+++ b/Modules/_lzmamodule.c
@@ -492,7 +492,9 @@ build_filter_spec(const lzma_filter *f)
 case LZMA_FILTER_ARMTHUMB:
 case LZMA_FILTER_SPARC: {
 lzma_options_bcj *options = f->options;
-ADD_FIELD(options, start_offset);
+if (options) {
+ADD_FIELD(options, start_offset);
+}
 break;
 }
 default:

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


[Python-checkins] [3.11] gh-104282: Fix null pointer dereference in `lzma._decode_filter_properties` (GH-104283) (GH-114182)

2024-01-17 Thread serhiy-storchaka
https://github.com/python/cpython/commit/76d0c4b6885365a08e840d99ab948ab2b7c4a34e
commit: 76d0c4b6885365a08e840d99ab948ab2b7c4a34e
branch: 3.11
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: serhiy-storchaka 
date: 2024-01-17T13:30:29Z
summary:

[3.11] gh-104282: Fix null pointer dereference in 
`lzma._decode_filter_properties` (GH-104283) (GH-114182)

(cherry picked from commit 0154405350c272833bd51f68138223655e142a37)

Co-authored-by: Radislav Chugunov <52372310+chgn...@users.noreply.github.com>

files:
A Misc/NEWS.d/next/Library/2023-05-08-09-30-00.gh-issue-104282.h4c6Eb.rst
M Lib/test/test_lzma.py
M Modules/_lzmamodule.c

diff --git a/Lib/test/test_lzma.py b/Lib/test/test_lzma.py
index 49042d7390b66d..d2ae133a41ff40 100644
--- a/Lib/test/test_lzma.py
+++ b/Lib/test/test_lzma.py
@@ -1409,6 +1409,14 @@ def test__decode_filter_properties(self):
 self.assertEqual(filterspec["lc"], 3)
 self.assertEqual(filterspec["dict_size"], 8 << 20)
 
+# see gh-104282
+filters = [lzma.FILTER_X86, lzma.FILTER_POWERPC,
+   lzma.FILTER_IA64, lzma.FILTER_ARM,
+   lzma.FILTER_ARMTHUMB, lzma.FILTER_SPARC]
+for f in filters:
+filterspec = lzma._decode_filter_properties(f, b"")
+self.assertEqual(filterspec, {"id": f})
+
 def test_filter_properties_roundtrip(self):
 spec1 = lzma._decode_filter_properties(
 lzma.FILTER_LZMA1, b"]\x00\x00\x80\x00")
diff --git 
a/Misc/NEWS.d/next/Library/2023-05-08-09-30-00.gh-issue-104282.h4c6Eb.rst 
b/Misc/NEWS.d/next/Library/2023-05-08-09-30-00.gh-issue-104282.h4c6Eb.rst
new file mode 100644
index 00..569ce66a5b9d5f
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-05-08-09-30-00.gh-issue-104282.h4c6Eb.rst
@@ -0,0 +1,3 @@
+Fix null pointer dereference in :func:`lzma._decode_filter_properties`
+due to improper handling of BCJ filters with properties of zero length.
+Patch by Radislav Chugunov.
diff --git a/Modules/_lzmamodule.c b/Modules/_lzmamodule.c
index b572d8cd909fd1..97453a28088131 100644
--- a/Modules/_lzmamodule.c
+++ b/Modules/_lzmamodule.c
@@ -494,7 +494,9 @@ build_filter_spec(const lzma_filter *f)
 case LZMA_FILTER_ARMTHUMB:
 case LZMA_FILTER_SPARC: {
 lzma_options_bcj *options = f->options;
-ADD_FIELD(options, start_offset);
+if (options) {
+ADD_FIELD(options, start_offset);
+}
 break;
 }
 default:

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


[Python-checkins] [3.12] gh-104282: Fix null pointer dereference in `lzma._decode_filter_properties` (GH-104283) (GH-114181)

2024-01-17 Thread serhiy-storchaka
https://github.com/python/cpython/commit/00e77935193221f1601405587b9ec05c14c13284
commit: 00e77935193221f1601405587b9ec05c14c13284
branch: 3.12
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: serhiy-storchaka 
date: 2024-01-17T13:31:33Z
summary:

[3.12] gh-104282: Fix null pointer dereference in 
`lzma._decode_filter_properties` (GH-104283) (GH-114181)

(cherry picked from commit 0154405350c272833bd51f68138223655e142a37)

Co-authored-by: Radislav Chugunov <52372310+chgn...@users.noreply.github.com>

files:
A Misc/NEWS.d/next/Library/2023-05-08-09-30-00.gh-issue-104282.h4c6Eb.rst
M Lib/test/test_lzma.py
M Modules/_lzmamodule.c

diff --git a/Lib/test/test_lzma.py b/Lib/test/test_lzma.py
index 13b200912f6abd..65e6488c5d7b10 100644
--- a/Lib/test/test_lzma.py
+++ b/Lib/test/test_lzma.py
@@ -1401,6 +1401,14 @@ def test__decode_filter_properties(self):
 self.assertEqual(filterspec["lc"], 3)
 self.assertEqual(filterspec["dict_size"], 8 << 20)
 
+# see gh-104282
+filters = [lzma.FILTER_X86, lzma.FILTER_POWERPC,
+   lzma.FILTER_IA64, lzma.FILTER_ARM,
+   lzma.FILTER_ARMTHUMB, lzma.FILTER_SPARC]
+for f in filters:
+filterspec = lzma._decode_filter_properties(f, b"")
+self.assertEqual(filterspec, {"id": f})
+
 def test_filter_properties_roundtrip(self):
 spec1 = lzma._decode_filter_properties(
 lzma.FILTER_LZMA1, b"]\x00\x00\x80\x00")
diff --git 
a/Misc/NEWS.d/next/Library/2023-05-08-09-30-00.gh-issue-104282.h4c6Eb.rst 
b/Misc/NEWS.d/next/Library/2023-05-08-09-30-00.gh-issue-104282.h4c6Eb.rst
new file mode 100644
index 00..569ce66a5b9d5f
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-05-08-09-30-00.gh-issue-104282.h4c6Eb.rst
@@ -0,0 +1,3 @@
+Fix null pointer dereference in :func:`lzma._decode_filter_properties`
+due to improper handling of BCJ filters with properties of zero length.
+Patch by Radislav Chugunov.
diff --git a/Modules/_lzmamodule.c b/Modules/_lzmamodule.c
index e34fbad230d51a..7bbd6569aa2e44 100644
--- a/Modules/_lzmamodule.c
+++ b/Modules/_lzmamodule.c
@@ -494,7 +494,9 @@ build_filter_spec(const lzma_filter *f)
 case LZMA_FILTER_ARMTHUMB:
 case LZMA_FILTER_SPARC: {
 lzma_options_bcj *options = f->options;
-ADD_FIELD(options, start_offset);
+if (options) {
+ADD_FIELD(options, start_offset);
+}
 break;
 }
 default:

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


[Python-checkins] [3.8] gh-109858: Protect zipfile from "quoted-overlap" zipbomb (GH-110016) (GH-113916)

2024-01-17 Thread ambv
https://github.com/python/cpython/commit/d05bac0b74153beb541b88b4fca33bf053990183
commit: d05bac0b74153beb541b88b4fca33bf053990183
branch: 3.8
author: Serhiy Storchaka 
committer: ambv 
date: 2024-01-17T14:41:50+01:00
summary:

[3.8] gh-109858: Protect zipfile from "quoted-overlap" zipbomb (GH-110016) 
(GH-113916)

Raise BadZipFile when try to read an entry that overlaps with other entry or
central directory.
(cherry picked from commit 66363b9a7b9fe7c99eba3a185b74c5fdbf842eba)

files:
A Misc/NEWS.d/next/Library/2023-09-28-13-15-51.gh-issue-109858.43e2dg.rst
M Lib/test/test_zipfile.py
M Lib/zipfile.py

diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py
index 31153445697fdd..05cb479857c2a3 100644
--- a/Lib/test/test_zipfile.py
+++ b/Lib/test/test_zipfile.py
@@ -1998,6 +1998,66 @@ def test_decompress_without_3rd_party_library(self):
 with zipfile.ZipFile(zip_file) as zf:
 self.assertRaises(RuntimeError, zf.extract, 'a.txt')
 
+@requires_zlib
+def test_full_overlap(self):
+data = (
+b'PK\x03\x04\x14\x00\x00\x00\x08\x00\xa0lH\x05\xe2\x1e'
+b'8\xbb\x10\x00\x00\x00\t\x04\x00\x00\x01\x00\x00\x00a\xed'
+b'\xc0\x81\x08\x00\x00\x00\xc00\xd6\xfbK\\d\x0b`P'
+b'K\x01\x02\x14\x00\x14\x00\x00\x00\x08\x00\xa0lH\x05\xe2'
+b'\x1e8\xbb\x10\x00\x00\x00\t\x04\x00\x00\x01\x00\x00\x00\x00'
+b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00aPK'
+b'\x01\x02\x14\x00\x14\x00\x00\x00\x08\x00\xa0lH\x05\xe2\x1e'
+b'8\xbb\x10\x00\x00\x00\t\x04\x00\x00\x01\x00\x00\x00\x00\x00'
+b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00bPK\x05'
+b'\x06\x00\x00\x00\x00\x02\x00\x02\x00^\x00\x00\x00/\x00\x00'
+b'\x00\x00\x00'
+)
+with zipfile.ZipFile(io.BytesIO(data), 'r') as zipf:
+self.assertEqual(zipf.namelist(), ['a', 'b'])
+zi = zipf.getinfo('a')
+self.assertEqual(zi.header_offset, 0)
+self.assertEqual(zi.compress_size, 16)
+self.assertEqual(zi.file_size, 1033)
+zi = zipf.getinfo('b')
+self.assertEqual(zi.header_offset, 0)
+self.assertEqual(zi.compress_size, 16)
+self.assertEqual(zi.file_size, 1033)
+self.assertEqual(len(zipf.read('a')), 1033)
+with self.assertRaisesRegex(zipfile.BadZipFile, 'File 
name.*differ'):
+zipf.read('b')
+
+@requires_zlib
+def test_quoted_overlap(self):
+data = (
+b'PK\x03\x04\x14\x00\x00\x00\x08\x00\xa0lH\x05Y\xfc'
+b'8\x044\x00\x00\x00(\x04\x00\x00\x01\x00\x00\x00a\x00'
+b'\x1f\x00\xe0\xffPK\x03\x04\x14\x00\x00\x00\x08\x00\xa0l'
+b'H\x05\xe2\x1e8\xbb\x10\x00\x00\x00\t\x04\x00\x00\x01\x00'
+b'\x00\x00b\xed\xc0\x81\x08\x00\x00\x00\xc00\xd6\xfbK\\'
+b'd\x0b`PK\x01\x02\x14\x00\x14\x00\x00\x00\x08\x00\xa0'
+b'lH\x05Y\xfc8\x044\x00\x00\x00(\x04\x00\x00\x01'
+b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+b'\x00aPK\x01\x02\x14\x00\x14\x00\x00\x00\x08\x00\xa0l'
+b'H\x05\xe2\x1e8\xbb\x10\x00\x00\x00\t\x04\x00\x00\x01\x00'
+b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\x00\x00\x00'
+b'bPK\x05\x06\x00\x00\x00\x00\x02\x00\x02\x00^\x00\x00'
+b'\x00S\x00\x00\x00\x00\x00'
+)
+with zipfile.ZipFile(io.BytesIO(data), 'r') as zipf:
+self.assertEqual(zipf.namelist(), ['a', 'b'])
+zi = zipf.getinfo('a')
+self.assertEqual(zi.header_offset, 0)
+self.assertEqual(zi.compress_size, 52)
+self.assertEqual(zi.file_size, 1064)
+zi = zipf.getinfo('b')
+self.assertEqual(zi.header_offset, 36)
+self.assertEqual(zi.compress_size, 16)
+self.assertEqual(zi.file_size, 1033)
+with self.assertRaisesRegex(zipfile.BadZipFile, 'Overlapped 
entries'):
+zipf.read('a')
+self.assertEqual(len(zipf.read('b')), 1033)
+
 def tearDown(self):
 unlink(TESTFN)
 unlink(TESTFN2)
diff --git a/Lib/zipfile.py b/Lib/zipfile.py
index e95e2b2d452df4..669f1a42309fd1 100644
--- a/Lib/zipfile.py
+++ b/Lib/zipfile.py
@@ -339,6 +339,7 @@ class ZipInfo (object):
 'compress_size',
 'file_size',
 '_raw_time',
+'_end_offset',
 )
 
 def __init__(self, filename="NoName", date_time=(1980,1,1,0,0,0)):
@@ -378,6 +379,7 @@ def __init__(self, filename="NoName", 
date_time=(1980,1,1,0,0,0)):
 self.volume = 0 # Volume number of file header
 self.internal_attr = 0  # Internal attributes
 self.external_attr = 0  # External file attributes
+self._end_offset = None # Start of the next local header or 
central directory
 # Other attributes are set by class

[Python-checkins] [3.8] gh-114021: Pin various sphinxcontrib extensions to older versions (GH-114022) (GH-114040)

2024-01-17 Thread ambv
https://github.com/python/cpython/commit/a9115165c800e72f1ce0db625a725ec3a20120cb
commit: a9115165c800e72f1ce0db625a725ec3a20120cb
branch: 3.8
author: Adam Turner <9087854+aa-tur...@users.noreply.github.com>
committer: ambv 
date: 2024-01-17T14:42:12+01:00
summary:

[3.8] gh-114021: Pin various sphinxcontrib extensions to older versions 
(GH-114022) (GH-114040)

(cherry picked from commit 94b1d1fa38ada8cf7d196184a04a195c152eed75)

Co-authored-by: Ronald Oussoren 

files:
A Doc/constraints.txt
M Doc/requirements.txt

diff --git a/Doc/constraints.txt b/Doc/constraints.txt
new file mode 100644
index 00..16b735ea07a72a
--- /dev/null
+++ b/Doc/constraints.txt
@@ -0,0 +1,24 @@
+# We have upper bounds on our transitive dependencies here
+# To avoid new releases unexpectedly breaking our build.
+# This file can be updated on an ad-hoc basis,
+# though it will probably have to be updated
+# whenever Doc/requirements.txt is updated.
+
+# Direct dependencies of Sphinx
+babel<3
+colorama<0.5
+imagesize<1.5
+Jinja2<3.2
+packaging<24
+Pygments>=2.16.1,<3
+requests<3
+snowballstemmer<3
+sphinxcontrib-applehelp<1.0.5
+sphinxcontrib-devhelp<1.0.6
+sphinxcontrib-htmlhelp<2.0.5
+sphinxcontrib-jsmath<1.1
+sphinxcontrib-qthelp<1.0.7
+sphinxcontrib-serializinghtml<1.1.10
+
+# Direct dependencies of Jinja2 (Jinja is a dependency of Sphinx, see above)
+MarkupSafe<2.2
diff --git a/Doc/requirements.txt b/Doc/requirements.txt
index b3d48f60893778..0e36985fd2a31a 100644
--- a/Doc/requirements.txt
+++ b/Doc/requirements.txt
@@ -18,3 +18,5 @@ blurb
 # The theme used by the documentation is stored separately, so we need
 # to install that as well.
 python-docs-theme
+
+-c constraints.txt

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


[Python-checkins] [3.8] gh-113659: Skip hidden .pth files (GH-113660) (GH-114147)

2024-01-17 Thread ambv
https://github.com/python/cpython/commit/01845a15d627d1f2c7eed9b245e462ffadd01701
commit: 01845a15d627d1f2c7eed9b245e462ffadd01701
branch: 3.8
author: Serhiy Storchaka 
committer: ambv 
date: 2024-01-17T14:42:31+01:00
summary:

[3.8] gh-113659: Skip hidden .pth files (GH-113660) (GH-114147)

Skip .pth files with names starting with a dot or hidden file attribute.
(cherry picked from commit 74208ed0c440244fb809d8acc97cb9ef51e888e3)

files:
A Misc/NEWS.d/next/Security/2024-01-02-19-52-23.gh-issue-113659.DkmnQc.rst
M Lib/site.py
M Lib/test/test_site.py

diff --git a/Lib/site.py b/Lib/site.py
index 9fa21cca386674..9b7314e8213a3e 100644
--- a/Lib/site.py
+++ b/Lib/site.py
@@ -74,6 +74,7 @@
 import builtins
 import _sitebuiltins
 import io
+import stat
 
 # Prefixes for site-packages; add additional prefixes like /usr/local here
 PREFIXES = [sys.prefix, sys.exec_prefix]
@@ -156,6 +157,13 @@ def addpackage(sitedir, name, known_paths):
 else:
 reset = False
 fullname = os.path.join(sitedir, name)
+try:
+st = os.lstat(fullname)
+except OSError:
+return
+if ((getattr(st, 'st_flags', 0) & stat.UF_HIDDEN) or
+(getattr(st, 'st_file_attributes', 0) & stat.FILE_ATTRIBUTE_HIDDEN)):
+return
 try:
 f = io.TextIOWrapper(io.open_code(fullname))
 except OSError:
@@ -203,7 +211,8 @@ def addsitedir(sitedir, known_paths=None):
 names = os.listdir(sitedir)
 except OSError:
 return
-names = [name for name in names if name.endswith(".pth")]
+names = [name for name in names
+ if name.endswith(".pth") and not name.startswith(".")]
 for name in sorted(names):
 addpackage(sitedir, name, known_paths)
 if reset:
diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py
index 9b2df6bfc39ee8..43233ab9b4ae83 100644
--- a/Lib/test/test_site.py
+++ b/Lib/test/test_site.py
@@ -18,6 +18,7 @@
 import urllib.request
 import urllib.error
 import shutil
+import stat
 import subprocess
 import sysconfig
 import tempfile
@@ -182,6 +183,44 @@ def test_addsitedir(self):
 finally:
 pth_file.cleanup()
 
+def test_addsitedir_dotfile(self):
+pth_file = PthFile('.dotfile')
+pth_file.cleanup(prep=True)
+try:
+pth_file.create()
+site.addsitedir(pth_file.base_dir, set())
+self.assertNotIn(site.makepath(pth_file.good_dir_path)[0], 
sys.path)
+self.assertIn(pth_file.base_dir, sys.path)
+finally:
+pth_file.cleanup()
+
+@unittest.skipUnless(hasattr(os, 'chflags'), 'test needs os.chflags()')
+def test_addsitedir_hidden_flags(self):
+pth_file = PthFile()
+pth_file.cleanup(prep=True)
+try:
+pth_file.create()
+st = os.stat(pth_file.file_path)
+os.chflags(pth_file.file_path, st.st_flags | stat.UF_HIDDEN)
+site.addsitedir(pth_file.base_dir, set())
+self.assertNotIn(site.makepath(pth_file.good_dir_path)[0], 
sys.path)
+self.assertIn(pth_file.base_dir, sys.path)
+finally:
+pth_file.cleanup()
+
+@unittest.skipUnless(sys.platform == 'win32', 'test needs Windows')
+def test_addsitedir_hidden_file_attribute(self):
+pth_file = PthFile()
+pth_file.cleanup(prep=True)
+try:
+pth_file.create()
+subprocess.check_call(['attrib', '+H', pth_file.file_path])
+site.addsitedir(pth_file.base_dir, set())
+self.assertNotIn(site.makepath(pth_file.good_dir_path)[0], 
sys.path)
+self.assertIn(pth_file.base_dir, sys.path)
+finally:
+pth_file.cleanup()
+
 # This tests _getuserbase, hence the double underline
 # to distinguish from a test for getuserbase
 def test__getuserbase(self):
diff --git 
a/Misc/NEWS.d/next/Security/2024-01-02-19-52-23.gh-issue-113659.DkmnQc.rst 
b/Misc/NEWS.d/next/Security/2024-01-02-19-52-23.gh-issue-113659.DkmnQc.rst
new file mode 100644
index 00..744687e72324d1
--- /dev/null
+++ b/Misc/NEWS.d/next/Security/2024-01-02-19-52-23.gh-issue-113659.DkmnQc.rst
@@ -0,0 +1 @@
+Skip ``.pth`` files with names starting with a dot or hidden file attribute.

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


[Python-checkins] [3.8] gh-108310: Fix TestPreHandshakeClose tests in test_ssl (#110718)

2024-01-17 Thread ambv
https://github.com/python/cpython/commit/0df2eb5b267fb56d93faf561024548a8816a0269
commit: 0df2eb5b267fb56d93faf561024548a8816a0269
branch: 3.8
author: Lumír 'Frenzy' Balhar 
committer: ambv 
date: 2024-01-17T14:43:00+01:00
summary:

[3.8] gh-108310: Fix TestPreHandshakeClose tests in test_ssl (#110718)

The new class is part of the fix for CVE-2023-40217:
https://github.com/python/cpython/commit/b4bcc06a9cfe13d96d5270809d963f8ba278f89b
but it's not in the lists of tests so they're not
executed. The new tests also need `SHORT_TIMEOUT`
constant not available in test.support in 3.8.

Co-authored-by: Łukasz Langa 

files:
A Misc/NEWS.d/next/Tests/2023-10-11-16-02-55.gh-issue-108310.URRe8Y.rst
M Lib/test/test_ssl.py

diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
index 67d3c09d36276c..e729c627064287 100644
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -150,6 +150,9 @@ def data_file(*name):
 OP_ENABLE_MIDDLEBOX_COMPAT = getattr(ssl, "OP_ENABLE_MIDDLEBOX_COMPAT", 0)
 OP_IGNORE_UNEXPECTED_EOF = getattr(ssl, "OP_IGNORE_UNEXPECTED_EOF", 0)
 
+# *_TIMEOUT constants are available in test.support in 3.9+
+SHORT_TIMEOUT = 30.0
+
 # Ubuntu has patched OpenSSL and changed behavior of security level 2
 # see https://bugs.python.org/issue41561#msg389003
 def is_ubuntu():
@@ -4835,7 +4838,7 @@ def __init__(self, *, name, call_after_accept, 
timeout=None):
 self.listener = None  # set by .start()
 self.port = None  # set by .start()
 if timeout is None:
-self.timeout = support.SHORT_TIMEOUT
+self.timeout = SHORT_TIMEOUT
 else:
 self.timeout = timeout
 super().__init__(name=name)
@@ -4917,7 +4920,7 @@ def test_preauth_data_to_tls_server(self):
 
 def call_after_accept(unused):
 server_accept_called.set()
-if not ready_for_server_wrap_socket.wait(support.SHORT_TIMEOUT):
+if not ready_for_server_wrap_socket.wait(SHORT_TIMEOUT):
 raise RuntimeError("wrap_socket event never set, test may 
fail.")
 return False  # Tell the server thread to continue.
 
@@ -4961,7 +4964,7 @@ def test_preauth_data_to_tls_client(self):
 client_can_continue_with_wrap_socket = threading.Event()
 
 def call_after_accept(conn_to_client):
-if not 
server_can_continue_with_wrap_socket.wait(support.SHORT_TIMEOUT):
+if not server_can_continue_with_wrap_socket.wait(SHORT_TIMEOUT):
 print("ERROR: test client took too long")
 
 # This forces an immediate connection close via RST on .close().
@@ -4987,7 +4990,7 @@ def call_after_accept(conn_to_client):
 client.connect(server.listener.getsockname())
 server_can_continue_with_wrap_socket.set()
 
-if not 
client_can_continue_with_wrap_socket.wait(support.SHORT_TIMEOUT):
+if not client_can_continue_with_wrap_socket.wait(SHORT_TIMEOUT):
 self.fail("test server took too long")
 ssl_ctx = ssl.create_default_context()
 try:
@@ -5026,7 +5029,7 @@ def connect(self):
 http.client.HTTPConnection.connect(self)
 
 # Wait for our fault injection server to have done its thing.
-if not server_responding.wait(support.SHORT_TIMEOUT) and 
support.verbose:
+if not server_responding.wait(SHORT_TIMEOUT) and 
support.verbose:
 sys.stdout.write("server_responding event never set.")
 self.sock = self._context.wrap_socket(
 self.sock, server_hostname=self.host)
@@ -5104,7 +5107,7 @@ def test_main(verbose=False):
 tests = [
 ContextTests, BasicSocketTests, SSLErrorTests, MemoryBIOTests,
 SSLObjectTests, SimpleBackgroundTests, ThreadedTests,
-TestPostHandshakeAuth, TestSSLDebug
+TestPostHandshakeAuth, TestSSLDebug, TestPreHandshakeClose
 ]
 
 if support.is_resource_enabled('network'):
diff --git 
a/Misc/NEWS.d/next/Tests/2023-10-11-16-02-55.gh-issue-108310.URRe8Y.rst 
b/Misc/NEWS.d/next/Tests/2023-10-11-16-02-55.gh-issue-108310.URRe8Y.rst
new file mode 100644
index 00..87f0a3b0ddfd30
--- /dev/null
+++ b/Misc/NEWS.d/next/Tests/2023-10-11-16-02-55.gh-issue-108310.URRe8Y.rst
@@ -0,0 +1,2 @@
+SSL tests for pre-handshake close were previously not enabled on Python 3.8
+due to an incorrect backport. This is now fixed. Patch by Lumír Balhar.

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


[Python-checkins] [3.8] bpo-37013: Fix the error handling in socket.if_indextoname() (GH-13503) (GH-113474)

2024-01-17 Thread ambv
https://github.com/python/cpython/commit/2e1156c562ad09f83596dc234e7ca9e8f938bf93
commit: 2e1156c562ad09f83596dc234e7ca9e8f938bf93
branch: 3.8
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: ambv 
date: 2024-01-17T14:44:07+01:00
summary:

[3.8] bpo-37013: Fix the error handling in socket.if_indextoname() (GH-13503) 
(GH-113474)

* Fix a crash when pass UINT_MAX.
* Fix an integer overflow on 64-bit non-Windows platforms.
(cherry picked from commit 0daf555c6fb3feba77989382135a58215e1d70a5)

Co-authored-by: Zackery Spytz 

files:
A Misc/NEWS.d/next/Library/2023-12-01-16-09-59.gh-issue-81194.FFad1c.rst
M Lib/test/test_socket.py
M Modules/socketmodule.c

diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
index eada6e929fe159..ed724ae03e1e73 100644
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -979,7 +979,20 @@ def testInterfaceNameIndex(self):
  'socket.if_indextoname() not available.')
 def testInvalidInterfaceIndexToName(self):
 self.assertRaises(OSError, socket.if_indextoname, 0)
+self.assertRaises(OverflowError, socket.if_indextoname, -1)
+self.assertRaises(OverflowError, socket.if_indextoname, 2**1000)
 self.assertRaises(TypeError, socket.if_indextoname, '_DEADBEEF')
+if hasattr(socket, 'if_nameindex'):
+indices = dict(socket.if_nameindex())
+for index in indices:
+index2 = index + 2**32
+if index2 not in indices:
+with self.assertRaises((OverflowError, OSError)):
+socket.if_indextoname(index2)
+for index in 2**32-1, 2**64-1:
+if index not in indices:
+with self.assertRaises((OverflowError, OSError)):
+socket.if_indextoname(index)
 
 @unittest.skipUnless(hasattr(socket, 'if_nametoindex'),
  'socket.if_nametoindex() not available.')
diff --git 
a/Misc/NEWS.d/next/Library/2023-12-01-16-09-59.gh-issue-81194.FFad1c.rst 
b/Misc/NEWS.d/next/Library/2023-12-01-16-09-59.gh-issue-81194.FFad1c.rst
new file mode 100644
index 00..feb7a8643b97f6
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-12-01-16-09-59.gh-issue-81194.FFad1c.rst
@@ -0,0 +1,3 @@
+Fix a crash in :func:`socket.if_indextoname` with specific value (UINT_MAX).
+Fix an integer overflow in :func:`socket.if_indextoname` on 64-bit
+non-Windows platforms.
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 5406f8b46f243f..c085b77bcd3348 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -6803,17 +6803,23 @@ Returns the interface index corresponding to the 
interface name if_name.");
 static PyObject *
 socket_if_indextoname(PyObject *self, PyObject *arg)
 {
+unsigned long index_long = PyLong_AsUnsignedLong(arg);
+if (index_long == (unsigned long) -1 && PyErr_Occurred()) {
+return NULL;
+}
+
 #ifdef MS_WINDOWS
-NET_IFINDEX index;
+NET_IFINDEX index = (NET_IFINDEX)index_long;
 #else
-unsigned long index;
+unsigned int index = (unsigned int)index_long;
 #endif
-char name[IF_NAMESIZE + 1];
 
-index = PyLong_AsUnsignedLong(arg);
-if (index == (unsigned long) -1)
+if ((unsigned long)index != index_long) {
+PyErr_SetString(PyExc_OverflowError, "index is too large");
 return NULL;
+}
 
+char name[IF_NAMESIZE + 1];
 if (if_indextoname(index, name) == NULL) {
 PyErr_SetFromErrno(PyExc_OSError);
 return NULL;

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


[Python-checkins] [3.8] gh-91133: tempfile.TemporaryDirectory: fix symlink bug in cleanup (GH-99930) (GH-112843)

2024-01-17 Thread ambv
https://github.com/python/cpython/commit/02a9259c717738dfe6b463c44d7e17f2b6d2cb3a
commit: 02a9259c717738dfe6b463c44d7e17f2b6d2cb3a
branch: 3.8
author: Serhiy Storchaka 
committer: ambv 
date: 2024-01-17T14:44:32+01:00
summary:

[3.8] gh-91133: tempfile.TemporaryDirectory: fix symlink bug in cleanup 
(GH-99930) (GH-112843)

(cherry picked from commit 81c16cd94ec38d61aa478b9a452436dc3b1b524d)

Co-authored-by: Søren Løvborg 

files:
A Misc/NEWS.d/next/Library/2022-12-01-16-57-44.gh-issue-91133.LKMVCV.rst
M Lib/tempfile.py
M Lib/test/test_tempfile.py

diff --git a/Lib/tempfile.py b/Lib/tempfile.py
index 8f9cb6c3ca3500..20ecd427c03fb6 100644
--- a/Lib/tempfile.py
+++ b/Lib/tempfile.py
@@ -263,6 +263,22 @@ def _mkstemp_inner(dir, pre, suf, flags, output_type):
 raise FileExistsError(_errno.EEXIST,
   "No usable temporary file name found")
 
+def _dont_follow_symlinks(func, path, *args):
+# Pass follow_symlinks=False, unless not supported on this platform.
+if func in _os.supports_follow_symlinks:
+func(path, *args, follow_symlinks=False)
+elif _os.name == 'nt' or not _os.path.islink(path):
+func(path, *args)
+
+def _resetperms(path):
+try:
+chflags = _os.chflags
+except AttributeError:
+pass
+else:
+_dont_follow_symlinks(chflags, path, 0)
+_dont_follow_symlinks(_os.chmod, path, 0o700)
+
 
 # User visible interfaces.
 
@@ -786,17 +802,10 @@ def __init__(self, suffix=None, prefix=None, dir=None):
 def _rmtree(cls, name):
 def onerror(func, path, exc_info):
 if issubclass(exc_info[0], PermissionError):
-def resetperms(path):
-try:
-_os.chflags(path, 0)
-except AttributeError:
-pass
-_os.chmod(path, 0o700)
-
 try:
 if path != name:
-resetperms(_os.path.dirname(path))
-resetperms(path)
+_resetperms(_os.path.dirname(path))
+_resetperms(path)
 
 try:
 _os.unlink(path)
diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py
index f129454f4c33ee..8cb36f38a2a35c 100644
--- a/Lib/test/test_tempfile.py
+++ b/Lib/test/test_tempfile.py
@@ -1377,6 +1377,103 @@ def test_cleanup_with_symlink_to_a_directory(self):
  "were deleted")
 d2.cleanup()
 
+@support.skip_unless_symlink
+def test_cleanup_with_symlink_modes(self):
+# cleanup() should not follow symlinks when fixing mode bits (#91133)
+with self.do_create(recurse=0) as d2:
+file1 = os.path.join(d2, 'file1')
+open(file1, 'wb').close()
+dir1 = os.path.join(d2, 'dir1')
+os.mkdir(dir1)
+for mode in range(8):
+mode <<= 6
+with self.subTest(mode=format(mode, '03o')):
+def test(target, target_is_directory):
+d1 = self.do_create(recurse=0)
+symlink = os.path.join(d1.name, 'symlink')
+os.symlink(target, symlink,
+target_is_directory=target_is_directory)
+try:
+os.chmod(symlink, mode, follow_symlinks=False)
+except NotImplementedError:
+pass
+try:
+os.chmod(symlink, mode)
+except FileNotFoundError:
+pass
+os.chmod(d1.name, mode)
+d1.cleanup()
+self.assertFalse(os.path.exists(d1.name))
+
+with self.subTest('nonexisting file'):
+test('nonexisting', target_is_directory=False)
+with self.subTest('nonexisting dir'):
+test('nonexisting', target_is_directory=True)
+
+with self.subTest('existing file'):
+os.chmod(file1, mode)
+old_mode = os.stat(file1).st_mode
+test(file1, target_is_directory=False)
+new_mode = os.stat(file1).st_mode
+self.assertEqual(new_mode, old_mode,
+ '%03o != %03o' % (new_mode, old_mode))
+
+with self.subTest('existing dir'):
+os.chmod(dir1, mode)
+old_mode = os.stat(dir1).st_mode
+test(dir1, target_is_directory=True)
+new_mode = os.stat(dir1).st_mode
+self.assertEqual(new_mode, old_mode,
+ '%03o != %03o' % (new_mode, old_mode))
+
+@unittest.skipUnless(hasattr(os, 'chfla

[Python-checkins] [3.8] gh-109991: Update Windows build to use OpenSSL 1.1.1w (GH-111266)

2024-01-17 Thread ambv
https://github.com/python/cpython/commit/d737623481241222c3733f0fb8a8bb7e2f75649a
commit: d737623481241222c3733f0fb8a8bb7e2f75649a
branch: 3.8
author: Zachary Ware 
committer: ambv 
date: 2024-01-17T14:45:48+01:00
summary:

[3.8] gh-109991: Update Windows build to use OpenSSL 1.1.1w (GH-111266)

(cherry picked from commit dcb16c98be61630369227f0d893f8d9262d25cac)

Co-authored-by: Steve Dower 

files:
A Misc/NEWS.d/next/Windows/2023-09-29-10-35-29.gh-issue-109991.GmuzGZ.rst
M PCbuild/get_externals.bat
M PCbuild/python.props

diff --git 
a/Misc/NEWS.d/next/Windows/2023-09-29-10-35-29.gh-issue-109991.GmuzGZ.rst 
b/Misc/NEWS.d/next/Windows/2023-09-29-10-35-29.gh-issue-109991.GmuzGZ.rst
new file mode 100644
index 00..e5b4b46630effa
--- /dev/null
+++ b/Misc/NEWS.d/next/Windows/2023-09-29-10-35-29.gh-issue-109991.GmuzGZ.rst
@@ -0,0 +1,4 @@
+Windows builds now use OpenSSL 1.1.1w. Note that OpenSSL 1.1 has reached its
+end of life and no future fixes will be made, and this version of Python is
+no longer receiving maintenance fixes and will not be updated to OpenSSL
+3.0.
diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat
index 16646bf551fa34..2322763d0d356f 100644
--- a/PCbuild/get_externals.bat
+++ b/PCbuild/get_externals.bat
@@ -53,7 +53,7 @@ echo.Fetching external libraries...
 set libraries=
 set libraries=%libraries%   bzip2-1.0.8
 if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries%  libffi-3.3.0
-if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1u
+if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1w
 set libraries=%libraries%   sqlite-3.35.5.0
 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% 
tcl-core-8.6.9.0
 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.9.0
@@ -77,7 +77,7 @@ echo.Fetching external binaries...
 
 set binaries=
 if NOT "%IncludeLibffi%"=="false"  set binaries=%binaries% libffi-3.3.0
-if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1u
+if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1w
 if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.9.0
 if NOT "%IncludeSSLSrc%"=="false"  set binaries=%binaries% nasm-2.11.06
 
diff --git a/PCbuild/python.props b/PCbuild/python.props
index 3d7c8df65c6c19..b5dc2a981b64ad 100644
--- a/PCbuild/python.props
+++ b/PCbuild/python.props
@@ -67,8 +67,8 @@
 $(ExternalsDir)libffi-3.3.0\
 $(libffiDir)$(ArchName)\
 $(libffiOutDir)include
-$(ExternalsDir)openssl-1.1.1u\
-$(ExternalsDir)openssl-bin-1.1.1u\$(ArchName)\
+$(ExternalsDir)openssl-1.1.1w\
+$(ExternalsDir)openssl-bin-1.1.1w\$(ArchName)\
 $(opensslOutDir)include
 $(ExternalsDir)\nasm-2.11.06\
 $(ExternalsDir)\zlib-1.2.12\

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


[Python-checkins] [3.9] gh-109991: Update GitHub CI workflows to use OpenSSL 3.0.11 and multissltests to use 1.1.1w and 3.0.11. (GH-110008)

2024-01-17 Thread ambv
https://github.com/python/cpython/commit/f4118e9995f858f6f2f09c48c841cb45b176d3c5
commit: f4118e9995f858f6f2f09c48c841cb45b176d3c5
branch: 3.9
author: Ned Deily 
committer: ambv 
date: 2024-01-17T14:46:46+01:00
summary:

[3.9] gh-109991: Update GitHub CI workflows to use OpenSSL 3.0.11 and 
multissltests to use 1.1.1w and 3.0.11. (GH-110008)

(cherry picked from commit c88037d137a98d7c399c7bd74d5117b5bcae1543)

files:
A Misc/NEWS.d/next/Tools-Demos/2023-09-27-23-31-54.gh-issue-109991.sUUYY8.rst
M .github/workflows/build.yml
M Tools/ssl/multissltests.py

diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index aa27c48acb97c5..d26ebc8e6bf5ac 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -182,7 +182,7 @@ jobs:
 needs: check_source
 if: needs.check_source.outputs.run_tests == 'true'
 env:
-  OPENSSL_VER: 1.1.1v
+  OPENSSL_VER: 3.0.11
   PYTHONSTRICTEXTENSIONBUILD: 1
 steps:
 - uses: actions/checkout@v4
@@ -224,7 +224,7 @@ jobs:
 strategy:
   fail-fast: false
   matrix:
-openssl_ver: [1.0.2u, 1.1.0l, 1.1.1v, 3.0.10, 3.1.2]
+openssl_ver: [1.0.2u, 1.1.0l, 1.1.1w, 3.0.11, 3.1.3]
 env:
   OPENSSL_VER: ${{ matrix.openssl_ver }}
   MULTISSL_DIR: ${{ github.workspace }}/multissl
diff --git 
a/Misc/NEWS.d/next/Tools-Demos/2023-09-27-23-31-54.gh-issue-109991.sUUYY8.rst 
b/Misc/NEWS.d/next/Tools-Demos/2023-09-27-23-31-54.gh-issue-109991.sUUYY8.rst
new file mode 100644
index 00..eb69e36df9e4ed
--- /dev/null
+++ 
b/Misc/NEWS.d/next/Tools-Demos/2023-09-27-23-31-54.gh-issue-109991.sUUYY8.rst
@@ -0,0 +1,2 @@
+Update GitHub CI workflows to use OpenSSL 3.0.11 and multissltests to use
+1.1.1w and 3.0.11.
diff --git a/Tools/ssl/multissltests.py b/Tools/ssl/multissltests.py
index 921f0f5cd5f41d..1a20e3f19a13c6 100755
--- a/Tools/ssl/multissltests.py
+++ b/Tools/ssl/multissltests.py
@@ -49,8 +49,8 @@
 ]
 
 OPENSSL_RECENT_VERSIONS = [
-"1.1.1v",
-"3.0.10",
+"1.1.1w",
+"3.0.11",
 ]
 
 LIBRESSL_OLD_VERSIONS = [

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


[Python-checkins] [3.9] gh-109991: Update Windows build to use OpenSSL 1.1.1w (GH-111265)

2024-01-17 Thread ambv
https://github.com/python/cpython/commit/75da5067cf4aa6a1e5671d0533f15eebf41f14ba
commit: 75da5067cf4aa6a1e5671d0533f15eebf41f14ba
branch: 3.9
author: Zachary Ware 
committer: ambv 
date: 2024-01-17T14:47:09+01:00
summary:

[3.9] gh-109991: Update Windows build to use OpenSSL 1.1.1w (GH-111265)

(cherry picked from commit dcb16c98be61630369227f0d893f8d9262d25cac)

Co-authored-by: Steve Dower 

files:
A Misc/NEWS.d/next/Windows/2023-09-29-10-35-29.gh-issue-109991.GmuzGZ.rst
M PCbuild/get_externals.bat
M PCbuild/python.props

diff --git 
a/Misc/NEWS.d/next/Windows/2023-09-29-10-35-29.gh-issue-109991.GmuzGZ.rst 
b/Misc/NEWS.d/next/Windows/2023-09-29-10-35-29.gh-issue-109991.GmuzGZ.rst
new file mode 100644
index 00..e5b4b46630effa
--- /dev/null
+++ b/Misc/NEWS.d/next/Windows/2023-09-29-10-35-29.gh-issue-109991.GmuzGZ.rst
@@ -0,0 +1,4 @@
+Windows builds now use OpenSSL 1.1.1w. Note that OpenSSL 1.1 has reached its
+end of life and no future fixes will be made, and this version of Python is
+no longer receiving maintenance fixes and will not be updated to OpenSSL
+3.0.
diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat
index 4067f27463f102..50ef2fc4c5b60f 100644
--- a/PCbuild/get_externals.bat
+++ b/PCbuild/get_externals.bat
@@ -53,7 +53,7 @@ echo.Fetching external libraries...
 set libraries=
 set libraries=%libraries%   bzip2-1.0.8
 if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries%  libffi-3.3.0
-if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1u
+if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1w
 set libraries=%libraries%   sqlite-3.37.2.0
 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% 
tcl-core-8.6.12.0
 if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.12.0
@@ -77,7 +77,7 @@ echo.Fetching external binaries...
 
 set binaries=
 if NOT "%IncludeLibffi%"=="false"  set binaries=%binaries% libffi-3.3.0
-if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1u
+if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1w
 if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.12.0
 if NOT "%IncludeSSLSrc%"=="false"  set binaries=%binaries% nasm-2.11.06
 
diff --git a/PCbuild/python.props b/PCbuild/python.props
index 1b88a2ff216df5..22d71a11b2eff0 100644
--- a/PCbuild/python.props
+++ b/PCbuild/python.props
@@ -68,8 +68,8 @@
 $(ExternalsDir)libffi-3.3.0\
 $(libffiDir)$(ArchName)\
 $(libffiOutDir)include
-$(ExternalsDir)openssl-1.1.1u\
-$(ExternalsDir)openssl-bin-1.1.1u\$(ArchName)\
+$(ExternalsDir)openssl-1.1.1w\
+$(ExternalsDir)openssl-bin-1.1.1w\$(ArchName)\
 $(opensslOutDir)include
 $(ExternalsDir)\nasm-2.11.06\
 $(ExternalsDir)\zlib-1.2.12\

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


[Python-checkins] [3.9] gh-91133: tempfile.TemporaryDirectory: fix symlink bug in cleanup (GH-99930) (GH-112842)

2024-01-17 Thread ambv
https://github.com/python/cpython/commit/d54e22a669ae6e987199bb5d2c69bb5a46b0083b
commit: d54e22a669ae6e987199bb5d2c69bb5a46b0083b
branch: 3.9
author: Serhiy Storchaka 
committer: ambv 
date: 2024-01-17T14:47:47+01:00
summary:

[3.9] gh-91133: tempfile.TemporaryDirectory: fix symlink bug in cleanup 
(GH-99930) (GH-112842)

(cherry picked from commit 81c16cd94ec38d61aa478b9a452436dc3b1b524d)

Co-authored-by: Søren Løvborg 

files:
A Misc/NEWS.d/next/Library/2022-12-01-16-57-44.gh-issue-91133.LKMVCV.rst
M Lib/tempfile.py
M Lib/test/test_tempfile.py

diff --git a/Lib/tempfile.py b/Lib/tempfile.py
index eafce6f25b6fb2..59a628a1744685 100644
--- a/Lib/tempfile.py
+++ b/Lib/tempfile.py
@@ -268,6 +268,22 @@ def _mkstemp_inner(dir, pre, suf, flags, output_type):
 raise FileExistsError(_errno.EEXIST,
   "No usable temporary file name found")
 
+def _dont_follow_symlinks(func, path, *args):
+# Pass follow_symlinks=False, unless not supported on this platform.
+if func in _os.supports_follow_symlinks:
+func(path, *args, follow_symlinks=False)
+elif _os.name == 'nt' or not _os.path.islink(path):
+func(path, *args)
+
+def _resetperms(path):
+try:
+chflags = _os.chflags
+except AttributeError:
+pass
+else:
+_dont_follow_symlinks(chflags, path, 0)
+_dont_follow_symlinks(_os.chmod, path, 0o700)
+
 
 # User visible interfaces.
 
@@ -789,17 +805,10 @@ def __init__(self, suffix=None, prefix=None, dir=None):
 def _rmtree(cls, name):
 def onerror(func, path, exc_info):
 if issubclass(exc_info[0], PermissionError):
-def resetperms(path):
-try:
-_os.chflags(path, 0)
-except AttributeError:
-pass
-_os.chmod(path, 0o700)
-
 try:
 if path != name:
-resetperms(_os.path.dirname(path))
-resetperms(path)
+_resetperms(_os.path.dirname(path))
+_resetperms(path)
 
 try:
 _os.unlink(path)
diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py
index 8ad1bb98e8e899..571263d9c957d7 100644
--- a/Lib/test/test_tempfile.py
+++ b/Lib/test/test_tempfile.py
@@ -1394,6 +1394,103 @@ def test_cleanup_with_symlink_to_a_directory(self):
  "were deleted")
 d2.cleanup()
 
+@support.skip_unless_symlink
+def test_cleanup_with_symlink_modes(self):
+# cleanup() should not follow symlinks when fixing mode bits (#91133)
+with self.do_create(recurse=0) as d2:
+file1 = os.path.join(d2, 'file1')
+open(file1, 'wb').close()
+dir1 = os.path.join(d2, 'dir1')
+os.mkdir(dir1)
+for mode in range(8):
+mode <<= 6
+with self.subTest(mode=format(mode, '03o')):
+def test(target, target_is_directory):
+d1 = self.do_create(recurse=0)
+symlink = os.path.join(d1.name, 'symlink')
+os.symlink(target, symlink,
+target_is_directory=target_is_directory)
+try:
+os.chmod(symlink, mode, follow_symlinks=False)
+except NotImplementedError:
+pass
+try:
+os.chmod(symlink, mode)
+except FileNotFoundError:
+pass
+os.chmod(d1.name, mode)
+d1.cleanup()
+self.assertFalse(os.path.exists(d1.name))
+
+with self.subTest('nonexisting file'):
+test('nonexisting', target_is_directory=False)
+with self.subTest('nonexisting dir'):
+test('nonexisting', target_is_directory=True)
+
+with self.subTest('existing file'):
+os.chmod(file1, mode)
+old_mode = os.stat(file1).st_mode
+test(file1, target_is_directory=False)
+new_mode = os.stat(file1).st_mode
+self.assertEqual(new_mode, old_mode,
+ '%03o != %03o' % (new_mode, old_mode))
+
+with self.subTest('existing dir'):
+os.chmod(dir1, mode)
+old_mode = os.stat(dir1).st_mode
+test(dir1, target_is_directory=True)
+new_mode = os.stat(dir1).st_mode
+self.assertEqual(new_mode, old_mode,
+ '%03o != %03o' % (new_mode, old_mode))
+
+@unittest.skipUnless(hasattr(os, 'chfla

[Python-checkins] [3.9] bpo-37013: Fix the error handling in socket.if_indextoname() (GH-13503) (GH-112600)

2024-01-17 Thread ambv
https://github.com/python/cpython/commit/a6f73f61147048187908299ae911c5ad498d813a
commit: a6f73f61147048187908299ae911c5ad498d813a
branch: 3.9
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: ambv 
date: 2024-01-17T14:47:26+01:00
summary:

[3.9] bpo-37013: Fix the error handling in socket.if_indextoname() (GH-13503) 
(GH-112600)

* Fix a crash when pass UINT_MAX.
* Fix an integer overflow on 64-bit non-Windows platforms.
(cherry picked from commit 0daf555c6fb3feba77989382135a58215e1d70a5)

Co-authored-by: Zackery Spytz 

files:
A Misc/NEWS.d/next/Library/2023-12-01-16-09-59.gh-issue-81194.FFad1c.rst
M Lib/test/test_socket.py
M Modules/socketmodule.c

diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
index 127d61cb6a89e6..043e5543889833 100755
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -1070,7 +1070,20 @@ def testInterfaceNameIndex(self):
  'socket.if_indextoname() not available.')
 def testInvalidInterfaceIndexToName(self):
 self.assertRaises(OSError, socket.if_indextoname, 0)
+self.assertRaises(OverflowError, socket.if_indextoname, -1)
+self.assertRaises(OverflowError, socket.if_indextoname, 2**1000)
 self.assertRaises(TypeError, socket.if_indextoname, '_DEADBEEF')
+if hasattr(socket, 'if_nameindex'):
+indices = dict(socket.if_nameindex())
+for index in indices:
+index2 = index + 2**32
+if index2 not in indices:
+with self.assertRaises((OverflowError, OSError)):
+socket.if_indextoname(index2)
+for index in 2**32-1, 2**64-1:
+if index not in indices:
+with self.assertRaises((OverflowError, OSError)):
+socket.if_indextoname(index)
 
 @unittest.skipUnless(hasattr(socket, 'if_nametoindex'),
  'socket.if_nametoindex() not available.')
diff --git 
a/Misc/NEWS.d/next/Library/2023-12-01-16-09-59.gh-issue-81194.FFad1c.rst 
b/Misc/NEWS.d/next/Library/2023-12-01-16-09-59.gh-issue-81194.FFad1c.rst
new file mode 100644
index 00..feb7a8643b97f6
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-12-01-16-09-59.gh-issue-81194.FFad1c.rst
@@ -0,0 +1,3 @@
+Fix a crash in :func:`socket.if_indextoname` with specific value (UINT_MAX).
+Fix an integer overflow in :func:`socket.if_indextoname` on 64-bit
+non-Windows platforms.
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 133470f9b8193c..9e0223b1272627 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -6890,17 +6890,23 @@ Returns the interface index corresponding to the 
interface name if_name.");
 static PyObject *
 socket_if_indextoname(PyObject *self, PyObject *arg)
 {
+unsigned long index_long = PyLong_AsUnsignedLong(arg);
+if (index_long == (unsigned long) -1 && PyErr_Occurred()) {
+return NULL;
+}
+
 #ifdef MS_WINDOWS
-NET_IFINDEX index;
+NET_IFINDEX index = (NET_IFINDEX)index_long;
 #else
-unsigned long index;
+unsigned int index = (unsigned int)index_long;
 #endif
-char name[IF_NAMESIZE + 1];
 
-index = PyLong_AsUnsignedLong(arg);
-if (index == (unsigned long) -1)
+if ((unsigned long)index != index_long) {
+PyErr_SetString(PyExc_OverflowError, "index is too large");
 return NULL;
+}
 
+char name[IF_NAMESIZE + 1];
 if (if_indextoname(index, name) == NULL) {
 PyErr_SetFromErrno(PyExc_OSError);
 return NULL;

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


[Python-checkins] [3.9] gh-109858: Protect zipfile from "quoted-overlap" zipbomb (GH-110016) (GH-113915)

2024-01-17 Thread ambv
https://github.com/python/cpython/commit/a2c59992e9e8d35baba9695eb186ad6c6ff85c51
commit: a2c59992e9e8d35baba9695eb186ad6c6ff85c51
branch: 3.9
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: ambv 
date: 2024-01-17T14:48:06+01:00
summary:

[3.9] gh-109858: Protect zipfile from "quoted-overlap" zipbomb (GH-110016) 
(GH-113915)

Raise BadZipFile when try to read an entry that overlaps with other entry or
central directory.
(cherry picked from commit 66363b9a7b9fe7c99eba3a185b74c5fdbf842eba)

Co-authored-by: Serhiy Storchaka 

files:
A Misc/NEWS.d/next/Library/2023-09-28-13-15-51.gh-issue-109858.43e2dg.rst
M Lib/test/test_zipfile.py
M Lib/zipfile.py

diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py
index bd383d3f68552b..17e95eb86239a5 100644
--- a/Lib/test/test_zipfile.py
+++ b/Lib/test/test_zipfile.py
@@ -2045,6 +2045,66 @@ def test_decompress_without_3rd_party_library(self):
 with zipfile.ZipFile(zip_file) as zf:
 self.assertRaises(RuntimeError, zf.extract, 'a.txt')
 
+@requires_zlib()
+def test_full_overlap(self):
+data = (
+b'PK\x03\x04\x14\x00\x00\x00\x08\x00\xa0lH\x05\xe2\x1e'
+b'8\xbb\x10\x00\x00\x00\t\x04\x00\x00\x01\x00\x00\x00a\xed'
+b'\xc0\x81\x08\x00\x00\x00\xc00\xd6\xfbK\\d\x0b`P'
+b'K\x01\x02\x14\x00\x14\x00\x00\x00\x08\x00\xa0lH\x05\xe2'
+b'\x1e8\xbb\x10\x00\x00\x00\t\x04\x00\x00\x01\x00\x00\x00\x00'
+b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00aPK'
+b'\x01\x02\x14\x00\x14\x00\x00\x00\x08\x00\xa0lH\x05\xe2\x1e'
+b'8\xbb\x10\x00\x00\x00\t\x04\x00\x00\x01\x00\x00\x00\x00\x00'
+b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00bPK\x05'
+b'\x06\x00\x00\x00\x00\x02\x00\x02\x00^\x00\x00\x00/\x00\x00'
+b'\x00\x00\x00'
+)
+with zipfile.ZipFile(io.BytesIO(data), 'r') as zipf:
+self.assertEqual(zipf.namelist(), ['a', 'b'])
+zi = zipf.getinfo('a')
+self.assertEqual(zi.header_offset, 0)
+self.assertEqual(zi.compress_size, 16)
+self.assertEqual(zi.file_size, 1033)
+zi = zipf.getinfo('b')
+self.assertEqual(zi.header_offset, 0)
+self.assertEqual(zi.compress_size, 16)
+self.assertEqual(zi.file_size, 1033)
+self.assertEqual(len(zipf.read('a')), 1033)
+with self.assertRaisesRegex(zipfile.BadZipFile, 'File 
name.*differ'):
+zipf.read('b')
+
+@requires_zlib()
+def test_quoted_overlap(self):
+data = (
+b'PK\x03\x04\x14\x00\x00\x00\x08\x00\xa0lH\x05Y\xfc'
+b'8\x044\x00\x00\x00(\x04\x00\x00\x01\x00\x00\x00a\x00'
+b'\x1f\x00\xe0\xffPK\x03\x04\x14\x00\x00\x00\x08\x00\xa0l'
+b'H\x05\xe2\x1e8\xbb\x10\x00\x00\x00\t\x04\x00\x00\x01\x00'
+b'\x00\x00b\xed\xc0\x81\x08\x00\x00\x00\xc00\xd6\xfbK\\'
+b'd\x0b`PK\x01\x02\x14\x00\x14\x00\x00\x00\x08\x00\xa0'
+b'lH\x05Y\xfc8\x044\x00\x00\x00(\x04\x00\x00\x01'
+b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+b'\x00aPK\x01\x02\x14\x00\x14\x00\x00\x00\x08\x00\xa0l'
+b'H\x05\xe2\x1e8\xbb\x10\x00\x00\x00\t\x04\x00\x00\x01\x00'
+b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\x00\x00\x00'
+b'bPK\x05\x06\x00\x00\x00\x00\x02\x00\x02\x00^\x00\x00'
+b'\x00S\x00\x00\x00\x00\x00'
+)
+with zipfile.ZipFile(io.BytesIO(data), 'r') as zipf:
+self.assertEqual(zipf.namelist(), ['a', 'b'])
+zi = zipf.getinfo('a')
+self.assertEqual(zi.header_offset, 0)
+self.assertEqual(zi.compress_size, 52)
+self.assertEqual(zi.file_size, 1064)
+zi = zipf.getinfo('b')
+self.assertEqual(zi.header_offset, 36)
+self.assertEqual(zi.compress_size, 16)
+self.assertEqual(zi.file_size, 1033)
+with self.assertRaisesRegex(zipfile.BadZipFile, 'Overlapped 
entries'):
+zipf.read('a')
+self.assertEqual(len(zipf.read('b')), 1033)
+
 def tearDown(self):
 unlink(TESTFN)
 unlink(TESTFN2)
diff --git a/Lib/zipfile.py b/Lib/zipfile.py
index 1e942a503e8ee1..95f95ee112667a 100644
--- a/Lib/zipfile.py
+++ b/Lib/zipfile.py
@@ -338,6 +338,7 @@ class ZipInfo (object):
 'compress_size',
 'file_size',
 '_raw_time',
+'_end_offset',
 )
 
 def __init__(self, filename="NoName", date_time=(1980,1,1,0,0,0)):
@@ -379,6 +380,7 @@ def __init__(self, filename="NoName", 
date_time=(1980,1,1,0,0,0)):
 self.external_attr = 0  # External file attributes
 self.compress_size = 0  # Size of the compressed file
 self.file_size = 0  # Size of the uncompressed file
+self._end_offset = None  

[Python-checkins] [3.9] gh-114021: Pin various sphinxcontrib extensions to older versions (GH-114022) (GH-114039)

2024-01-17 Thread ambv
https://github.com/python/cpython/commit/2613df8ee2687e270d026020bd79b80220284a6a
commit: 2613df8ee2687e270d026020bd79b80220284a6a
branch: 3.9
author: Adam Turner <9087854+aa-tur...@users.noreply.github.com>
committer: ambv 
date: 2024-01-17T14:48:31+01:00
summary:

[3.9] gh-114021: Pin various sphinxcontrib extensions to older versions 
(GH-114022) (GH-114039)

(cherry picked from commit 94b1d1fa38ada8cf7d196184a04a195c152eed75)

Co-authored-by: Ronald Oussoren 

files:
A Doc/constraints.txt
M Doc/requirements.txt

diff --git a/Doc/constraints.txt b/Doc/constraints.txt
new file mode 100644
index 00..16b735ea07a72a
--- /dev/null
+++ b/Doc/constraints.txt
@@ -0,0 +1,24 @@
+# We have upper bounds on our transitive dependencies here
+# To avoid new releases unexpectedly breaking our build.
+# This file can be updated on an ad-hoc basis,
+# though it will probably have to be updated
+# whenever Doc/requirements.txt is updated.
+
+# Direct dependencies of Sphinx
+babel<3
+colorama<0.5
+imagesize<1.5
+Jinja2<3.2
+packaging<24
+Pygments>=2.16.1,<3
+requests<3
+snowballstemmer<3
+sphinxcontrib-applehelp<1.0.5
+sphinxcontrib-devhelp<1.0.6
+sphinxcontrib-htmlhelp<2.0.5
+sphinxcontrib-jsmath<1.1
+sphinxcontrib-qthelp<1.0.7
+sphinxcontrib-serializinghtml<1.1.10
+
+# Direct dependencies of Jinja2 (Jinja is a dependency of Sphinx, see above)
+MarkupSafe<2.2
diff --git a/Doc/requirements.txt b/Doc/requirements.txt
index d674857a353d2b..52bdaf742f36d8 100644
--- a/Doc/requirements.txt
+++ b/Doc/requirements.txt
@@ -18,3 +18,5 @@ blurb
 # The theme used by the documentation is stored separately, so we need
 # to install that as well.
 python-docs-theme>=2022.1
+
+-c constraints.txt

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


[Python-checkins] [3.10] bpo-37013: Fix the error handling in socket.if_indextoname() (GH-13503) (GH-112599)

2024-01-17 Thread ambv
https://github.com/python/cpython/commit/32e7acdc05a3adb9a32c65242c63eb456696dfb6
commit: 32e7acdc05a3adb9a32c65242c63eb456696dfb6
branch: 3.10
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: ambv 
date: 2024-01-17T14:49:40+01:00
summary:

[3.10] bpo-37013: Fix the error handling in socket.if_indextoname() (GH-13503) 
(GH-112599)

* Fix a crash when pass UINT_MAX.
* Fix an integer overflow on 64-bit non-Windows platforms.
(cherry picked from commit 0daf555c6fb3feba77989382135a58215e1d70a5)

Co-authored-by: Zackery Spytz 

files:
A Misc/NEWS.d/next/Library/2023-12-01-16-09-59.gh-issue-81194.FFad1c.rst
M Lib/test/test_socket.py
M Modules/socketmodule.c

diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
index 211fd8c02da0a4..4f1fc3fd92db21 100644
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -1070,7 +1070,20 @@ def testInterfaceNameIndex(self):
  'socket.if_indextoname() not available.')
 def testInvalidInterfaceIndexToName(self):
 self.assertRaises(OSError, socket.if_indextoname, 0)
+self.assertRaises(OverflowError, socket.if_indextoname, -1)
+self.assertRaises(OverflowError, socket.if_indextoname, 2**1000)
 self.assertRaises(TypeError, socket.if_indextoname, '_DEADBEEF')
+if hasattr(socket, 'if_nameindex'):
+indices = dict(socket.if_nameindex())
+for index in indices:
+index2 = index + 2**32
+if index2 not in indices:
+with self.assertRaises((OverflowError, OSError)):
+socket.if_indextoname(index2)
+for index in 2**32-1, 2**64-1:
+if index not in indices:
+with self.assertRaises((OverflowError, OSError)):
+socket.if_indextoname(index)
 
 @unittest.skipUnless(hasattr(socket, 'if_nametoindex'),
  'socket.if_nametoindex() not available.')
diff --git 
a/Misc/NEWS.d/next/Library/2023-12-01-16-09-59.gh-issue-81194.FFad1c.rst 
b/Misc/NEWS.d/next/Library/2023-12-01-16-09-59.gh-issue-81194.FFad1c.rst
new file mode 100644
index 00..feb7a8643b97f6
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-12-01-16-09-59.gh-issue-81194.FFad1c.rst
@@ -0,0 +1,3 @@
+Fix a crash in :func:`socket.if_indextoname` with specific value (UINT_MAX).
+Fix an integer overflow in :func:`socket.if_indextoname` on 64-bit
+non-Windows platforms.
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 0762a8df8663d2..be628a03da17ac 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -6827,17 +6827,23 @@ Returns the interface index corresponding to the 
interface name if_name.");
 static PyObject *
 socket_if_indextoname(PyObject *self, PyObject *arg)
 {
+unsigned long index_long = PyLong_AsUnsignedLong(arg);
+if (index_long == (unsigned long) -1 && PyErr_Occurred()) {
+return NULL;
+}
+
 #ifdef MS_WINDOWS
-NET_IFINDEX index;
+NET_IFINDEX index = (NET_IFINDEX)index_long;
 #else
-unsigned long index;
+unsigned int index = (unsigned int)index_long;
 #endif
-char name[IF_NAMESIZE + 1];
 
-index = PyLong_AsUnsignedLong(arg);
-if (index == (unsigned long) -1)
+if ((unsigned long)index != index_long) {
+PyErr_SetString(PyExc_OverflowError, "index is too large");
 return NULL;
+}
 
+char name[IF_NAMESIZE + 1];
 if (if_indextoname(index, name) == NULL) {
 PyErr_SetFromErrno(PyExc_OSError);
 return NULL;

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


[Python-checkins] [3.10] gh-91133: tempfile.TemporaryDirectory: fix symlink bug in cleanup (GH-99930) (GH-112840)

2024-01-17 Thread ambv
https://github.com/python/cpython/commit/8eaeefe49d179ca4908d052745e3bb8b6f238f82
commit: 8eaeefe49d179ca4908d052745e3bb8b6f238f82
branch: 3.10
author: Serhiy Storchaka 
committer: ambv 
date: 2024-01-17T14:49:56+01:00
summary:

[3.10] gh-91133: tempfile.TemporaryDirectory: fix symlink bug in cleanup 
(GH-99930) (GH-112840)

(cherry picked from commit 81c16cd94ec38d61aa478b9a452436dc3b1b524d)

Co-authored-by: Søren Løvborg 

files:
A Misc/NEWS.d/next/Library/2022-12-01-16-57-44.gh-issue-91133.LKMVCV.rst
M Lib/tempfile.py
M Lib/test/test_tempfile.py

diff --git a/Lib/tempfile.py b/Lib/tempfile.py
index 96da93053ac712..fd78998df9fd85 100644
--- a/Lib/tempfile.py
+++ b/Lib/tempfile.py
@@ -269,6 +269,22 @@ def _mkstemp_inner(dir, pre, suf, flags, output_type):
 raise FileExistsError(_errno.EEXIST,
   "No usable temporary file name found")
 
+def _dont_follow_symlinks(func, path, *args):
+# Pass follow_symlinks=False, unless not supported on this platform.
+if func in _os.supports_follow_symlinks:
+func(path, *args, follow_symlinks=False)
+elif _os.name == 'nt' or not _os.path.islink(path):
+func(path, *args)
+
+def _resetperms(path):
+try:
+chflags = _os.chflags
+except AttributeError:
+pass
+else:
+_dont_follow_symlinks(chflags, path, 0)
+_dont_follow_symlinks(_os.chmod, path, 0o700)
+
 
 # User visible interfaces.
 
@@ -827,17 +843,10 @@ def __init__(self, suffix=None, prefix=None, dir=None,
 def _rmtree(cls, name, ignore_errors=False):
 def onerror(func, path, exc_info):
 if issubclass(exc_info[0], PermissionError):
-def resetperms(path):
-try:
-_os.chflags(path, 0)
-except AttributeError:
-pass
-_os.chmod(path, 0o700)
-
 try:
 if path != name:
-resetperms(_os.path.dirname(path))
-resetperms(path)
+_resetperms(_os.path.dirname(path))
+_resetperms(path)
 
 try:
 _os.unlink(path)
diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py
index 1946b043d04d79..30d57baf977f52 100644
--- a/Lib/test/test_tempfile.py
+++ b/Lib/test/test_tempfile.py
@@ -1499,6 +1499,103 @@ def test_cleanup_with_symlink_to_a_directory(self):
  "were deleted")
 d2.cleanup()
 
+@os_helper.skip_unless_symlink
+def test_cleanup_with_symlink_modes(self):
+# cleanup() should not follow symlinks when fixing mode bits (#91133)
+with self.do_create(recurse=0) as d2:
+file1 = os.path.join(d2, 'file1')
+open(file1, 'wb').close()
+dir1 = os.path.join(d2, 'dir1')
+os.mkdir(dir1)
+for mode in range(8):
+mode <<= 6
+with self.subTest(mode=format(mode, '03o')):
+def test(target, target_is_directory):
+d1 = self.do_create(recurse=0)
+symlink = os.path.join(d1.name, 'symlink')
+os.symlink(target, symlink,
+target_is_directory=target_is_directory)
+try:
+os.chmod(symlink, mode, follow_symlinks=False)
+except NotImplementedError:
+pass
+try:
+os.chmod(symlink, mode)
+except FileNotFoundError:
+pass
+os.chmod(d1.name, mode)
+d1.cleanup()
+self.assertFalse(os.path.exists(d1.name))
+
+with self.subTest('nonexisting file'):
+test('nonexisting', target_is_directory=False)
+with self.subTest('nonexisting dir'):
+test('nonexisting', target_is_directory=True)
+
+with self.subTest('existing file'):
+os.chmod(file1, mode)
+old_mode = os.stat(file1).st_mode
+test(file1, target_is_directory=False)
+new_mode = os.stat(file1).st_mode
+self.assertEqual(new_mode, old_mode,
+ '%03o != %03o' % (new_mode, old_mode))
+
+with self.subTest('existing dir'):
+os.chmod(dir1, mode)
+old_mode = os.stat(dir1).st_mode
+test(dir1, target_is_directory=True)
+new_mode = os.stat(dir1).st_mode
+self.assertEqual(new_mode, old_mode,
+ '%03o != %03o' % (new_mode, old_mode))
+
+@unittest.skipU

[Python-checkins] [3.10] gh-114021: Pin various sphinxcontrib extensions to older versions (GH-114022) (GH-114038)

2024-01-17 Thread ambv
https://github.com/python/cpython/commit/6661b228ba4b4bbae8d549d43cc00941f59551b3
commit: 6661b228ba4b4bbae8d549d43cc00941f59551b3
branch: 3.10
author: Adam Turner <9087854+aa-tur...@users.noreply.github.com>
committer: ambv 
date: 2024-01-17T14:50:24+01:00
summary:

[3.10] gh-114021: Pin various sphinxcontrib extensions to older versions 
(GH-114022) (GH-114038)

(cherry picked from commit 94b1d1fa38ada8cf7d196184a04a195c152eed75)

Co-authored-by: Ronald Oussoren 

files:
A Doc/constraints.txt
M Doc/requirements.txt

diff --git a/Doc/constraints.txt b/Doc/constraints.txt
new file mode 100644
index 00..16b735ea07a72a
--- /dev/null
+++ b/Doc/constraints.txt
@@ -0,0 +1,24 @@
+# We have upper bounds on our transitive dependencies here
+# To avoid new releases unexpectedly breaking our build.
+# This file can be updated on an ad-hoc basis,
+# though it will probably have to be updated
+# whenever Doc/requirements.txt is updated.
+
+# Direct dependencies of Sphinx
+babel<3
+colorama<0.5
+imagesize<1.5
+Jinja2<3.2
+packaging<24
+Pygments>=2.16.1,<3
+requests<3
+snowballstemmer<3
+sphinxcontrib-applehelp<1.0.5
+sphinxcontrib-devhelp<1.0.6
+sphinxcontrib-htmlhelp<2.0.5
+sphinxcontrib-jsmath<1.1
+sphinxcontrib-qthelp<1.0.7
+sphinxcontrib-serializinghtml<1.1.10
+
+# Direct dependencies of Jinja2 (Jinja is a dependency of Sphinx, see above)
+MarkupSafe<2.2
diff --git a/Doc/requirements.txt b/Doc/requirements.txt
index f43ce2c6e4efd8..da5c38ae1a0298 100644
--- a/Doc/requirements.txt
+++ b/Doc/requirements.txt
@@ -16,3 +16,5 @@ blurb
 # The theme used by the documentation is stored separately, so we need
 # to install that as well.
 python-docs-theme>=2022.1
+
+-c constraints.txt

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


[Python-checkins] [3.10] gh-109858: Protect zipfile from "quoted-overlap" zipbomb (GH-110016) (GH-113914)

2024-01-17 Thread ambv
https://github.com/python/cpython/commit/30fe5d853b56138dbec62432d370a1f99409fc85
commit: 30fe5d853b56138dbec62432d370a1f99409fc85
branch: 3.10
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: ambv 
date: 2024-01-17T14:50:10+01:00
summary:

[3.10] gh-109858: Protect zipfile from "quoted-overlap" zipbomb (GH-110016) 
(GH-113914)

Raise BadZipFile when try to read an entry that overlaps with other entry or
central directory.
(cherry picked from commit 66363b9a7b9fe7c99eba3a185b74c5fdbf842eba)

Co-authored-by: Serhiy Storchaka 

files:
A Misc/NEWS.d/next/Library/2023-09-28-13-15-51.gh-issue-109858.43e2dg.rst
M Lib/test/test_zipfile.py
M Lib/zipfile.py

diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py
index 3495fc6548b425..32c01704d9d1d6 100644
--- a/Lib/test/test_zipfile.py
+++ b/Lib/test/test_zipfile.py
@@ -2059,6 +2059,66 @@ def test_decompress_without_3rd_party_library(self):
 with zipfile.ZipFile(zip_file) as zf:
 self.assertRaises(RuntimeError, zf.extract, 'a.txt')
 
+@requires_zlib()
+def test_full_overlap(self):
+data = (
+b'PK\x03\x04\x14\x00\x00\x00\x08\x00\xa0lH\x05\xe2\x1e'
+b'8\xbb\x10\x00\x00\x00\t\x04\x00\x00\x01\x00\x00\x00a\xed'
+b'\xc0\x81\x08\x00\x00\x00\xc00\xd6\xfbK\\d\x0b`P'
+b'K\x01\x02\x14\x00\x14\x00\x00\x00\x08\x00\xa0lH\x05\xe2'
+b'\x1e8\xbb\x10\x00\x00\x00\t\x04\x00\x00\x01\x00\x00\x00\x00'
+b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00aPK'
+b'\x01\x02\x14\x00\x14\x00\x00\x00\x08\x00\xa0lH\x05\xe2\x1e'
+b'8\xbb\x10\x00\x00\x00\t\x04\x00\x00\x01\x00\x00\x00\x00\x00'
+b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00bPK\x05'
+b'\x06\x00\x00\x00\x00\x02\x00\x02\x00^\x00\x00\x00/\x00\x00'
+b'\x00\x00\x00'
+)
+with zipfile.ZipFile(io.BytesIO(data), 'r') as zipf:
+self.assertEqual(zipf.namelist(), ['a', 'b'])
+zi = zipf.getinfo('a')
+self.assertEqual(zi.header_offset, 0)
+self.assertEqual(zi.compress_size, 16)
+self.assertEqual(zi.file_size, 1033)
+zi = zipf.getinfo('b')
+self.assertEqual(zi.header_offset, 0)
+self.assertEqual(zi.compress_size, 16)
+self.assertEqual(zi.file_size, 1033)
+self.assertEqual(len(zipf.read('a')), 1033)
+with self.assertRaisesRegex(zipfile.BadZipFile, 'File 
name.*differ'):
+zipf.read('b')
+
+@requires_zlib()
+def test_quoted_overlap(self):
+data = (
+b'PK\x03\x04\x14\x00\x00\x00\x08\x00\xa0lH\x05Y\xfc'
+b'8\x044\x00\x00\x00(\x04\x00\x00\x01\x00\x00\x00a\x00'
+b'\x1f\x00\xe0\xffPK\x03\x04\x14\x00\x00\x00\x08\x00\xa0l'
+b'H\x05\xe2\x1e8\xbb\x10\x00\x00\x00\t\x04\x00\x00\x01\x00'
+b'\x00\x00b\xed\xc0\x81\x08\x00\x00\x00\xc00\xd6\xfbK\\'
+b'd\x0b`PK\x01\x02\x14\x00\x14\x00\x00\x00\x08\x00\xa0'
+b'lH\x05Y\xfc8\x044\x00\x00\x00(\x04\x00\x00\x01'
+b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+b'\x00aPK\x01\x02\x14\x00\x14\x00\x00\x00\x08\x00\xa0l'
+b'H\x05\xe2\x1e8\xbb\x10\x00\x00\x00\t\x04\x00\x00\x01\x00'
+b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\x00\x00\x00'
+b'bPK\x05\x06\x00\x00\x00\x00\x02\x00\x02\x00^\x00\x00'
+b'\x00S\x00\x00\x00\x00\x00'
+)
+with zipfile.ZipFile(io.BytesIO(data), 'r') as zipf:
+self.assertEqual(zipf.namelist(), ['a', 'b'])
+zi = zipf.getinfo('a')
+self.assertEqual(zi.header_offset, 0)
+self.assertEqual(zi.compress_size, 52)
+self.assertEqual(zi.file_size, 1064)
+zi = zipf.getinfo('b')
+self.assertEqual(zi.header_offset, 36)
+self.assertEqual(zi.compress_size, 16)
+self.assertEqual(zi.file_size, 1033)
+with self.assertRaisesRegex(zipfile.BadZipFile, 'Overlapped 
entries'):
+zipf.read('a')
+self.assertEqual(len(zipf.read('b')), 1033)
+
 def tearDown(self):
 unlink(TESTFN)
 unlink(TESTFN2)
diff --git a/Lib/zipfile.py b/Lib/zipfile.py
index 42e11d7e255caa..7d18bc2479fcda 100644
--- a/Lib/zipfile.py
+++ b/Lib/zipfile.py
@@ -341,6 +341,7 @@ class ZipInfo (object):
 'compress_size',
 'file_size',
 '_raw_time',
+'_end_offset',
 )
 
 def __init__(self, filename="NoName", date_time=(1980,1,1,0,0,0)):
@@ -382,6 +383,7 @@ def __init__(self, filename="NoName", 
date_time=(1980,1,1,0,0,0)):
 self.external_attr = 0  # External file attributes
 self.compress_size = 0  # Size of the compressed file
 self.file_size = 0  # Size of the uncompressed file
+self._end_offset = None

[Python-checkins] [3.8] gh-107888: Fix test_mmap.test_access_parameter() on macOS 14 (GH-109928) (GH-114183)

2024-01-17 Thread ambv
https://github.com/python/cpython/commit/648c44d3f7a020c7fed95d57b105738cf018a7cc
commit: 648c44d3f7a020c7fed95d57b105738cf018a7cc
branch: 3.8
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: ambv 
date: 2024-01-17T15:02:24+01:00
summary:

[3.8] gh-107888: Fix test_mmap.test_access_parameter() on macOS 14 (GH-109928) 
(GH-114183)

(cherry picked from commit 9dbfe2dc8e7bba25e52f9470ae6969821a365297)

Co-authored-by: Victor Stinner 

files:
M Lib/test/test_mmap.py

diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py
index 88c501d81a07f9..358a01d7185232 100644
--- a/Lib/test/test_mmap.py
+++ b/Lib/test/test_mmap.py
@@ -240,10 +240,15 @@ def test_access_parameter(self):
 # Try writing with PROT_EXEC and without PROT_WRITE
 prot = mmap.PROT_READ | getattr(mmap, 'PROT_EXEC', 0)
 with open(TESTFN, "r+b") as f:
-m = mmap.mmap(f.fileno(), mapsize, prot=prot)
-self.assertRaises(TypeError, m.write, b"abcdef")
-self.assertRaises(TypeError, m.write_byte, 0)
-m.close()
+try:
+m = mmap.mmap(f.fileno(), mapsize, prot=prot)
+except PermissionError:
+# on macOS 14, PROT_READ | PROT_WRITE is not allowed
+pass
+else:
+self.assertRaises(TypeError, m.write, b"abcdef")
+self.assertRaises(TypeError, m.write_byte, 0)
+m.close()
 
 def test_bad_file_desc(self):
 # Try opening a bad file descriptor...

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


[Python-checkins] [3.10] gh-107888: Fix test_mmap.test_access_parameter() on macOS 14 (GH-109928) (GH-114185)

2024-01-17 Thread ambv
https://github.com/python/cpython/commit/12748967273bc433432052a5c0a414ef10668d92
commit: 12748967273bc433432052a5c0a414ef10668d92
branch: 3.10
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: ambv 
date: 2024-01-17T15:02:42+01:00
summary:

[3.10] gh-107888: Fix test_mmap.test_access_parameter() on macOS 14 (GH-109928) 
(GH-114185)

(cherry picked from commit 9dbfe2dc8e7bba25e52f9470ae6969821a365297)

Co-authored-by: Victor Stinner 

files:
M Lib/test/test_mmap.py

diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py
index 8f34c182f82eaf..307e2b93559ff2 100644
--- a/Lib/test/test_mmap.py
+++ b/Lib/test/test_mmap.py
@@ -241,10 +241,15 @@ def test_access_parameter(self):
 # Try writing with PROT_EXEC and without PROT_WRITE
 prot = mmap.PROT_READ | getattr(mmap, 'PROT_EXEC', 0)
 with open(TESTFN, "r+b") as f:
-m = mmap.mmap(f.fileno(), mapsize, prot=prot)
-self.assertRaises(TypeError, m.write, b"abcdef")
-self.assertRaises(TypeError, m.write_byte, 0)
-m.close()
+try:
+m = mmap.mmap(f.fileno(), mapsize, prot=prot)
+except PermissionError:
+# on macOS 14, PROT_READ | PROT_WRITE is not allowed
+pass
+else:
+self.assertRaises(TypeError, m.write, b"abcdef")
+self.assertRaises(TypeError, m.write_byte, 0)
+m.close()
 
 def test_bad_file_desc(self):
 # Try opening a bad file descriptor...

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


[Python-checkins] [3.11] gh-70835: Clarify error message for CSV file opened with wrong newline (GH-113786) (GH-113906)

2024-01-17 Thread ambv
https://github.com/python/cpython/commit/99a7bdc646f1a7020231156e4aca19b949d8ee71
commit: 99a7bdc646f1a7020231156e4aca19b949d8ee71
branch: 3.11
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: ambv 
date: 2024-01-17T15:06:39+01:00
summary:

[3.11] gh-70835: Clarify error message for CSV file opened with wrong newline 
(GH-113786) (GH-113906)

Based on patch by SilentGhost.
(cherry picked from commit 568d220993fa9b4b812ff1b425edd80dbe17dda9)

Co-authored-by: Serhiy Storchaka 

files:
M Lib/test/test_csv.py
M Modules/_csv.c

diff --git a/Lib/test/test_csv.py b/Lib/test/test_csv.py
index 05653a26841799..1bf487bcf9bd70 100644
--- a/Lib/test/test_csv.py
+++ b/Lib/test/test_csv.py
@@ -305,13 +305,18 @@ def test_read_oddinputs(self):
   [b'abc'], None)
 
 def test_read_eol(self):
-self._read_test(['a,b'], [['a','b']])
-self._read_test(['a,b\n'], [['a','b']])
-self._read_test(['a,b\r\n'], [['a','b']])
-self._read_test(['a,b\r'], [['a','b']])
-self.assertRaises(csv.Error, self._read_test, ['a,b\rc,d'], [])
-self.assertRaises(csv.Error, self._read_test, ['a,b\nc,d'], [])
-self.assertRaises(csv.Error, self._read_test, ['a,b\r\nc,d'], [])
+self._read_test(['a,b', 'c,d'], [['a','b'], ['c','d']])
+self._read_test(['a,b\n', 'c,d\n'], [['a','b'], ['c','d']])
+self._read_test(['a,b\r\n', 'c,d\r\n'], [['a','b'], ['c','d']])
+self._read_test(['a,b\r', 'c,d\r'], [['a','b'], ['c','d']])
+
+errmsg = "with newline=''"
+with self.assertRaisesRegex(csv.Error, errmsg):
+next(csv.reader(['a,b\rc,d']))
+with self.assertRaisesRegex(csv.Error, errmsg):
+next(csv.reader(['a,b\nc,d']))
+with self.assertRaisesRegex(csv.Error, errmsg):
+next(csv.reader(['a,b\r\nc,d']))
 
 def test_read_eof(self):
 self._read_test(['a,"'], [['a', '']])
diff --git a/Modules/_csv.c b/Modules/_csv.c
index 7314d9c7053778..407d6f03540d9c 100644
--- a/Modules/_csv.c
+++ b/Modules/_csv.c
@@ -841,7 +841,8 @@ parse_process_char(ReaderObj *self, _csvstate 
*module_state, Py_UCS4 c)
 self->state = START_RECORD;
 else {
 PyErr_Format(module_state->error_obj,
- "new-line character seen in unquoted field - do you 
need to open the file in universal-newline mode?");
+ "new-line character seen in unquoted field - "
+ "do you need to open the file with newline=''?");
 return -1;
 }
 break;

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


[Python-checkins] [3.11] gh-111777: Fix assertion errors on incorrectly still-tracked GC object destruction (GH-111778) (GH-111990)

2024-01-17 Thread ambv
https://github.com/python/cpython/commit/67424458d23428d524e7c08e1556d7687297dbaa
commit: 67424458d23428d524e7c08e1556d7687297dbaa
branch: 3.11
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: ambv 
date: 2024-01-17T15:10:12+01:00
summary:

[3.11] gh-111777: Fix assertion errors on incorrectly still-tracked GC object 
destruction (GH-111778) (GH-111990)

In PyObject_GC_Del, in Py_DEBUG mode, when warning about GC objects that
were not properly untracked before starting destruction, take care to
untrack the object _before_ warning, to avoid triggering a GC run and
causing the problem the code tries to warn about. Also make sure to save and
restore any pending exceptions, which the warning would otherwise clobber or
trigger an assertion error on.
(cherry picked from commit ce6a533c4bf1afa3775dfcaee5fc7d5c15a4af8c)

Co-authored-by: T. Wouters 

files:
M Modules/gcmodule.c

diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index dcd46feff0cc48..347ded80b7c18f 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -2347,14 +2347,18 @@ PyObject_GC_Del(void *op)
 size_t presize = _PyType_PreHeaderSize(((PyObject *)op)->ob_type);
 PyGC_Head *g = AS_GC(op);
 if (_PyObject_GC_IS_TRACKED(op)) {
+gc_list_remove(g);
 #ifdef Py_DEBUG
+PyObject *exc, *exc_value, *exc_tb;
+PyErr_Fetch(&exc, &exc_value, &exc_tb);
 if (PyErr_WarnExplicitFormat(PyExc_ResourceWarning, "gc", 0,
  "gc", NULL, "Object of type %s is not 
untracked before destruction",
  ((PyObject*)op)->ob_type->tp_name)) {
 PyErr_WriteUnraisable(NULL);
 }
+if (exc != NULL)
+PyErr_Restore(exc, exc_value, exc_tb);
 #endif
-gc_list_remove(g);
 }
 GCState *gcstate = get_gc_state();
 if (gcstate->generations[0].count > 0) {

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


[Python-checkins] [3.9] gh-107888: Fix test_mmap.test_access_parameter() on macOS 14 (GH-109928) (GH-114184)

2024-01-17 Thread ambv
https://github.com/python/cpython/commit/dd068eaf48cd5e94610031845107e96b35bc0d87
commit: dd068eaf48cd5e94610031845107e96b35bc0d87
branch: 3.9
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: ambv 
date: 2024-01-17T15:10:35+01:00
summary:

[3.9] gh-107888: Fix test_mmap.test_access_parameter() on macOS 14 (GH-109928) 
(GH-114184)

(cherry picked from commit 9dbfe2dc8e7bba25e52f9470ae6969821a365297)

Co-authored-by: Victor Stinner 

files:
M Lib/test/test_mmap.py

diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py
index 5400f25f50800b..89ada50998633e 100644
--- a/Lib/test/test_mmap.py
+++ b/Lib/test/test_mmap.py
@@ -240,10 +240,15 @@ def test_access_parameter(self):
 # Try writing with PROT_EXEC and without PROT_WRITE
 prot = mmap.PROT_READ | getattr(mmap, 'PROT_EXEC', 0)
 with open(TESTFN, "r+b") as f:
-m = mmap.mmap(f.fileno(), mapsize, prot=prot)
-self.assertRaises(TypeError, m.write, b"abcdef")
-self.assertRaises(TypeError, m.write_byte, 0)
-m.close()
+try:
+m = mmap.mmap(f.fileno(), mapsize, prot=prot)
+except PermissionError:
+# on macOS 14, PROT_READ | PROT_WRITE is not allowed
+pass
+else:
+self.assertRaises(TypeError, m.write, b"abcdef")
+self.assertRaises(TypeError, m.write_byte, 0)
+m.close()
 
 def test_bad_file_desc(self):
 # Try opening a bad file descriptor...

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


[Python-checkins] gh-111301: Advertise importlib methods removal in What's new in Python 3.12 (GH-111630)

2024-01-17 Thread ambv
https://github.com/python/cpython/commit/f49752552e673e5192f22eae0076b2650c7d6afc
commit: f49752552e673e5192f22eae0076b2650c7d6afc
branch: main
author: Karolina Surma <33810531+befel...@users.noreply.github.com>
committer: ambv 
date: 2024-01-17T15:25:42+01:00
summary:

gh-111301: Advertise importlib methods removal in What's new in Python 3.12 
(GH-111630)

files:
M Doc/whatsnew/3.12.rst

diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst
index 9a2ccf7ebc6a68..77b12f9284ba0d 100644
--- a/Doc/whatsnew/3.12.rst
+++ b/Doc/whatsnew/3.12.rst
@@ -1374,6 +1374,18 @@ APIs:
 * :meth:`!unittest.TestProgram.usageExit` (:gh:`67048`)
 * :class:`!webbrowser.MacOSX` (:gh:`86421`)
 * :class:`classmethod` descriptor chaining (:gh:`89519`)
+* :mod:`importlib.resources` deprecated methods:
+
+  * ``contents()``
+  * ``is_resource()``
+  * ``open_binary()``
+  * ``open_text()``
+  * ``path()``
+  * ``read_binary()``
+  * ``read_text()``
+
+  Use :func:`importlib.resources.files()` instead.  Refer to 
`importlib-resources: Migrating from Legacy
+  
`_
 (:gh:`106531`)
 
 Pending Removal in Python 3.14
 --

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


[Python-checkins] [3.9] gh-113659: Skip hidden .pth files (GH-113660) (GH-114146)

2024-01-17 Thread ambv
https://github.com/python/cpython/commit/8fc8c45b6717be58ad927def1bf3ea05c83cab8c
commit: 8fc8c45b6717be58ad927def1bf3ea05c83cab8c
branch: 3.9
author: Serhiy Storchaka 
committer: ambv 
date: 2024-01-17T15:28:17+01:00
summary:

[3.9] gh-113659: Skip hidden .pth files (GH-113660) (GH-114146)

(cherry picked from commit 74208ed0c440244fb809d8acc97cb9ef51e888e3)

Co-authored-by: Łukasz Langa 

files:
A Misc/NEWS.d/next/Security/2024-01-02-19-52-23.gh-issue-113659.DkmnQc.rst
M Lib/site.py
M Lib/test/test_site.py

diff --git a/Lib/site.py b/Lib/site.py
index 9e617afb00f1e4..54ffc4fdc03fff 100644
--- a/Lib/site.py
+++ b/Lib/site.py
@@ -74,6 +74,7 @@
 import builtins
 import _sitebuiltins
 import io
+import stat
 
 # Prefixes for site-packages; add additional prefixes like /usr/local here
 PREFIXES = [sys.prefix, sys.exec_prefix]
@@ -156,6 +157,13 @@ def addpackage(sitedir, name, known_paths):
 else:
 reset = False
 fullname = os.path.join(sitedir, name)
+try:
+st = os.lstat(fullname)
+except OSError:
+return
+if ((getattr(st, 'st_flags', 0) & stat.UF_HIDDEN) or
+(getattr(st, 'st_file_attributes', 0) & stat.FILE_ATTRIBUTE_HIDDEN)):
+return
 try:
 f = io.TextIOWrapper(io.open_code(fullname))
 except OSError:
@@ -203,7 +211,8 @@ def addsitedir(sitedir, known_paths=None):
 names = os.listdir(sitedir)
 except OSError:
 return
-names = [name for name in names if name.endswith(".pth")]
+names = [name for name in names
+ if name.endswith(".pth") and not name.startswith(".")]
 for name in sorted(names):
 addpackage(sitedir, name, known_paths)
 if reset:
diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py
index 3d25d7e473f957..e578cd7db3daaa 100644
--- a/Lib/test/test_site.py
+++ b/Lib/test/test_site.py
@@ -16,6 +16,7 @@
 import os
 import re
 import shutil
+import stat
 import subprocess
 import sys
 import sysconfig
@@ -185,6 +186,44 @@ def test_addsitedir(self):
 finally:
 pth_file.cleanup()
 
+def test_addsitedir_dotfile(self):
+pth_file = PthFile('.dotfile')
+pth_file.cleanup(prep=True)
+try:
+pth_file.create()
+site.addsitedir(pth_file.base_dir, set())
+self.assertNotIn(site.makepath(pth_file.good_dir_path)[0], 
sys.path)
+self.assertIn(pth_file.base_dir, sys.path)
+finally:
+pth_file.cleanup()
+
+@unittest.skipUnless(hasattr(os, 'chflags'), 'test needs os.chflags()')
+def test_addsitedir_hidden_flags(self):
+pth_file = PthFile()
+pth_file.cleanup(prep=True)
+try:
+pth_file.create()
+st = os.stat(pth_file.file_path)
+os.chflags(pth_file.file_path, st.st_flags | stat.UF_HIDDEN)
+site.addsitedir(pth_file.base_dir, set())
+self.assertNotIn(site.makepath(pth_file.good_dir_path)[0], 
sys.path)
+self.assertIn(pth_file.base_dir, sys.path)
+finally:
+pth_file.cleanup()
+
+@unittest.skipUnless(sys.platform == 'win32', 'test needs Windows')
+def test_addsitedir_hidden_file_attribute(self):
+pth_file = PthFile()
+pth_file.cleanup(prep=True)
+try:
+pth_file.create()
+subprocess.check_call(['attrib', '+H', pth_file.file_path])
+site.addsitedir(pth_file.base_dir, set())
+self.assertNotIn(site.makepath(pth_file.good_dir_path)[0], 
sys.path)
+self.assertIn(pth_file.base_dir, sys.path)
+finally:
+pth_file.cleanup()
+
 # This tests _getuserbase, hence the double underline
 # to distinguish from a test for getuserbase
 def test__getuserbase(self):
diff --git 
a/Misc/NEWS.d/next/Security/2024-01-02-19-52-23.gh-issue-113659.DkmnQc.rst 
b/Misc/NEWS.d/next/Security/2024-01-02-19-52-23.gh-issue-113659.DkmnQc.rst
new file mode 100644
index 00..744687e72324d1
--- /dev/null
+++ b/Misc/NEWS.d/next/Security/2024-01-02-19-52-23.gh-issue-113659.DkmnQc.rst
@@ -0,0 +1 @@
+Skip ``.pth`` files with names starting with a dot or hidden file attribute.

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


[Python-checkins] gh-112343: pdb: Use tokenize to replace convenience variables (#112380)

2024-01-17 Thread iritkatriel
https://github.com/python/cpython/commit/5c351fc85afd2ed167694a7dfe066741a5cdab53
commit: 5c351fc85afd2ed167694a7dfe066741a5cdab53
branch: main
author: Tian Gao 
committer: iritkatriel <1055913+iritkatr...@users.noreply.github.com>
date: 2024-01-17T14:50:31Z
summary:

gh-112343: pdb: Use tokenize to replace convenience variables (#112380)

files:
A Misc/NEWS.d/next/Library/2023-11-24-19-08-50.gh-issue-112343.RarGFC.rst
M Lib/pdb.py
M Lib/test/test_pdb.py

diff --git a/Lib/pdb.py b/Lib/pdb.py
index 83b7fefec63636..68f810620f8826 100755
--- a/Lib/pdb.py
+++ b/Lib/pdb.py
@@ -76,6 +76,7 @@
 import dis
 import code
 import glob
+import token
 import codeop
 import pprint
 import signal
@@ -601,6 +602,39 @@ def default(self, line):
 except:
 self._error_exc()
 
+def _replace_convenience_variables(self, line):
+"""Replace the convenience variables in 'line' with their values.
+   e.g. $foo is replaced by __pdb_convenience_variables["foo"].
+   Note: such pattern in string literals will be skipped"""
+
+if "$" not in line:
+return line
+
+dollar_start = dollar_end = -1
+replace_variables = []
+try:
+for t in tokenize.generate_tokens(io.StringIO(line).readline):
+token_type, token_string, start, end, _ = t
+if token_type == token.OP and token_string == '$':
+dollar_start, dollar_end = start, end
+elif start == dollar_end and token_type == token.NAME:
+# line is a one-line command so we only care about column
+replace_variables.append((dollar_start[1], end[1], 
token_string))
+except tokenize.TokenError:
+return line
+
+if not replace_variables:
+return line
+
+last_end = 0
+line_pieces = []
+for start, end, name in replace_variables:
+line_pieces.append(line[last_end:start] + 
f'__pdb_convenience_variables["{name}"]')
+last_end = end
+line_pieces.append(line[last_end:])
+
+return ''.join(line_pieces)
+
 def precmd(self, line):
 """Handle alias expansion and ';;' separator."""
 if not line.strip():
@@ -635,7 +669,7 @@ def precmd(self, line):
 line = line[:marker].rstrip()
 
 # Replace all the convenience variables
-line = re.sub(r'\$([a-zA-Z_][a-zA-Z0-9_]*)', 
r'__pdb_convenience_variables["\1"]', line)
+line = self._replace_convenience_variables(line)
 
 return line
 
diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py
index d53fe3c611bc35..333d8a95dc4b7b 100644
--- a/Lib/test/test_pdb.py
+++ b/Lib/test/test_pdb.py
@@ -847,9 +847,12 @@ def test_convenience_variables():
 
 >>> with PdbTestInput([  # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
 ... '$_frame.f_lineno', # Check frame convenience variable
+... '$ _frame', # This should be a syntax error
 ... '$a = 10',  # Set a convenience variable
 ... '$a',   # Print its value
+... 'p "$a"',   # Print the string $a
 ... 'p $a + 2', # Do some calculation
+... 'p f"$a = {$a}"',   # Make sure $ in string is not converted and 
f-string works
 ... 'u',# Switch frame
 ... '$_frame.f_lineno', # Make sure the frame changed
 ... '$a',   # Make sure the value persists
@@ -869,11 +872,17 @@ def test_convenience_variables():
 -> try:
 (Pdb) $_frame.f_lineno
 3
+(Pdb) $ _frame
+*** SyntaxError: invalid syntax
 (Pdb) $a = 10
 (Pdb) $a
 10
+(Pdb) p "$a"
+'$a'
 (Pdb) p $a + 2
 12
+(Pdb) p f"$a = {$a}"
+'$a = 10'
 (Pdb) u
 > (2)test_function()
 -> util_function()
diff --git 
a/Misc/NEWS.d/next/Library/2023-11-24-19-08-50.gh-issue-112343.RarGFC.rst 
b/Misc/NEWS.d/next/Library/2023-11-24-19-08-50.gh-issue-112343.RarGFC.rst
new file mode 100644
index 00..aaa50fce3ac962
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-11-24-19-08-50.gh-issue-112343.RarGFC.rst
@@ -0,0 +1 @@
+Improve handling of pdb convenience variables to avoid replacing string 
contents.

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


[Python-checkins] [3.11] gh-113858: GH Actions: Make ccache smaller (GH-114082) (#114188)

2024-01-17 Thread hugovk
https://github.com/python/cpython/commit/8e0c9213ac8d8ee8cb17c889aaabeafc40cb29f3
commit: 8e0c9213ac8d8ee8cb17c889aaabeafc40cb29f3
branch: 3.11
author: Petr Viktorin 
committer: hugovk <1324225+hug...@users.noreply.github.com>
date: 2024-01-17T16:06:52Z
summary:

[3.11] gh-113858: GH Actions: Make ccache smaller (GH-114082) (#114188)

Co-authored-by: Hugo van Kemenade 

files:
M .github/workflows/build.yml
M .github/workflows/reusable-ubuntu.yml

diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index ad9ec980a9540a..080db450cf 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -156,6 +156,8 @@ jobs:
 run: echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV
   - name: Configure ccache action
 uses: hendrikmuhs/ccache-action@v1.2
+with:
+  save: false
   - name: Check Autoconf version 2.69 and aclocal 1.16.3
 run: |
   grep "Generated by GNU Autoconf 2.69" configure
@@ -266,6 +268,8 @@ jobs:
 echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV
 - name: Configure ccache action
   uses: hendrikmuhs/ccache-action@v1.2
+  with:
+save: false
 - name: Configure CPython
   run: ./configure --config-cache --with-pydebug 
--with-openssl=$OPENSSL_DIR
 - name: Build CPython
@@ -319,6 +323,9 @@ jobs:
 echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV
 - name: Configure ccache action
   uses: hendrikmuhs/ccache-action@v1.2
+  with:
+save: ${{ github.event_name == 'push' }}
+max-size: "200M"
 - name: Configure CPython
   run: ./configure --config-cache --with-address-sanitizer 
--without-pymalloc
 - name: Build CPython
diff --git a/.github/workflows/reusable-ubuntu.yml 
b/.github/workflows/reusable-ubuntu.yml
index 56268c8bfd3419..db4ca4d4667399 100644
--- a/.github/workflows/reusable-ubuntu.yml
+++ b/.github/workflows/reusable-ubuntu.yml
@@ -41,6 +41,9 @@ jobs:
 echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV
 - name: Configure ccache action
   uses: hendrikmuhs/ccache-action@v1.2
+  with:
+save: ${{ github.event_name == 'push' }}
+max-size: "200M"
 - name: Setup directory envs for out-of-tree builds
   run: |
 echo "CPYTHON_RO_SRCDIR=$(realpath -m 
${GITHUB_WORKSPACE}/../cpython-ro-srcdir)" >> $GITHUB_ENV

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


[Python-checkins] gh-114178: Fix generate_sbom.py for out-of-tree builds (#114179)

2024-01-17 Thread erlend-aasland
https://github.com/python/cpython/commit/7a0ac89b292324b629114a4c49b95fc5a78df7ca
commit: 7a0ac89b292324b629114a4c49b95fc5a78df7ca
branch: main
author: Erlend E. Aasland 
committer: erlend-aasland 
date: 2024-01-17T17:25:39+01:00
summary:

gh-114178: Fix generate_sbom.py for out-of-tree builds (#114179)

files:
M Tools/build/generate_sbom.py

diff --git a/Tools/build/generate_sbom.py b/Tools/build/generate_sbom.py
index 282ee20cc402b0..317d48fee3a9d4 100644
--- a/Tools/build/generate_sbom.py
+++ b/Tools/build/generate_sbom.py
@@ -106,6 +106,7 @@ def filter_gitignored_paths(paths: list[str]) -> list[str]:
 # Non-matching files show up as '::'
 git_check_ignore_proc = subprocess.run(
 ["git", "check-ignore", "--verbose", "--non-matching", *paths],
+cwd=CPYTHON_ROOT_DIR,
 check=False,
 stdout=subprocess.PIPE,
 )

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


[Python-checkins] gh-114070: fix token reference warnings in expressions.rst (#114169)

2024-01-17 Thread hugovk
https://github.com/python/cpython/commit/029ecee10dcb7c88382849f0220dba58a654e303
commit: 029ecee10dcb7c88382849f0220dba58a654e303
branch: main
author: Sergey B Kirpichev 
committer: hugovk <1324225+hug...@users.noreply.github.com>
date: 2024-01-17T18:39:50+02:00
summary:

gh-114070: fix token reference warnings in expressions.rst (#114169)

files:
M Doc/reference/expressions.rst

diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst
index 3f6d5bfafee9d1..e543c1228d4d19 100644
--- a/Doc/reference/expressions.rst
+++ b/Doc/reference/expressions.rst
@@ -14,7 +14,7 @@ be used to describe syntax, not lexical analysis.  When (one 
alternative of) a
 syntax rule has the form
 
 .. productionlist:: python-grammar
-   name: `othername`
+   name: othername
 
 and no semantics are given, the semantics of this form of ``name`` are the same
 as for ``othername``.
@@ -422,7 +422,8 @@ Yield expressions
 
 .. productionlist:: python-grammar
yield_atom: "(" `yield_expression` ")"
-   yield_expression: "yield" [`expression_list` | "from" `expression`]
+   yield_from: "yield" "from" `expression`
+   yield_expression: "yield" `expression_list` | `yield_from`
 
 The yield expression is used when defining a :term:`generator` function
 or an :term:`asynchronous generator` function and

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


[Python-checkins] [3.12] gh-114070: fix token reference warnings in expressions.rst (GH-114169) (#114192)

2024-01-17 Thread hugovk
https://github.com/python/cpython/commit/74a6b7f6393a2417df8422b4663642e3588687fd
commit: 74a6b7f6393a2417df8422b4663642e3588687fd
branch: 3.12
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: hugovk <1324225+hug...@users.noreply.github.com>
date: 2024-01-17T16:46:02Z
summary:

[3.12] gh-114070: fix token reference warnings in expressions.rst (GH-114169) 
(#114192)

Co-authored-by: Sergey B Kirpichev 

files:
M Doc/reference/expressions.rst

diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst
index e78dff979787f6..c30a97f3f2e7f6 100644
--- a/Doc/reference/expressions.rst
+++ b/Doc/reference/expressions.rst
@@ -14,7 +14,7 @@ be used to describe syntax, not lexical analysis.  When (one 
alternative of) a
 syntax rule has the form
 
 .. productionlist:: python-grammar
-   name: `othername`
+   name: othername
 
 and no semantics are given, the semantics of this form of ``name`` are the same
 as for ``othername``.
@@ -422,7 +422,8 @@ Yield expressions
 
 .. productionlist:: python-grammar
yield_atom: "(" `yield_expression` ")"
-   yield_expression: "yield" [`expression_list` | "from" `expression`]
+   yield_from: "yield" "from" `expression`
+   yield_expression: "yield" `expression_list` | `yield_from`
 
 The yield expression is used when defining a :term:`generator` function
 or an :term:`asynchronous generator` function and

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


[Python-checkins] [3.11] gh-114070: fix token reference warnings in expressions.rst (GH-114169) (#114193)

2024-01-17 Thread hugovk
https://github.com/python/cpython/commit/654c70a655f592cb61c6816b76c5b1dd452d51aa
commit: 654c70a655f592cb61c6816b76c5b1dd452d51aa
branch: 3.11
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: hugovk <1324225+hug...@users.noreply.github.com>
date: 2024-01-17T18:53:08+02:00
summary:

[3.11] gh-114070: fix token reference warnings in expressions.rst (GH-114169) 
(#114193)

Co-authored-by: Sergey B Kirpichev 

files:
M Doc/reference/expressions.rst

diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst
index 7130aa2f6b7b7b..05055b62498d91 100644
--- a/Doc/reference/expressions.rst
+++ b/Doc/reference/expressions.rst
@@ -14,7 +14,7 @@ be used to describe syntax, not lexical analysis.  When (one 
alternative of) a
 syntax rule has the form
 
 .. productionlist:: python-grammar
-   name: `othername`
+   name: othername
 
 and no semantics are given, the semantics of this form of ``name`` are the same
 as for ``othername``.
@@ -422,7 +422,8 @@ Yield expressions
 
 .. productionlist:: python-grammar
yield_atom: "(" `yield_expression` ")"
-   yield_expression: "yield" [`expression_list` | "from" `expression`]
+   yield_from: "yield" "from" `expression`
+   yield_expression: "yield" `expression_list` | `yield_from`
 
 The yield expression is used when defining a :term:`generator` function
 or an :term:`asynchronous generator` function and

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


[Python-checkins] gh-114149: [Enum] fix tuple subclass handling when using custom __new__ (GH-114160)

2024-01-17 Thread ethanfurman
https://github.com/python/cpython/commit/33b47a2c2853066b549f242065f6c2e12e18b33b
commit: 33b47a2c2853066b549f242065f6c2e12e18b33b
branch: main
author: Ethan Furman 
committer: ethanfurman 
date: 2024-01-17T09:47:11-08:00
summary:

gh-114149: [Enum] fix tuple subclass handling when using custom __new__ 
(GH-114160)

files:
A Misc/NEWS.d/next/Library/2024-01-16-15-59-06.gh-issue-114149.LJ8IPm.rst
M Lib/enum.py
M Lib/test/test_enum.py

diff --git a/Lib/enum.py b/Lib/enum.py
index a8a50a58380375..e51850d9b45d33 100644
--- a/Lib/enum.py
+++ b/Lib/enum.py
@@ -250,7 +250,7 @@ def __set_name__(self, enum_class, member_name):
 delattr(enum_class, member_name)
 # second step: create member based on enum_class
 value = self.value
-if not isinstance(value, tuple):
+if type(value) is not tuple:
 args = (value, )
 else:
 args = value
@@ -1777,7 +1777,7 @@ def convert_class(cls):
 else:
 # create the member
 if use_args:
-if not isinstance(value, tuple):
+if type(value) is not tuple:
 value = (value, )
 member = new_member(enum_class, *value)
 value = value[0]
@@ -1826,7 +1826,7 @@ def convert_class(cls):
 else:
 # create the member
 if use_args:
-if not isinstance(value, tuple):
+if type(value) is not tuple:
 value = (value, )
 member = new_member(enum_class, *value)
 value = value[0]
diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py
index f99d4ca204b5a7..48e0b02b2b6219 100644
--- a/Lib/test/test_enum.py
+++ b/Lib/test/test_enum.py
@@ -3201,6 +3201,22 @@ class NTEnum(Enum):
 [x.value for x in NTEnum],
 [TTuple(id=0, a=0, blist=[]), TTuple(id=1, a=2, blist=[4]), 
TTuple(id=2, a=4, blist=[0, 1, 2])],
 )
+#
+class NTDEnum(Enum):
+def __new__(cls, t_value):
+member = object.__new__(cls)
+member._value_ = t_value[0]
+member.id = t_value[0]
+member.a = t_value[1]
+member.blist = t_value[2]
+return member
+NONE = TTuple(0, 0, [])
+A = TTuple(1, 2, [4])
+B = TTuple(2, 4, [0, 1, 2])
+self.assertEqual(repr(NTDEnum.NONE), "")
+self.assertEqual(NTDEnum.NONE.id, 0)
+self.assertEqual(NTDEnum.A.a, 2)
+self.assertEqual(NTDEnum.B.blist, [0, 1 ,2])
 
 def test_flag_with_custom_new(self):
 class FlagFromChar(IntFlag):
diff --git 
a/Misc/NEWS.d/next/Library/2024-01-16-15-59-06.gh-issue-114149.LJ8IPm.rst 
b/Misc/NEWS.d/next/Library/2024-01-16-15-59-06.gh-issue-114149.LJ8IPm.rst
new file mode 100644
index 00..1403d78d0d4905
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-01-16-15-59-06.gh-issue-114149.LJ8IPm.rst
@@ -0,0 +1 @@
+Enum: correctly handle tuple subclasses in custom ``__new__``.

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


[Python-checkins] gh-105102: Fix nested unions in structures when the system byteorder is the opposite (GH-105106)

2024-01-17 Thread serhiy-storchaka
https://github.com/python/cpython/commit/0b541f64c472976b2fee1ec9919bc7b02a798242
commit: 0b541f64c472976b2fee1ec9919bc7b02a798242
branch: main
author: Sheidan <37596668+sh3i...@users.noreply.github.com>
committer: serhiy-storchaka 
date: 2024-01-17T18:20:39Z
summary:

gh-105102: Fix nested unions in structures when the system byteorder is the 
opposite (GH-105106)

files:
A Misc/NEWS.d/next/Library/2023-05-30-18-30-11.gh-issue-105102.SnpK04.rst
M Lib/ctypes/_endian.py
M Lib/test/test_ctypes/test_byteswap.py

diff --git a/Lib/ctypes/_endian.py b/Lib/ctypes/_endian.py
index 3febb3118b8230..6382dd22b8acc8 100644
--- a/Lib/ctypes/_endian.py
+++ b/Lib/ctypes/_endian.py
@@ -15,8 +15,8 @@ def _other_endian(typ):
 # if typ is array
 if isinstance(typ, _array_type):
 return _other_endian(typ._type_) * typ._length_
-# if typ is structure
-if issubclass(typ, Structure):
+# if typ is structure or union
+if issubclass(typ, (Structure, Union)):
 return typ
 raise TypeError("This type does not support other endian: %s" % typ)
 
diff --git a/Lib/test/test_ctypes/test_byteswap.py 
b/Lib/test/test_ctypes/test_byteswap.py
index b97b57646ecd71..78eff0392c4548 100644
--- a/Lib/test/test_ctypes/test_byteswap.py
+++ b/Lib/test/test_ctypes/test_byteswap.py
@@ -363,6 +363,24 @@ class TestUnion(parent):
 self.assertEqual(s.point.x, 1)
 self.assertEqual(s.point.y, 2)
 
+def test_build_struct_union_opposite_system_byteorder(self):
+# gh-105102
+if sys.byteorder == "little":
+_Structure = BigEndianStructure
+_Union = BigEndianUnion
+else:
+_Structure = LittleEndianStructure
+_Union = LittleEndianUnion
+
+class S1(_Structure):
+_fields_ = [("a", c_byte), ("b", c_byte)]
+
+class U1(_Union):
+_fields_ = [("s1", S1), ("ab", c_short)]
+
+class S2(_Structure):
+_fields_ = [("u1", U1), ("c", c_byte)]
+
 
 if __name__ == "__main__":
 unittest.main()
diff --git 
a/Misc/NEWS.d/next/Library/2023-05-30-18-30-11.gh-issue-105102.SnpK04.rst 
b/Misc/NEWS.d/next/Library/2023-05-30-18-30-11.gh-issue-105102.SnpK04.rst
new file mode 100644
index 00..7ca21afefa3132
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-05-30-18-30-11.gh-issue-105102.SnpK04.rst
@@ -0,0 +1,2 @@
+Allow :class:`ctypes.Union` to be nested in :class:`ctypes.Structure` when
+the system endianness is the opposite of the classes.

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


[Python-checkins] Fix typo in tkinter.ttk.rst (GH-106157)

2024-01-17 Thread serhiy-storchaka
https://github.com/python/cpython/commit/7573c44c3278eacf0233146037d843bb2563877a
commit: 7573c44c3278eacf0233146037d843bb2563877a
branch: main
author: Christophe Nanteuil <35002064+christophe...@users.noreply.github.com>
committer: serhiy-storchaka 
date: 2024-01-17T18:23:25Z
summary:

Fix typo in tkinter.ttk.rst (GH-106157)

files:
M Doc/library/tkinter.ttk.rst

diff --git a/Doc/library/tkinter.ttk.rst b/Doc/library/tkinter.ttk.rst
index 1609dc2ce9218e..bd0d8b3799a0f1 100644
--- a/Doc/library/tkinter.ttk.rst
+++ b/Doc/library/tkinter.ttk.rst
@@ -1118,7 +1118,7 @@ ttk.Treeview
   as the item identifier; *iid* must not already exist in the tree.
   Otherwise, a new unique identifier is generated.
 
-  See `Item Options`_ for the list of available points.
+  See `Item Options`_ for the list of available options.
 
 
.. method:: item(item, option=None, **kw)

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


[Python-checkins] [3.12] Fix typo in tkinter.ttk.rst (GH-106157) (GH-114200)

2024-01-17 Thread serhiy-storchaka
https://github.com/python/cpython/commit/01344cfe9e9646b8f53b0ba2a1053d343a66634c
commit: 01344cfe9e9646b8f53b0ba2a1053d343a66634c
branch: 3.12
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: serhiy-storchaka 
date: 2024-01-17T21:23:50+02:00
summary:

[3.12] Fix typo in tkinter.ttk.rst (GH-106157) (GH-114200)

(cherry picked from commit 7573c44c3278eacf0233146037d843bb2563877a)

Co-authored-by: Christophe Nanteuil 
<35002064+christophe...@users.noreply.github.com>

files:
M Doc/library/tkinter.ttk.rst

diff --git a/Doc/library/tkinter.ttk.rst b/Doc/library/tkinter.ttk.rst
index 794c96eb3c389c..66144e0eec0dcf 100644
--- a/Doc/library/tkinter.ttk.rst
+++ b/Doc/library/tkinter.ttk.rst
@@ -1118,7 +1118,7 @@ ttk.Treeview
   as the item identifier; *iid* must not already exist in the tree.
   Otherwise, a new unique identifier is generated.
 
-  See `Item Options`_ for the list of available points.
+  See `Item Options`_ for the list of available options.
 
 
.. method:: item(item, option=None, **kw)

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


[Python-checkins] [3.11] Fix typo in tkinter.ttk.rst (GH-106157) (GH-114201)

2024-01-17 Thread serhiy-storchaka
https://github.com/python/cpython/commit/5dcb15da881173bf2b1e4d4336752a4fd1da4f2a
commit: 5dcb15da881173bf2b1e4d4336752a4fd1da4f2a
branch: 3.11
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: serhiy-storchaka 
date: 2024-01-17T21:24:10+02:00
summary:

[3.11] Fix typo in tkinter.ttk.rst (GH-106157) (GH-114201)

(cherry picked from commit 7573c44c3278eacf0233146037d843bb2563877a)

Co-authored-by: Christophe Nanteuil 
<35002064+christophe...@users.noreply.github.com>

files:
M Doc/library/tkinter.ttk.rst

diff --git a/Doc/library/tkinter.ttk.rst b/Doc/library/tkinter.ttk.rst
index 794c96eb3c389c..66144e0eec0dcf 100644
--- a/Doc/library/tkinter.ttk.rst
+++ b/Doc/library/tkinter.ttk.rst
@@ -1118,7 +1118,7 @@ ttk.Treeview
   as the item identifier; *iid* must not already exist in the tree.
   Otherwise, a new unique identifier is generated.
 
-  See `Item Options`_ for the list of available points.
+  See `Item Options`_ for the list of available options.
 
 
.. method:: item(item, option=None, **kw)

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


[Python-checkins] [3.11] gh-105102: Fix nested unions in structures when the system byteorder is the opposite (GH-105106) (GH-114205)

2024-01-17 Thread serhiy-storchaka
https://github.com/python/cpython/commit/2b032590222fd633e9d696faae7cb04dae5170bd
commit: 2b032590222fd633e9d696faae7cb04dae5170bd
branch: 3.11
author: Serhiy Storchaka 
committer: serhiy-storchaka 
date: 2024-01-17T19:58:28Z
summary:

[3.11] gh-105102: Fix nested unions in structures when the system byteorder is 
the opposite (GH-105106) (GH-114205)

(cherry picked from commit 0b541f64c472976b2fee1ec9919bc7b02a798242)

Co-authored-by: Sheidan <37596668+sh3i...@users.noreply.github.com>

files:
A Misc/NEWS.d/next/Library/2023-05-30-18-30-11.gh-issue-105102.SnpK04.rst
M Lib/ctypes/_endian.py
M Lib/ctypes/test/test_byteswap.py

diff --git a/Lib/ctypes/_endian.py b/Lib/ctypes/_endian.py
index 34dee64b1a65a6..6f674b21371c40 100644
--- a/Lib/ctypes/_endian.py
+++ b/Lib/ctypes/_endian.py
@@ -15,8 +15,8 @@ def _other_endian(typ):
 # if typ is array
 if isinstance(typ, _array_type):
 return _other_endian(typ._type_) * typ._length_
-# if typ is structure
-if issubclass(typ, Structure):
+# if typ is structure or union
+if issubclass(typ, (Structure, Union)):
 return typ
 raise TypeError("This type does not support other endian: %s" % typ)
 
diff --git a/Lib/ctypes/test/test_byteswap.py b/Lib/ctypes/test/test_byteswap.py
index caefb774cc5375..44d32ff27ba923 100644
--- a/Lib/ctypes/test/test_byteswap.py
+++ b/Lib/ctypes/test/test_byteswap.py
@@ -352,5 +352,24 @@ class TestUnion(parent):
 self.assertEqual(s.point.x, 1)
 self.assertEqual(s.point.y, 2)
 
+def test_build_struct_union_opposite_system_byteorder(self):
+# gh-105102
+if sys.byteorder == "little":
+_Structure = BigEndianStructure
+_Union = BigEndianUnion
+else:
+_Structure = LittleEndianStructure
+_Union = LittleEndianUnion
+
+class S1(_Structure):
+_fields_ = [("a", c_byte), ("b", c_byte)]
+
+class U1(_Union):
+_fields_ = [("s1", S1), ("ab", c_short)]
+
+class S2(_Structure):
+_fields_ = [("u1", U1), ("c", c_byte)]
+
+
 if __name__ == "__main__":
 unittest.main()
diff --git 
a/Misc/NEWS.d/next/Library/2023-05-30-18-30-11.gh-issue-105102.SnpK04.rst 
b/Misc/NEWS.d/next/Library/2023-05-30-18-30-11.gh-issue-105102.SnpK04.rst
new file mode 100644
index 00..7ca21afefa3132
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-05-30-18-30-11.gh-issue-105102.SnpK04.rst
@@ -0,0 +1,2 @@
+Allow :class:`ctypes.Union` to be nested in :class:`ctypes.Structure` when
+the system endianness is the opposite of the classes.

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


[Python-checkins] gh-38807: Fix race condition in Lib/trace.py (GH-110143)

2024-01-17 Thread serhiy-storchaka
https://github.com/python/cpython/commit/78fcde039a33d8463e34356d5462fecee0f2831a
commit: 78fcde039a33d8463e34356d5462fecee0f2831a
branch: main
author: buermarc <44375277+buerm...@users.noreply.github.com>
committer: serhiy-storchaka 
date: 2024-01-17T22:02:14+02:00
summary:

gh-38807: Fix race condition in Lib/trace.py (GH-110143)

Instead of checking if a directory does not exist and thereafter
creating it, directly call os.makedirs() with the exist_ok=True.

files:
A Misc/NEWS.d/next/Library/2023-09-22-22-17-45.gh-issue-38807.m9McRN.rst
M Lib/trace.py

diff --git a/Lib/trace.py b/Lib/trace.py
index 7cb6f897634b14..7886959fa64f68 100755
--- a/Lib/trace.py
+++ b/Lib/trace.py
@@ -265,8 +265,7 @@ def write_results(self, show_missing=True, summary=False, 
coverdir=None, *,
 modulename = _modname(filename)
 else:
 dir = coverdir
-if not os.path.exists(dir):
-os.makedirs(dir)
+os.makedirs(dir, exist_ok=True)
 modulename = _fullmodname(filename)
 
 # If desired, get a list of the line numbers which represent
diff --git 
a/Misc/NEWS.d/next/Library/2023-09-22-22-17-45.gh-issue-38807.m9McRN.rst 
b/Misc/NEWS.d/next/Library/2023-09-22-22-17-45.gh-issue-38807.m9McRN.rst
new file mode 100644
index 00..4219723d15b9e6
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-09-22-22-17-45.gh-issue-38807.m9McRN.rst
@@ -0,0 +1,3 @@
+Fix race condition in :mod:`trace`. Instead of checking if a directory
+exists and creating it, directly call :func:`os.makedirs` with the kwarg
+``exist_ok=True``.

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


[Python-checkins] [3.12] gh-105102: Fix nested unions in structures when the system byteorder is the opposite (GH-105106) (GH-114204)

2024-01-17 Thread serhiy-storchaka
https://github.com/python/cpython/commit/a735fea6b17c45b0dc0f650e59901770074176e1
commit: a735fea6b17c45b0dc0f650e59901770074176e1
branch: 3.12
author: Serhiy Storchaka 
committer: serhiy-storchaka 
date: 2024-01-17T20:11:44Z
summary:

[3.12] gh-105102: Fix nested unions in structures when the system byteorder is 
the opposite (GH-105106) (GH-114204)

(cherry picked from commit 0b541f64c472976b2fee1ec9919bc7b02a798242)

Co-authored-by: Sheidan <37596668+sh3i...@users.noreply.github.com>

files:
A Misc/NEWS.d/next/Library/2023-05-30-18-30-11.gh-issue-105102.SnpK04.rst
M Lib/ctypes/_endian.py
M Lib/test/test_ctypes/test_byteswap.py

diff --git a/Lib/ctypes/_endian.py b/Lib/ctypes/_endian.py
index b5446c049bc9dc..04389008a8a694 100644
--- a/Lib/ctypes/_endian.py
+++ b/Lib/ctypes/_endian.py
@@ -15,8 +15,8 @@ def _other_endian(typ):
 # if typ is array
 if isinstance(typ, _array_type):
 return _other_endian(typ._type_) * typ._length_
-# if typ is structure
-if issubclass(typ, Structure):
+# if typ is structure or union
+if issubclass(typ, (Structure, Union)):
 return typ
 raise TypeError("This type does not support other endian: %s" % typ)
 
diff --git a/Lib/test/test_ctypes/test_byteswap.py 
b/Lib/test/test_ctypes/test_byteswap.py
index caefb774cc5375..44d32ff27ba923 100644
--- a/Lib/test/test_ctypes/test_byteswap.py
+++ b/Lib/test/test_ctypes/test_byteswap.py
@@ -352,5 +352,24 @@ class TestUnion(parent):
 self.assertEqual(s.point.x, 1)
 self.assertEqual(s.point.y, 2)
 
+def test_build_struct_union_opposite_system_byteorder(self):
+# gh-105102
+if sys.byteorder == "little":
+_Structure = BigEndianStructure
+_Union = BigEndianUnion
+else:
+_Structure = LittleEndianStructure
+_Union = LittleEndianUnion
+
+class S1(_Structure):
+_fields_ = [("a", c_byte), ("b", c_byte)]
+
+class U1(_Union):
+_fields_ = [("s1", S1), ("ab", c_short)]
+
+class S2(_Structure):
+_fields_ = [("u1", U1), ("c", c_byte)]
+
+
 if __name__ == "__main__":
 unittest.main()
diff --git 
a/Misc/NEWS.d/next/Library/2023-05-30-18-30-11.gh-issue-105102.SnpK04.rst 
b/Misc/NEWS.d/next/Library/2023-05-30-18-30-11.gh-issue-105102.SnpK04.rst
new file mode 100644
index 00..7ca21afefa3132
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-05-30-18-30-11.gh-issue-105102.SnpK04.rst
@@ -0,0 +1,2 @@
+Allow :class:`ctypes.Union` to be nested in :class:`ctypes.Structure` when
+the system endianness is the opposite of the classes.

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


[Python-checkins] [3.11] gh-38807: Fix race condition in Lib/trace.py (GH-110143) (GH-114207)

2024-01-17 Thread serhiy-storchaka
https://github.com/python/cpython/commit/2dca68935e4884216822d18debcbf9a8e252dc21
commit: 2dca68935e4884216822d18debcbf9a8e252dc21
branch: 3.11
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: serhiy-storchaka 
date: 2024-01-17T20:26:09Z
summary:

[3.11] gh-38807: Fix race condition in Lib/trace.py (GH-110143) (GH-114207)

Instead of checking if a directory does not exist and thereafter
creating it, directly call os.makedirs() with the exist_ok=True.
(cherry picked from commit 78fcde039a33d8463e34356d5462fecee0f2831a)

Co-authored-by: buermarc <44375277+buerm...@users.noreply.github.com>

files:
A Misc/NEWS.d/next/Library/2023-09-22-22-17-45.gh-issue-38807.m9McRN.rst
M Lib/trace.py

diff --git a/Lib/trace.py b/Lib/trace.py
index fb9a423ea09fce..761916b18097d6 100755
--- a/Lib/trace.py
+++ b/Lib/trace.py
@@ -258,8 +258,7 @@ def write_results(self, show_missing=True, summary=False, 
coverdir=None):
 modulename = _modname(filename)
 else:
 dir = coverdir
-if not os.path.exists(dir):
-os.makedirs(dir)
+os.makedirs(dir, exist_ok=True)
 modulename = _fullmodname(filename)
 
 # If desired, get a list of the line numbers which represent
diff --git 
a/Misc/NEWS.d/next/Library/2023-09-22-22-17-45.gh-issue-38807.m9McRN.rst 
b/Misc/NEWS.d/next/Library/2023-09-22-22-17-45.gh-issue-38807.m9McRN.rst
new file mode 100644
index 00..4219723d15b9e6
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-09-22-22-17-45.gh-issue-38807.m9McRN.rst
@@ -0,0 +1,3 @@
+Fix race condition in :mod:`trace`. Instead of checking if a directory
+exists and creating it, directly call :func:`os.makedirs` with the kwarg
+``exist_ok=True``.

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


[Python-checkins] [3.12] gh-38807: Fix race condition in Lib/trace.py (GH-110143) (GH-114206)

2024-01-17 Thread serhiy-storchaka
https://github.com/python/cpython/commit/24d23929d6b77d644fc6ffec5d565deba2231504
commit: 24d23929d6b77d644fc6ffec5d565deba2231504
branch: 3.12
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: serhiy-storchaka 
date: 2024-01-17T20:35:00Z
summary:

[3.12] gh-38807: Fix race condition in Lib/trace.py (GH-110143) (GH-114206)

Instead of checking if a directory does not exist and thereafter
creating it, directly call os.makedirs() with the exist_ok=True.
(cherry picked from commit 78fcde039a33d8463e34356d5462fecee0f2831a)

Co-authored-by: buermarc <44375277+buerm...@users.noreply.github.com>

files:
A Misc/NEWS.d/next/Library/2023-09-22-22-17-45.gh-issue-38807.m9McRN.rst
M Lib/trace.py

diff --git a/Lib/trace.py b/Lib/trace.py
index fb9a423ea09fce..761916b18097d6 100755
--- a/Lib/trace.py
+++ b/Lib/trace.py
@@ -258,8 +258,7 @@ def write_results(self, show_missing=True, summary=False, 
coverdir=None):
 modulename = _modname(filename)
 else:
 dir = coverdir
-if not os.path.exists(dir):
-os.makedirs(dir)
+os.makedirs(dir, exist_ok=True)
 modulename = _fullmodname(filename)
 
 # If desired, get a list of the line numbers which represent
diff --git 
a/Misc/NEWS.d/next/Library/2023-09-22-22-17-45.gh-issue-38807.m9McRN.rst 
b/Misc/NEWS.d/next/Library/2023-09-22-22-17-45.gh-issue-38807.m9McRN.rst
new file mode 100644
index 00..4219723d15b9e6
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-09-22-22-17-45.gh-issue-38807.m9McRN.rst
@@ -0,0 +1,3 @@
+Fix race condition in :mod:`trace`. Instead of checking if a directory
+exists and creating it, directly call :func:`os.makedirs` with the kwarg
+``exist_ok=True``.

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


[Python-checkins] [3.12] gh-114149: [Enum] fix tuple subclass handling when using custom __new__ (GH-114160) (GH-114196)

2024-01-17 Thread ethanfurman
https://github.com/python/cpython/commit/c1890e666eaaa819a318b4a6b4f2c8c33a8c679e
commit: c1890e666eaaa819a318b4a6b4f2c8c33a8c679e
branch: 3.12
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: ethanfurman 
date: 2024-01-17T13:34:48-08:00
summary:

[3.12] gh-114149: [Enum] fix tuple subclass handling when using custom __new__ 
(GH-114160) (GH-114196)

(cherry picked from commit 33b47a2c2853066b549f242065f6c2e12e18b33b)

Co-authored-by: Ethan Furman 

files:
A Misc/NEWS.d/next/Library/2024-01-16-15-59-06.gh-issue-114149.LJ8IPm.rst
M Lib/enum.py
M Lib/test/test_enum.py

diff --git a/Lib/enum.py b/Lib/enum.py
index 1502bfe9158520..0cf88471d504a2 100644
--- a/Lib/enum.py
+++ b/Lib/enum.py
@@ -254,7 +254,7 @@ def __set_name__(self, enum_class, member_name):
 delattr(enum_class, member_name)
 # second step: create member based on enum_class
 value = self.value
-if not isinstance(value, tuple):
+if type(value) is not tuple:
 args = (value, )
 else:
 args = value
@@ -1757,7 +1757,7 @@ def convert_class(cls):
 else:
 # create the member
 if use_args:
-if not isinstance(value, tuple):
+if type(value) is not tuple:
 value = (value, )
 member = new_member(enum_class, *value)
 value = value[0]
@@ -1807,7 +1807,7 @@ def convert_class(cls):
 else:
 # create the member
 if use_args:
-if not isinstance(value, tuple):
+if type(value) is not tuple:
 value = (value, )
 member = new_member(enum_class, *value)
 value = value[0]
diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py
index 3bd918fb941c76..2db3b2f95fc845 100644
--- a/Lib/test/test_enum.py
+++ b/Lib/test/test_enum.py
@@ -3163,6 +3163,22 @@ class NTEnum(Enum):
 [x.value for x in NTEnum],
 [TTuple(id=0, a=0, blist=[]), TTuple(id=1, a=2, blist=[4]), 
TTuple(id=2, a=4, blist=[0, 1, 2])],
 )
+#
+class NTDEnum(Enum):
+def __new__(cls, t_value):
+member = object.__new__(cls)
+member._value_ = t_value[0]
+member.id = t_value[0]
+member.a = t_value[1]
+member.blist = t_value[2]
+return member
+NONE = TTuple(0, 0, [])
+A = TTuple(1, 2, [4])
+B = TTuple(2, 4, [0, 1, 2])
+self.assertEqual(repr(NTDEnum.NONE), "")
+self.assertEqual(NTDEnum.NONE.id, 0)
+self.assertEqual(NTDEnum.A.a, 2)
+self.assertEqual(NTDEnum.B.blist, [0, 1 ,2])
 
 def test_flag_with_custom_new(self):
 class FlagFromChar(IntFlag):
diff --git 
a/Misc/NEWS.d/next/Library/2024-01-16-15-59-06.gh-issue-114149.LJ8IPm.rst 
b/Misc/NEWS.d/next/Library/2024-01-16-15-59-06.gh-issue-114149.LJ8IPm.rst
new file mode 100644
index 00..1403d78d0d4905
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-01-16-15-59-06.gh-issue-114149.LJ8IPm.rst
@@ -0,0 +1 @@
+Enum: correctly handle tuple subclasses in custom ``__new__``.

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


[Python-checkins] [3.12] gh-112343: pdb: Use tokenize to replace convenience variables (GH-112380) (#114202)

2024-01-17 Thread iritkatriel
https://github.com/python/cpython/commit/2c9cf64a3fa2b476c66eb80970e02933b7d33d05
commit: 2c9cf64a3fa2b476c66eb80970e02933b7d33d05
branch: 3.12
author: Tian Gao 
committer: iritkatriel <1055913+iritkatr...@users.noreply.github.com>
date: 2024-01-17T22:15:44Z
summary:

[3.12] gh-112343: pdb: Use tokenize to replace convenience variables 
(GH-112380) (#114202)

files:
A Misc/NEWS.d/next/Library/2023-11-24-19-08-50.gh-issue-112343.RarGFC.rst
M Lib/pdb.py
M Lib/test/test_pdb.py

diff --git a/Lib/pdb.py b/Lib/pdb.py
index 2e048ac5ba6e6a..a838a26b038df6 100755
--- a/Lib/pdb.py
+++ b/Lib/pdb.py
@@ -76,6 +76,7 @@
 import dis
 import code
 import glob
+import token
 import pprint
 import signal
 import inspect
@@ -467,6 +468,39 @@ def default(self, line):
 except:
 self._error_exc()
 
+def _replace_convenience_variables(self, line):
+"""Replace the convenience variables in 'line' with their values.
+   e.g. $foo is replaced by __pdb_convenience_variables["foo"].
+   Note: such pattern in string literals will be skipped"""
+
+if "$" not in line:
+return line
+
+dollar_start = dollar_end = -1
+replace_variables = []
+try:
+for t in tokenize.generate_tokens(io.StringIO(line).readline):
+token_type, token_string, start, end, _ = t
+if token_type == token.OP and token_string == '$':
+dollar_start, dollar_end = start, end
+elif start == dollar_end and token_type == token.NAME:
+# line is a one-line command so we only care about column
+replace_variables.append((dollar_start[1], end[1], 
token_string))
+except tokenize.TokenError:
+return line
+
+if not replace_variables:
+return line
+
+last_end = 0
+line_pieces = []
+for start, end, name in replace_variables:
+line_pieces.append(line[last_end:start] + 
f'__pdb_convenience_variables["{name}"]')
+last_end = end
+line_pieces.append(line[last_end:])
+
+return ''.join(line_pieces)
+
 def precmd(self, line):
 """Handle alias expansion and ';;' separator."""
 if not line.strip():
@@ -492,7 +526,8 @@ def precmd(self, line):
 line = line[:marker].rstrip()
 
 # Replace all the convenience variables
-line = re.sub(r'\$([a-zA-Z_][a-zA-Z0-9_]*)', 
r'__pdb_convenience_variables["\1"]', line)
+line = self._replace_convenience_variables(line)
+
 return line
 
 def onecmd(self, line):
diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py
index 08b2867266e3c4..56ee6c4c1e2847 100644
--- a/Lib/test/test_pdb.py
+++ b/Lib/test/test_pdb.py
@@ -389,7 +389,7 @@ def 
test_pdb_breakpoints_preserved_across_interactive_sessions():
 1   breakpoint   keep yes   at ...test_pdb.py:...
 2   breakpoint   keep yes   at ...test_pdb.py:...
 (Pdb) break pdb.find_function
-Breakpoint 3 at ...pdb.py:97
+Breakpoint 3 at ...pdb.py:...
 (Pdb) break
 Num Type Disp Enb   Where
 1   breakpoint   keep yes   at ...test_pdb.py:...
@@ -770,9 +770,12 @@ def test_convenience_variables():
 
 >>> with PdbTestInput([  # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
 ... '$_frame.f_lineno', # Check frame convenience variable
+... '$ _frame', # This should be a syntax error
 ... '$a = 10',  # Set a convenience variable
 ... '$a',   # Print its value
+... 'p "$a"',   # Print the string $a
 ... 'p $a + 2', # Do some calculation
+... 'p f"$a = {$a}"',   # Make sure $ in string is not converted and 
f-string works
 ... 'u',# Switch frame
 ... '$_frame.f_lineno', # Make sure the frame changed
 ... '$a',   # Make sure the value persists
@@ -792,11 +795,17 @@ def test_convenience_variables():
 -> try:
 (Pdb) $_frame.f_lineno
 3
+(Pdb) $ _frame
+*** SyntaxError: invalid syntax
 (Pdb) $a = 10
 (Pdb) $a
 10
+(Pdb) p "$a"
+'$a'
 (Pdb) p $a + 2
 12
+(Pdb) p f"$a = {$a}"
+'$a = 10'
 (Pdb) u
 > (2)test_function()
 -> util_function()
diff --git 
a/Misc/NEWS.d/next/Library/2023-11-24-19-08-50.gh-issue-112343.RarGFC.rst 
b/Misc/NEWS.d/next/Library/2023-11-24-19-08-50.gh-issue-112343.RarGFC.rst
new file mode 100644
index 00..aaa50fce3ac962
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-11-24-19-08-50.gh-issue-112343.RarGFC.rst
@@ -0,0 +1 @@
+Improve handling of pdb convenience variables to avoid replacing string 
contents.

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

[Python-checkins] gh-112984: Fix test_ctypes.test_loading.test_load_dll_with_flags when directory name includes a dot (GH-114217)

2024-01-17 Thread zooba
https://github.com/python/cpython/commit/945540306c12116154d2e4cc6c17a8efd2290537
commit: 945540306c12116154d2e4cc6c17a8efd2290537
branch: main
author: Steve Dower 
committer: zooba 
date: 2024-01-18T00:26:31Z
summary:

gh-112984: Fix test_ctypes.test_loading.test_load_dll_with_flags when directory 
name includes a dot (GH-114217)

files:
M Lib/test/test_ctypes/test_loading.py

diff --git a/Lib/test/test_ctypes/test_loading.py 
b/Lib/test/test_ctypes/test_loading.py
index 9f0547f4c955c0..59d7f51935f3cd 100644
--- a/Lib/test/test_ctypes/test_loading.py
+++ b/Lib/test/test_ctypes/test_loading.py
@@ -141,7 +141,7 @@ def test_load_hasattr(self):
 def test_load_dll_with_flags(self):
 _sqlite3 = import_helper.import_module("_sqlite3")
 src = _sqlite3.__file__
-if src.partition(".")[0].lower().endswith("_d"):
+if os.path.basename(src).partition(".")[0].lower().endswith("_d"):
 ext = "_d.dll"
 else:
 ext = ".dll"

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


[Python-checkins] gh-114149: [Enum] revert #114160 and add more tuple-subclass tests (GH-114215)

2024-01-17 Thread ethanfurman
https://github.com/python/cpython/commit/4c7e09d0129dafddba58979ced9580f856f65efa
commit: 4c7e09d0129dafddba58979ced9580f856f65efa
branch: main
author: Ethan Furman 
committer: ethanfurman 
date: 2024-01-17T16:31:00-08:00
summary:

gh-114149: [Enum] revert #114160 and add more tuple-subclass tests (GH-114215)

This reverts commit 05e142b1543eb9662d6cc33722e7e16250c9219f.

files:
M Lib/enum.py
M Lib/test/test_enum.py

diff --git a/Lib/enum.py b/Lib/enum.py
index e51850d9b45d33..a8a50a58380375 100644
--- a/Lib/enum.py
+++ b/Lib/enum.py
@@ -250,7 +250,7 @@ def __set_name__(self, enum_class, member_name):
 delattr(enum_class, member_name)
 # second step: create member based on enum_class
 value = self.value
-if type(value) is not tuple:
+if not isinstance(value, tuple):
 args = (value, )
 else:
 args = value
@@ -1777,7 +1777,7 @@ def convert_class(cls):
 else:
 # create the member
 if use_args:
-if type(value) is not tuple:
+if not isinstance(value, tuple):
 value = (value, )
 member = new_member(enum_class, *value)
 value = value[0]
@@ -1826,7 +1826,7 @@ def convert_class(cls):
 else:
 # create the member
 if use_args:
-if type(value) is not tuple:
+if not isinstance(value, tuple):
 value = (value, )
 member = new_member(enum_class, *value)
 value = value[0]
diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py
index 48e0b02b2b6219..d045739efa46b8 100644
--- a/Lib/test/test_enum.py
+++ b/Lib/test/test_enum.py
@@ -3201,19 +3201,34 @@ class NTEnum(Enum):
 [x.value for x in NTEnum],
 [TTuple(id=0, a=0, blist=[]), TTuple(id=1, a=2, blist=[4]), 
TTuple(id=2, a=4, blist=[0, 1, 2])],
 )
+
+self.assertRaises(AttributeError, getattr, NTEnum.NONE, 'id')
+#
+class NTCEnum(TTuple, Enum):
+NONE = 0, 0, []
+A = 1, 2, [4]
+B = 2, 4, [0, 1, 2]
+self.assertEqual(repr(NTCEnum.NONE), "")
+self.assertEqual(NTCEnum.NONE.value, TTuple(id=0, a=0, blist=[]))
+self.assertEqual(NTCEnum.NONE.id, 0)
+self.assertEqual(NTCEnum.A.a, 2)
+self.assertEqual(NTCEnum.B.blist, [0, 1 ,2])
+self.assertEqual(
+[x.value for x in NTCEnum],
+[TTuple(id=0, a=0, blist=[]), TTuple(id=1, a=2, blist=[4]), 
TTuple(id=2, a=4, blist=[0, 1, 2])],
+)
 #
 class NTDEnum(Enum):
-def __new__(cls, t_value):
+def __new__(cls, id, a, blist):
 member = object.__new__(cls)
-member._value_ = t_value[0]
-member.id = t_value[0]
-member.a = t_value[1]
-member.blist = t_value[2]
+member.id = id
+member.a = a
+member.blist = blist
 return member
 NONE = TTuple(0, 0, [])
 A = TTuple(1, 2, [4])
 B = TTuple(2, 4, [0, 1, 2])
-self.assertEqual(repr(NTDEnum.NONE), "")
+self.assertEqual(repr(NTDEnum.NONE), "")
 self.assertEqual(NTDEnum.NONE.id, 0)
 self.assertEqual(NTDEnum.A.a, 2)
 self.assertEqual(NTDEnum.B.blist, [0, 1 ,2])

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


[Python-checkins] gh-104522: Fix OSError raised when run a subprocess (#114195)

2024-01-17 Thread gpshead
https://github.com/python/cpython/commit/e2c097ebdee447ded1109f99a235e65aa3533bf8
commit: e2c097ebdee447ded1109f99a235e65aa3533bf8
branch: main
author: Serhiy Storchaka 
committer: gpshead 
date: 2024-01-17T16:52:42-08:00
summary:

gh-104522: Fix OSError raised when run a subprocess (#114195)

Only set filename to cwd if it was caused by failed chdir(cwd).

_fork_exec() now returns "noexec:chdir" for failed chdir(cwd).

Co-authored-by: Robert O'Shea 

files:
A Misc/NEWS.d/next/Library/2024-01-17-18-53-51.gh-issue-104522.3NyDf4.rst
M Lib/subprocess.py
M Lib/test/test_subprocess.py
M Modules/_posixsubprocess.c

diff --git a/Lib/subprocess.py b/Lib/subprocess.py
index d5bd9a9e31aa04..20db7747d5db13 100644
--- a/Lib/subprocess.py
+++ b/Lib/subprocess.py
@@ -1944,16 +1944,21 @@ def _execute_child(self, args, executable, preexec_fn, 
close_fds,
 SubprocessError)
 if issubclass(child_exception_type, OSError) and hex_errno:
 errno_num = int(hex_errno, 16)
-child_exec_never_called = (err_msg == "noexec")
-if child_exec_never_called:
+if err_msg == "noexec:chdir":
 err_msg = ""
 # The error must be from chdir(cwd).
 err_filename = cwd
+elif err_msg == "noexec":
+err_msg = ""
+err_filename = None
 else:
 err_filename = orig_executable
 if errno_num != 0:
 err_msg = os.strerror(errno_num)
-raise child_exception_type(errno_num, err_msg, 
err_filename)
+if err_filename is not None:
+raise child_exception_type(errno_num, err_msg, 
err_filename)
+else:
+raise child_exception_type(errno_num, err_msg)
 raise child_exception_type(err_msg)
 
 
diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py
index 944a7de4210bc9..12b88294a2d370 100644
--- a/Lib/test/test_subprocess.py
+++ b/Lib/test/test_subprocess.py
@@ -2017,11 +2017,12 @@ def test_user(self):
  "import os; print(os.getuid())"],
 user=user,
 close_fds=close_fds)
-except PermissionError:  # (EACCES, EPERM)
-pass
+except PermissionError as e:  # (EACCES, EPERM)
+self.assertIsNone(e.filename)
 except OSError as e:
 if e.errno not in (errno.EACCES, errno.EPERM):
 raise
+self.assertIsNone(e.filename)
 else:
 if isinstance(user, str):
 user_uid = pwd.getpwnam(user).pw_uid
@@ -2065,8 +2066,8 @@ def test_group(self):
  "import os; print(os.getgid())"],
 group=group,
 close_fds=close_fds)
-except PermissionError:  # (EACCES, EPERM)
-pass
+except PermissionError as e:  # (EACCES, EPERM)
+self.assertIsNone(e.filename)
 else:
 if isinstance(group, str):
 group_gid = grp.getgrnam(group).gr_gid
@@ -2114,7 +2115,8 @@ def _test_extra_groups_impl(self, *, gid, group_list):
 [sys.executable, "-c",
  "import os, sys, json; json.dump(os.getgroups(), 
sys.stdout)"],
 extra_groups=group_list)
-except PermissionError:
+except PermissionError as e:
+self.assertIsNone(e.filename)
 self.skipTest("setgroup() EPERM; this test may require root.")
 else:
 parent_groups = os.getgroups()
diff --git 
a/Misc/NEWS.d/next/Library/2024-01-17-18-53-51.gh-issue-104522.3NyDf4.rst 
b/Misc/NEWS.d/next/Library/2024-01-17-18-53-51.gh-issue-104522.3NyDf4.rst
new file mode 100644
index 00..ca980945ea12d3
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-01-17-18-53-51.gh-issue-104522.3NyDf4.rst
@@ -0,0 +1,3 @@
+:exc:`OSError` raised when run a subprocess now only has *filename*
+attribute set to *cwd* if the error was caused by a failed attempt to change
+the current directory.
diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c
index d0dd8f064e0395..aa1a300e4378dd 100644
--- a/Modules/_posixsubprocess.c
+++ b/Modules/_posixsubprocess.c
@@ -673,9 +673,10 @@ child_exec(char *const exec_array[],
PyObject *preexec_fn,
PyObject *preexec_fn_args_tuple)
 {
-int i, saved_errno, reached_preexec = 0;
+int i, saved_errno;
 PyObject *result;
-const char* err_msg =

[Python-checkins] gh-113205: test_multiprocessing.test_terminate: Test the API on threadpools (#114186)

2024-01-17 Thread gpshead
https://github.com/python/cpython/commit/c1db9606081bdbe0207f83a861a3c70c356d3704
commit: c1db9606081bdbe0207f83a861a3c70c356d3704
branch: main
author: Petr Viktorin 
committer: gpshead 
date: 2024-01-17T17:15:29-08:00
summary:

gh-113205: test_multiprocessing.test_terminate: Test the API on threadpools 
(#114186)

gh-113205: test_multiprocessing.test_terminate: Test the API works on 
threadpools

Threads can't be forced to terminate (without potentially corrupting too much
state), so the  expected behaviour of `ThreadPool.terminate` is to wait for
the currently executing tasks to finish.

The entire test was skipped in GH-110848 
(0e9c364f4ac18a2237bdbac702b96bcf8ef9cb09).
Instead of skipping it entirely, we should ensure the API eventually succeeds:
use a shorter timeout.

For the record: on my machine, when the test is un-skipped, the task manages to
start in about 1.5% cases.

files:
M Lib/test/_test_multiprocessing.py

diff --git a/Lib/test/_test_multiprocessing.py 
b/Lib/test/_test_multiprocessing.py
index 8e4e0765d46809..6a050fa541db1e 100644
--- a/Lib/test/_test_multiprocessing.py
+++ b/Lib/test/_test_multiprocessing.py
@@ -2693,12 +2693,17 @@ def test_make_pool(self):
 p.join()
 
 def test_terminate(self):
+# Simulate slow tasks which take "forever" to complete
+sleep_time = support.LONG_TIMEOUT
+
 if self.TYPE == 'threads':
-self.skipTest("Threads cannot be terminated")
+# Thread pool workers can't be forced to quit, so if the first
+# task starts early enough, we will end up waiting for it.
+# Sleep for a shorter time, so the test doesn't block.
+sleep_time = 1
 
-# Simulate slow tasks which take "forever" to complete
 p = self.Pool(3)
-args = [support.LONG_TIMEOUT for i in range(10_000)]
+args = [sleep_time for i in range(10_000)]
 result = p.map_async(time.sleep, args, chunksize=1)
 p.terminate()
 p.join()

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


[Python-checkins] [3.12] gh-104522: Fix OSError raised when run a subprocess (GH-114195) (#114219)

2024-01-17 Thread gpshead
https://github.com/python/cpython/commit/f8fc8534c4abd384160b3b03a253bb0a30e6ba68
commit: f8fc8534c4abd384160b3b03a253bb0a30e6ba68
branch: 3.12
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: gpshead 
date: 2024-01-18T01:19:11Z
summary:

[3.12] gh-104522: Fix OSError raised when run a subprocess (GH-114195) (#114219)

gh-104522: Fix OSError raised when run a subprocess (GH-114195)

Only set filename to cwd if it was caused by failed chdir(cwd).

_fork_exec() now returns "noexec:chdir" for failed chdir(cwd).

(cherry picked from commit e2c097ebdee447ded1109f99a235e65aa3533bf8)

Co-authored-by: Serhiy Storchaka 
Co-authored-by: Robert O'Shea 

files:
A Misc/NEWS.d/next/Library/2024-01-17-18-53-51.gh-issue-104522.3NyDf4.rst
M Lib/subprocess.py
M Lib/test/test_subprocess.py
M Modules/_posixsubprocess.c

diff --git a/Lib/subprocess.py b/Lib/subprocess.py
index 6df5dd551ea67e..3264d9afc7ebf3 100644
--- a/Lib/subprocess.py
+++ b/Lib/subprocess.py
@@ -1938,16 +1938,21 @@ def _execute_child(self, args, executable, preexec_fn, 
close_fds,
 SubprocessError)
 if issubclass(child_exception_type, OSError) and hex_errno:
 errno_num = int(hex_errno, 16)
-child_exec_never_called = (err_msg == "noexec")
-if child_exec_never_called:
+if err_msg == "noexec:chdir":
 err_msg = ""
 # The error must be from chdir(cwd).
 err_filename = cwd
+elif err_msg == "noexec":
+err_msg = ""
+err_filename = None
 else:
 err_filename = orig_executable
 if errno_num != 0:
 err_msg = os.strerror(errno_num)
-raise child_exception_type(errno_num, err_msg, 
err_filename)
+if err_filename is not None:
+raise child_exception_type(errno_num, err_msg, 
err_filename)
+else:
+raise child_exception_type(errno_num, err_msg)
 raise child_exception_type(err_msg)
 
 
diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py
index 9ade90f741bc6f..5f94a4018820c0 100644
--- a/Lib/test/test_subprocess.py
+++ b/Lib/test/test_subprocess.py
@@ -2032,11 +2032,12 @@ def test_user(self):
  "import os; print(os.getuid())"],
 user=user,
 close_fds=close_fds)
-except PermissionError:  # (EACCES, EPERM)
-pass
+except PermissionError as e:  # (EACCES, EPERM)
+self.assertIsNone(e.filename)
 except OSError as e:
 if e.errno not in (errno.EACCES, errno.EPERM):
 raise
+self.assertIsNone(e.filename)
 else:
 if isinstance(user, str):
 user_uid = pwd.getpwnam(user).pw_uid
@@ -2080,8 +2081,8 @@ def test_group(self):
  "import os; print(os.getgid())"],
 group=group,
 close_fds=close_fds)
-except PermissionError:  # (EACCES, EPERM)
-pass
+except PermissionError as e:  # (EACCES, EPERM)
+self.assertIsNone(e.filename)
 else:
 if isinstance(group, str):
 group_gid = grp.getgrnam(group).gr_gid
@@ -2129,7 +2130,8 @@ def _test_extra_groups_impl(self, *, gid, group_list):
 [sys.executable, "-c",
  "import os, sys, json; json.dump(os.getgroups(), 
sys.stdout)"],
 extra_groups=group_list)
-except PermissionError:
+except PermissionError as e:
+self.assertIsNone(e.filename)
 self.skipTest("setgroup() EPERM; this test may require root.")
 else:
 parent_groups = os.getgroups()
diff --git 
a/Misc/NEWS.d/next/Library/2024-01-17-18-53-51.gh-issue-104522.3NyDf4.rst 
b/Misc/NEWS.d/next/Library/2024-01-17-18-53-51.gh-issue-104522.3NyDf4.rst
new file mode 100644
index 00..ca980945ea12d3
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-01-17-18-53-51.gh-issue-104522.3NyDf4.rst
@@ -0,0 +1,3 @@
+:exc:`OSError` raised when run a subprocess now only has *filename*
+attribute set to *cwd* if the error was caused by a failed attempt to change
+the current directory.
diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c
index 85634d7efe2161..d75bb92757c7a4 100644
--- a/Modules/_posixsubprocess.c
+++ b/Modules/_posixsubprocess.c
@@ -589,9 +589,10 @@ ch

[Python-checkins] gh-114211: Update EmailMessage doc about ordered keys (#114224)

2024-01-17 Thread terryjreedy
https://github.com/python/cpython/commit/8cda72037b262772399b2b7fc36dee9340d74fd6
commit: 8cda72037b262772399b2b7fc36dee9340d74fd6
branch: main
author: Terry Jan Reedy 
committer: terryjreedy 
date: 2024-01-18T02:25:22Z
summary:

gh-114211: Update EmailMessage doc about ordered keys (#114224)

Ordered keys are no longer unlike 'real dict's.

files:
M Doc/library/email.message.rst

diff --git a/Doc/library/email.message.rst b/Doc/library/email.message.rst
index f58d93da6ed687..adea067e082615 100644
--- a/Doc/library/email.message.rst
+++ b/Doc/library/email.message.rst
@@ -40,9 +40,9 @@ over the object tree.
 The :class:`EmailMessage` dictionary-like interface is indexed by the header
 names, which must be ASCII values.  The values of the dictionary are strings
 with some extra methods.  Headers are stored and returned in case-preserving
-form, but field names are matched case-insensitively.  Unlike a real dict,
-there is an ordering to the keys, and there can be duplicate keys.  Additional
-methods are provided for working with headers that have duplicate keys.
+form, but field names are matched case-insensitively.  The keys are ordered,
+but unlike a real dict, there can be duplicates.  Addtional methods are
+provided for working with headers that have duplicate keys.
 
 The *payload* is either a string or bytes object, in the case of simple message
 objects, or a list of :class:`EmailMessage` objects, for MIME container

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


[Python-checkins] [3.12] gh-114211: Update EmailMessage doc about ordered keys (GH-114224) (#114225)

2024-01-17 Thread terryjreedy
https://github.com/python/cpython/commit/87198f6c2377a52ee7ec779b7f85daa8deef7f02
commit: 87198f6c2377a52ee7ec779b7f85daa8deef7f02
branch: 3.12
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: terryjreedy 
date: 2024-01-17T21:55:40-05:00
summary:

[3.12] gh-114211: Update EmailMessage doc about ordered keys (GH-114224) 
(#114225)

Ordered keys are no longer unlike 'real dict's.
(cherry picked from commit 8cda72037b262772399b2b7fc36dee9340d74fd6)

Co-authored-by: Terry Jan Reedy 

files:
M Doc/library/email.message.rst

diff --git a/Doc/library/email.message.rst b/Doc/library/email.message.rst
index f58d93da6ed687..adea067e082615 100644
--- a/Doc/library/email.message.rst
+++ b/Doc/library/email.message.rst
@@ -40,9 +40,9 @@ over the object tree.
 The :class:`EmailMessage` dictionary-like interface is indexed by the header
 names, which must be ASCII values.  The values of the dictionary are strings
 with some extra methods.  Headers are stored and returned in case-preserving
-form, but field names are matched case-insensitively.  Unlike a real dict,
-there is an ordering to the keys, and there can be duplicate keys.  Additional
-methods are provided for working with headers that have duplicate keys.
+form, but field names are matched case-insensitively.  The keys are ordered,
+but unlike a real dict, there can be duplicates.  Addtional methods are
+provided for working with headers that have duplicate keys.
 
 The *payload* is either a string or bytes object, in the case of simple message
 objects, or a list of :class:`EmailMessage` objects, for MIME container

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


[Python-checkins] [3.11] gh-114211: Update EmailMessage doc about ordered keys (GH-114224) (#114226)

2024-01-17 Thread terryjreedy
https://github.com/python/cpython/commit/4ec2e244267bc65af2a2f505ef4dcc60365e
commit: 4ec2e244267bc65af2a2f505ef4dcc60365e
branch: 3.11
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: terryjreedy 
date: 2024-01-17T21:56:03-05:00
summary:

[3.11] gh-114211: Update EmailMessage doc about ordered keys (GH-114224) 
(#114226)

Ordered keys are no longer unlike 'real dict's.
(cherry picked from commit 8cda72037b262772399b2b7fc36dee9340d74fd6)

Co-authored-by: Terry Jan Reedy 

files:
M Doc/library/email.message.rst

diff --git a/Doc/library/email.message.rst b/Doc/library/email.message.rst
index f58d93da6ed687..adea067e082615 100644
--- a/Doc/library/email.message.rst
+++ b/Doc/library/email.message.rst
@@ -40,9 +40,9 @@ over the object tree.
 The :class:`EmailMessage` dictionary-like interface is indexed by the header
 names, which must be ASCII values.  The values of the dictionary are strings
 with some extra methods.  Headers are stored and returned in case-preserving
-form, but field names are matched case-insensitively.  Unlike a real dict,
-there is an ordering to the keys, and there can be duplicate keys.  Additional
-methods are provided for working with headers that have duplicate keys.
+form, but field names are matched case-insensitively.  The keys are ordered,
+but unlike a real dict, there can be duplicates.  Addtional methods are
+provided for working with headers that have duplicate keys.
 
 The *payload* is either a string or bytes object, in the case of simple message
 objects, or a list of :class:`EmailMessage` objects, for MIME container

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


[Python-checkins] [3.12] gh-114149: [Enum] revert GH-114196 and add more tuple-subclass tests (GH-114215) (GH-114218)

2024-01-17 Thread ethanfurman
https://github.com/python/cpython/commit/35e330ba859c915043d2e9808b44120f67328873
commit: 35e330ba859c915043d2e9808b44120f67328873
branch: 3.12
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: ethanfurman 
date: 2024-01-17T20:36:28-08:00
summary:

[3.12] gh-114149: [Enum] revert GH-114196 and add more tuple-subclass tests 
(GH-114215) (GH-114218)

gh-114149: [Enum] revert GH-114160 and add more tuple-subclass tests (GH-114215)

This reverts commit 05e142b1543eb9662d6cc33722e7e16250c9219f.
(cherry picked from commit 4c7e09d0129dafddba58979ced9580f856f65efa)

Co-authored-by: Ethan Furman 

files:
M Lib/enum.py
M Lib/test/test_enum.py

diff --git a/Lib/enum.py b/Lib/enum.py
index 0cf88471d504a2..1502bfe9158520 100644
--- a/Lib/enum.py
+++ b/Lib/enum.py
@@ -254,7 +254,7 @@ def __set_name__(self, enum_class, member_name):
 delattr(enum_class, member_name)
 # second step: create member based on enum_class
 value = self.value
-if type(value) is not tuple:
+if not isinstance(value, tuple):
 args = (value, )
 else:
 args = value
@@ -1757,7 +1757,7 @@ def convert_class(cls):
 else:
 # create the member
 if use_args:
-if type(value) is not tuple:
+if not isinstance(value, tuple):
 value = (value, )
 member = new_member(enum_class, *value)
 value = value[0]
@@ -1807,7 +1807,7 @@ def convert_class(cls):
 else:
 # create the member
 if use_args:
-if type(value) is not tuple:
+if not isinstance(value, tuple):
 value = (value, )
 member = new_member(enum_class, *value)
 value = value[0]
diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py
index 2db3b2f95fc845..23be142c24de0f 100644
--- a/Lib/test/test_enum.py
+++ b/Lib/test/test_enum.py
@@ -3163,19 +3163,34 @@ class NTEnum(Enum):
 [x.value for x in NTEnum],
 [TTuple(id=0, a=0, blist=[]), TTuple(id=1, a=2, blist=[4]), 
TTuple(id=2, a=4, blist=[0, 1, 2])],
 )
+
+self.assertRaises(AttributeError, getattr, NTEnum.NONE, 'id')
+#
+class NTCEnum(TTuple, Enum):
+NONE = 0, 0, []
+A = 1, 2, [4]
+B = 2, 4, [0, 1, 2]
+self.assertEqual(repr(NTCEnum.NONE), "")
+self.assertEqual(NTCEnum.NONE.value, TTuple(id=0, a=0, blist=[]))
+self.assertEqual(NTCEnum.NONE.id, 0)
+self.assertEqual(NTCEnum.A.a, 2)
+self.assertEqual(NTCEnum.B.blist, [0, 1 ,2])
+self.assertEqual(
+[x.value for x in NTCEnum],
+[TTuple(id=0, a=0, blist=[]), TTuple(id=1, a=2, blist=[4]), 
TTuple(id=2, a=4, blist=[0, 1, 2])],
+)
 #
 class NTDEnum(Enum):
-def __new__(cls, t_value):
+def __new__(cls, id, a, blist):
 member = object.__new__(cls)
-member._value_ = t_value[0]
-member.id = t_value[0]
-member.a = t_value[1]
-member.blist = t_value[2]
+member.id = id
+member.a = a
+member.blist = blist
 return member
 NONE = TTuple(0, 0, [])
 A = TTuple(1, 2, [4])
 B = TTuple(2, 4, [0, 1, 2])
-self.assertEqual(repr(NTDEnum.NONE), "")
+self.assertEqual(repr(NTDEnum.NONE), "")
 self.assertEqual(NTDEnum.NONE.id, 0)
 self.assertEqual(NTDEnum.A.a, 2)
 self.assertEqual(NTDEnum.B.blist, [0, 1 ,2])

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


[Python-checkins] gh-96905: In IDLE code, stop redefining built-ins 'dict' and 'object' (#114227)

2024-01-17 Thread terryjreedy
https://github.com/python/cpython/commit/6f4b242a03e521a55f0b9e440703b424ed18ce2f
commit: 6f4b242a03e521a55f0b9e440703b424ed18ce2f
branch: main
author: Terry Jan Reedy 
committer: terryjreedy 
date: 2024-01-18T04:39:12Z
summary:

gh-96905: In IDLE code, stop redefining built-ins 'dict' and 'object' (#114227)

Prefix 'dict' with 'o', 'g', or 'l' for 'object', 'global', or 'local'.
Suffix 'object' with '_'.

files:
A Misc/NEWS.d/next/IDLE/2024-01-17-23-18-15.gh-issue-96905.UYaxoU.rst
M Lib/idlelib/News3.txt
M Lib/idlelib/debugger.py
M Lib/idlelib/debugger_r.py
M Lib/idlelib/debugobj.py
M Lib/idlelib/idle_test/test_calltip.py
M Lib/idlelib/rpc.py
M Lib/idlelib/stackviewer.py

diff --git a/Lib/idlelib/News3.txt b/Lib/idlelib/News3.txt
index ee36fa7e1d5341..241b1f48e5c1d8 100644
--- a/Lib/idlelib/News3.txt
+++ b/Lib/idlelib/News3.txt
@@ -4,6 +4,8 @@ Released on 2024-10-xx
 =
 
 
+gh-96905: In idlelib code, stop redefining built-ins 'dict' and 'object'.
+
 gh-72284: Improve the lists of features, editor key bindings,
 and shell key bingings in the IDLE doc.
 
diff --git a/Lib/idlelib/debugger.py b/Lib/idlelib/debugger.py
index f487b4c4b16a60..d90dbcd11f9f61 100644
--- a/Lib/idlelib/debugger.py
+++ b/Lib/idlelib/debugger.py
@@ -508,11 +508,11 @@ def show_source(self, index):
 class NamespaceViewer:
 "Global/local namespace viewer for debugger GUI."
 
-def __init__(self, master, title, dict=None):
+def __init__(self, master, title, odict=None):  # XXX odict never passed.
 width = 0
 height = 40
-if dict:
-height = 20*len(dict) # XXX 20 == observed height of Entry widget
+if odict:
+height = 20*len(odict) # XXX 20 == observed height of Entry widget
 self.master = master
 self.title = title
 import reprlib
@@ -533,24 +533,24 @@ def __init__(self, master, title, dict=None):
 canvas["yscrollcommand"] = vbar.set
 self.subframe = subframe = Frame(canvas)
 self.sfid = canvas.create_window(0, 0, window=subframe, anchor="nw")
-self.load_dict(dict)
+self.load_dict(odict)
 
-dict = -1
+prev_odict = -1  # Needed for initial comparison below.
 
-def load_dict(self, dict, force=0, rpc_client=None):
-if dict is self.dict and not force:
+def load_dict(self, odict, force=0, rpc_client=None):
+if odict is self.prev_odict and not force:
 return
 subframe = self.subframe
 frame = self.frame
 for c in list(subframe.children.values()):
 c.destroy()
-self.dict = None
-if not dict:
+self.prev_odict = None
+if not odict:
 l = Label(subframe, text="None")
 l.grid(row=0, column=0)
 else:
 #names = sorted(dict)
-###
+#
 # Because of (temporary) limitations on the dict_keys type (not yet
 # public or pickleable), have the subprocess to send a list of
 # keys, not a dict_keys object.  sorted() will take a dict_keys
@@ -560,12 +560,12 @@ def load_dict(self, dict, force=0, rpc_client=None):
 # interpreter gets into a loop requesting non-existing dict[0],
 # dict[1], dict[2], etc from the debugger_r.DictProxy.
 # TODO recheck above; see debugger_r 159ff, debugobj 60.
-keys_list = dict.keys()
+keys_list = odict.keys()
 names = sorted(keys_list)
-###
+
 row = 0
 for name in names:
-value = dict[name]
+value = odict[name]
 svalue = self.repr.repr(value) # repr(value)
 # Strip extra quotes caused by calling repr on the (already)
 # repr'd value sent across the RPC interface:
@@ -577,7 +577,7 @@ def load_dict(self, dict, force=0, rpc_client=None):
 l.insert(0, svalue)
 l.grid(row=row, column=1, sticky="nw")
 row = row+1
-self.dict = dict
+self.prev_odict = odict
 # XXX Could we use a  callback for the following?
 subframe.update_idletasks() # Alas!
 width = subframe.winfo_reqwidth()
diff --git a/Lib/idlelib/debugger_r.py b/Lib/idlelib/debugger_r.py
index 26204438858d8a..ad3355d9f82765 100644
--- a/Lib/idlelib/debugger_r.py
+++ b/Lib/idlelib/debugger_r.py
@@ -125,16 +125,16 @@ def frame_attr(self, fid, name):
 
 def frame_globals(self, fid):
 frame = frametable[fid]
-dict = frame.f_globals
-did = id(dict)
-dicttable[did] = dict
+gdict = frame.f_globals
+did = id(gdict)
+dicttable[did] = gdict
 return did
 
 def frame_locals(self, fid):
 frame = frametable[fid]
-dict = frame.f_locals
-did = id(dict)
-dicttable[did] = dict
+ldict = frame.f_locals
+did = id(ldict)
+dicttable[did] = ldict
  

[Python-checkins] [3.11] gh-96905: In IDLE code, stop redefining built-ins 'dict' and 'object' (GH-114227) (#114229)

2024-01-17 Thread terryjreedy
https://github.com/python/cpython/commit/f49a1ce6b2008d80bc874f0cc20848004307
commit: f49a1ce6b2008d80bc874f0cc20848004307
branch: 3.11
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: terryjreedy 
date: 2024-01-18T00:05:00-05:00
summary:

[3.11] gh-96905: In IDLE code, stop redefining built-ins 'dict' and 'object' 
(GH-114227) (#114229)

Prefix 'dict' with 'o', 'g', or 'l' for 'object', 'global', or 'local'.
Suffix 'object' with '_'.
(cherry picked from commit 6f4b242a03e521a55f0b9e440703b424ed18ce2f)

Co-authored-by: Terry Jan Reedy 

files:
A Misc/NEWS.d/next/IDLE/2024-01-17-23-18-15.gh-issue-96905.UYaxoU.rst
M Lib/idlelib/News3.txt
M Lib/idlelib/debugger.py
M Lib/idlelib/debugger_r.py
M Lib/idlelib/debugobj.py
M Lib/idlelib/idle_test/test_calltip.py
M Lib/idlelib/rpc.py
M Lib/idlelib/stackviewer.py

diff --git a/Lib/idlelib/News3.txt b/Lib/idlelib/News3.txt
index 6e7ad60ff34fee..2010da3caa56b2 100644
--- a/Lib/idlelib/News3.txt
+++ b/Lib/idlelib/News3.txt
@@ -4,6 +4,8 @@ Released after 2022-10-24
 =
 
 
+gh-96905: In idlelib code, stop redefining built-ins 'dict' and 'object'.
+
 gh-72284: Improve the lists of features, editor key bindings,
 and shell key bingings in the IDLE doc.
 
diff --git a/Lib/idlelib/debugger.py b/Lib/idlelib/debugger.py
index f487b4c4b16a60..d90dbcd11f9f61 100644
--- a/Lib/idlelib/debugger.py
+++ b/Lib/idlelib/debugger.py
@@ -508,11 +508,11 @@ def show_source(self, index):
 class NamespaceViewer:
 "Global/local namespace viewer for debugger GUI."
 
-def __init__(self, master, title, dict=None):
+def __init__(self, master, title, odict=None):  # XXX odict never passed.
 width = 0
 height = 40
-if dict:
-height = 20*len(dict) # XXX 20 == observed height of Entry widget
+if odict:
+height = 20*len(odict) # XXX 20 == observed height of Entry widget
 self.master = master
 self.title = title
 import reprlib
@@ -533,24 +533,24 @@ def __init__(self, master, title, dict=None):
 canvas["yscrollcommand"] = vbar.set
 self.subframe = subframe = Frame(canvas)
 self.sfid = canvas.create_window(0, 0, window=subframe, anchor="nw")
-self.load_dict(dict)
+self.load_dict(odict)
 
-dict = -1
+prev_odict = -1  # Needed for initial comparison below.
 
-def load_dict(self, dict, force=0, rpc_client=None):
-if dict is self.dict and not force:
+def load_dict(self, odict, force=0, rpc_client=None):
+if odict is self.prev_odict and not force:
 return
 subframe = self.subframe
 frame = self.frame
 for c in list(subframe.children.values()):
 c.destroy()
-self.dict = None
-if not dict:
+self.prev_odict = None
+if not odict:
 l = Label(subframe, text="None")
 l.grid(row=0, column=0)
 else:
 #names = sorted(dict)
-###
+#
 # Because of (temporary) limitations on the dict_keys type (not yet
 # public or pickleable), have the subprocess to send a list of
 # keys, not a dict_keys object.  sorted() will take a dict_keys
@@ -560,12 +560,12 @@ def load_dict(self, dict, force=0, rpc_client=None):
 # interpreter gets into a loop requesting non-existing dict[0],
 # dict[1], dict[2], etc from the debugger_r.DictProxy.
 # TODO recheck above; see debugger_r 159ff, debugobj 60.
-keys_list = dict.keys()
+keys_list = odict.keys()
 names = sorted(keys_list)
-###
+
 row = 0
 for name in names:
-value = dict[name]
+value = odict[name]
 svalue = self.repr.repr(value) # repr(value)
 # Strip extra quotes caused by calling repr on the (already)
 # repr'd value sent across the RPC interface:
@@ -577,7 +577,7 @@ def load_dict(self, dict, force=0, rpc_client=None):
 l.insert(0, svalue)
 l.grid(row=row, column=1, sticky="nw")
 row = row+1
-self.dict = dict
+self.prev_odict = odict
 # XXX Could we use a  callback for the following?
 subframe.update_idletasks() # Alas!
 width = subframe.winfo_reqwidth()
diff --git a/Lib/idlelib/debugger_r.py b/Lib/idlelib/debugger_r.py
index 26204438858d8a..ad3355d9f82765 100644
--- a/Lib/idlelib/debugger_r.py
+++ b/Lib/idlelib/debugger_r.py
@@ -125,16 +125,16 @@ def frame_attr(self, fid, name):
 
 def frame_globals(self, fid):
 frame = frametable[fid]
-dict = frame.f_globals
-did = id(dict)
-dicttable[did] = dict
+gdict = frame.f_globals
+did = id(gdict)
+dicttable[did] = gdict
 return did
 
 def frame_locals(self, fid):
 frame = frametable[

[Python-checkins] [3.12] gh-96905: In IDLE code, stop redefining built-ins 'dict' and 'object' (GH-114227) (#114228)

2024-01-17 Thread terryjreedy
https://github.com/python/cpython/commit/e7a5577b53885b9432d201417f0dace22acf6804
commit: e7a5577b53885b9432d201417f0dace22acf6804
branch: 3.12
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: terryjreedy 
date: 2024-01-18T05:09:26Z
summary:

[3.12] gh-96905: In IDLE code, stop redefining built-ins 'dict' and 'object' 
(GH-114227) (#114228)

Prefix 'dict' with 'o', 'g', or 'l' for 'object', 'global', or 'local'.
Suffix 'object' with '_'.
(cherry picked from commit 6f4b242a03e521a55f0b9e440703b424ed18ce2f)

Co-authored-by: Terry Jan Reedy 

files:
A Misc/NEWS.d/next/IDLE/2024-01-17-23-18-15.gh-issue-96905.UYaxoU.rst
M Lib/idlelib/News3.txt
M Lib/idlelib/debugger.py
M Lib/idlelib/debugger_r.py
M Lib/idlelib/debugobj.py
M Lib/idlelib/idle_test/test_calltip.py
M Lib/idlelib/rpc.py
M Lib/idlelib/stackviewer.py

diff --git a/Lib/idlelib/News3.txt b/Lib/idlelib/News3.txt
index efb8d00dc979d2..8d04ff30ad7ecf 100644
--- a/Lib/idlelib/News3.txt
+++ b/Lib/idlelib/News3.txt
@@ -4,6 +4,8 @@ Released after 2023-10-02
 =
 
 
+gh-96905: In idlelib code, stop redefining built-ins 'dict' and 'object'.
+
 gh-72284: Improve the lists of features, editor key bindings,
 and shell key bingings in the IDLE doc.
 
diff --git a/Lib/idlelib/debugger.py b/Lib/idlelib/debugger.py
index f487b4c4b16a60..d90dbcd11f9f61 100644
--- a/Lib/idlelib/debugger.py
+++ b/Lib/idlelib/debugger.py
@@ -508,11 +508,11 @@ def show_source(self, index):
 class NamespaceViewer:
 "Global/local namespace viewer for debugger GUI."
 
-def __init__(self, master, title, dict=None):
+def __init__(self, master, title, odict=None):  # XXX odict never passed.
 width = 0
 height = 40
-if dict:
-height = 20*len(dict) # XXX 20 == observed height of Entry widget
+if odict:
+height = 20*len(odict) # XXX 20 == observed height of Entry widget
 self.master = master
 self.title = title
 import reprlib
@@ -533,24 +533,24 @@ def __init__(self, master, title, dict=None):
 canvas["yscrollcommand"] = vbar.set
 self.subframe = subframe = Frame(canvas)
 self.sfid = canvas.create_window(0, 0, window=subframe, anchor="nw")
-self.load_dict(dict)
+self.load_dict(odict)
 
-dict = -1
+prev_odict = -1  # Needed for initial comparison below.
 
-def load_dict(self, dict, force=0, rpc_client=None):
-if dict is self.dict and not force:
+def load_dict(self, odict, force=0, rpc_client=None):
+if odict is self.prev_odict and not force:
 return
 subframe = self.subframe
 frame = self.frame
 for c in list(subframe.children.values()):
 c.destroy()
-self.dict = None
-if not dict:
+self.prev_odict = None
+if not odict:
 l = Label(subframe, text="None")
 l.grid(row=0, column=0)
 else:
 #names = sorted(dict)
-###
+#
 # Because of (temporary) limitations on the dict_keys type (not yet
 # public or pickleable), have the subprocess to send a list of
 # keys, not a dict_keys object.  sorted() will take a dict_keys
@@ -560,12 +560,12 @@ def load_dict(self, dict, force=0, rpc_client=None):
 # interpreter gets into a loop requesting non-existing dict[0],
 # dict[1], dict[2], etc from the debugger_r.DictProxy.
 # TODO recheck above; see debugger_r 159ff, debugobj 60.
-keys_list = dict.keys()
+keys_list = odict.keys()
 names = sorted(keys_list)
-###
+
 row = 0
 for name in names:
-value = dict[name]
+value = odict[name]
 svalue = self.repr.repr(value) # repr(value)
 # Strip extra quotes caused by calling repr on the (already)
 # repr'd value sent across the RPC interface:
@@ -577,7 +577,7 @@ def load_dict(self, dict, force=0, rpc_client=None):
 l.insert(0, svalue)
 l.grid(row=row, column=1, sticky="nw")
 row = row+1
-self.dict = dict
+self.prev_odict = odict
 # XXX Could we use a  callback for the following?
 subframe.update_idletasks() # Alas!
 width = subframe.winfo_reqwidth()
diff --git a/Lib/idlelib/debugger_r.py b/Lib/idlelib/debugger_r.py
index 26204438858d8a..ad3355d9f82765 100644
--- a/Lib/idlelib/debugger_r.py
+++ b/Lib/idlelib/debugger_r.py
@@ -125,16 +125,16 @@ def frame_attr(self, fid, name):
 
 def frame_globals(self, fid):
 frame = frametable[fid]
-dict = frame.f_globals
-did = id(dict)
-dicttable[did] = dict
+gdict = frame.f_globals
+did = id(gdict)
+dicttable[did] = gdict
 return did
 
 def frame_locals(self, fid):
 frame = frametable[fid]