Skip to content

Commit ff73795

Browse files
committed
Removed the API to create unbound methods and simplified the API for bound methods. The signature is PyMethod_New(func, instance).
Also removed im_class and renamed im_self to __self__ and im_func to __func__. im_class can be substituted with method.__self__.__class__. I've also updated some parts of the documenation.
1 parent 0d3fb8a commit ff73795

23 files changed

+152
-268
lines changed

Doc/library/inspect.rst

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,11 @@ attributes:
4949
| | __name__ | name with which this |
5050
| | | method was defined |
5151
+-----------+-----------------+---------------------------+
52-
| | im_class | class object that asked |
53-
| | | for this method |
54-
+-----------+-----------------+---------------------------+
55-
| | im_func | function object |
52+
| | __func__ | function object |
5653
| | | containing implementation |
5754
| | | of method |
5855
+-----------+-----------------+---------------------------+
59-
| | im_self | instance to which this |
56+
| | __self__ | instance to which this |
6057
| | | method is bound, or |
6158
| | | ``None`` |
6259
+-----------+-----------------+---------------------------+
@@ -264,7 +261,7 @@ attributes:
264261
Methods implemented via descriptors that also pass one of the other tests
265262
return false from the :func:`ismethoddescriptor` test, simply because the
266263
other tests promise more -- you can, e.g., count on having the
267-
:attr:`im_func` attribute (etc) when an object passes :func:`ismethod`.
264+
:attr:`__func__` attribute (etc) when an object passes :func:`ismethod`.
268265

269266

270267
.. function:: isdatadescriptor(object)

Doc/library/new.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ non-sensical arguments which crash the interpreter when the object is used.
1717
The :mod:`new` module defines the following functions:
1818

1919

20-
.. function:: instancemethod(function, instance, class)
20+
.. function:: instancemethod(function, instance)
2121

22-
This function will return a method object, bound to *instance*, or unbound if
23-
*instance* is ``None``. *function* must be callable.
22+
This function will return a method object, bound to *instance*.
23+
*function* must be callable.
2424

2525

2626
.. function:: function(code, globals[, name[, argdefs[, closure]]])

Doc/library/stdtypes.rst

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2216,21 +2216,21 @@ instance methods. Built-in methods are described with the types that support
22162216
them.
22172217

22182218
The implementation adds two special read-only attributes to class instance
2219-
methods: ``m.im_self`` is the object on which the method operates, and
2220-
``m.im_func`` is the function implementing the method. Calling ``m(arg-1,
2221-
arg-2, ..., arg-n)`` is completely equivalent to calling ``m.im_func(m.im_self,
2222-
arg-1, arg-2, ..., arg-n)``.
2219+
methods: ``m.__self__`` is the object on which the method operates, and
2220+
``m.__func__`` is the function implementing the method. Calling ``m(arg-1,
2221+
arg-2, ..., arg-n)`` is completely equivalent to calling ``m.__func__(
2222+
m.__self__, arg-1, arg-2, ..., arg-n)``.
22232223

22242224
Class instance methods are either *bound* or *unbound*, referring to whether the
22252225
method was accessed through an instance or a class, respectively. When a method
2226-
is unbound, its ``im_self`` attribute will be ``None`` and if called, an
2226+
is unbound, its ``__self__`` attribute will be ``None`` and if called, an
22272227
explicit ``self`` object must be passed as the first argument. In this case,
22282228
``self`` must be an instance of the unbound method's class (or a subclass of
22292229
that class), otherwise a :exc:`TypeError` is raised.
22302230

22312231
Like function objects, methods objects support getting arbitrary attributes.
22322232
However, since method attributes are actually stored on the underlying function
2233-
object (``meth.im_func``), setting method attributes on either bound or unbound
2233+
object (``meth.__func__``), setting method attributes on either bound or unbound
22342234
methods is disallowed. Attempting to set a method attribute results in a
22352235
:exc:`TypeError` being raised. In order to set a method attribute, you need to
22362236
explicitly set it on the underlying function object::
@@ -2240,7 +2240,7 @@ explicitly set it on the underlying function object::
22402240
pass
22412241

22422242
c = C()
2243-
c.method.im_func.whoami = 'my name is c'
2243+
c.method.__func__.whoami = 'my name is c'
22442244

22452245
See :ref:`types` for more information.
22462246

Doc/reference/datamodel.rst

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -538,20 +538,18 @@ Callable types
538538
A user-defined method object combines a class, a class instance (or ``None``)
539539
and any callable object (normally a user-defined function).
540540

541-
Special read-only attributes: :attr:`im_self` is the class instance object,
542-
:attr:`im_func` is the function object; :attr:`im_class` is the class of
543-
:attr:`im_self` for bound methods or the class that asked for the method for
544-
unbound methods; :attr:`__doc__` is the method's documentation (same as
545-
``im_func.__doc__``); :attr:`__name__` is the method name (same as
546-
``im_func.__name__``); :attr:`__module__` is the name of the module the method
547-
was defined in, or ``None`` if unavailable.
541+
Special read-only attributes: :attr:`__self__` is the class instance object,
542+
:attr:`__func__` is the function object; :attr:`__doc__` is the method's
543+
documentation (same as ``__func__.__doc__``); :attr:`__name__` is the
544+
method name (same as ``__func__.__name__``); :attr:`__module__` is the
545+
name of the module the method was defined in, or ``None`` if unavailable.
548546

549547
.. index::
550548
single: __doc__ (method attribute)
551549
single: __name__ (method attribute)
552550
single: __module__ (method attribute)
553-
single: im_func (method attribute)
554-
single: im_self (method attribute)
551+
single: __func__ (method attribute)
552+
single: __self__ (method attribute)
555553

556554
Methods also support accessing (but not setting) the arbitrary function
557555
attributes on the underlying function object.
@@ -565,49 +563,46 @@ Callable types
565563
the original method object is used as it is.
566564

567565
.. index::
568-
single: im_class (method attribute)
569-
single: im_func (method attribute)
570-
single: im_self (method attribute)
566+
single: __func__ (method attribute)
567+
single: __self__ (method attribute)
571568

572569
When a user-defined method object is created by retrieving a user-defined
573-
function object from a class, its :attr:`im_self` attribute is ``None``
570+
function object from a class, its :attr:`__self__` attribute is ``None``
574571
and the method object is said to be unbound. When one is created by
575572
retrieving a user-defined function object from a class via one of its
576-
instances, its :attr:`im_self` attribute is the instance, and the method
577-
object is said to be bound. In either case, the new method's
578-
:attr:`im_class` attribute is the class from which the retrieval takes
579-
place, and its :attr:`im_func` attribute is the original function object.
573+
instances, its :attr:`__self__` attribute is the instance, and the method
574+
object is said to be bound. Its :attr:`__func__` attribute is the
575+
original function object.
580576

581-
.. index:: single: im_func (method attribute)
577+
.. index:: single: __func__ (method attribute)
582578

583579
When a user-defined method object is created by retrieving another method object
584580
from a class or instance, the behaviour is the same as for a function object,
585-
except that the :attr:`im_func` attribute of the new instance is not the
586-
original method object but its :attr:`im_func` attribute.
581+
except that the :attr:`__func__` attribute of the new instance is not the
582+
original method object but its :attr:`__func__` attribute.
587583

588584
.. index::
589-
single: im_class (method attribute)
590-
single: im_func (method attribute)
591-
single: im_self (method attribute)
585+
single: __func__ (method attribute)
586+
single: __self__ (method attribute)
592587

593588
When a user-defined method object is created by retrieving a class method object
594-
from a class or instance, its :attr:`im_self` attribute is the class itself (the
595-
same as the :attr:`im_class` attribute), and its :attr:`im_func` attribute is
589+
from a class or instance, its :attr:`__self__` attribute is the class itself (the
590+
same as the :attr:`im_class` attribute), and its :attr:`__func__` attribute is
596591
the function object underlying the class method.
597592

598593
When an unbound user-defined method object is called, the underlying function
599-
(:attr:`im_func`) is called, with the restriction that the first argument must
594+
(:attr:`__func__`) is called, with the restriction that the first argument must
600595
be an instance of the proper class (:attr:`im_class`) or of a derived class
601596
thereof.
602597

603598
When a bound user-defined method object is called, the underlying function
604-
(:attr:`im_func`) is called, inserting the class instance (:attr:`im_self`) in
599+
(:attr:`__func__`) is called, inserting the class instance (:attr:`__self__`) in
605600
front of the argument list. For instance, when :class:`C` is a class which
606601
contains a definition for a function :meth:`f`, and ``x`` is an instance of
607602
:class:`C`, calling ``x.f(1)`` is equivalent to calling ``C.f(x, 1)``.
608603

609604
When a user-defined method object is derived from a class method object, the
610-
"class instance" stored in :attr:`im_self` will actually be the class itself, so
605+
"class instance" stored in :attr:`__self__` will actually be the class itself, so
611606
that calling either ``x.f(1)`` or ``C.f(1)`` is equivalent to calling ``f(C,1)``
612607
where ``f`` is the underlying function.
613608

@@ -741,7 +736,7 @@ Custom classes
741736
transformed into an unbound user-defined method object whose :attr:`im_class`
742737
attribute is :class:`C`. When it would yield a class method object, it is
743738
transformed into a bound user-defined method object whose :attr:`im_class`
744-
and :attr:`im_self` attributes are both :class:`C`. When it would yield a
739+
and :attr:`__self__` attributes are both :class:`C`. When it would yield a
745740
static method object, it is transformed into the object wrapped by the static
746741
method object. See section :ref:`descriptors` for another way in which
747742
attributes retrieved from a class may differ from those actually contained in
@@ -786,7 +781,7 @@ Class instances
786781
is the class (call it :class:`C`) of the instance for which the attribute
787782
reference was initiated or one of its bases, it is transformed into a bound
788783
user-defined method object whose :attr:`im_class` attribute is :class:`C` and
789-
whose :attr:`im_self` attribute is the instance. Static method and class method
784+
whose :attr:`__self__` attribute is the instance. Static method and class method
790785
objects are also transformed, as if they had been retrieved from class
791786
:class:`C`; see above under "Classes". See section :ref:`descriptors` for
792787
another way in which attributes of a class retrieved via its instances may

Doc/tutorial/classes.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -576,8 +576,8 @@ data from a string buffer instead, and pass it as an argument.
576576
.. % \code{sys.stdin} will not cause the interpreter to read further input
577577
.. % from it.)
578578
579-
Instance method objects have attributes, too: ``m.im_self`` is the instance
580-
object with the method :meth:`m`, and ``m.im_func`` is the function object
579+
Instance method objects have attributes, too: ``m.__self__`` is the instance
580+
object with the method :meth:`m`, and ``m.__func__`` is the function object
581581
corresponding to the method.
582582

583583

Include/classobject.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Former class object interface -- now only (un)bound methods are here */
1+
/* Former class object interface -- now only bound methods are here */
22

33
/* Revealing some structures (not for general use) */
44

@@ -11,16 +11,15 @@ extern "C" {
1111
typedef struct {
1212
PyObject_HEAD
1313
PyObject *im_func; /* The callable object implementing the method */
14-
PyObject *im_self; /* The instance it is bound to, or NULL */
15-
PyObject *im_class; /* The class that asked for the method */
14+
PyObject *im_self; /* The instance it is bound to */
1615
PyObject *im_weakreflist; /* List of weak references */
1716
} PyMethodObject;
1817

1918
PyAPI_DATA(PyTypeObject) PyMethod_Type;
2019

2120
#define PyMethod_Check(op) ((op)->ob_type == &PyMethod_Type)
2221

23-
PyAPI_FUNC(PyObject *) PyMethod_New(PyObject *, PyObject *, PyObject *);
22+
PyAPI_FUNC(PyObject *) PyMethod_New(PyObject *, PyObject *);
2423

2524
PyAPI_FUNC(PyObject *) PyMethod_Function(PyObject *);
2625
PyAPI_FUNC(PyObject *) PyMethod_Self(PyObject *);
@@ -32,8 +31,6 @@ PyAPI_FUNC(PyObject *) PyMethod_Class(PyObject *);
3231
(((PyMethodObject *)meth) -> im_func)
3332
#define PyMethod_GET_SELF(meth) \
3433
(((PyMethodObject *)meth) -> im_self)
35-
#define PyMethod_GET_CLASS(meth) \
36-
(((PyMethodObject *)meth) -> im_class)
3734

3835
#ifdef __cplusplus
3936
}

Lib/ctypes/test/test_callbacks.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@ def callback(self, *args):
1414
return args[-1]
1515

1616
def check_type(self, typ, arg):
17-
PROTO = self.functype.im_func(typ, typ)
17+
PROTO = self.functype.__func__(typ, typ)
1818
result = PROTO(self.callback)(arg)
1919
if typ == c_float:
2020
self.failUnlessAlmostEqual(result, arg, places=5)
2121
else:
2222
self.failUnlessEqual(self.got_args, (arg,))
2323
self.failUnlessEqual(result, arg)
2424

25-
PROTO = self.functype.im_func(typ, c_byte, typ)
25+
PROTO = self.functype.__func__(typ, c_byte, typ)
2626
result = PROTO(self.callback)(-3, arg)
2727
if typ == c_float:
2828
self.failUnlessAlmostEqual(result, arg, places=5)
@@ -110,12 +110,12 @@ def test_unsupported_restype_1(self):
110110
# functions, the type must have a non-NULL stgdict->setfunc.
111111
# POINTER(c_double), for example, is not supported.
112112

113-
prototype = self.functype.im_func(POINTER(c_double))
113+
prototype = self.functype.__func__(POINTER(c_double))
114114
# The type is checked when the prototype is called
115115
self.assertRaises(TypeError, prototype, lambda: None)
116116

117117
def test_unsupported_restype_2(self):
118-
prototype = self.functype.im_func(object)
118+
prototype = self.functype.__func__(object)
119119
self.assertRaises(TypeError, prototype, lambda: None)
120120

121121
try:

Lib/dis.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ def dis(x=None):
1818
if x is None:
1919
distb()
2020
return
21-
if hasattr(x, 'im_func'):
22-
x = x.im_func
21+
if hasattr(x, '__func__'):
22+
x = x.__func__
2323
if hasattr(x, '__code__'):
2424
x = x.__code__
2525
if hasattr(x, '__dict__'):

Lib/doctest.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -913,7 +913,7 @@ def _find(self, tests, obj, name, module, source_lines, globs, seen):
913913
if isinstance(val, staticmethod):
914914
val = getattr(obj, valname)
915915
if isinstance(val, classmethod):
916-
val = getattr(obj, valname).im_func
916+
val = getattr(obj, valname).__func__
917917

918918
# Recurse to methods, properties, and nested classes.
919919
if ((inspect.isfunction(val) or inspect.isclass(val) or
@@ -985,7 +985,7 @@ def _find_lineno(self, obj, source_lines):
985985
break
986986

987987
# Find the line number for functions & methods.
988-
if inspect.ismethod(obj): obj = obj.im_func
988+
if inspect.ismethod(obj): obj = obj.__func__
989989
if inspect.isfunction(obj): obj = obj.__code__
990990
if inspect.istraceback(obj): obj = obj.tb_frame
991991
if inspect.isframe(obj): obj = obj.f_code

Lib/idlelib/CallTips.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ def get_entity(self, name):
116116
def _find_constructor(class_ob):
117117
"Find the nearest __init__() in the class tree."
118118
try:
119-
return class_ob.__init__.im_func
119+
return class_ob.__init__.__func__
120120
except AttributeError:
121121
for base in class_ob.__bases__:
122122
init = _find_constructor(base)
@@ -133,7 +133,7 @@ def get_argspec(ob):
133133
if fob is None:
134134
fob = lambda: None
135135
elif isinstance(ob, types.MethodType):
136-
fob = ob.im_func
136+
fob = ob.__func__
137137
else:
138138
fob = ob
139139
if isinstance(fob, (types.FunctionType, types.LambdaType)):
@@ -183,7 +183,7 @@ def test(tests):
183183
name = t.__name__
184184
# exercise fetch_tip(), not just get_argspec()
185185
try:
186-
qualified_name = "%s.%s" % (t.im_class.__name__, name)
186+
qualified_name = "%s.%s" % (t.__self__.__class__.__name__, name)
187187
except AttributeError:
188188
qualified_name = name
189189
argspec = ct.fetch_tip(qualified_name)

Lib/inspect.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,8 @@ def ismethod(object):
5555
Instance method objects provide these attributes:
5656
__doc__ documentation string
5757
__name__ name with which this method was defined
58-
im_class class object in which this method belongs
59-
im_func function object containing implementation of method
60-
im_self instance to which this method is bound"""
58+
__func__ function object containing implementation of method
59+
__self__ instance to which this method is bound"""
6160
return isinstance(object, types.MethodType)
6261

6362
def ismethoddescriptor(object):
@@ -73,7 +72,7 @@ def ismethoddescriptor(object):
7372
Methods implemented via descriptors that also pass one of the other
7473
tests return false from the ismethoddescriptor() test, simply because
7574
the other tests promise more -- you can, e.g., count on having the
76-
im_func attribute (etc) when an object passes ismethod()."""
75+
__func__ attribute (etc) when an object passes ismethod()."""
7776
return (hasattr(object, "__get__")
7877
and not hasattr(object, "__set__") # else it's a data descriptor
7978
and not ismethod(object) # mutual exclusion
@@ -351,7 +350,7 @@ def getfile(object):
351350
return object.__file__
352351
raise TypeError('arg is a built-in class')
353352
if ismethod(object):
354-
object = object.im_func
353+
object = object.__func__
355354
if isfunction(object):
356355
object = object.__code__
357356
if istraceback(object):
@@ -494,7 +493,7 @@ def findsource(object):
494493
raise IOError('could not find class definition')
495494

496495
if ismethod(object):
497-
object = object.im_func
496+
object = object.__func__
498497
if isfunction(object):
499498
object = object.__code__
500499
if istraceback(object):
@@ -744,7 +743,7 @@ def getfullargspec(func):
744743
"""
745744

746745
if ismethod(func):
747-
func = func.im_func
746+
func = func.__func__
748747
if not isfunction(func):
749748
raise TypeError('arg is not a Python function')
750749
args, varargs, kwonlyargs, varkw = _getfullargs(func.__code__)

Lib/lib-tk/Tkinter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1081,7 +1081,7 @@ def _register(self, func, subst=None, needcleanup=1):
10811081
f = CallWrapper(func, subst, self).__call__
10821082
name = repr(id(f))
10831083
try:
1084-
func = func.im_func
1084+
func = func.__func__
10851085
except AttributeError:
10861086
pass
10871087
try:

Lib/pdb.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -345,8 +345,8 @@ def do_break(self, arg, temporary = 0):
345345
except:
346346
func = arg
347347
try:
348-
if hasattr(func, 'im_func'):
349-
func = func.im_func
348+
if hasattr(func, '__func__'):
349+
func = func.__func__
350350
code = func.__code__
351351
#use co_name to identify the bkpt (function names
352352
#could be aliased, but co_name is invariant)
@@ -789,7 +789,7 @@ def do_whatis(self, arg):
789789
print('Function', code.co_name, file=self.stdout)
790790
return
791791
# Is it an instance method?
792-
try: code = value.im_func.__code__
792+
try: code = value.__func__.__code__
793793
except: pass
794794
if code:
795795
print('Method', code.co_name, file=self.stdout)

0 commit comments

Comments
 (0)