Zope3-Adapter für python-builtins

Manchmal muss man von einem python-builtin (z.b. str) oder einer von python importierten Klasse (z.b. decimal.Decimal) adaptieren ...

by Michael Howitz posted at 2006-01-30 11:30 last modified 2006-01-30 11:30

Definition

Im Beispiel wird ein Adapter für str gebaut. Andere Klassen können analog adaptiert werden.
Für das Beispiel soll von str nach ITest adaptiert werden:

interfaces.py:

from zope.interface import Interface

class ITest(Interface):
"Das Interface auf das adaptiert werden soll."

def makeUpper():
"Die Methode, für die Großschreibung"

Der Adapter von str nach ITest kommt nach adapter.py:

class StrTest(object):
"Adapterklasse von IStr nach ITest."

def __init__(self, context):
self.context = context

def makeUpper(self):
return self.context.upper()

In der configure.zcml wird alles zusammengebracht:

<configure xmlns="http://namespaces.zope.org/zope">

<adapter
for="str"
provides=".interfaces.ITest"
factory=".adapter.strtest"
/>

</configure>

Das for-Attribut des Adapter-Tags kann als Parameter ein Interface oder eine Klasse erhalten.

Unittest

Um den Adapter in einem Unittest benutzen zu können ist folgendes notwendig:

zusätzliche Imports (zu denen von ITest und StrTest):

from zope.app.testing import ztapi

Registrierung des Adapters:

ztapi.provideAdapter(str, ITest, StrTest)

Benutzung des Adatpers:

a = ITest('asdf')

Probleme mit der Sicherheitsmaschinerie von Zope3

Wenn es sich bei dem python-builtin um keinen "Rock" im Sinne der Sicherheitsmaschinerie von Zope3 handelt, das python-builtin also in einen Security-Proxy verpackt wird, sind außerdem folgende Arbeiten notwendig. (Das trifft zum Beispiel für decimal.Decimal zu.)

Ich zeige die Benutzung ausgehend von obigen str-Beispiel, auch wenn das dafür nicht notwendig ist. Aber es schadet auch nicht.

Per ZCML muss der Zugriff auf die Methoden des Builtins freigegeben werden. Das ist aber nur auf Interface-Ebene möglich. Also wird ein Interface für das python-builtin benötigt, welches alle Methoden definiert, die benutzt werden sollen.

class IStr(Interface):
"Interface für das python-builtin str."

def upper(self):
"Methode upper als Beispiel herausgegriffen."

Im configure.zcml ist das interface dem python-builtin zuzuordnen und freizugeben. Am einfachsten ist sicher die Freigabe mit allow, aber auch einer gezielteren Freigabe mit acquire-pemission sollte nichts im Weg stehen.

<class class="str">
<implements interface=".interfaces.IStr" />
<allow interface=".interfaces.IStr" />
</class>
Category(s)
Zope 3
The URL to Trackback this entry is:
http://blog.gocept.com/zope3-adapter-fuer-python-builtins/tbping