On Mon, Jan 24, 2011 at 2:13 AM, Alan Franzoni <mail...@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 -- http://mail.python.org/mailman/listinfo/python-list