[Python-checkins] gh-120296: Fix format string of fcntl.ioctl() audit (#120301)

2024-06-10 Thread vstinner
https://github.com/python/cpython/commit/e5a7bc6f2eb9a3875063423caa67bb0ffcc3a6b8
commit: e5a7bc6f2eb9a3875063423caa67bb0ffcc3a6b8
branch: main
author: Clinton 
committer: vstinner 
date: 2024-06-10T08:17:50Z
summary:

gh-120296: Fix format string of fcntl.ioctl() audit (#120301)

files:
M Modules/fcntlmodule.c

diff --git a/Modules/fcntlmodule.c b/Modules/fcntlmodule.c
index 873bdf2ac0657a..0c06c03a6c403e 100644
--- a/Modules/fcntlmodule.c
+++ b/Modules/fcntlmodule.c
@@ -170,7 +170,7 @@ fcntl_ioctl_impl(PyObject *module, int fd, unsigned long 
code,
 Py_ssize_t len;
 char buf[IOCTL_BUFSZ+1];  /* argument plus NUL byte */
 
-if (PySys_Audit("fcntl.ioctl", "iIO", fd, code,
+if (PySys_Audit("fcntl.ioctl", "ikO", fd, code,
 ob_arg ? ob_arg : Py_None) < 0) {
 return NULL;
 }

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


[Python-checkins] bpo-24766: doc= argument to subclasses of property not handled correctly (GH-2487)

2024-06-10 Thread serhiy-storchaka
https://github.com/python/cpython/commit/4829522b8d3e1a28930f1cccfcc9635e035a0eb4
commit: 4829522b8d3e1a28930f1cccfcc9635e035a0eb4
branch: main
author: E. M. Bray 
committer: serhiy-storchaka 
date: 2024-06-10T08:55:49Z
summary:

bpo-24766: doc= argument to subclasses of property not handled correctly 
(GH-2487)

Co-authored-by: Serhiy Storchaka 

files:
A Misc/NEWS.d/next/Core and Builtins/2018-10-09-15-14-53.bpo-24766.c_C1Wc.rst
M Lib/test/test_property.py
M Objects/descrobject.c

diff --git a/Lib/test/test_property.py b/Lib/test/test_property.py
index 408e64f53142db..b7a2219b96149a 100644
--- a/Lib/test/test_property.py
+++ b/Lib/test/test_property.py
@@ -463,6 +463,40 @@ def getter3(self):
 self.assertEqual(p.__doc__, "user")
 self.assertEqual(p2.__doc__, "user")
 
[email protected](sys.flags.optimize >= 2,
+ "Docstrings are omitted with -O2 and above")
+def test_prefer_explicit_doc(self):
+# Issue 25757: subclasses of property lose docstring
+self.assertEqual(property(doc="explicit doc").__doc__, "explicit doc")
+self.assertEqual(PropertySub(doc="explicit doc").__doc__, "explicit 
doc")
+
+class Foo:
+spam = PropertySub(doc="spam explicit doc")
+
[email protected]
+def spam(self):
+"""ignored as doc already set"""
+return 1
+
+def _stuff_getter(self):
+"""ignored as doc set directly"""
+stuff = PropertySub(doc="stuff doc argument", fget=_stuff_getter)
+
+#self.assertEqual(Foo.spam.__doc__, "spam explicit doc")
+self.assertEqual(Foo.stuff.__doc__, "stuff doc argument")
+
+def test_property_no_doc_on_getter(self):
+# If a property's getter has no __doc__ then the property's doc should
+# be None; test that this is consistent with subclasses as well; see
+# GH-2487
+class NoDoc:
+@property
+def __doc__(self):
+raise AttributeError
+
+self.assertEqual(property(NoDoc()).__doc__, None)
+self.assertEqual(PropertySub(NoDoc()).__doc__, None)
+
 @unittest.skipIf(sys.flags.optimize >= 2,
  "Docstrings are omitted with -O2 and above")
 def test_property_setter_copies_getter_docstring(self):
diff --git a/Misc/NEWS.d/next/Core and 
Builtins/2018-10-09-15-14-53.bpo-24766.c_C1Wc.rst b/Misc/NEWS.d/next/Core and 
Builtins/2018-10-09-15-14-53.bpo-24766.c_C1Wc.rst
new file mode 100644
index 00..93a8562efe6d6f
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and 
Builtins/2018-10-09-15-14-53.bpo-24766.c_C1Wc.rst   
@@ -0,0 +1 @@
+Fix handling of ``doc`` argument to subclasses of ``property``.
diff --git a/Objects/descrobject.c b/Objects/descrobject.c
index 1b7e2fde3ceccd..4eccd1704eb95a 100644
--- a/Objects/descrobject.c
+++ b/Objects/descrobject.c
@@ -1859,22 +1859,9 @@ property_init_impl(propertyobject *self, PyObject *fget, 
PyObject *fset,
 /* if no docstring given and the getter has one, use that one */
 else if (fget != NULL) {
 int rc = PyObject_GetOptionalAttr(fget, &_Py_ID(__doc__), &prop_doc);
-if (rc <= 0) {
+if (rc < 0) {
 return rc;
 }
-if (!Py_IS_TYPE(self, &PyProperty_Type) &&
-prop_doc != NULL && prop_doc != Py_None) {
-// This oddity preserves the long existing behavior of surfacing
-// an AttributeError when using a dict-less (__slots__) property
-// subclass as a decorator on a getter method with a docstring.
-// See PropertySubclassTest.test_slots_docstring_copy_exception.
-int err = PyObject_SetAttr(
-(PyObject *)self, &_Py_ID(__doc__), prop_doc);
-if (err < 0) {
-Py_DECREF(prop_doc);  // release our new reference.
-return -1;
-}
-}
 if (prop_doc == Py_None) {
 prop_doc = NULL;
 Py_DECREF(Py_None);
@@ -1902,7 +1889,9 @@ property_init_impl(propertyobject *self, PyObject *fget, 
PyObject *fset,
 Py_DECREF(prop_doc);
 if (err < 0) {
 assert(PyErr_Occurred());
-if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
+if (!self->getter_doc &&
+PyErr_ExceptionMatches(PyExc_AttributeError))
+{
 PyErr_Clear();
 // 
https://github.com/python/cpython/issues/98963#issuecomment-1574413319
 // Python silently dropped this doc assignment through 3.11.

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


[Python-checkins] gh-120155: Fix Coverity issue in zoneinfo load_data() (#120232)

2024-06-10 Thread vstinner
https://github.com/python/cpython/commit/b90bd3e5bbc136f53b24ee791824acd6b17e0d42
commit: b90bd3e5bbc136f53b24ee791824acd6b17e0d42
branch: main
author: Victor Stinner 
committer: vstinner 
date: 2024-06-10T11:54:35+02:00
summary:

gh-120155: Fix Coverity issue in zoneinfo load_data() (#120232)

Declare the 'rv' varaible at the top of the load_data() function to
make sure that it's initialized before the first 'goto error' which
uses 'rv' (return rv).

Fix the Coverity issue:

Error: UNINIT (CWE-457):
Python-3.12.2/Modules/_zoneinfo.c:1233:5: skipped_decl: Jumping over 
declaration of ""rv"".
Python-3.12.2/Modules/_zoneinfo.c:1284:5: uninit_use: Using uninitialized value 
""rv"".
  1282|   }
  1283|
  1284|-> return rv;
  1285|   }
  1286|

files:
M Modules/_zoneinfo.c

diff --git a/Modules/_zoneinfo.c b/Modules/_zoneinfo.c
index 38c3f0c45d803f..902ece795b575b 100644
--- a/Modules/_zoneinfo.c
+++ b/Modules/_zoneinfo.c
@@ -944,6 +944,7 @@ ttinfo_eq(const _ttinfo *const tti0, const _ttinfo *const 
tti1)
 static int
 load_data(zoneinfo_state *state, PyZoneInfo_ZoneInfo *self, PyObject *file_obj)
 {
+int rv = 0;
 PyObject *data_tuple = NULL;
 
 long *utcoff = NULL;
@@ -1220,7 +1221,6 @@ load_data(zoneinfo_state *state, PyZoneInfo_ZoneInfo 
*self, PyObject *file_obj)
 }
 }
 
-int rv = 0;
 goto cleanup;
 error:
 // These resources only need to be freed if we have failed, if we succeed

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


[Python-checkins] [3.12] gh-120155: Fix Coverity issue in zoneinfo load_data() (GH-120232) (#120311)

2024-06-10 Thread vstinner
https://github.com/python/cpython/commit/ff980e3f7a8fab768148cf09aad40c20e05eb126
commit: ff980e3f7a8fab768148cf09aad40c20e05eb126
branch: 3.12
author: Miss Islington (bot) <[email protected]>
committer: vstinner 
date: 2024-06-10T10:12:25Z
summary:

[3.12] gh-120155: Fix Coverity issue in zoneinfo load_data() (GH-120232) 
(#120311)

gh-120155: Fix Coverity issue in zoneinfo load_data() (GH-120232)

Declare the 'rv' varaible at the top of the load_data() function to
make sure that it's initialized before the first 'goto error' which
uses 'rv' (return rv).

Fix the Coverity issue:

Error: UNINIT (CWE-457):
Python-3.12.2/Modules/_zoneinfo.c:1233:5: skipped_decl: Jumping over 
declaration of ""rv"".
Python-3.12.2/Modules/_zoneinfo.c:1284:5: uninit_use: Using uninitialized value 
""rv"".
  1282|   }
  1283|
  1284|-> return rv;
  1285|   }
  1286|
(cherry picked from commit b90bd3e5bbc136f53b24ee791824acd6b17e0d42)

Co-authored-by: Victor Stinner 

files:
M Modules/_zoneinfo.c

diff --git a/Modules/_zoneinfo.c b/Modules/_zoneinfo.c
index 8fc86162410619..47e40125cf8091 100644
--- a/Modules/_zoneinfo.c
+++ b/Modules/_zoneinfo.c
@@ -954,6 +954,7 @@ ttinfo_eq(const _ttinfo *const tti0, const _ttinfo *const 
tti1)
 static int
 load_data(zoneinfo_state *state, PyZoneInfo_ZoneInfo *self, PyObject *file_obj)
 {
+int rv = 0;
 PyObject *data_tuple = NULL;
 
 long *utcoff = NULL;
@@ -1230,7 +1231,6 @@ load_data(zoneinfo_state *state, PyZoneInfo_ZoneInfo 
*self, PyObject *file_obj)
 }
 }
 
-int rv = 0;
 goto cleanup;
 error:
 // These resources only need to be freed if we have failed, if we succeed

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


[Python-checkins] [3.13] gh-120155: Fix Coverity issue in zoneinfo load_data() (GH-120232) (#120310)

2024-06-10 Thread vstinner
https://github.com/python/cpython/commit/14ff4c979c8564376707de4b5a84dd3e4fcb5d1d
commit: 14ff4c979c8564376707de4b5a84dd3e4fcb5d1d
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: vstinner 
date: 2024-06-10T10:18:18Z
summary:

[3.13] gh-120155: Fix Coverity issue in zoneinfo load_data() (GH-120232) 
(#120310)

gh-120155: Fix Coverity issue in zoneinfo load_data() (GH-120232)

Declare the 'rv' varaible at the top of the load_data() function to
make sure that it's initialized before the first 'goto error' which
uses 'rv' (return rv).

Fix the Coverity issue:

Error: UNINIT (CWE-457):
Python-3.12.2/Modules/_zoneinfo.c:1233:5: skipped_decl: Jumping over 
declaration of ""rv"".
Python-3.12.2/Modules/_zoneinfo.c:1284:5: uninit_use: Using uninitialized value 
""rv"".
  1282|   }
  1283|
  1284|-> return rv;
  1285|   }
  1286|
(cherry picked from commit b90bd3e5bbc136f53b24ee791824acd6b17e0d42)

Co-authored-by: Victor Stinner 

files:
M Modules/_zoneinfo.c

diff --git a/Modules/_zoneinfo.c b/Modules/_zoneinfo.c
index 38c3f0c45d803f..902ece795b575b 100644
--- a/Modules/_zoneinfo.c
+++ b/Modules/_zoneinfo.c
@@ -944,6 +944,7 @@ ttinfo_eq(const _ttinfo *const tti0, const _ttinfo *const 
tti1)
 static int
 load_data(zoneinfo_state *state, PyZoneInfo_ZoneInfo *self, PyObject *file_obj)
 {
+int rv = 0;
 PyObject *data_tuple = NULL;
 
 long *utcoff = NULL;
@@ -1220,7 +1221,6 @@ load_data(zoneinfo_state *state, PyZoneInfo_ZoneInfo 
*self, PyObject *file_obj)
 }
 }
 
-int rv = 0;
 goto cleanup;
 error:
 // These resources only need to be freed if we have failed, if we succeed

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


[Python-checkins] [3.12] bpo-24766: doc= argument to subclasses of property not handled correctly (GH-2487) (GH-120312)

2024-06-10 Thread serhiy-storchaka
https://github.com/python/cpython/commit/7545b7cb63a7b27de2a829b626f546088b24de47
commit: 7545b7cb63a7b27de2a829b626f546088b24de47
branch: 3.12
author: Serhiy Storchaka 
committer: serhiy-storchaka 
date: 2024-06-10T10:32:45Z
summary:

[3.12] bpo-24766: doc= argument to subclasses of property not handled correctly 
(GH-2487) (GH-120312)

(cherry picked from commit 4829522b8d3e1a28930f1cccfcc9635e035a0eb4)

Co-authored-by: E. M. Bray 

files:
A Misc/NEWS.d/next/Core and Builtins/2018-10-09-15-14-53.bpo-24766.c_C1Wc.rst
M Lib/test/test_property.py
M Objects/descrobject.c

diff --git a/Lib/test/test_property.py b/Lib/test/test_property.py
index 4de2bb3781f870..157a4835379bda 100644
--- a/Lib/test/test_property.py
+++ b/Lib/test/test_property.py
@@ -431,6 +431,40 @@ def getter3(self):
 self.assertEqual(p.__doc__, "user")
 self.assertEqual(p2.__doc__, "user")
 
[email protected](sys.flags.optimize >= 2,
+ "Docstrings are omitted with -O2 and above")
+def test_prefer_explicit_doc(self):
+# Issue 25757: subclasses of property lose docstring
+self.assertEqual(property(doc="explicit doc").__doc__, "explicit doc")
+self.assertEqual(PropertySub(doc="explicit doc").__doc__, "explicit 
doc")
+
+class Foo:
+spam = PropertySub(doc="spam explicit doc")
+
[email protected]
+def spam(self):
+"""ignored as doc already set"""
+return 1
+
+def _stuff_getter(self):
+"""ignored as doc set directly"""
+stuff = PropertySub(doc="stuff doc argument", fget=_stuff_getter)
+
+#self.assertEqual(Foo.spam.__doc__, "spam explicit doc")
+self.assertEqual(Foo.stuff.__doc__, "stuff doc argument")
+
+def test_property_no_doc_on_getter(self):
+# If a property's getter has no __doc__ then the property's doc should
+# be None; test that this is consistent with subclasses as well; see
+# GH-2487
+class NoDoc:
+@property
+def __doc__(self):
+raise AttributeError
+
+self.assertEqual(property(NoDoc()).__doc__, None)
+self.assertEqual(PropertySub(NoDoc()).__doc__, None)
+
 @unittest.skipIf(sys.flags.optimize >= 2,
  "Docstrings are omitted with -O2 and above")
 def test_property_setter_copies_getter_docstring(self):
diff --git a/Misc/NEWS.d/next/Core and 
Builtins/2018-10-09-15-14-53.bpo-24766.c_C1Wc.rst b/Misc/NEWS.d/next/Core and 
Builtins/2018-10-09-15-14-53.bpo-24766.c_C1Wc.rst
new file mode 100644
index 00..93a8562efe6d6f
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and 
Builtins/2018-10-09-15-14-53.bpo-24766.c_C1Wc.rst   
@@ -0,0 +1 @@
+Fix handling of ``doc`` argument to subclasses of ``property``.
diff --git a/Objects/descrobject.c b/Objects/descrobject.c
index 18876fd2b883bb..a6c90e7ac1323f 100644
--- a/Objects/descrobject.c
+++ b/Objects/descrobject.c
@@ -1788,22 +1788,9 @@ property_init_impl(propertyobject *self, PyObject *fget, 
PyObject *fset,
 /* if no docstring given and the getter has one, use that one */
 else if (fget != NULL) {
 int rc = _PyObject_LookupAttr(fget, &_Py_ID(__doc__), &prop_doc);
-if (rc <= 0) {
+if (rc < 0) {
 return rc;
 }
-if (!Py_IS_TYPE(self, &PyProperty_Type) &&
-prop_doc != NULL && prop_doc != Py_None) {
-// This oddity preserves the long existing behavior of surfacing
-// an AttributeError when using a dict-less (__slots__) property
-// subclass as a decorator on a getter method with a docstring.
-// See PropertySubclassTest.test_slots_docstring_copy_exception.
-int err = PyObject_SetAttr(
-(PyObject *)self, &_Py_ID(__doc__), prop_doc);
-if (err < 0) {
-Py_DECREF(prop_doc);  // release our new reference.
-return -1;
-}
-}
 if (prop_doc == Py_None) {
 prop_doc = NULL;
 Py_DECREF(Py_None);
@@ -1831,7 +1818,9 @@ property_init_impl(propertyobject *self, PyObject *fget, 
PyObject *fset,
 Py_DECREF(prop_doc);
 if (err < 0) {
 assert(PyErr_Occurred());
-if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
+if (!self->getter_doc &&
+PyErr_ExceptionMatches(PyExc_AttributeError))
+{
 PyErr_Clear();
 // 
https://github.com/python/cpython/issues/98963#issuecomment-1574413319
 // Python silently dropped this doc assignment through 3.11.

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


[Python-checkins] gh-115801: Only allow sequence of strings as input for difflib.unified_diff (GH-118333)

2024-06-10 Thread serhiy-storchaka
https://github.com/python/cpython/commit/c3b6dbff2c8886de1edade737febe85dd47ff4d0
commit: c3b6dbff2c8886de1edade737febe85dd47ff4d0
branch: main
author: Pieter Eendebak 
committer: serhiy-storchaka 
date: 2024-06-10T14:06:18+03:00
summary:

gh-115801: Only allow sequence of strings as input for difflib.unified_diff 
(GH-118333)

files:
A Misc/NEWS.d/next/Core and 
Builtins/2024-04-27-18-36-46.gh-issue-115801.SVeHSy.rst
M Lib/difflib.py
M Lib/test/test_difflib.py

diff --git a/Lib/difflib.py b/Lib/difflib.py
index 0443963b4fd697..7f595b6c72e641 100644
--- a/Lib/difflib.py
+++ b/Lib/difflib.py
@@ -1264,6 +1264,12 @@ def _check_types(a, b, *args):
 if b and not isinstance(b[0], str):
 raise TypeError('lines to compare must be str, not %s (%r)' %
 (type(b[0]).__name__, b[0]))
+if isinstance(a, str):
+raise TypeError('input must be a sequence of strings, not %s' %
+type(a).__name__)
+if isinstance(b, str):
+raise TypeError('input must be a sequence of strings, not %s' %
+type(b).__name__)
 for arg in args:
 if not isinstance(arg, str):
 raise TypeError('all arguments must be str, not: %r' % (arg,))
diff --git a/Lib/test/test_difflib.py b/Lib/test/test_difflib.py
index bf6e5b1152b4a2..9e217249be7332 100644
--- a/Lib/test/test_difflib.py
+++ b/Lib/test/test_difflib.py
@@ -295,7 +295,7 @@ def test_close_matches_aligned(self):
 
 class TestOutputFormat(unittest.TestCase):
 def test_tab_delimiter(self):
-args = ['one', 'two', 'Original', 'Current',
+args = [['one'], ['two'], 'Original', 'Current',
 '2005-01-26 23:30:50', '2010-04-02 10:20:52']
 ud = difflib.unified_diff(*args, lineterm='')
 self.assertEqual(list(ud)[0:2], [
@@ -307,7 +307,7 @@ def test_tab_delimiter(self):
"--- Current\t2010-04-02 10:20:52"])
 
 def test_no_trailing_tab_on_empty_filedate(self):
-args = ['one', 'two', 'Original', 'Current']
+args = [['one'], ['two'], 'Original', 'Current']
 ud = difflib.unified_diff(*args, lineterm='')
 self.assertEqual(list(ud)[0:2], ["--- Original", "+++ Current"])
 
@@ -447,6 +447,28 @@ def assertDiff(expect, actual):
 lineterm=b'')
 assertDiff(expect, actual)
 
+
+class TestInputTypes(unittest.TestCase):
+def _assert_type_error(self, msg, generator, *args):
+with self.assertRaises(TypeError) as ctx:
+list(generator(*args))
+self.assertEqual(msg, str(ctx.exception))
+
+def test_input_type_checks(self):
+unified = difflib.unified_diff
+context = difflib.context_diff
+
+expect = "input must be a sequence of strings, not str"
+self._assert_type_error(expect, unified, 'a', ['b'])
+self._assert_type_error(expect, context, 'a', ['b'])
+
+self._assert_type_error(expect, unified, ['a'], 'b')
+self._assert_type_error(expect, context, ['a'], 'b')
+
+expect = "lines to compare must be str, not NoneType (None)"
+self._assert_type_error(expect, unified, ['a'], [None])
+self._assert_type_error(expect, context, ['a'], [None])
+
 def test_mixed_types_content(self):
 # type of input content must be consistent: all str or all bytes
 a = [b'hello']
@@ -495,10 +517,6 @@ def test_mixed_types_dates(self):
 b = ['bar\n']
 list(difflib.unified_diff(a, b, 'a', 'b', datea, dateb))
 
-def _assert_type_error(self, msg, generator, *args):
-with self.assertRaises(TypeError) as ctx:
-list(generator(*args))
-self.assertEqual(msg, str(ctx.exception))
 
 class TestJunkAPIs(unittest.TestCase):
 def test_is_line_junk_true(self):
diff --git a/Misc/NEWS.d/next/Core and 
Builtins/2024-04-27-18-36-46.gh-issue-115801.SVeHSy.rst b/Misc/NEWS.d/next/Core 
and Builtins/2024-04-27-18-36-46.gh-issue-115801.SVeHSy.rst
new file mode 100644
index 00..93b176d5767335
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and 
Builtins/2024-04-27-18-36-46.gh-issue-115801.SVeHSy.rst 
@@ -0,0 +1 @@
+Raise ``TypeError`` when passing a string to :func:`difflib.unified_diff` and 
:func:`difflib.context_diff`.

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


[Python-checkins] [3.12] GH-115983: skip building shared modules for testing under WASI (GH-116528) (#120316)

2024-06-10 Thread vstinner
https://github.com/python/cpython/commit/a9f2daf1ab182d95b44ee94dc9fb8faec60e34b1
commit: a9f2daf1ab182d95b44ee94dc9fb8faec60e34b1
branch: 3.12
author: Miss Islington (bot) <[email protected]>
committer: vstinner 
date: 2024-06-10T13:27:04Z
summary:

[3.12] GH-115983: skip building shared modules for testing under WASI 
(GH-116528) (#120316)

GH-115983: skip building shared modules for testing under WASI (GH-116528)
(cherry picked from commit 8c094c3095feb4de2efebd00f67fb6cc3b2bc240)

Co-authored-by: Brett Cannon 

files:
A Misc/NEWS.d/next/Build/2024-03-08-17-05-15.gh-issue-115983.ZQqk0Q.rst
M configure
M configure.ac

diff --git 
a/Misc/NEWS.d/next/Build/2024-03-08-17-05-15.gh-issue-115983.ZQqk0Q.rst 
b/Misc/NEWS.d/next/Build/2024-03-08-17-05-15.gh-issue-115983.ZQqk0Q.rst
new file mode 100644
index 00..a8d39921d59092
--- /dev/null
+++ b/Misc/NEWS.d/next/Build/2024-03-08-17-05-15.gh-issue-115983.ZQqk0Q.rst
@@ -0,0 +1 @@
+Skip building test modules that must be built as shared under WASI.
diff --git a/configure b/configure
index 9b400038b21d65..d151475f257a98 100755
--- a/configure
+++ b/configure
@@ -28646,9 +28646,15 @@ case $ac_sys_system in #(
 
 
 py_cv_module__ctypes_test=n/a
+py_cv_module__testexternalinspection=n/a
+py_cv_module__testimportmultiple=n/a
+py_cv_module__testmultiphase=n/a
+py_cv_module__testsinglephase=n/a
 py_cv_module_fcntl=n/a
 py_cv_module_mmap=n/a
 py_cv_module_termios=n/a
+py_cv_module_xxlimited=n/a
+py_cv_module_xxlimited_35=n/a
 py_cv_module_=n/a
 
 
diff --git a/configure.ac b/configure.ac
index 475a6140960d42..6df37e29f922dc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -7300,11 +7300,19 @@ AS_CASE([$ac_sys_system],
   [Emscripten/node*], [],
   [WASI/*], [
 dnl WASI SDK 15.0 does not support file locking, mmap, and more.
+dnl Test modules that must be compiled as shared libraries are not 
supported
+dnl (see Modules/Setup.stdlib.in).
 PY_STDLIB_MOD_SET_NA(
   [_ctypes_test],
+  [_testexternalinspection],
+  [_testimportmultiple],
+  [_testmultiphase],
+  [_testsinglephase],
   [fcntl],
   [mmap],
   [termios],
+  [xxlimited],
+  [xxlimited_35],
 )
   ]
 )

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


[Python-checkins] gh-119786: copy compiler doc from devguide to InternalDocs and convert to markdown (#120134)

2024-06-10 Thread iritkatriel
https://github.com/python/cpython/commit/56c3815ba14c790d2e9a227b4ac0ead5e6b1e570
commit: 56c3815ba14c790d2e9a227b4ac0ead5e6b1e570
branch: main
author: Irit Katriel <[email protected]>
committer: iritkatriel <[email protected]>
date: 2024-06-10T16:15:12+01:00
summary:

gh-119786: copy compiler doc from devguide to InternalDocs and convert to 
markdown (#120134)

* gh-119876: move compiler doc from devguide to InternalDocs

Copy of 
https://github.com/python/devguide/commit/78fc0d7aa9fd0d6733d10c23b178b2a0e2799afc

Co-Authored-By: Adam Turner <[email protected]>
Co-Authored-By: Adam Turner <[email protected]>
Co-Authored-By: Brett Cannon 
Co-Authored-By: Carol Willing 
Co-Authored-By: Daniel Porteous 
Co-Authored-By: Dennis Sweeney <[email protected]>
Co-Authored-By: Éric Araujo 
Co-Authored-By: Erlend Egeberg Aasland 
Co-Authored-By: Ezio Melotti 
Co-Authored-By: Georg Brandl 
Co-Authored-By: Guido van Rossum 
Co-Authored-By: Hugo van Kemenade 
Co-Authored-By: Irit Katriel <[email protected]>
Co-Authored-By: Jeff Allen 
Co-Authored-By: Jim Fasarakis-Hilliard 
Co-Authored-By: Ken Jin <[email protected]>
Co-Authored-By: Lincoln <[email protected]>
Co-Authored-By: Mariatta 
Co-Authored-By: Muhammad Mahad 
Co-Authored-By: Ned Deily 
Co-Authored-By: Pablo Galindo Salgado 
Co-Authored-By: Serhiy Storchaka 
Co-Authored-By: Stéphane Wirtel 
Co-Authored-By: Suriyaa ✌️️ 
Co-Authored-By: Zachary Ware 
Co-Authored-By: psyker156 <[email protected]>
Co-Authored-By: slateny <[email protected]>
Co-Authored-By: svelankar <[email protected]>
Co-Authored-By: zikcheng 

* convert to markdown

* add to index

* update more of the out of date stuff

-

Co-authored-by: Adam Turner <[email protected]>
Co-authored-by: Brett Cannon 
Co-authored-by: Carol Willing 
Co-authored-by: Daniel Porteous 
Co-authored-by: Dennis Sweeney <[email protected]>
Co-authored-by: Éric Araujo 
Co-authored-by: Erlend Egeberg Aasland 
Co-authored-by: Ezio Melotti 
Co-authored-by: Georg Brandl 
Co-authored-by: Guido van Rossum 
Co-authored-by: Hugo van Kemenade 
Co-authored-by: Jeff Allen 
Co-authored-by: Jim Fasarakis-Hilliard 
Co-authored-by: Ken Jin <[email protected]>
Co-authored-by: Lincoln <[email protected]>
Co-authored-by: Mariatta 
Co-authored-by: Muhammad Mahad 
Co-authored-by: Ned Deily 
Co-authored-by: Pablo Galindo Salgado 
Co-authored-by: Serhiy Storchaka 
Co-authored-by: Stéphane Wirtel 
Co-authored-by: Suriyaa ✌️️ 
Co-authored-by: Zachary Ware 
Co-authored-by: psyker156 <[email protected]>
Co-authored-by: slateny <[email protected]>
Co-authored-by: svelankar <[email protected]>
Co-authored-by: zikcheng 

files:
A InternalDocs/compiler.md
M InternalDocs/README.md

diff --git a/InternalDocs/README.md b/InternalDocs/README.md
index a2502fbf198735..42f6125794266a 100644
--- a/InternalDocs/README.md
+++ b/InternalDocs/README.md
@@ -12,6 +12,8 @@ it is not, please report that through the
 [issue tracker](https://github.com/python/cpython/issues).
 
 
+[Compiler Design](compiler.md)
+
 [Exception Handling](exception_handling.md)
 
 [Adaptive Instruction Families](adaptive.md)
diff --git a/InternalDocs/compiler.md b/InternalDocs/compiler.md
new file mode 100644
index 00..0abc10da6e05c6
--- /dev/null
+++ b/InternalDocs/compiler.md
@@ -0,0 +1,651 @@
+
+Compiler design
+===
+
+Abstract
+
+
+In CPython, the compilation from source code to bytecode involves several 
steps:
+
+1. Tokenize the source code
+   [Parser/lexer/](https://github.com/python/cpython/blob/main/Parser/lexer/)
+   and 
[Parser/tokenizer/](https://github.com/python/cpython/blob/main/Parser/tokenizer/).
+2. Parse the stream of tokens into an Abstract Syntax Tree
+   
[Parser/parser.c](https://github.com/python/cpython/blob/main/Parser/parser.c).
+3. Transform AST into an instruction sequence
+   
[Python/compile.c](https://github.com/python/cpython/blob/main/Python/compile.c).
+4. Construct a Control Flow Graph and apply optimizations to it
+   
[Python/flowgraph.c](https://github.com/python/cpython/blob/main/Python/flowgraph.c).
+5. Emit bytecode based on the Control Flow Graph
+   
[Python/assemble.c](https://github.com/python/cpython/blob/main/Python/assemble.c).
+
+This document outlines how these steps of the process work.
+
+This document only describes parsing in enough depth to explain what is needed
+for understanding compilation.  This document provides a detailed, though not
+exhaustive, view of the how the entire system works.  You will most likely need
+

[Python-checkins] gh-120057: Add os.environ.refresh() method (#120059)

2024-06-10 Thread vstinner
https://github.com/python/cpython/commit/7aff2de62bc28eb23888270b698c6b6915f69b21
commit: 7aff2de62bc28eb23888270b698c6b6915f69b21
branch: main
author: Victor Stinner 
committer: vstinner 
date: 2024-06-10T16:34:17Z
summary:

gh-120057: Add os.environ.refresh() method (#120059)

files:
A Misc/NEWS.d/next/Library/2024-06-04-18-53-10.gh-issue-120057.RSD9_Z.rst
M Doc/library/os.rst
M Doc/whatsnew/3.14.rst
M Lib/os.py
M Lib/test/test_os.py
M Modules/clinic/posixmodule.c.h
M Modules/posixmodule.c

diff --git a/Doc/library/os.rst b/Doc/library/os.rst
index b93b06d4e72afc..360d71e70960c7 100644
--- a/Doc/library/os.rst
+++ b/Doc/library/os.rst
@@ -193,6 +193,10 @@ process and user.
to the environment made after this time are not reflected in 
:data:`os.environ`,
except for changes made by modifying :data:`os.environ` directly.
 
+   The :meth:`!os.environ.refresh()` method updates :data:`os.environ` with
+   changes to the environment made by :func:`os.putenv`, by
+   :func:`os.unsetenv`, or made outside Python in the same process.
+
This mapping may be used to modify the environment as well as query the
environment.  :func:`putenv` will be called automatically when the mapping
is modified.
@@ -225,6 +229,9 @@ process and user.
.. versionchanged:: 3.9
   Updated to support :pep:`584`'s merge (``|``) and update (``|=``) 
operators.
 
+   .. versionchanged:: 3.14
+  Added the :meth:`!os.environ.refresh()` method.
+
 
 .. data:: environb
 
@@ -561,6 +568,8 @@ process and user.
of :data:`os.environ`. This also applies to :func:`getenv` and 
:func:`getenvb`, which
respectively use :data:`os.environ` and :data:`os.environb` in their 
implementations.
 
+   See also the :data:`os.environ.refresh() ` method.
+
.. note::
 
   On some platforms, including FreeBSD and macOS, setting ``environ`` may
@@ -809,6 +818,8 @@ process and user.
don't update :data:`os.environ`, so it is actually preferable to delete 
items of
:data:`os.environ`.
 
+   See also the :data:`os.environ.refresh() ` method.
+
.. audit-event:: os.unsetenv key os.unsetenv
 
.. versionchanged:: 3.9
diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst
index b2dd80b64a691a..b77ff30a8fbbee 100644
--- a/Doc/whatsnew/3.14.rst
+++ b/Doc/whatsnew/3.14.rst
@@ -92,6 +92,13 @@ ast
 Added :func:`ast.compare` for comparing two ASTs.
 (Contributed by Batuhan Taskaya and Jeremy Hylton in :issue:`15987`.)
 
+os
+--
+
+* Added the :data:`os.environ.refresh() ` method to update
+  :data:`os.environ` with changes to the environment made by :func:`os.putenv`,
+  by :func:`os.unsetenv`, or made outside Python in the same process.
+  (Contributed by Victor Stinner in :gh:`120057`.)
 
 
 Optimizations
diff --git a/Lib/os.py b/Lib/os.py
index 0408e2db79e66e..4b48afb040e565 100644
--- a/Lib/os.py
+++ b/Lib/os.py
@@ -64,6 +64,10 @@ def _get_exports_list(module):
 from posix import _have_functions
 except ImportError:
 pass
+try:
+from posix import _create_environ
+except ImportError:
+pass
 
 import posix
 __all__.extend(_get_exports_list(posix))
@@ -88,6 +92,10 @@ def _get_exports_list(module):
 from nt import _have_functions
 except ImportError:
 pass
+try:
+from nt import _create_environ
+except ImportError:
+pass
 
 else:
 raise ImportError('no os specific module found')
@@ -773,7 +781,18 @@ def __ror__(self, other):
 new.update(self)
 return new
 
-def _createenviron():
+if _exists("_create_environ"):
+def refresh(self):
+data = _create_environ()
+if name == 'nt':
+data = {self.encodekey(key): value
+for key, value in data.items()}
+
+# modify in-place to keep os.environb in sync
+self._data.clear()
+self._data.update(data)
+
+def _create_environ_mapping():
 if name == 'nt':
 # Where Env Var Names Must Be UPPERCASE
 def check_str(value):
@@ -803,8 +822,8 @@ def decode(value):
 encode, decode)
 
 # unicode environ
-environ = _createenviron()
-del _createenviron
+environ = _create_environ_mapping()
+del _create_environ_mapping
 
 
 def getenv(key, default=None):
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index 2beb9ca8aa6ccb..f93937fb587386 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -1298,6 +1298,52 @@ def test_ror_operator(self):
 self._test_underlying_process_env('_A_', '')
 self._test_underlying_process_env(overridden_key, original_value)
 
+def test_refresh(self):
+# Test os.environ.refresh()
+has_environb = hasattr(os, 'environb')
+
+# Test with putenv() which doesn't update os.environ
+os.environ['test_env'] = 'python_value'
+os.putenv("test_env", "new_value")
+self.assertEqual(os.environ['test_env'], 'python_value')
+if has_environb:
+se

[Python-checkins] Fix the CODEOWNERS for _interpretersmodule.c (gh-120288)

2024-06-10 Thread ericsnowcurrently
https://github.com/python/cpython/commit/6efe3460693c4f39de198a64ceb8b1d4e8b6
commit: 6efe3460693c4f39de198a64ceb8b1d4e8b6
branch: main
author: AN Long 
committer: ericsnowcurrently 
date: 2024-06-10T10:45:16-06:00
summary:

Fix the CODEOWNERS for _interpretersmodule.c (gh-120288)

files:
M .github/CODEOWNERS

diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 811b8cfdab17dc..8bc40fcb9e8999 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -245,7 +245,7 @@ Doc/howto/clinic.rst  @erlend-aasland
 **/*interpreteridobject.* @ericsnowcurrently
 **/*crossinterp*  @ericsnowcurrently
 Lib/test/support/interpreters/  @ericsnowcurrently
-Modules/_xx*interp*module.c   @ericsnowcurrently
+Modules/_interp*module.c  @ericsnowcurrently
 Lib/test/test_interpreters/   @ericsnowcurrently
 
 # Android

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


[Python-checkins] [3.13] Fix the CODEOWNERS for _interpretersmodule.c (gh-120324)

2024-06-10 Thread ericsnowcurrently
https://github.com/python/cpython/commit/ffc8e21c80627c46be7a7467ee5427924fdeb885
commit: ffc8e21c80627c46be7a7467ee5427924fdeb885
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: ericsnowcurrently 
date: 2024-06-10T17:11:22Z
summary:

[3.13] Fix the CODEOWNERS for _interpretersmodule.c (gh-120324)

(cherry picked from commit 6efe3460693c4f39de198a64ceb8b1d4e8b6, AKA 
gh-120288)

Co-authored-by: AN Long 

files:
M .github/CODEOWNERS

diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 45a5f3ceb67b44..a7d60f222d1f2e 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -240,7 +240,7 @@ Doc/howto/clinic.rst  @erlend-aasland
 **/*interpreteridobject.* @ericsnowcurrently
 **/*crossinterp*  @ericsnowcurrently
 Lib/test/support/interpreters/  @ericsnowcurrently
-Modules/_xx*interp*module.c   @ericsnowcurrently
+Modules/_interp*module.c  @ericsnowcurrently
 Lib/test/test_interpreters/   @ericsnowcurrently
 
 # Android

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


[Python-checkins] gh-119600: mock: do not access attributes of original when new_callable is set (#119601)

2024-06-10 Thread cjw296
https://github.com/python/cpython/commit/422c4fc855afd18bcc6415902ea1d85a50cb7ce1
commit: 422c4fc855afd18bcc6415902ea1d85a50cb7ce1
branch: main
author: Robert Collins 
committer: cjw296 
date: 2024-06-11T06:41:12+01:00
summary:

gh-119600: mock: do not access attributes of original when new_callable is set 
(#119601)

In order to patch flask.g e.g. as in #84982, that
proxies getattr must not be invoked. For that,
mock must not try to read from the original
object. In some cases that is unavoidable, e.g.
when doing autospec. However, patch("flask.g",
new_callable=MagicMock) should be entirely safe.

files:
A Misc/NEWS.d/next/Library/2024-06-10-14-00-40.gh-issue-119600.jJMf4C.rst
M Lib/test/test_unittest/testmock/support.py
M Lib/test/test_unittest/testmock/testpatch.py
M Lib/unittest/mock.py

diff --git a/Lib/test/test_unittest/testmock/support.py 
b/Lib/test/test_unittest/testmock/support.py
index 49986d65dc47af..6c535b7944f261 100644
--- a/Lib/test/test_unittest/testmock/support.py
+++ b/Lib/test/test_unittest/testmock/support.py
@@ -14,3 +14,14 @@ def wibble(self): pass
 
 class X(object):
 pass
+
+# A standin for weurkzeug.local.LocalProxy - issue 119600
+def _inaccessible(*args, **kwargs):
+raise AttributeError
+
+
+class OpaqueProxy:
+__getattribute__ = _inaccessible
+
+
+g = OpaqueProxy()
diff --git a/Lib/test/test_unittest/testmock/testpatch.py 
b/Lib/test/test_unittest/testmock/testpatch.py
index be75fda7826af1..f26e74ce0bc1ba 100644
--- a/Lib/test/test_unittest/testmock/testpatch.py
+++ b/Lib/test/test_unittest/testmock/testpatch.py
@@ -2045,6 +2045,13 @@ def test(): pass
 with self.assertRaises(TypeError):
 test()
 
+def test_patch_proxy_object(self):
+@patch("test.test_unittest.testmock.support.g", 
new_callable=MagicMock())
+def test(_):
+pass
+
+test()
+
 
 if __name__ == '__main__':
 unittest.main()
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
index 3ef83e263f53b7..edabb4520c13cd 100644
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -1508,13 +1508,12 @@ def __enter__(self):
 if isinstance(original, type):
 # If we're patching out a class and there is a spec
 inherit = True
-if spec is None and _is_async_obj(original):
-Klass = AsyncMock
-else:
-Klass = MagicMock
-_kwargs = {}
+
+# Determine the Klass to use
 if new_callable is not None:
 Klass = new_callable
+elif spec is None and _is_async_obj(original):
+Klass = AsyncMock
 elif spec is not None or spec_set is not None:
 this_spec = spec
 if spec_set is not None:
@@ -1527,7 +1526,12 @@ def __enter__(self):
 Klass = AsyncMock
 elif not_callable:
 Klass = NonCallableMagicMock
+else:
+Klass = MagicMock
+else:
+Klass = MagicMock
 
+_kwargs = {}
 if spec is not None:
 _kwargs['spec'] = spec
 if spec_set is not None:
diff --git 
a/Misc/NEWS.d/next/Library/2024-06-10-14-00-40.gh-issue-119600.jJMf4C.rst 
b/Misc/NEWS.d/next/Library/2024-06-10-14-00-40.gh-issue-119600.jJMf4C.rst
new file mode 100644
index 00..04c9ca9c3fd737
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-06-10-14-00-40.gh-issue-119600.jJMf4C.rst
@@ -0,0 +1,2 @@
+Fix :func:`unittest.mock.patch` to not read attributes of the target when
+``new_callable`` is set. Patch by Robert Collins.

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


[Python-checkins] gh-65454: avoid triggering call to a PropertyMock in NonCallableMock.__setattr__ (#120019)

2024-06-10 Thread cjw296
https://github.com/python/cpython/commit/9e9ee50421c857b443e2060274f17fb884d54473
commit: 9e9ee50421c857b443e2060274f17fb884d54473
branch: main
author: blhsing 
committer: cjw296 
date: 2024-06-11T05:42:49Z
summary:

gh-65454: avoid triggering call to a PropertyMock in 
NonCallableMock.__setattr__ (#120019)

files:
A Misc/NEWS.d/next/Library/2024-06-04-08-57-02.gh-issue-65454.o9j4wF.rst
M Lib/test/test_unittest/testmock/testhelpers.py
M Lib/unittest/mock.py

diff --git a/Lib/test/test_unittest/testmock/testhelpers.py 
b/Lib/test/test_unittest/testmock/testhelpers.py
index 74785a83757a92..c9c20f008ca5a2 100644
--- a/Lib/test/test_unittest/testmock/testhelpers.py
+++ b/Lib/test/test_unittest/testmock/testhelpers.py
@@ -1127,6 +1127,14 @@ def test_propertymock_side_effect(self):
 p.assert_called_once_with()
 
 
+def test_propertymock_attach(self):
+m = Mock()
+p = PropertyMock()
+type(m).foo = p
+m.attach_mock(p, 'foo')
+self.assertEqual(m.mock_calls, [])
+
+
 class TestCallablePredicate(unittest.TestCase):
 
 def test_type(self):
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
index edabb4520c13cd..08975e0e1bd132 100644
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -830,6 +830,9 @@ def __setattr__(self, name, value):
 mock_name = f'{self._extract_mock_name()}.{name}'
 raise AttributeError(f'Cannot set {mock_name}')
 
+if isinstance(value, PropertyMock):
+self.__dict__[name] = value
+return
 return object.__setattr__(self, name, value)
 
 
diff --git 
a/Misc/NEWS.d/next/Library/2024-06-04-08-57-02.gh-issue-65454.o9j4wF.rst 
b/Misc/NEWS.d/next/Library/2024-06-04-08-57-02.gh-issue-65454.o9j4wF.rst
new file mode 100644
index 00..0b232cf8ca1baf
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-06-04-08-57-02.gh-issue-65454.o9j4wF.rst
@@ -0,0 +1 @@
+:func:`unittest.mock.Mock.attach_mock` no longer triggers a call to a 
``PropertyMock`` being attached.

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


[Python-checkins] [3.12] gh-119600: mock: do not access attributes of original when new_callable is set (GH-119601) (#120335)

2024-06-10 Thread cjw296
https://github.com/python/cpython/commit/fa291a35eb29c53958aa5d2e2b58aea2441ffca8
commit: fa291a35eb29c53958aa5d2e2b58aea2441ffca8
branch: 3.12
author: Miss Islington (bot) <[email protected]>
committer: cjw296 
date: 2024-06-11T06:01:02Z
summary:

[3.12] gh-119600: mock: do not access attributes of original when new_callable 
is set (GH-119601) (#120335)

gh-119600: mock: do not access attributes of original when new_callable is set 
(GH-119601)

In order to patch flask.g e.g. as in GH-84982, that
proxies getattr must not be invoked. For that,
mock must not try to read from the original
object. In some cases that is unavoidable, e.g.
when doing autospec. However, patch("flask.g",
new_callable=MagicMock) should be entirely safe.
(cherry picked from commit 422c4fc855afd18bcc6415902ea1d85a50cb7ce1)

Co-authored-by: Robert Collins 

files:
A Misc/NEWS.d/next/Library/2024-06-10-14-00-40.gh-issue-119600.jJMf4C.rst
M Lib/test/test_unittest/testmock/support.py
M Lib/test/test_unittest/testmock/testpatch.py
M Lib/unittest/mock.py

diff --git a/Lib/test/test_unittest/testmock/support.py 
b/Lib/test/test_unittest/testmock/support.py
index 49986d65dc47af..6c535b7944f261 100644
--- a/Lib/test/test_unittest/testmock/support.py
+++ b/Lib/test/test_unittest/testmock/support.py
@@ -14,3 +14,14 @@ def wibble(self): pass
 
 class X(object):
 pass
+
+# A standin for weurkzeug.local.LocalProxy - issue 119600
+def _inaccessible(*args, **kwargs):
+raise AttributeError
+
+
+class OpaqueProxy:
+__getattribute__ = _inaccessible
+
+
+g = OpaqueProxy()
diff --git a/Lib/test/test_unittest/testmock/testpatch.py 
b/Lib/test/test_unittest/testmock/testpatch.py
index be75fda7826af1..f26e74ce0bc1ba 100644
--- a/Lib/test/test_unittest/testmock/testpatch.py
+++ b/Lib/test/test_unittest/testmock/testpatch.py
@@ -2045,6 +2045,13 @@ def test(): pass
 with self.assertRaises(TypeError):
 test()
 
+def test_patch_proxy_object(self):
+@patch("test.test_unittest.testmock.support.g", 
new_callable=MagicMock())
+def test(_):
+pass
+
+test()
+
 
 if __name__ == '__main__':
 unittest.main()
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
index 486e0c634b82c1..854010c7fb893e 100644
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -1478,13 +1478,12 @@ def __enter__(self):
 if isinstance(original, type):
 # If we're patching out a class and there is a spec
 inherit = True
-if spec is None and _is_async_obj(original):
-Klass = AsyncMock
-else:
-Klass = MagicMock
-_kwargs = {}
+
+# Determine the Klass to use
 if new_callable is not None:
 Klass = new_callable
+elif spec is None and _is_async_obj(original):
+Klass = AsyncMock
 elif spec is not None or spec_set is not None:
 this_spec = spec
 if spec_set is not None:
@@ -1497,7 +1496,12 @@ def __enter__(self):
 Klass = AsyncMock
 elif not_callable:
 Klass = NonCallableMagicMock
+else:
+Klass = MagicMock
+else:
+Klass = MagicMock
 
+_kwargs = {}
 if spec is not None:
 _kwargs['spec'] = spec
 if spec_set is not None:
diff --git 
a/Misc/NEWS.d/next/Library/2024-06-10-14-00-40.gh-issue-119600.jJMf4C.rst 
b/Misc/NEWS.d/next/Library/2024-06-10-14-00-40.gh-issue-119600.jJMf4C.rst
new file mode 100644
index 00..04c9ca9c3fd737
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-06-10-14-00-40.gh-issue-119600.jJMf4C.rst
@@ -0,0 +1,2 @@
+Fix :func:`unittest.mock.patch` to not read attributes of the target when
+``new_callable`` is set. Patch by Robert Collins.

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


[Python-checkins] [3.13] gh-119600: mock: do not access attributes of original when new_callable is set (GH-119601) (#120334)

2024-06-10 Thread cjw296
https://github.com/python/cpython/commit/aba5f2a4d10a7b261d4af03a54a8b1083bd83700
commit: aba5f2a4d10a7b261d4af03a54a8b1083bd83700
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: cjw296 
date: 2024-06-11T06:04:06Z
summary:

[3.13] gh-119600: mock: do not access attributes of original when new_callable 
is set (GH-119601) (#120334)

gh-119600: mock: do not access attributes of original when new_callable is set 
(GH-119601)

In order to patch flask.g e.g. as in GH-84982, that
proxies getattr must not be invoked. For that,
mock must not try to read from the original
object. In some cases that is unavoidable, e.g.
when doing autospec. However, patch("flask.g",
new_callable=MagicMock) should be entirely safe.
(cherry picked from commit 422c4fc855afd18bcc6415902ea1d85a50cb7ce1)

Co-authored-by: Robert Collins 

files:
A Misc/NEWS.d/next/Library/2024-06-10-14-00-40.gh-issue-119600.jJMf4C.rst
M Lib/test/test_unittest/testmock/support.py
M Lib/test/test_unittest/testmock/testpatch.py
M Lib/unittest/mock.py

diff --git a/Lib/test/test_unittest/testmock/support.py 
b/Lib/test/test_unittest/testmock/support.py
index 49986d65dc47af..6c535b7944f261 100644
--- a/Lib/test/test_unittest/testmock/support.py
+++ b/Lib/test/test_unittest/testmock/support.py
@@ -14,3 +14,14 @@ def wibble(self): pass
 
 class X(object):
 pass
+
+# A standin for weurkzeug.local.LocalProxy - issue 119600
+def _inaccessible(*args, **kwargs):
+raise AttributeError
+
+
+class OpaqueProxy:
+__getattribute__ = _inaccessible
+
+
+g = OpaqueProxy()
diff --git a/Lib/test/test_unittest/testmock/testpatch.py 
b/Lib/test/test_unittest/testmock/testpatch.py
index be75fda7826af1..f26e74ce0bc1ba 100644
--- a/Lib/test/test_unittest/testmock/testpatch.py
+++ b/Lib/test/test_unittest/testmock/testpatch.py
@@ -2045,6 +2045,13 @@ def test(): pass
 with self.assertRaises(TypeError):
 test()
 
+def test_patch_proxy_object(self):
+@patch("test.test_unittest.testmock.support.g", 
new_callable=MagicMock())
+def test(_):
+pass
+
+test()
+
 
 if __name__ == '__main__':
 unittest.main()
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
index a2634b6164062a..d0f2b8b7761c53 100644
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -1508,13 +1508,12 @@ def __enter__(self):
 if isinstance(original, type):
 # If we're patching out a class and there is a spec
 inherit = True
-if spec is None and _is_async_obj(original):
-Klass = AsyncMock
-else:
-Klass = MagicMock
-_kwargs = {}
+
+# Determine the Klass to use
 if new_callable is not None:
 Klass = new_callable
+elif spec is None and _is_async_obj(original):
+Klass = AsyncMock
 elif spec is not None or spec_set is not None:
 this_spec = spec
 if spec_set is not None:
@@ -1527,7 +1526,12 @@ def __enter__(self):
 Klass = AsyncMock
 elif not_callable:
 Klass = NonCallableMagicMock
+else:
+Klass = MagicMock
+else:
+Klass = MagicMock
 
+_kwargs = {}
 if spec is not None:
 _kwargs['spec'] = spec
 if spec_set is not None:
diff --git 
a/Misc/NEWS.d/next/Library/2024-06-10-14-00-40.gh-issue-119600.jJMf4C.rst 
b/Misc/NEWS.d/next/Library/2024-06-10-14-00-40.gh-issue-119600.jJMf4C.rst
new file mode 100644
index 00..04c9ca9c3fd737
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-06-10-14-00-40.gh-issue-119600.jJMf4C.rst
@@ -0,0 +1,2 @@
+Fix :func:`unittest.mock.patch` to not read attributes of the target when
+``new_callable`` is set. Patch by Robert Collins.

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


[Python-checkins] [3.12] gh-65454: avoid triggering call to a PropertyMock in NonCallableMock.__setattr__ (GH-120019) (#120337)

2024-06-10 Thread cjw296
https://github.com/python/cpython/commit/f6481925d80080f09c3bb264da7f5eedf0f86068
commit: f6481925d80080f09c3bb264da7f5eedf0f86068
branch: 3.12
author: Miss Islington (bot) <[email protected]>
committer: cjw296 
date: 2024-06-11T06:07:25Z
summary:

[3.12] gh-65454: avoid triggering call to a PropertyMock in 
NonCallableMock.__setattr__ (GH-120019) (#120337)

gh-65454: avoid triggering call to a PropertyMock in 
NonCallableMock.__setattr__ (GH-120019)
(cherry picked from commit 9e9ee50421c857b443e2060274f17fb884d54473)

Co-authored-by: blhsing 

files:
A Misc/NEWS.d/next/Library/2024-06-04-08-57-02.gh-issue-65454.o9j4wF.rst
M Lib/test/test_unittest/testmock/testhelpers.py
M Lib/unittest/mock.py

diff --git a/Lib/test/test_unittest/testmock/testhelpers.py 
b/Lib/test/test_unittest/testmock/testhelpers.py
index 74785a83757a92..c9c20f008ca5a2 100644
--- a/Lib/test/test_unittest/testmock/testhelpers.py
+++ b/Lib/test/test_unittest/testmock/testhelpers.py
@@ -1127,6 +1127,14 @@ def test_propertymock_side_effect(self):
 p.assert_called_once_with()
 
 
+def test_propertymock_attach(self):
+m = Mock()
+p = PropertyMock()
+type(m).foo = p
+m.attach_mock(p, 'foo')
+self.assertEqual(m.mock_calls, [])
+
+
 class TestCallablePredicate(unittest.TestCase):
 
 def test_type(self):
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
index 854010c7fb893e..ad4b4ebcd42a4f 100644
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -800,6 +800,9 @@ def __setattr__(self, name, value):
 mock_name = f'{self._extract_mock_name()}.{name}'
 raise AttributeError(f'Cannot set {mock_name}')
 
+if isinstance(value, PropertyMock):
+self.__dict__[name] = value
+return
 return object.__setattr__(self, name, value)
 
 
diff --git 
a/Misc/NEWS.d/next/Library/2024-06-04-08-57-02.gh-issue-65454.o9j4wF.rst 
b/Misc/NEWS.d/next/Library/2024-06-04-08-57-02.gh-issue-65454.o9j4wF.rst
new file mode 100644
index 00..0b232cf8ca1baf
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-06-04-08-57-02.gh-issue-65454.o9j4wF.rst
@@ -0,0 +1 @@
+:func:`unittest.mock.Mock.attach_mock` no longer triggers a call to a 
``PropertyMock`` being attached.

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


[Python-checkins] [3.13] gh-65454: avoid triggering call to a PropertyMock in NonCallableMock.__setattr__ (GH-120019) (#120336)

2024-06-10 Thread cjw296
https://github.com/python/cpython/commit/81eae217335fc66bec343b9f11f1b68fe85667bf
commit: 81eae217335fc66bec343b9f11f1b68fe85667bf
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: cjw296 
date: 2024-06-11T06:12:16Z
summary:

[3.13] gh-65454: avoid triggering call to a PropertyMock in 
NonCallableMock.__setattr__ (GH-120019) (#120336)

gh-65454: avoid triggering call to a PropertyMock in 
NonCallableMock.__setattr__ (GH-120019)
(cherry picked from commit 9e9ee50421c857b443e2060274f17fb884d54473)

Co-authored-by: blhsing 

files:
A Misc/NEWS.d/next/Library/2024-06-04-08-57-02.gh-issue-65454.o9j4wF.rst
M Lib/test/test_unittest/testmock/testhelpers.py
M Lib/unittest/mock.py

diff --git a/Lib/test/test_unittest/testmock/testhelpers.py 
b/Lib/test/test_unittest/testmock/testhelpers.py
index 74785a83757a92..c9c20f008ca5a2 100644
--- a/Lib/test/test_unittest/testmock/testhelpers.py
+++ b/Lib/test/test_unittest/testmock/testhelpers.py
@@ -1127,6 +1127,14 @@ def test_propertymock_side_effect(self):
 p.assert_called_once_with()
 
 
+def test_propertymock_attach(self):
+m = Mock()
+p = PropertyMock()
+type(m).foo = p
+m.attach_mock(p, 'foo')
+self.assertEqual(m.mock_calls, [])
+
+
 class TestCallablePredicate(unittest.TestCase):
 
 def test_type(self):
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
index d0f2b8b7761c53..b701ec33f3b9bb 100644
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -830,6 +830,9 @@ def __setattr__(self, name, value):
 mock_name = f'{self._extract_mock_name()}.{name}'
 raise AttributeError(f'Cannot set {mock_name}')
 
+if isinstance(value, PropertyMock):
+self.__dict__[name] = value
+return
 return object.__setattr__(self, name, value)
 
 
diff --git 
a/Misc/NEWS.d/next/Library/2024-06-04-08-57-02.gh-issue-65454.o9j4wF.rst 
b/Misc/NEWS.d/next/Library/2024-06-04-08-57-02.gh-issue-65454.o9j4wF.rst
new file mode 100644
index 00..0b232cf8ca1baf
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-06-04-08-57-02.gh-issue-65454.o9j4wF.rst
@@ -0,0 +1 @@
+:func:`unittest.mock.Mock.attach_mock` no longer triggers a call to a 
``PropertyMock`` being attached.

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