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 ...
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