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; }