From 175c181a0993b9405d7d66f8141f172ad9fb03f0 Mon Sep 17 00:00:00 2001 From: Martijn Pieters Date: Mon, 4 Mar 2019 17:00:07 +0000 Subject: [PATCH 1/2] Clean up 'unbound' method left-overs Methods are always bound, and `__self__` can no longer be `NULL` (`method_new()` and `PyMethod_New()` both explicitly check for this). Moreover, once a bound method is bound, it *stays* bound and won't be re-bound to something else, so the section in the datamodel that talks about accessing an methods in a different descriptor-binding context doesn't apply any more in Python 3. --- Doc/reference/datamodel.rst | 6 ------ Objects/classobject.c | 21 +++------------------ 2 files changed, 3 insertions(+), 24 deletions(-) diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 9422ae66cb9c11..c3e79ce6c88120 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -578,12 +578,6 @@ Callable types to be bound. The new method's :attr:`__func__` attribute is the original function object. - When a user-defined method object is created by retrieving another method - object from a class or instance, the behaviour is the same as for a - function object, except that the :attr:`__func__` attribute of the new - instance is not the original method object but its :attr:`__func__` - attribute. - When an instance method object is created by retrieving a class method object from a class or instance, its :attr:`__self__` attribute is the class itself, and its :attr:`__func__` attribute is the function object diff --git a/Objects/classobject.c b/Objects/classobject.c index 0d1cf7a95ccca6..1ee897847fb03e 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -267,10 +267,7 @@ static Py_hash_t method_hash(PyMethodObject *a) { Py_hash_t x, y; - if (a->im_self == NULL) - x = _Py_HashPointer(Py_None); - else - x = _Py_HashPointer(a->im_self); + x = _Py_HashPointer(a->im_self); y = PyObject_Hash(a->im_func); if (y == -1) return -1; @@ -294,11 +291,6 @@ method_call(PyObject *method, PyObject *args, PyObject *kwargs) PyObject *self, *func; self = PyMethod_GET_SELF(method); - if (self == NULL) { - PyErr_BadInternalCall(); - return NULL; - } - func = PyMethod_GET_FUNCTION(method); return _PyObject_Call_Prepend(func, self, args, kwargs); @@ -307,15 +299,8 @@ method_call(PyObject *method, PyObject *args, PyObject *kwargs) static PyObject * method_descr_get(PyObject *meth, PyObject *obj, PyObject *cls) { - /* Don't rebind an already bound method of a class that's not a base - class of cls. */ - if (PyMethod_GET_SELF(meth) != NULL) { - /* Already bound */ - Py_INCREF(meth); - return meth; - } - /* Bind it to obj */ - return PyMethod_New(PyMethod_GET_FUNCTION(meth), obj); + Py_INCREF(meth); + return meth; } PyTypeObject PyMethod_Type = { From cbee241ae00bcb847064c8e7445d9b1e0dfc85bc Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" Date: Mon, 4 Mar 2019 18:05:34 +0000 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Core and Builtins/2019-03-04-18-05-31.bpo-36188.EuUZNz.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-03-04-18-05-31.bpo-36188.EuUZNz.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-03-04-18-05-31.bpo-36188.EuUZNz.rst b/Misc/NEWS.d/next/Core and Builtins/2019-03-04-18-05-31.bpo-36188.EuUZNz.rst new file mode 100644 index 00000000000000..f018e31ede91e0 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-03-04-18-05-31.bpo-36188.EuUZNz.rst @@ -0,0 +1,2 @@ +Cleaned up left-over vestiges of Python 2 unbound method handling in method objects and documentation. +Patch by Martijn Pieters \ No newline at end of file