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

Nick Coghlan ncoghlan at gmail.com
Thu Aug 30 03:30:27 CEST 2012


On Thu, Aug 30, 2012 at 9:13 AM, Sven Marnach <sven at marnach.net> wrote:
> I'd usually simply use ``hasattr(a, "__add__")``.  This is also what
> e.g. MutableMapping.update() currently does.  The chances that someone
> accidentally passes in an object that has a callable instance variable
> called "__add__" seem pretty low, and we don't need to protect against
> people intentionally trying to break things.
>
> That said, ``hasmethod()`` can be implemented in a quite
> straight-forward way in pure Python:
>
>     def hasmethod(obj, name):
>         return inspect.ismethod(getattr(obj, name, None))

I don't think that's *quite* what Guido is getting at: it's more about
exposing the semantics of _PyType_Lookup at the Python level.

There are currently two different ways of approximating that. The one
which mimics _PyType_Lookup most closely (by treating proxy types as
instances of the proxy type, rather than the target type) is to do
"type(x.).attr", "getattr(type(x), 'attr')" or "hasattr(type(x),
'attr')" rather than performing those operations directly on 'x'.

There's an alternative which treats proxy objects as an instance of
the *target* type, which is to respect the claimed value of __class__:
"x.__class__.attr", "getattr(x.__class__, 'attr')" or
"hasattr(x.__class__, 'attr')"

Yet *both* of those alternatives have the problem Guido noted, where
they can find metaclass methods that the descriptor protocol would
ignore:

>>> class C: pass
...
>>> c = C()
>>> type(c)
<class '__main__.C'>
>>> c.__class__
<class '__main__.C'>
>>> hasattr(c, "mro")
False
>>> hasattr(type(c), "mro")
True

_PyType_Lookup is essentially "ordinary attribute lookup, but ignore
the instance variables and don't supply the instance to descriptors",
or, equivalently, "class attribute lookup, but don't fallback to the
metaclass". It's a necessary part of the language semantics, but it's
not currently accessible from Python code.

I believe the last time this came up, the main idea being kicked
around was a new function in the operator module (e.g.
"operator.gettypeattr()") rather than a new builtin.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia



More information about the Python-ideas mailing list