From 9b3187769c592293987ae7a0bb7708ae5ec27b71 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Fri, 9 Feb 2024 16:04:29 +0300 Subject: [PATCH 1/7] gh-115231: fill __module__ attribute for built-in staticmethods --- Lib/test/test_funcattrs.py | 23 +++++++++++++++++++ ...-02-10-05-42-26.gh-issue-115231.6T7dzi.rst | 2 ++ Objects/typeobject.c | 4 +++- 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-02-10-05-42-26.gh-issue-115231.6T7dzi.rst diff --git a/Lib/test/test_funcattrs.py b/Lib/test/test_funcattrs.py index b3fc5ad42e7fde..7c9e80ec5b27f6 100644 --- a/Lib/test/test_funcattrs.py +++ b/Lib/test/test_funcattrs.py @@ -453,6 +453,29 @@ class BuiltinFunctionPropertiesTest(unittest.TestCase): # XXX Not sure where this should really go since I can't find a # test module specifically for builtin_function_or_method. + def test_builtin__module__(self): + import decimal + import math + + # builtin function: + self.assertEqual(len.__module__, 'builtins') + self.assertEqual(math.sin.__module__, 'math') + + # instance method: + self.assertRaises(AttributeError, getattr, int.to_bytes, '__module__') + self.assertRaises(AttributeError, getattr, decimal.Decimal.exp, '__module__') + self.assertEqual(int.to_bytes.__objclass__.__module__, 'builtins') + self.assertEqual(decimal.Decimal.exp.__objclass__.__module__, 'decimal') + + # builtin classmethod: + self.assertEqual(int.from_bytes.__module__, None) + self.assertEqual(int.from_bytes.__self__.__module__, 'builtins') + self.assertEqual(decimal.Decimal.from_float.__module__, None) + self.assertEqual(decimal.Decimal.from_float.__self__.__module__, 'decimal') + + # builtin staticmethod: + self.assertEqual(bytes.maketrans.__module__, 'builtins') + def test_builtin__qualname__(self): import time diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-02-10-05-42-26.gh-issue-115231.6T7dzi.rst b/Misc/NEWS.d/next/Core and Builtins/2024-02-10-05-42-26.gh-issue-115231.6T7dzi.rst new file mode 100644 index 00000000000000..0e41bc963bebec --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2024-02-10-05-42-26.gh-issue-115231.6T7dzi.rst @@ -0,0 +1,2 @@ +Setup ``__module__`` attribute for built-in static methods. Patch by Sergey +B Kirpichev. diff --git a/Objects/typeobject.c b/Objects/typeobject.c index c65d0ec2acae52..febb98b648cb90 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -6653,7 +6653,9 @@ type_add_method(PyTypeObject *type, PyMethodDef *meth) descr = PyDescr_NewClassMethod(type, meth); } else if (meth->ml_flags & METH_STATIC) { - PyObject *cfunc = PyCFunction_NewEx(meth, (PyObject*)type, NULL); + PyObject *mod = PyObject_GetAttr((PyObject*)type, &_Py_ID(__module__)); + PyObject *cfunc = PyCFunction_NewEx(meth, (PyObject*)type, mod); + Py_XDECREF(mod); if (cfunc == NULL) { return -1; } From be1c7ef5f0290fccfa6463fd8fae4714902f2895 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Sat, 10 Feb 2024 16:27:22 +0300 Subject: [PATCH 2/7] PyObject_GetAttr -> PyObject_GetOptionalAttr Co-authored-by: Nikita Sobolev --- Objects/typeobject.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index febb98b648cb90..c01c48ec107982 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -6653,7 +6653,8 @@ type_add_method(PyTypeObject *type, PyMethodDef *meth) descr = PyDescr_NewClassMethod(type, meth); } else if (meth->ml_flags & METH_STATIC) { - PyObject *mod = PyObject_GetAttr((PyObject*)type, &_Py_ID(__module__)); + PyObject *mod; + PyObject_GetOptionalAttr((PyObject*)type, &_Py_ID(__module__), &mod); PyObject *cfunc = PyCFunction_NewEx(meth, (PyObject*)type, mod); Py_XDECREF(mod); if (cfunc == NULL) { From c4dec1066f1c3cf3ade2ab32ed2f4c6d29983037 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Sun, 11 Feb 2024 05:59:54 +0300 Subject: [PATCH 3/7] fill __module__ attribute for built-in classmethods too --- Lib/test/test_funcattrs.py | 4 ++-- .../2024-02-10-05-42-26.gh-issue-115231.6T7dzi.rst | 4 ++-- Objects/descrobject.c | 7 ++++++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_funcattrs.py b/Lib/test/test_funcattrs.py index 7c9e80ec5b27f6..8a4d4ae6663653 100644 --- a/Lib/test/test_funcattrs.py +++ b/Lib/test/test_funcattrs.py @@ -468,9 +468,9 @@ def test_builtin__module__(self): self.assertEqual(decimal.Decimal.exp.__objclass__.__module__, 'decimal') # builtin classmethod: - self.assertEqual(int.from_bytes.__module__, None) + self.assertEqual(int.from_bytes.__module__, 'builtins') self.assertEqual(int.from_bytes.__self__.__module__, 'builtins') - self.assertEqual(decimal.Decimal.from_float.__module__, None) + self.assertEqual(decimal.Decimal.from_float.__module__, 'decimal') self.assertEqual(decimal.Decimal.from_float.__self__.__module__, 'decimal') # builtin staticmethod: diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-02-10-05-42-26.gh-issue-115231.6T7dzi.rst b/Misc/NEWS.d/next/Core and Builtins/2024-02-10-05-42-26.gh-issue-115231.6T7dzi.rst index 0e41bc963bebec..12c622f6c086c4 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2024-02-10-05-42-26.gh-issue-115231.6T7dzi.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2024-02-10-05-42-26.gh-issue-115231.6T7dzi.rst @@ -1,2 +1,2 @@ -Setup ``__module__`` attribute for built-in static methods. Patch by Sergey -B Kirpichev. +Setup ``__module__`` attribute for built-in class/static methods. Patch by +Sergey B Kirpichev. diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 8d771adf307dc4..1131cd3fa928a1 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -130,7 +130,12 @@ classmethod_get(PyObject *self, PyObject *obj, PyObject *type) if (descr->d_method->ml_flags & METH_METHOD) { cls = descr->d_common.d_type; } - return PyCMethod_New(descr->d_method, type, NULL, cls); + PyObject *mod; + PyObject_GetOptionalAttr((PyObject*)type, &_Py_ID(__module__), &mod); + PyErr_Clear(); + PyObject *result = PyCMethod_New(descr->d_method, type, mod, cls); + Py_XDECREF(mod); + return result; } static PyObject * From 1e25d8477f635b4b5cbfa49847865496379c736e Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Sun, 11 Feb 2024 06:35:53 +0300 Subject: [PATCH 4/7] use PyObject_GetAttr & ignore exceptions --- Objects/descrobject.c | 3 +-- Objects/typeobject.c | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 1131cd3fa928a1..571948229054d0 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -130,8 +130,7 @@ classmethod_get(PyObject *self, PyObject *obj, PyObject *type) if (descr->d_method->ml_flags & METH_METHOD) { cls = descr->d_common.d_type; } - PyObject *mod; - PyObject_GetOptionalAttr((PyObject*)type, &_Py_ID(__module__), &mod); + PyObject *mod = PyObject_GetAttr((PyObject*)type, &_Py_ID(__module__)); PyErr_Clear(); PyObject *result = PyCMethod_New(descr->d_method, type, mod, cls); Py_XDECREF(mod); diff --git a/Objects/typeobject.c b/Objects/typeobject.c index c01c48ec107982..fcd54a2b040e9d 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -6653,8 +6653,8 @@ type_add_method(PyTypeObject *type, PyMethodDef *meth) descr = PyDescr_NewClassMethod(type, meth); } else if (meth->ml_flags & METH_STATIC) { - PyObject *mod; - PyObject_GetOptionalAttr((PyObject*)type, &_Py_ID(__module__), &mod); + PyObject *mod = PyObject_GetAttr((PyObject*)type, &_Py_ID(__module__)); + PyErr_Clear(); PyObject *cfunc = PyCFunction_NewEx(meth, (PyObject*)type, mod); Py_XDECREF(mod); if (cfunc == NULL) { From 777bc8d363e81a7c712ee3426a1b80ee5ab26aa7 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Sat, 2 Nov 2024 14:20:55 +0300 Subject: [PATCH 5/7] address review: use type_module() --- Objects/typeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index e87763a54d4ae8..813b77a9002bcf 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -7611,7 +7611,7 @@ type_add_method(PyTypeObject *type, PyMethodDef *meth) descr = PyDescr_NewClassMethod(type, meth); } else if (meth->ml_flags & METH_STATIC) { - PyObject *mod = PyObject_GetAttr((PyObject*)type, &_Py_ID(__module__)); + PyObject *mod = type_module(type); PyErr_Clear(); PyObject *cfunc = PyCFunction_NewEx(meth, (PyObject*)type, mod); Py_XDECREF(mod); From d1650bfa3c56c97076e1eaa22000ca2fa012d082 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Sat, 2 Nov 2024 14:33:05 +0300 Subject: [PATCH 6/7] + rename news --- .../2024-02-10-05-42-26.gh-issue-115231.6T7dzi.rst | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Misc/NEWS.d/next/{Core and Builtins => Core_and_Builtins}/2024-02-10-05-42-26.gh-issue-115231.6T7dzi.rst (100%) diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-02-10-05-42-26.gh-issue-115231.6T7dzi.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-02-10-05-42-26.gh-issue-115231.6T7dzi.rst similarity index 100% rename from Misc/NEWS.d/next/Core and Builtins/2024-02-10-05-42-26.gh-issue-115231.6T7dzi.rst rename to Misc/NEWS.d/next/Core_and_Builtins/2024-02-10-05-42-26.gh-issue-115231.6T7dzi.rst From e20339bfa96f00cae28fcbc8f06f404544e4068e Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Sat, 2 Nov 2024 16:23:23 +0300 Subject: [PATCH 7/7] XXX Revert "address review: use type_module()" This reverts commit 777bc8d363e81a7c712ee3426a1b80ee5ab26aa7. --- Objects/typeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 813b77a9002bcf..e87763a54d4ae8 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -7611,7 +7611,7 @@ type_add_method(PyTypeObject *type, PyMethodDef *meth) descr = PyDescr_NewClassMethod(type, meth); } else if (meth->ml_flags & METH_STATIC) { - PyObject *mod = type_module(type); + PyObject *mod = PyObject_GetAttr((PyObject*)type, &_Py_ID(__module__)); PyErr_Clear(); PyObject *cfunc = PyCFunction_NewEx(meth, (PyObject*)type, mod); Py_XDECREF(mod);