[Python-checkins] gh-120296: Fix format string of fcntl.ioctl() audit (#120301)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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]
