diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst
index cf14de97202..988b73775e9 100644
--- a/Doc/library/inspect.rst
+++ b/Doc/library/inspect.rst
@@ -49,14 +49,11 @@ attributes:
| | __name__ | name with which this |
| | | method was defined |
+-----------+-----------------+---------------------------+
-| | im_class | class object that asked |
-| | | for this method |
-+-----------+-----------------+---------------------------+
-| | im_func | function object |
+| | __func__ | function object |
| | | containing implementation |
| | | of method |
+-----------+-----------------+---------------------------+
-| | im_self | instance to which this |
+| | __self__ | instance to which this |
| | | method is bound, or |
| | | ``None`` |
+-----------+-----------------+---------------------------+
@@ -264,7 +261,7 @@ attributes:
Methods implemented via descriptors that also pass one of the other tests
return false from the :func:`ismethoddescriptor` test, simply because the
other tests promise more -- you can, e.g., count on having the
- :attr:`im_func` attribute (etc) when an object passes :func:`ismethod`.
+ :attr:`__func__` attribute (etc) when an object passes :func:`ismethod`.
.. function:: isdatadescriptor(object)
diff --git a/Doc/library/new.rst b/Doc/library/new.rst
index 6153ff148bc..6c5a4bf8176 100644
--- a/Doc/library/new.rst
+++ b/Doc/library/new.rst
@@ -17,10 +17,10 @@ non-sensical arguments which crash the interpreter when the object is used.
The :mod:`new` module defines the following functions:
-.. function:: instancemethod(function, instance, class)
+.. function:: instancemethod(function, instance)
- This function will return a method object, bound to *instance*, or unbound if
- *instance* is ``None``. *function* must be callable.
+ This function will return a method object, bound to *instance*.
+ *function* must be callable.
.. function:: function(code, globals[, name[, argdefs[, closure]]])
diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst
index e6f7e7b52ad..1e81ed935f9 100644
--- a/Doc/library/stdtypes.rst
+++ b/Doc/library/stdtypes.rst
@@ -2216,21 +2216,21 @@ instance methods. Built-in methods are described with the types that support
them.
The implementation adds two special read-only attributes to class instance
-methods: ``m.im_self`` is the object on which the method operates, and
-``m.im_func`` is the function implementing the method. Calling ``m(arg-1,
-arg-2, ..., arg-n)`` is completely equivalent to calling ``m.im_func(m.im_self,
-arg-1, arg-2, ..., arg-n)``.
+methods: ``m.__self__`` is the object on which the method operates, and
+``m.__func__`` is the function implementing the method. Calling ``m(arg-1,
+arg-2, ..., arg-n)`` is completely equivalent to calling ``m.__func__(
+m.__self__, arg-1, arg-2, ..., arg-n)``.
Class instance methods are either *bound* or *unbound*, referring to whether the
method was accessed through an instance or a class, respectively. When a method
-is unbound, its ``im_self`` attribute will be ``None`` and if called, an
+is unbound, its ``__self__`` attribute will be ``None`` and if called, an
explicit ``self`` object must be passed as the first argument. In this case,
``self`` must be an instance of the unbound method's class (or a subclass of
that class), otherwise a :exc:`TypeError` is raised.
Like function objects, methods objects support getting arbitrary attributes.
However, since method attributes are actually stored on the underlying function
-object (``meth.im_func``), setting method attributes on either bound or unbound
+object (``meth.__func__``), setting method attributes on either bound or unbound
methods is disallowed. Attempting to set a method attribute results in a
:exc:`TypeError` being raised. In order to set a method attribute, you need to
explicitly set it on the underlying function object::
@@ -2240,7 +2240,7 @@ explicitly set it on the underlying function object::
pass
c = C()
- c.method.im_func.whoami = 'my name is c'
+ c.method.__func__.whoami = 'my name is c'
See :ref:`types` for more information.
diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst
index 1e85f8305e1..75cb52f5d3e 100644
--- a/Doc/reference/datamodel.rst
+++ b/Doc/reference/datamodel.rst
@@ -538,20 +538,18 @@ Callable types
A user-defined method object combines a class, a class instance (or ``None``)
and any callable object (normally a user-defined function).
- Special read-only attributes: :attr:`im_self` is the class instance object,
- :attr:`im_func` is the function object; :attr:`im_class` is the class of
- :attr:`im_self` for bound methods or the class that asked for the method for
- unbound methods; :attr:`__doc__` is the method's documentation (same as
- ``im_func.__doc__``); :attr:`__name__` is the method name (same as
- ``im_func.__name__``); :attr:`__module__` is the name of the module the method
- was defined in, or ``None`` if unavailable.
+ Special read-only attributes: :attr:`__self__` is the class instance object,
+ :attr:`__func__` is the function object; :attr:`__doc__` is the method's
+ documentation (same as ``__func__.__doc__``); :attr:`__name__` is the
+ method name (same as ``__func__.__name__``); :attr:`__module__` is the
+ name of the module the method was defined in, or ``None`` if unavailable.
.. index::
single: __doc__ (method attribute)
single: __name__ (method attribute)
single: __module__ (method attribute)
- single: im_func (method attribute)
- single: im_self (method attribute)
+ single: __func__ (method attribute)
+ single: __self__ (method attribute)
Methods also support accessing (but not setting) the arbitrary function
attributes on the underlying function object.
@@ -565,49 +563,46 @@ Callable types
the original method object is used as it is.
.. index::
- single: im_class (method attribute)
- single: im_func (method attribute)
- single: im_self (method attribute)
+ single: __func__ (method attribute)
+ single: __self__ (method attribute)
When a user-defined method object is created by retrieving a user-defined
- function object from a class, its :attr:`im_self` attribute is ``None``
+ function object from a class, its :attr:`__self__` attribute is ``None``
and the method object is said to be unbound. When one is created by
retrieving a user-defined function object from a class via one of its
- instances, its :attr:`im_self` attribute is the instance, and the method
- object is said to be bound. In either case, the new method's
- :attr:`im_class` attribute is the class from which the retrieval takes
- place, and its :attr:`im_func` attribute is the original function object.
+ instances, its :attr:`__self__` attribute is the instance, and the method
+ object is said to be bound. Its :attr:`__func__` attribute is the
+ original function object.
- .. index:: single: im_func (method attribute)
+ .. index:: single: __func__ (method attribute)
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:`im_func` attribute of the new instance is not the
- original method object but its :attr:`im_func` attribute.
+ except that the :attr:`__func__` attribute of the new instance is not the
+ original method object but its :attr:`__func__` attribute.
.. index::
- single: im_class (method attribute)
- single: im_func (method attribute)
- single: im_self (method attribute)
+ single: __func__ (method attribute)
+ single: __self__ (method attribute)
When a user-defined method object is created by retrieving a class method object
- from a class or instance, its :attr:`im_self` attribute is the class itself (the
- same as the :attr:`im_class` attribute), and its :attr:`im_func` attribute is
+ from a class or instance, its :attr:`__self__` attribute is the class itself (the
+ same as the :attr:`im_class` attribute), and its :attr:`__func__` attribute is
the function object underlying the class method.
When an unbound user-defined method object is called, the underlying function
- (:attr:`im_func`) is called, with the restriction that the first argument must
+ (:attr:`__func__`) is called, with the restriction that the first argument must
be an instance of the proper class (:attr:`im_class`) or of a derived class
thereof.
When a bound user-defined method object is called, the underlying function
- (:attr:`im_func`) is called, inserting the class instance (:attr:`im_self`) in
+ (:attr:`__func__`) is called, inserting the class instance (:attr:`__self__`) in
front of the argument list. For instance, when :class:`C` is a class which
contains a definition for a function :meth:`f`, and ``x`` is an instance of
:class:`C`, calling ``x.f(1)`` is equivalent to calling ``C.f(x, 1)``.
When a user-defined method object is derived from a class method object, the
- "class instance" stored in :attr:`im_self` will actually be the class itself, so
+ "class instance" stored in :attr:`__self__` will actually be the class itself, so
that calling either ``x.f(1)`` or ``C.f(1)`` is equivalent to calling ``f(C,1)``
where ``f`` is the underlying function.
@@ -741,7 +736,7 @@ Custom classes
transformed into an unbound user-defined method object whose :attr:`im_class`
attribute is :class:`C`. When it would yield a class method object, it is
transformed into a bound user-defined method object whose :attr:`im_class`
- and :attr:`im_self` attributes are both :class:`C`. When it would yield a
+ and :attr:`__self__` attributes are both :class:`C`. When it would yield a
static method object, it is transformed into the object wrapped by the static
method object. See section :ref:`descriptors` for another way in which
attributes retrieved from a class may differ from those actually contained in
@@ -786,7 +781,7 @@ Class instances
is the class (call it :class:`C`) of the instance for which the attribute
reference was initiated or one of its bases, it is transformed into a bound
user-defined method object whose :attr:`im_class` attribute is :class:`C` and
- whose :attr:`im_self` attribute is the instance. Static method and class method
+ whose :attr:`__self__` attribute is the instance. Static method and class method
objects are also transformed, as if they had been retrieved from class
:class:`C`; see above under "Classes". See section :ref:`descriptors` for
another way in which attributes of a class retrieved via its instances may
diff --git a/Doc/tutorial/classes.rst b/Doc/tutorial/classes.rst
index ef6498e885e..4e954195a07 100644
--- a/Doc/tutorial/classes.rst
+++ b/Doc/tutorial/classes.rst
@@ -576,8 +576,8 @@ data from a string buffer instead, and pass it as an argument.
.. % \code{sys.stdin} will not cause the interpreter to read further input
.. % from it.)
-Instance method objects have attributes, too: ``m.im_self`` is the instance
-object with the method :meth:`m`, and ``m.im_func`` is the function object
+Instance method objects have attributes, too: ``m.__self__`` is the instance
+object with the method :meth:`m`, and ``m.__func__`` is the function object
corresponding to the method.
diff --git a/Include/classobject.h b/Include/classobject.h
index 885c43e4cfd..e6ca421a5be 100644
--- a/Include/classobject.h
+++ b/Include/classobject.h
@@ -1,4 +1,4 @@
-/* Former class object interface -- now only (un)bound methods are here */
+/* Former class object interface -- now only bound methods are here */
/* Revealing some structures (not for general use) */
@@ -11,8 +11,7 @@ extern "C" {
typedef struct {
PyObject_HEAD
PyObject *im_func; /* The callable object implementing the method */
- PyObject *im_self; /* The instance it is bound to, or NULL */
- PyObject *im_class; /* The class that asked for the method */
+ PyObject *im_self; /* The instance it is bound to */
PyObject *im_weakreflist; /* List of weak references */
} PyMethodObject;
@@ -20,7 +19,7 @@ PyAPI_DATA(PyTypeObject) PyMethod_Type;
#define PyMethod_Check(op) ((op)->ob_type == &PyMethod_Type)
-PyAPI_FUNC(PyObject *) PyMethod_New(PyObject *, PyObject *, PyObject *);
+PyAPI_FUNC(PyObject *) PyMethod_New(PyObject *, PyObject *);
PyAPI_FUNC(PyObject *) PyMethod_Function(PyObject *);
PyAPI_FUNC(PyObject *) PyMethod_Self(PyObject *);
@@ -32,8 +31,6 @@ PyAPI_FUNC(PyObject *) PyMethod_Class(PyObject *);
(((PyMethodObject *)meth) -> im_func)
#define PyMethod_GET_SELF(meth) \
(((PyMethodObject *)meth) -> im_self)
-#define PyMethod_GET_CLASS(meth) \
- (((PyMethodObject *)meth) -> im_class)
#ifdef __cplusplus
}
diff --git a/Lib/ctypes/test/test_callbacks.py b/Lib/ctypes/test/test_callbacks.py
index d870eb424c4..bf580ae8bd8 100644
--- a/Lib/ctypes/test/test_callbacks.py
+++ b/Lib/ctypes/test/test_callbacks.py
@@ -14,7 +14,7 @@ def callback(self, *args):
return args[-1]
def check_type(self, typ, arg):
- PROTO = self.functype.im_func(typ, typ)
+ PROTO = self.functype.__func__(typ, typ)
result = PROTO(self.callback)(arg)
if typ == c_float:
self.failUnlessAlmostEqual(result, arg, places=5)
@@ -22,7 +22,7 @@ def check_type(self, typ, arg):
self.failUnlessEqual(self.got_args, (arg,))
self.failUnlessEqual(result, arg)
- PROTO = self.functype.im_func(typ, c_byte, typ)
+ PROTO = self.functype.__func__(typ, c_byte, typ)
result = PROTO(self.callback)(-3, arg)
if typ == c_float:
self.failUnlessAlmostEqual(result, arg, places=5)
@@ -110,12 +110,12 @@ def test_unsupported_restype_1(self):
# functions, the type must have a non-NULL stgdict->setfunc.
# POINTER(c_double), for example, is not supported.
- prototype = self.functype.im_func(POINTER(c_double))
+ prototype = self.functype.__func__(POINTER(c_double))
# The type is checked when the prototype is called
self.assertRaises(TypeError, prototype, lambda: None)
def test_unsupported_restype_2(self):
- prototype = self.functype.im_func(object)
+ prototype = self.functype.__func__(object)
self.assertRaises(TypeError, prototype, lambda: None)
try:
diff --git a/Lib/dis.py b/Lib/dis.py
index 4cf452a097a..6d52694a75d 100644
--- a/Lib/dis.py
+++ b/Lib/dis.py
@@ -18,8 +18,8 @@ def dis(x=None):
if x is None:
distb()
return
- if hasattr(x, 'im_func'):
- x = x.im_func
+ if hasattr(x, '__func__'):
+ x = x.__func__
if hasattr(x, '__code__'):
x = x.__code__
if hasattr(x, '__dict__'):
diff --git a/Lib/doctest.py b/Lib/doctest.py
index 5b1807301af..f1350272480 100644
--- a/Lib/doctest.py
+++ b/Lib/doctest.py
@@ -913,7 +913,7 @@ def _find(self, tests, obj, name, module, source_lines, globs, seen):
if isinstance(val, staticmethod):
val = getattr(obj, valname)
if isinstance(val, classmethod):
- val = getattr(obj, valname).im_func
+ val = getattr(obj, valname).__func__
# Recurse to methods, properties, and nested classes.
if ((inspect.isfunction(val) or inspect.isclass(val) or
@@ -985,7 +985,7 @@ def _find_lineno(self, obj, source_lines):
break
# Find the line number for functions & methods.
- if inspect.ismethod(obj): obj = obj.im_func
+ if inspect.ismethod(obj): obj = obj.__func__
if inspect.isfunction(obj): obj = obj.__code__
if inspect.istraceback(obj): obj = obj.tb_frame
if inspect.isframe(obj): obj = obj.f_code
diff --git a/Lib/idlelib/CallTips.py b/Lib/idlelib/CallTips.py
index aee7e612871..cda2be979d2 100644
--- a/Lib/idlelib/CallTips.py
+++ b/Lib/idlelib/CallTips.py
@@ -116,7 +116,7 @@ def get_entity(self, name):
def _find_constructor(class_ob):
"Find the nearest __init__() in the class tree."
try:
- return class_ob.__init__.im_func
+ return class_ob.__init__.__func__
except AttributeError:
for base in class_ob.__bases__:
init = _find_constructor(base)
@@ -133,7 +133,7 @@ def get_argspec(ob):
if fob is None:
fob = lambda: None
elif isinstance(ob, types.MethodType):
- fob = ob.im_func
+ fob = ob.__func__
else:
fob = ob
if isinstance(fob, (types.FunctionType, types.LambdaType)):
@@ -183,7 +183,7 @@ def test(tests):
name = t.__name__
# exercise fetch_tip(), not just get_argspec()
try:
- qualified_name = "%s.%s" % (t.im_class.__name__, name)
+ qualified_name = "%s.%s" % (t.__self__.__class__.__name__, name)
except AttributeError:
qualified_name = name
argspec = ct.fetch_tip(qualified_name)
diff --git a/Lib/inspect.py b/Lib/inspect.py
index 3a95796792f..a1910e4ff96 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -55,9 +55,8 @@ def ismethod(object):
Instance method objects provide these attributes:
__doc__ documentation string
__name__ name with which this method was defined
- im_class class object in which this method belongs
- im_func function object containing implementation of method
- im_self instance to which this method is bound"""
+ __func__ function object containing implementation of method
+ __self__ instance to which this method is bound"""
return isinstance(object, types.MethodType)
def ismethoddescriptor(object):
@@ -73,7 +72,7 @@ def ismethoddescriptor(object):
Methods implemented via descriptors that also pass one of the other
tests return false from the ismethoddescriptor() test, simply because
the other tests promise more -- you can, e.g., count on having the
- im_func attribute (etc) when an object passes ismethod()."""
+ __func__ attribute (etc) when an object passes ismethod()."""
return (hasattr(object, "__get__")
and not hasattr(object, "__set__") # else it's a data descriptor
and not ismethod(object) # mutual exclusion
@@ -351,7 +350,7 @@ def getfile(object):
return object.__file__
raise TypeError('arg is a built-in class')
if ismethod(object):
- object = object.im_func
+ object = object.__func__
if isfunction(object):
object = object.__code__
if istraceback(object):
@@ -494,7 +493,7 @@ def findsource(object):
raise IOError('could not find class definition')
if ismethod(object):
- object = object.im_func
+ object = object.__func__
if isfunction(object):
object = object.__code__
if istraceback(object):
@@ -744,7 +743,7 @@ def getfullargspec(func):
"""
if ismethod(func):
- func = func.im_func
+ func = func.__func__
if not isfunction(func):
raise TypeError('arg is not a Python function')
args, varargs, kwonlyargs, varkw = _getfullargs(func.__code__)
diff --git a/Lib/lib-tk/Tkinter.py b/Lib/lib-tk/Tkinter.py
index f40a55328e3..aecb317efae 100644
--- a/Lib/lib-tk/Tkinter.py
+++ b/Lib/lib-tk/Tkinter.py
@@ -1081,7 +1081,7 @@ def _register(self, func, subst=None, needcleanup=1):
f = CallWrapper(func, subst, self).__call__
name = repr(id(f))
try:
- func = func.im_func
+ func = func.__func__
except AttributeError:
pass
try:
diff --git a/Lib/pdb.py b/Lib/pdb.py
index 3d79b4da1c4..f5bdb205c8e 100755
--- a/Lib/pdb.py
+++ b/Lib/pdb.py
@@ -345,8 +345,8 @@ def do_break(self, arg, temporary = 0):
except:
func = arg
try:
- if hasattr(func, 'im_func'):
- func = func.im_func
+ if hasattr(func, '__func__'):
+ func = func.__func__
code = func.__code__
#use co_name to identify the bkpt (function names
#could be aliased, but co_name is invariant)
@@ -789,7 +789,7 @@ def do_whatis(self, arg):
print('Function', code.co_name, file=self.stdout)
return
# Is it an instance method?
- try: code = value.im_func.__code__
+ try: code = value.__func__.__code__
except: pass
if code:
print('Method', code.co_name, file=self.stdout)
diff --git a/Lib/pydoc.py b/Lib/pydoc.py
index 3cffa065cfb..51d627ea4dd 100755
--- a/Lib/pydoc.py
+++ b/Lib/pydoc.py
@@ -848,17 +848,17 @@ def docroutine(self, object, name=None, mod=None,
note = ''
skipdocs = 0
if inspect.ismethod(object):
- imclass = object.im_class
+ imclass = object.__self__.__class__
if cl:
if imclass is not cl:
note = ' from ' + self.classlink(imclass, mod)
else:
- if object.im_self is not None:
+ if object.__self__ is not None:
note = ' method of %s instance' % self.classlink(
- object.im_self.__class__, mod)
+ object.__self__.__class__, mod)
else:
note = ' unbound %s method' % self.classlink(imclass,mod)
- object = object.im_func
+ object = object.__func__
if name == realname:
title = '%s' % (anchor, realname)
@@ -1227,17 +1227,17 @@ def docroutine(self, object, name=None, mod=None, cl=None):
note = ''
skipdocs = 0
if inspect.ismethod(object):
- imclass = object.im_class
+ imclass = object.__self__.__class__
if cl:
if imclass is not cl:
note = ' from ' + classname(imclass, mod)
else:
- if object.im_self is not None:
+ if object.__self__ is not None:
note = ' method of %s instance' % classname(
- object.im_self.__class__, mod)
+ object.__self__.__class__, mod)
else:
note = ' unbound %s method' % classname(imclass,mod)
- object = object.im_func
+ object = object.__func__
if name == realname:
title = self.bold(realname)
diff --git a/Lib/test/crashers/borrowed_ref_2.py b/Lib/test/crashers/borrowed_ref_2.py
index f3ca35016da..6e403eb344c 100644
--- a/Lib/test/crashers/borrowed_ref_2.py
+++ b/Lib/test/crashers/borrowed_ref_2.py
@@ -33,6 +33,6 @@ def g():
i = 0
del a
while 1:
- c.d = 42 # segfaults in PyMethod_New(im_func=D.__set__, im_self=d)
+ c.d = 42 # segfaults in PyMethod_New(__func__=D.__set__, __self__=d)
lst[i] = c.g # consume the free list of instancemethod objects
i += 1
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index e093ce8edfb..a518f162408 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -280,12 +280,12 @@ def Cmethod(self): pass
c = C()
vereq(interesting(dir(c)), cstuff)
- #verify('im_self' in dir(C.Cmethod))
+ #verify('__self__' in dir(C.Cmethod))
c.cdata = 2
c.cmethod = lambda self: 0
vereq(interesting(dir(c)), cstuff + ['cdata', 'cmethod'])
- #verify('im_self' in dir(c.Cmethod))
+ #verify('__self__' in dir(c.Cmethod))
class A(C):
Adata = 1
@@ -293,13 +293,13 @@ def Amethod(self): pass
astuff = ['Adata', 'Amethod'] + cstuff
vereq(interesting(dir(A)), astuff)
- #verify('im_self' in dir(A.Amethod))
+ #verify('__self__' in dir(A.Amethod))
a = A()
vereq(interesting(dir(a)), astuff)
a.adata = 42
a.amethod = lambda self: 3
vereq(interesting(dir(a)), astuff + ['adata', 'amethod'])
- #verify('im_self' in dir(a.Amethod))
+ #verify('__self__' in dir(a.Amethod))
# Try a module subclass.
import sys
@@ -1418,10 +1418,10 @@ def f(cls, arg): return (cls, arg)
vereq(ff.__get__(0)(42), (int, 42))
# Test super() with classmethods (SF bug 535444)
- veris(C.goo.im_self, C)
- veris(D.goo.im_self, D)
- veris(super(D,D).goo.im_self, D)
- veris(super(D,d).goo.im_self, D)
+ veris(C.goo.__self__, C)
+ veris(D.goo.__self__, D)
+ veris(super(D,D).goo.__self__, D)
+ veris(super(D,d).goo.__self__, D)
vereq(super(D,D).goo(), (D,))
vereq(super(D,d).goo(), (D,))
@@ -1507,7 +1507,7 @@ class E: # *not* subclassing from C
r = repr(E().foo)
verify(r.startswith("im_self;
}
-PyObject *
-PyMethod_Class(PyObject *im)
-{
- if (!PyMethod_Check(im)) {
- PyErr_BadInternalCall();
- return NULL;
- }
- return ((PyMethodObject *)im)->im_class;
-}
-
-
-/* Method objects are used for two purposes:
- (a) as bound instance methods (returned by instancename.methodname)
- (b) as unbound methods (returned by ClassName.methodname)
- In case (b), im_self is NULL
+/* Method objects are used for bound instance methods returned by
+ instancename.methodname. ClassName.methodname returns an ordinary
+ function.
*/
static PyMethodObject *free_list;
PyObject *
-PyMethod_New(PyObject *func, PyObject *self, PyObject *klass)
+PyMethod_New(PyObject *func, PyObject *self)
{
register PyMethodObject *im;
if (!PyCallable_Check(func)) {
PyErr_BadInternalCall();
return NULL;
}
+ if (self == NULL) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
im = free_list;
if (im != NULL) {
free_list = (PyMethodObject *)(im->im_self);
@@ -68,25 +60,21 @@ PyMethod_New(PyObject *func, PyObject *self, PyObject *klass)
im->im_func = func;
Py_XINCREF(self);
im->im_self = self;
- Py_XINCREF(klass);
- im->im_class = klass;
_PyObject_GC_TRACK(im);
return (PyObject *)im;
}
/* Descriptors for PyMethod attributes */
-/* im_class, im_func and im_self are stored in the PyMethod object */
+/* im_func and im_self are stored in the PyMethod object */
#define OFF(x) offsetof(PyMethodObject, x)
static PyMemberDef method_memberlist[] = {
- {"im_class", T_OBJECT, OFF(im_class), READONLY|RESTRICTED,
- "the class associated with a method"},
- {"im_func", T_OBJECT, OFF(im_func), READONLY|RESTRICTED,
+ {"__func__", T_OBJECT, OFF(im_func), READONLY|RESTRICTED,
"the function (or other callable) implementing a method"},
- {"im_self", T_OBJECT, OFF(im_self), READONLY|RESTRICTED,
- "the instance to which a method is bound; None for unbound methods"},
+ {"__self__", T_OBJECT, OFF(im_self), READONLY|RESTRICTED,
+ "the instance to which a method is bound"},
{NULL} /* Sentinel */
};
@@ -141,7 +129,7 @@ method_getattro(PyObject *obj, PyObject *name)
}
PyDoc_STRVAR(method_doc,
-"method(function, instance, class)\n\
+"method(function, instance)\n\
\n\
Create an instance method object.");
@@ -150,27 +138,24 @@ method_new(PyTypeObject* type, PyObject* args, PyObject *kw)
{
PyObject *func;
PyObject *self;
- PyObject *classObj = NULL;
if (!_PyArg_NoKeywords("instancemethod", kw))
return NULL;
if (!PyArg_UnpackTuple(args, "method", 2, 3,
- &func, &self, &classObj))
+ &func, &self))
return NULL;
if (!PyCallable_Check(func)) {
PyErr_SetString(PyExc_TypeError,
"first argument must be callable");
return NULL;
}
- if (self == Py_None)
- self = NULL;
- if (self == NULL && classObj == NULL) {
+ if (self == NULL || self == Py_None) {
PyErr_SetString(PyExc_TypeError,
- "unbound methods must have non-NULL im_class");
+ "self must not be None");
return NULL;
}
- return PyMethod_New(func, self, classObj);
+ return PyMethod_New(func, self);
}
static void
@@ -181,7 +166,6 @@ method_dealloc(register PyMethodObject *im)
PyObject_ClearWeakRefs((PyObject *)im);
Py_DECREF(im->im_func);
Py_XDECREF(im->im_self);
- Py_XDECREF(im->im_class);
im->im_self = (PyObject *)free_list;
free_list = im;
}
@@ -225,10 +209,15 @@ method_repr(PyMethodObject *a)
{
PyObject *self = a->im_self;
PyObject *func = a->im_func;
- PyObject *klass = a->im_class;
- PyObject *funcname = NULL, *klassname = NULL, *result = NULL;
+ PyObject *klass = (PyObject*)Py_Type(self);
+ PyObject *funcname = NULL ,*klassname = NULL, *result = NULL;
char *defname = "?";
+ if (self == NULL) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+
funcname = PyObject_GetAttrString(func, "__name__");
if (funcname == NULL) {
if (!PyErr_ExceptionMatches(PyExc_AttributeError))
@@ -239,6 +228,7 @@ method_repr(PyMethodObject *a)
Py_DECREF(funcname);
funcname = NULL;
}
+
if (klass == NULL)
klassname = NULL;
else {
@@ -253,16 +243,12 @@ method_repr(PyMethodObject *a)
klassname = NULL;
}
}
- if (self == NULL)
- result = PyUnicode_FromFormat("",
- klassname, defname,
- funcname, defname);
- else {
- /* XXX Shouldn't use repr()/%R here! */
- result = PyUnicode_FromFormat("",
- klassname, defname,
- funcname, defname, self);
- }
+
+ /* XXX Shouldn't use repr()/%R here! */
+ result = PyUnicode_FromFormat("",
+ klassname, defname,
+ funcname, defname, self);
+
Py_XDECREF(funcname);
Py_XDECREF(klassname);
return result;
@@ -292,92 +278,19 @@ method_traverse(PyMethodObject *im, visitproc visit, void *arg)
{
Py_VISIT(im->im_func);
Py_VISIT(im->im_self);
- Py_VISIT(im->im_class);
return 0;
}
-static void
-getclassname(PyObject *klass, char *buf, int bufsize)
-{
- PyObject *name;
-
- assert(bufsize > 1);
- strcpy(buf, "?"); /* Default outcome */
- if (klass == NULL)
- return;
- name = PyObject_GetAttrString(klass, "__name__");
- if (name == NULL) {
- /* This function cannot return an exception */
- PyErr_Clear();
- return;
- }
- if (PyUnicode_Check(name)) {
- strncpy(buf, PyUnicode_AsString(name), bufsize);
- buf[bufsize-1] = '\0';
- }
- Py_DECREF(name);
-}
-
-static void
-getinstclassname(PyObject *inst, char *buf, int bufsize)
-{
- PyObject *klass;
-
- if (inst == NULL) {
- assert(bufsize > 0 && (size_t)bufsize > strlen("nothing"));
- strcpy(buf, "nothing");
- return;
- }
-
- klass = PyObject_GetAttrString(inst, "__class__");
- if (klass == NULL) {
- /* This function cannot return an exception */
- PyErr_Clear();
- klass = (PyObject *)(inst->ob_type);
- Py_INCREF(klass);
- }
- getclassname(klass, buf, bufsize);
- Py_XDECREF(klass);
-}
-
static PyObject *
method_call(PyObject *func, PyObject *arg, PyObject *kw)
{
PyObject *self = PyMethod_GET_SELF(func);
- PyObject *klass = PyMethod_GET_CLASS(func);
PyObject *result;
func = PyMethod_GET_FUNCTION(func);
if (self == NULL) {
- /* Unbound methods must be called with an instance of
- the class (or a derived class) as first argument */
- int ok;
- if (PyTuple_Size(arg) >= 1)
- self = PyTuple_GET_ITEM(arg, 0);
- if (self == NULL)
- ok = 0;
- else {
- ok = PyObject_IsInstance(self, klass);
- if (ok < 0)
- return NULL;
- }
- if (!ok) {
- char clsbuf[256];
- char instbuf[256];
- getclassname(klass, clsbuf, sizeof(clsbuf));
- getinstclassname(self, instbuf, sizeof(instbuf));
- PyErr_Format(PyExc_TypeError,
- "unbound method %s%s must be called with "
- "%s instance as first argument "
- "(got %s%s instead)",
- PyEval_GetFuncName(func),
- PyEval_GetFuncDesc(func),
- clsbuf,
- instbuf,
- self == NULL ? "" : " instance");
- return NULL;
- }
- Py_INCREF(arg);
+ PyErr_BadInternalCall();
+ return NULL;
}
else {
Py_ssize_t argcount = PyTuple_Size(arg);
@@ -402,27 +315,15 @@ method_call(PyObject *func, PyObject *arg, PyObject *kw)
static PyObject *
method_descr_get(PyObject *meth, PyObject *obj, PyObject *cls)
{
- /* Don't rebind an already bound method, or an unbound method
- of a class that's not a base class of 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;
}
- /* No, it is an unbound method */
- if (PyMethod_GET_CLASS(meth) != NULL && cls != NULL) {
- /* Do subclass test. If it fails, return meth unchanged. */
- int ok = PyObject_IsSubclass(cls, PyMethod_GET_CLASS(meth));
- if (ok < 0)
- return NULL;
- if (!ok) {
- Py_INCREF(meth);
- return meth;
- }
- }
/* Bind it to obj */
- return PyMethod_New(PyMethod_GET_FUNCTION(meth), obj, cls);
+ return PyMethod_New(PyMethod_GET_FUNCTION(meth), obj);
}
PyTypeObject PyMethod_Type = {
diff --git a/Objects/funcobject.c b/Objects/funcobject.c
index f9b0346eaa4..ac68edce39c 100644
--- a/Objects/funcobject.c
+++ b/Objects/funcobject.c
@@ -647,7 +647,7 @@ func_descr_get(PyObject *func, PyObject *obj, PyObject *type)
Py_INCREF(func);
return func;
}
- return PyMethod_New(func, obj, type);
+ return PyMethod_New(func, obj);
}
PyTypeObject PyFunction_Type = {
@@ -751,8 +751,7 @@ cm_descr_get(PyObject *self, PyObject *obj, PyObject *type)
}
if (type == NULL)
type = (PyObject *)(Py_Type(obj));
- return PyMethod_New(cm->cm_callable,
- type, (PyObject *)(Py_Type(type)));
+ return PyMethod_New(cm->cm_callable, type);
}
static int