Behaviour-based interface/protocol implementation?

Chris Rebert clp2 at rebertia.com
Tue Jan 25 01:55:52 EST 2011


On Mon, Jan 24, 2011 at 2:13 AM, Alan Franzoni <mailing at franzoni.eu> wrote:
> Hello,
> I'd like to have a system which lets me do certain actions if the
> duck-type of a certain objects matches what I expect, i.e. I'd like to
> have a formalization of what it's sometimes done through getattr()
> calls:
>
> if getattr(myobj, "somemethod", None) is not None:
>    myobj.somemethod(somevalue)
>
>
> The above approach is sometimes too naive, because a) clutters code
> with many getattr calls and ifs b) I might want to check for multiple
> attributes and c) only checks for the method name and not for the
> method's signature.
>
> After looking at PyProtocols, zope.interface and python's own abc
> module, I'm left with a doubt: does any behaviour-based "interface
> testing" system exist for Python?
>
>
> I mean:
> all these three libraries use a register-based or inheritance-based
> approach; in abc, if I want instances of a class of mine "FooClass" to
> be "BarInterface" instances, I can either a) inherit from BarInterface
> or b) run "BarInterface.register(FooClass)".

Not true actually:

Python 2.7.1 (r271:86832, Dec  5 2010, 00:12:20)
[GCC 4.2.1 (Apple Inc. build 5664)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> class MyContainer(object):# no special inheritance
...     def __len__(self):
...         return 42
...
>>> # didn't do any registration.
>>> from collections import Sized
>>> issubclass(MyContainer, Sized)
True
>>> isinstance(MyContainer(), Sized)
True

Several of the other ABCs in the `collections` module (which are based
on the `abc` module) work similarly. Registration and subclassing are
just additional ways to indicate support for an interface. Provided
the ABC is properly coded, registration/subclassing isn't mandatory.

<snip>
> What happens if I define my own ABC for my own purpose? There might be
> builtin objects, or third party libraries, which already offer objects
> that satisfy such interface, but I'd need to import such modules and
> register such classes as implementing my ABC, which is suboptimal.
<snip>
> I'd like to do a kind of runtime-check for signatures. Of course there
> couldn't be an absolute certainty of interface implementation, because
> a runtime dynamic proxy method (accepting *args and **kwargs in its
> signature, as an example)  might  just fool my signature check.
>
> So, my questions are:
>
> a) does anything like that already exist in the python ecosystem?

Not precisely that I know of, no. The `abc`/`collections` system comes
closest, but it does not check method signatures; it merely verifies
methods' existence.

You could *definitely* write something like that by combining the
`abc` and `inspect` modules though:
http://docs.python.org/library/inspect.html#inspect.getargspec
http://docs.python.org/library/abc.html#abc.ABCMeta.__subclasshook__

> b) can anybody see any flaw either in what I'd like to do ("you
> shouldn't do that because...")

Duck typing partisans would question what the point of such an
elaborate mechanism would be when it won't change the fact that your
type errors will still occur at run-time and be of essentially the
same character as if you didn't use such a mechanism in the first
place.
But I'm not such a partisan; not that they wouldn't have a point
though. At /some/ point, you're just fighting the inherent nature of
the language, which is a losing battle (unless perhaps the language is
a Lisp).

Cheers,
Chris
--
http://blog.rebertia.com



More information about the Python-list mailing list