[Python-ideas] Add a "hasmethod()" builtin?

Guido van Rossum guido at python.org
Thu Aug 30 00:48:01 CEST 2012

There's a concept that's sometimes useful when explaining behavior of
certain Python operations in terms of simpler ones, and it is "does
the class of x define a method m?".

This currently cannot expressed using hasattr(): hasattr(x, 'm') might
find an instance variable named m, but that is not a method (and there
are contexts where they are not interchangeable); hasattr(type(x),
'm') might find a *metaclass* method.

Example of the former (assume Python 3):

class C:
  def __add__(self, other): return 42

c = C()
c.__add__ = lambda *args: 0
c + 1  # prints 42, not 0

Example of the latter:

class C: pass
c = C()
hasattr(C, 'mro')  # prints True, since mro() is a method of the
standard metaclass ('type').
c.mro()  # raises AttributeError

The use case I am mainly thinking of is the formal explanation of the
semantics of binary (and other) operators, e.g.

def __add__(a, b):
  r = NotImplemented
  if hasmethod(a, '__add__'):
    r = a.__add__(b)
  if r is NotImplemented and hasmethod(b, '__radd__'):
    r = b.__radd__(a)
  if r is NotImplemented:
    raise TypeError
  return r

(Caveat: it's even more complicated if type(b) is a subclass of type(a).)

I'm not sure if it would be better if the first argument of
hasmethod() was a type instead of an instance (so the example would
use hasattr(type(a), '__add__') etc.). It's also interesting to figure
out what should happen for proxy types. (Proxy types in general need a
better foundation.)


--Guido van Rossum (python.org/~guido)

More information about the Python-ideas mailing list