[Zope-Checkins] CVS: Zope/lib/python/Interface - iclass.py:1.11.8.2
Shane Hathaway
shane@digicool.com
Tue, 7 Aug 2001 11:27:44 -0400
Update of /cvs-repository/Zope/lib/python/Interface
In directory cvs.zope.org:/tmp/cvs-serv24074
Modified Files:
Tag: NR-branch
iclass.py
Log Message:
Made it possible to store interfaces by reference to a module and name,
the same as classes, using deep internals of pickling machinery.
Don't shoot me unless you know a better way to achieve this. :-)
=== Zope/lib/python/Interface/iclass.py 1.11.8.1 => 1.11.8.2 ===
"""
+from inspect import currentframe
+import sys
+
from Method import Method
from Attr import Attribute
from types import FunctionType, ClassType
@@ -16,11 +19,11 @@
from InterfaceBase import InterfaceBase
try:
- from ExtensionClass import Base
+ import ExtensionClass
except ImportError:
ClassTypes = (ClassType,)
else:
- class dummy (Base): pass
+ class dummy (ExtensionClass.Base): pass
ClassTypes = (type(dummy), ClassType)
@@ -32,7 +35,7 @@
def __init__(self, name, bases=(), attrs=None, __doc__=None):
"""Create a new interface
- """
+ """
for b in bases:
if not isinstance(b, Interface):
raise TypeError, 'Expected base interfaces'
@@ -164,7 +167,69 @@
return "<Interface %s at %x>" % (self.__name__, id(self))
-Base=Interface("Interface")
+# Persist interfaces created from classes by reference using
+# a module and name.
+
+
+class InterfaceFromClass (Interface):
+ def __init__(self, name, bases=(), attrs=None, __doc__=None,
+ __module__=None):
+ if __module__ is None:
+ if attrs is not None and attrs.has_key('__module__'):
+ __module__ = attrs['__module__']
+ del attrs['__module__']
+ else:
+ try:
+ # Figure out what module defined the interface.
+ # This is how cPython figures out the module of
+ # a class, but of course it does it in C, making
+ # it more reliable. :-/
+ __module__ = currentframe().f_back.f_globals['__name__']
+ except AttributeError, KeyError:
+ pass
+ self.__module__ = __module__
+ Interface.__init__(self, name, bases, attrs, __doc__)
+
+ def __getinitargs__(self):
+ # What this returns will be passed as arguments to
+ # interface_loader.__call__().
+ if not self.__module__:
+ raise SystemError, 'Module of interface object is unknown'
+ return (self.__module__, self.__name__)
+
+ def __getstate__(self):
+ # No need to save details.
+ return None
+
+ def __setstate__(self, state):
+ assert state == None
+
+ def __repr__(self):
+ name = self.__name__
+ m = self.__module__
+ if m:
+ name = '%s.%s' % (m, name)
+ return "<InterfaceFromClass %s at %x>" % (name, id(self))
+
+
+class InterfaceLoader:
+
+ __safe_for_unpickling__ = 1
+
+ def __call__(self, module, name):
+ __import__(module)
+ mod = sys.modules[module]
+ i = getattr(mod, name)
+ return i
+
+interface_loader = InterfaceLoader()
+
+
+InterfaceFromClass.__name__ = 'interface_loader' # Trick unpicklers.
+
+Base = InterfaceFromClass("Interface")
+
+
class Named(Base):
"Objects that have a name."