Purpose of Zope Interfaces? - python

I have started using Zope interfaces in my code, and as of now, they are really only documentation. I use them to specify what attributes the class should possess, explicitly implement them in the appropriate classes and explicitly check for them where I expect one. This is fine, but I would like them to do more if possible, such as actually verify that the class has implemented the interface, instead of just verifying that I have said that the class implements the interface. I have read the zope wiki a couple of times, but still cannot see much more use for interfaces than what I am currently doing. So, my question is what else can you use these interfaces for, and how do you use them for more.

Where I work, we use Interfaces so that we can use ZCA, or the Zope Component Architecture, which is a whole framework for making components that are swappable and pluggable using Interfaces. We use ZCA so that we can cope with all manner of per-client customisations without necessarily having to fork our software or have all of the many per-client bits messing up the main tree. The Zope wiki is often quite incomplete, unfortunately. There's a good-but-terse explanation of most of ZCA's features on its ZCA's pypi page.
I don't use Interfaces for anything like checking that a class implements all the methods for a given Interface. In theory, that might be useful when you add another method to an interface, to check that you've remembered to add the new method to all of the classes that implement the interface. Personally I strongly prefer to create a new Interface over modifying an old one. Modifying old Interfaces is usually a very bad idea once they're in eggs that have been released to pypi or to the rest of your organisation.
A quick note on terminology: classes implement Interfaces, and objects (instances of classes) provide Interfaces. If you want to check for an Interface, you would either write ISomething.implementedBy(SomeClass) or ISomething.providedBy(some_object).
So, down to examples of where ZCA is useful. Let's pretend that we're writing a blog, using the ZCA to make it modular. We'll have a BlogPost object for each post, which will provide an IBlogPost interface, all defined in our handy-dandy my.blog egg. We'll also store the blog's configuration in BlogConfiguration objects which provide IBlogConfiguration. Using this as a starting point, we can implement new features without necessarily having to touch my.blog at all.
The following is a list of examples of things that we can do by using ZCA, without having to alter the base my.blog egg. I or my co-workers have done all of these things (and found them useful) on real for-client projects, though we weren't implementing blogs at the time. :) Some of the use cases here could be better solved by other means, such as a print CSS file.
Adding extra views (BrowserViews, usually registered in ZCML with the browser:page directive) to all objects which provide IBlogPost. I could make a my.blog.printable egg. That egg would register a BrowserView called print for IBlogPost, which renders the blog post through a Zope Page Template designed to produce HTML that prints nicely. That BrowserView would then appear at the URL /path/to/blogpost/##print.
The event subscription mechanism in Zope. Say I want to publish RSS feeds, and I want to generate them in advance rather than on request. I could create a my.blog.rss egg. In that egg, I'd register a subscriber for events that provide IObjectModified (zope.lifecycleevent.interfaces.IObjectModified), on objects that provide IBlogPost. That subscriber would get get called every time an attribute changed on anything providing IBlogPost, and I could use it to update all the RSS feeds that the blog post should appear in.
In this case, it might be better to have an IBlogPostModified event that is sent at the end of each of the BrowserViews that modify blog posts, since IObjectModified gets sent once on every single attribute change - which might be too often for performance's sake.
Adapters. Adapters are effectively "casts" from one Interface to another. For programming language geeks: Zope adapters implement "open" multiple-dispatch in Python (by "open" I mean "you can add more cases from any egg"), with more-specific interface matches taking priority over less-specific matches (Interface classes can be subclasses of one another, and this does exactly what you'd hope it would do.)
Adapters from one Interface can be called with a very nice syntax, ISomething(object_to_adapt), or can be looked up via the function zope.component.getAdapter. Adapters from multiple Interfaces have to be looked up via the function zope.component.getMultiAdapter, which is slightly less pretty.
You can have more than one adapter for a given set of Interfaces, differentiated by a string name that you provide when registering the adapter. The name defaults to "". For example, BrowserViews are actually adapters that adapt from the interface that they're registered on and an interface that the HTTPRequest class implements. You can also look up all of the adapters that are registered from one sequence of Interfaces to another Interface, using zope.component.getAdapters( (IAdaptFrom,), IAdaptTo ), which returns a sequence of (name, adapter) pairs. This can be used as a very nice way to provide hooks for plugins to attach themselves to.
Say I wanted to save all my blog's posts and configuration as one big XML file. I create a my.blog.xmldump egg which defines an IXMLSegment, and registers an adapter from IBlogPost to IXMLSegment and an adapter from IBlogConfiguration to IXMLSegment. I can now call whichever adapter is appropriate for some object I want to serialize by writing IXMLSegment(object_to_serialize).
I could even add more adapters from various other things to IXMLSegment from eggs other than my.blog.xmldump. ZCML has a feature where it can run a particular directive if and only if some egg is installed. I could use this to have my.blog.rss register an adapter from IRSSFeed to IXMLSegment iff my.blog.xmldump happens to be installed, without making my.blog.rss depend on my.blog.xmldump.
Viewlets are like little BrowserViews that you can have 'subscribe' to a particular spot inside a page. I can't remember all the details right now but these are very good for things like plugins that you want to appear in a sidebar.
I can't remember offhand whether they're part of base Zope or Plone. I would recommend against using Plone unless the problem that you are trying to solve actually needs a real CMS, since it's a big and complicated piece of software and it tends to be kinda slow.
You don't necessarily actually need Viewlets anyway, since BrowserViews can call one another, either by using 'object/##some_browser_view' in a TAL expression, or by using queryMultiAdapter( (ISomething, IHttpRequest), name='some_browser_view' ), but they're pretty nice regardless.
Marker Interfaces. A marker Interface is an Interface that provides no methods and no attributes. You can add a marker Interface any object at runtime using ISomething.alsoProvidedBy. This allows you to, for example, alter which adapters will get used on a particular object and which BrowserViews will be defined on it.
I apologise that I haven't gone into enough detail to be able to implement each of these examples straight away, but they'd take approximately a blog post each.

You can actually test if your object or class implements your interface.
For that you can use verify module (you would normally use it in your tests):
>>> from zope.interface import Interface, Attribute, implements
>>> class IFoo(Interface):
... x = Attribute("The X attribute")
... y = Attribute("The Y attribute")
>>> class Foo(object):
... implements(IFoo)
... x = 1
... def __init__(self):
... self.y = 2
>>> from zope.interface.verify import verifyObject
>>> verifyObject(IFoo, Foo())
True
>>> from zope.interface.verify import verifyClass
>>> verifyClass(IFoo, Foo)
True
Interfaces can also be used for setting and testing invariants.
You can find more information here:
http://www.muthukadan.net/docs/zca.html#interfaces

Zope interfaces can provide a useful way to decouple two pieces of code that shouldn't depend on each other.
Say we have a component that knows how to print a greeting in module a.py:
>>> class Greeter(object):
... def greet(self):
... print 'Hello'
And some code that needs to print a greeting in module b.py:
>>> Greeter().greet()
'Hello'
This arrangement makes it hard to swap out the code that handles the greeting without touching b.py (which might be distributed in a separate package). Instead, we could introduce a third module c.py which defines an IGreeter interface:
>>> from zope.interface import Interface
>>> class IGreeter(Interface):
... def greet():
... """ Gives a greeting. """
Now we can use this to decouple a.py and b.py. Instead of instantiating a Greeter class, b.py will now ask for a utility providing the IGreeter interface. And a.py will declare that the Greeter class implements that interface:
(a.py)
>>> from zope.interface import implementer
>>> from zope.component import provideUtility
>>> from c import IGreeter
>>> #implementer(IGreeter)
... class Greeter(object):
... def greet(self):
... print 'Hello'
>>> provideUtility(Greeter(), IGreeter)
(b.py)
>>> from zope.component import getUtility
>>> from c import IGreeter
>>> greeter = getUtility(IGreeter)
>>> greeter.greet()
'Hello'

I've never used Zope interfaces, but you might consider writing a metaclass, which on initialization checks the members of the class against the interface, and raises a runtime exception if a method isn't implemented.
With Python you don't have other options. Either have a "compile" step that inspects your code, or dynamically inspect it at runtime.

Related

OOP: Using conditional statement while initializing a class

This question geared toward OOP best practices.
Background:
I've created a set of scripts that are either automatically triggered by cronjobs or are constantly running in the background to collect data in real time. In the past, I've used Python's smtplib to send myself notifications when errors occur or a job is successfully completed. Recently, I migrated these programs to the Google Cloud platform which by default blocks popular SMTP ports. To get around this I used linux's mail command to continue sending myself the reports.
Originally, my hacky solution was to have two separate modules for sending alerts that were initiated based on an argument I passed to the main script.
Ex:
$ python mycode.py my_arg
if sys.argv[1] == 'my_arg':
mailer = Class1()
else:
mailer = Class2()
I want to improve upon this and create a module that automatically handles this without the added code. The question I have is whether it is "proper" to include a conditional statement while initializing the class to handle the situation.
Ex:
Class Alert(object):
def __init__(self, sys.platform, other_args):
# Google Cloud Platform
if sys.platform == "linux":
#instantiate Class1 variables and methods
#local copy
else:
#instantiate Class2 variables and methods
My gut instinct says this is wrong but I'm not sure what the proper approach would be.
I'm mostly interested in answers regarding how to create OO classes/modules that handle environmental dependencies to provide the same service. In my case, a blocked port requires a different set of code altogether.
Edit: After some suggestions here are my favorite readings on this topic.
http://python-3-patterns-idioms-test.readthedocs.io/en/latest/Factory.html
This seems like a wonderful use-case for a factory class, which encapsulates the conditional, and always returns an instance of one of N classes, all of which implement the same interface, so that the rest of your code can use it without caring about the concrete class being used.
This is a way to do it. But I would rather use something like creating a dynamic class instance. To do that, you could have only one class instead of selecting from two different classes. The class would then take some arguments and return the result depending the on the arguments provided. There are quite some examples out there and I'm sure you can use them in your use-case. Try searching for how to create a dynamic class in python.

Tests for Basic Python Data Structure Interfaces

A fairly small question: does anyone know about a pre-made suite of Python unit tests that just check if a class conforms to one of the standard Python data structure interfaces (e.g., lists, sets, dictionaries, queues, etc). It's not overly hard to write them, but I'd hate to bother doing so if someone has already done this. It seems like very basic functionality that someone has probably done already.
The use case is that I am using a factory pattern to create data structures due to different restrictions related to platforms. As such, I need to be able to test that the resulting created objects still conform to the standard interfaces on the surface. Also, I should note that by "conform" I mean that the tests should check not just that the interface functions exist, but also check that they work (e.g., can set and retrieve a value in a map, for instance). Python 2.7 tests would be preferred.
First, "the standard Python data structure interfaces" are not lists, sets, dictionaries, queues, etc. Those are specific implementations of the interfaces. (And queue isn't even a data structure in the sense you're thinking of—its salient features are that its operations are atomic, and put and get optionally synchronize on a Condition, and so on.)
Anyway, the interfaces are defined in five different not-quite-compatible ways.
The Built-in Types section of the documentation describes what it means to be an iterator type, a sequence type, etc. However, these are not nearly as rigorous as you'd expect for reference documentation (at least if you're used to, say, C++ or Java).
I'm not aware of any tests for such a thing, so I think you'd have to build them from scratch.
The collections module contains Collections Abstract Base Classes that define the interfaces, and provide a way to register "virtual subclasses" via the abc module. So, you can declare "I am a mapping" by inheriting from collections.Mapping, or calling collections.Mapping.register. But that doesn't actually prove that you are a mapping, just that you're claiming to be. (If you inherit from Mapping, it also acts as a mixin that helps you complete the interface by implementing, e.g., __contains__ on top of __getitem__.)
If you want to test the ABC meaning, defuz's answer is very close, and with a little more work I think he or someone else can complete it.
The CPython C API defines an Abstract Objects Layer. While this is not actually authoritative for the language, it's obviously intended that the C-API protocols and the language-level interfaces are supposed to match. And, unlike the latter, the former are rigorously defined. And of course the source code from CPython 2.7, and maybe other implementations like PyPy, may help.
There are tests for this that come with CPython, but really, they're for testing that calling PyMapping_GetItem from C properly calls your mymapping.__getitem__ in Python, which is really at a tangent to what you want to test, so I don't think it will help much.
The actual concrete classes have additional interface on top of the protocols, that you may want to test, but that's harder to describe. In particular, the way the __new__ and __init__ methods work is often important. Implementing the Mapping protocol means someone can construct an empty Foo instance and add items to it with foo[key] = value, but it doesn't mean someone can construct Foo(key=value), or Foo({key: value}) or Foo([(key, value)]).
And for this case, there are existing tests that come with all of the standard Python implementations. CPython comes with a very extensive test suite that includes things like test_dict.py. PyPy runs all the (Python-level) CPython tests, and some extra ones besides.
You will obviously have to modify these tests to run on an arbitrary class instead of one hardcoded into the tests, and you may also have to modify them to handle whichever definition you pick. Plus, they probably test more than you asked for. You just want to know if a class conforms to the protocol, not whether its methods do the right thing, right? But still, I think they're a good starting point.
Finally, the C API defines a Concrete Objects Layer that, although it's not authoritative, matches the previous definition and is more rigorously defined.
Unfortunately, the tests for this one are definitely not going to be very useful to you, because they're checking things like whether PyDict_Check and PyDict_GetItem work on your class, which they will not for any mapping defined in pure Python.
If you do build something complete for any of these definitions, I would strongly suggest putting it on PyPI, and posting about it to python-list, so you get feedback (and bug reports).
There are abstract base classes in standart module collections based on ABC module.
You have to inherit your classes from these classes to be sure that your classes correspond to the standard behavior:
import collections
class MyDict(collections.Mapping):
...
Also, your can test already existed class that does not obviously inherit the abstract class:
class MyPerfectDict(object):
... realization ...
def is_inherit(cls, abstract):
try:
class Test(abstract, cls): pass
test = Test()
except TypeError:
return False
else:
return True
is_inherit(MyPerfectDict, Mapping) # False
is_inherit(dict, Mapping) # True

Python app design patterns - instance must be available for most other instances

I'm writing pretty big and complex application, so I want to stick to design patterns to keep code in good quality. I have problem with one instance that needs to be available for almost all other instances.
Lets say I have instance of BusMonitor (class for logging messages) and other instances that use this instance for logging actions, in example Reactor that parses incoming frames from network protocol and depending on frame it logs different messages.
I have one main instance that creates BusMonitor, Reactor and few more instances.
Now I want Reactor to be able to use BusMonitor instance, how can I do that according to design patterns?
Setting it as a variable for Reactor seems ugly for me:
self._reactor.set_busmonitor(self._busmonitor)
I would do that for every instance that needs access to BusMonitor.
Importing this instance seems even worse.
Altough I can make BusMonitor as Singleton, I mean not as Class but as Module and then import this module but I want to keep things in classes to retain consistency.
What approach would be the best?
I want to keep things in classes to retain consistency
Why? Why is consistency important (other than being a hobgoblin of little minds)?
Use classes where they make sense. Use modules where they don't. Classes in Python are really for encapsulating data and retaining state. If you're not doing those things, don't use classes. Otherwise you're fighting against the language.
As you already have a hierarchy, you could use a chain to get it.. it's not the Chain-of-responsibility pattern, but the idea is similar.
Each widget has a getbusmonitor call, which is return self.parent().getbusmonitor() for all widgets except the root one. You could also cache the results..
I found good way I think. I made module with class BusMonitor, and in the same module, after class definition I make instance of this class. Now I can import it from everywhere in project and I retain consistency using classes and encapsulation.

How is introspection useful?

I have been programming mainly in PHP, and I am trying to make a switch to python. I am skilled with PHP, and I have never needed to use introspection / introspection like capabilities. What good is code introspection, and in what situations would I find it indispensable?
Here is the only way I find it useful:
From the examples I saw in 'Dive into Python', introspection basically means that you can list all of the functions and attributes of an object. To me it seems that introspection is just there as a "user's manual" to an object. It lets you look at the object and its functionality from the python shell.
I just do not see why or in what situation you would take an arbitrary object, introspect upon it, and do something useful.
Suppose you are given a custom object and you want to know if the object has certain attributes or has as a certain method, then the introspection function such as hasattr can be used to find that out.
Also like the DiveintoPython book already illustrates, suppose you are building a GUI Editor with Auto-Completion feature, you want to get the public methods of the object which are callable at the run-time, then you can use the introspection methods like getattr for each for the methods got via dir and check if it is callable and then display it in your auto-completion list.
One example where I have used introspection on a real project:
We had a service that was managing background tasks called TaskService. Each task was actually implemented as a class that was implementing the Start() Stop() methods of a given interface. We had a config file, in which we were matching each task with its class. So when running TaskService, it just browsed the config file, and for each task it took the name of the class and instanciated it (during runtime) through reflection (introspection is a subpart of reflection).
Another example of where introspection can be useful is in the use of annotations in your programming language. Annotations are used to give metainformation about your classes to other third party programs (like ORMs), for instance you can use annotations to tell whether a class is an entity class (it is the case in Java, I don't know about Python sorry), or about the type of association of certain attributs etc.
Code Completion is another example of the usefulness of introspection.
And by the way, as you mentionned, introspection helps a lot to program documentation tools.
I wrote a documentation validator that runs tests on PDF files to check for various problems with them. The tests are methods of special classes that represent Subversion branches, products, manuals, and arbitrary groupings of various types. The validator engine uses introspection to find these special classes, instantiate them, and run their methods.
I could have written the validator so that you have to write boilerplate code to instantiate each class, call each method, etc. But that is repeating yourself and it is prone to maintenance problems (failure to update both places when adding/removing tests, in this case). By taking advantage of the fact that you want to apply the same operation to all the special classes, the computer can essentially do the boilerplate stuff for you, and it won't make mistakes. That way, you have to declare the structure of the documentation in only one place.
A little bit late on this, but another example of introspection in use is with Active Record (a Ruby library that maps objects to database tables). Active Record uses introspection to look at the name of the class, determine the associated table, and defines methods that access object attributes after inferring their names from the database schema. It reads the schema at runtime (metaprogramming & introspection in play here). So for example, if you have a class Person, you don't have to write accessor methods e.g nameoremail. As long as columns by the same name (in this case nameandemail) exist in the associated table (in this case people`), Active Record defines accessor methods for these attributes of the same name at runtime.

Creating an interface and swappable implementations in python

Would it be possible to create a class interface in python and various implementations of the interface.
Example: I want to create a class for pop3 access (and all methods etc.). If I go with a commercial component, I want to wrap it to adhere to a contract.
In the future, if I want to use another component or code my own, I want to be able to swap things out and not have things very tightly coupled.
Possible? I'm new to python.
For people coming from a strongly typed language background, Python does not need a class interface. You can simulate it using a base class.
class BaseAccess:
def open(arg):
raise NotImplementedError()
class Pop3Access(BaseAccess):
def open(arg):
...
class AlternateAccess(BaseAccess):
def open(arg):
...
But you can easily write the same code without using BaseAccess. Strongly typed language needs the interface for type checking during compile time. For Python, this is not necessary because everything is looked up dynamically in run time. Google 'duck typing' for its philosophy.
There is a Abstract Base Classes module added in Python 2.6. But I haven't have used it.
Of course. There is no need to create a base class or an interface in this case either, as everything is dynamic.
One option is to use zope interfaces. However, as was stated by Wai Yip Tung, you do not need to use interfaces to achieve the same results.
The zope.interface package is really more a tool for discovering how to interact with objects (generally within large code bases with multiple developers).
Yes, this is possible. There are typically no impediments to doing so: just keep a stable API and change how you implement it.

Categories