Title: Hint about correct ismethod and isfunction usage
Type: enhancement Stage: resolved
Components: Documentation Versions: Python 3.2, Python 3.3, Python 3.4, Python 2.7
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: ezio.melotti Nosy List: Anna Koroliuk, Jelle Zijlstra, chris.jerdonek, docs@python, eric.araujo, ezio.melotti, federico.reghenzani, gregcouch, pitrou, python-dev, takluyver, vstinner, wdanilo
Priority: normal Keywords: easy, patch

Created on 2013-01-03 16:41 by wdanilo, last changed 2016-06-04 22:36 by berker.peksag. This issue is now closed.

File name Uploaded Description Edit
inspect.patch federico.reghenzani, 2013-01-08 10:06 review
inspect2.patch Anna Koroliuk, 2016-03-11 10:25 Patch for 2.7.
Messages (10)
msg178964 - (view) Author: Wojciech Danilo (wdanilo) Date: 2013-01-03 16:41
Hi! I think this behaviour is bug. Lets concider the following code:

import inspect
class X(object):
    def a(self):pass
    def b(self):pass
    def c(self):pass

print(inspect.getmembers(X, predicate=inspect.ismethod))
print(inspect.getmembers(X, predicate=inspect.isfunction))

In python 2.7, the results are:
[('a', <unbound method X.a>), ('b', <unbound method X.b>), ('c', <unbound method X.c>)]

and in Python 3.2:
[('a', <function a at 0x1b0fd10>), ('b', <function b at 0x1b0fe20>), ('c', <function c at 0x1b160d8>)]

I think, the results from python 2.7 are correct.
msg178966 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2013-01-03 16:56
I think that's expected and by design.  In Python 3 there are no unbound methods, but simply functions:
>>> class X:
...   def add(a, b): return a+b
>>> add = X.add
>>> add
<function add at 0xb740d26c>
>>> add(3, 4)
>>> def add(a, b): return a+b
>>> add
<function add at 0xb740d22c>
>>> add(3, 4)

As you can see there's no real difference between the two "add".

It's different though with bound methods (obtained from an instance rather than a class):

>>> add = X().add
>>> add
<bound method X.add of <__main__.X object at 0xb740e0ec>>

The documentation is also clear that ismethod() "Return true if the object is a bound method written in Python.".  Maybe an additional note can be added to state that "unbound methods" are not included, and that are instead recognized by isfunction().
msg181937 - (view) Author: Greg Couch (gregcouch) Date: 2013-02-12 00:07
In my opinion, the Python 2.7 results are wrong.

In Python 2.7, inspect.ismethod returns True for both bound and unbound methods -- ie., is broken according to the documentation.  As a workaround, I'm using:

def is_bound_method(obj):
    return hasattr(obj, '__self__') and obj.__self__ is not None

is_bound_method also works for methods of classes implemented in C, e.g., int:

>>> a = 1
>>> is_bound_method(a.__add__)
>>> is_bound_method(int.__add__)

But is not very useful in that case because inspect.getargspec does not work for functions implemented in C.

is_bound_method works unchanged in Python 3, but as noted above, in Python 3, inspect.ismethod properly distinguishes between bound and unbound methods, so it is not necessary.
msg183439 - (view) Author: Thomas Kluyver (takluyver) * Date: 2013-03-04 12:36
I agree that the docs for inspect.ismethod() for Python 2 are wrong.

The docs say: "Return true if the object is a bound method written in Python."

However, it also returns True for an unbound method:

>>> class A:
...     def meth(self):
...         pass
>>> A.meth
<unbound method A.meth>
>>> import inspect
>>> inspect.ismethod(A.meth)
msg183481 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2013-03-04 18:00
I checked the tests on 2.7 and found this:

        # contrary to spec, ismethod() is also True for unbound methods
        # (see #1785)
        self.assertIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))

#1785 also has some discussion about this.
msg261557 - (view) Author: Anna Koroliuk (Anna Koroliuk) * Date: 2016-03-11 10:25
This patch fixes Python 2.7.
msg261558 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2016-03-11 10:28
New changeset 813a0e0934ce by Victor Stinner in branch '2.7':
Fix inspect.ismethod() doc
msg261559 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2016-03-11 10:30
Thanks Anna, I pushed your doc fix.

Can you please sign the Python Contributor Agreement?
msg261560 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2016-03-11 10:32
New changeset a90b39aa6af4 by Victor Stinner in branch '2.7':
Issue #16851: Add Anna Koroliuk to Misc/ACKS
msg267304 - (view) Author: Jelle Zijlstra (Jelle Zijlstra) * (Python triager) Date: 2016-06-04 19:42
Sounds like this can be closed?
Date User Action Args
2016-06-04 22:36:03berker.peksagsetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2016-06-04 19:42:52Jelle Zijlstrasetnosy: + Jelle Zijlstra
messages: + msg267304
2016-03-11 10:32:00python-devsetmessages: + msg261560
2016-03-11 10:30:20vstinnersetstatus: closed -> open

nosy: + vstinner
messages: + msg261559

resolution: fixed -> (no value)
stage: resolved -> patch review
2016-03-11 10:28:21python-devsetstatus: open -> closed

nosy: + python-dev
messages: + msg261558

resolution: fixed
stage: patch review -> resolved
2016-03-11 10:25:41Anna Koroliuksetfiles: + inspect2.patch
nosy: + Anna Koroliuk
messages: + msg261557

2013-03-04 18:00:18ezio.melottisetnosy: + pitrou
messages: + msg183481
2013-03-04 12:36:20takluyversetnosy: + takluyver
messages: + msg183439
2013-02-12 00:07:09gregcouchsetnosy: + gregcouch
messages: + msg181937
2013-01-11 05:54:23chris.jerdoneksetnosy: + chris.jerdonek
2013-01-09 06:06:55ezio.melottisetassignee: docs@python -> ezio.melotti
stage: needs patch -> patch review
2013-01-08 13:32:19federico.reghenzanisetnosy: + federico.reghenzani
2013-01-08 12:57:52eric.araujosettitle: ismethod and isfunction methods error -> Hint about correct ismethod and isfunction usage
2013-01-08 12:57:22eric.araujosetnosy: + eric.araujo
2013-01-08 10:06:48federico.reghenzanisetfiles: + inspect.patch
keywords: + patch
2013-01-03 16:56:22ezio.melottisetassignee: docs@python
type: behavior -> enhancement
components: + Documentation, - Library (Lib)
versions: + Python 3.3, Python 3.4
keywords: + easy
nosy: + docs@python, ezio.melotti

messages: + msg178966
stage: needs patch
2013-01-03 16:41:29wdanilocreate