Package pyxmpp :: Module interface_micro_impl |
[hide private]

# Source Code for Module pyxmpp.interface_micro_impl

      1  #
      2  # (C) Copyright 2006 Jacek Konieczny <jajcus@jajcus.net>
      3  #
      4  # This program is free software; you can redistribute it and/or modify
      5  # it under the terms of the GNU Lesser General Public License Version
      6  # 2.1 as published by the Free Software Foundation.
      7  #
      8  # This program is distributed in the hope that it will be useful,
      9  # but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     11  # GNU Lesser General Public License for more details.
     12  #
     13  # You should have received a copy of the GNU Lesser General Public
     14  # License along with this program; if not, write to the Free Software
     15  # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     16  #
     17
     18  """Interface API, minimal implementation.
     19
     20  This is minimal Zope Interfaces API implementation, as required by PyXMPP, not add another dependencies.
     21
     22  If zope.interface package is available it will be used instead of this one. Never import this module directly."""
     23
     24  __revision__="$Id: utils.py 647 2006-08-26 18:27:39Z jajcus $"
     25  __docformat__="restructuredtext en"
     26
     27  import sys
     28  from types import FunctionType
     29
     30 -def classImplements(cls, *interfaces):
     31      if not isinstance(cls, classobj):
     32          raise TypeError, "%r is not a class"
     33      for interface in interfaces:
     34          if not isinstance(interface, InterfaceClass):
     35              raise TypeError, "Only interfaces may be implemented"
     36      cls.__implemented__ = tuple(interfaces)
     37
     38 -def implements(*interfaces):
     39      for interface in interfaces:
     40          if not isinstance(interface, InterfaceClass):
     41              raise TypeError, "Only interfaces may be implemented"
     42
     43      frame = sys._getframe(1)
     44      locals = frame.f_locals
     45
     46      if (locals is frame.f_globals) or ('__module__' not in locals):
     47          raise TypeError, "implements() may only be used in a class definition"
     48
     49      if "__implemented__" in locals:
     50          raise TypeError, "implements() may be used only once"
     51
     52      locals["__implemented__"] = tuple(interfaces)
     53
     54 -def _whole_tree(cls):
     55      yield cls
     56      for base in cls.__bases__:
     57          for b in _whole_tree(base):
     58              yield b
     59
     60 -def implementedBy(cls):
     61      try:
     62          for interface in cls.__implemented__:
     63              for c in _whole_tree(interface):
     64                  yield c
     65      except AttributeError:
     66          pass
     67      for base in cls.__bases__:
     68          for interface in implementedBy(base):
     69              yield interface
     70
     71 -def providedBy(ob):
     72      try:
     73          for interface in ob.__provides__:
     74              yield interface
     75      except AttributeError:
     76          try:
     77              for interface in implementedBy(ob.__class__):
     78                  yield interface
     79          except AttributeError:
     80              return
     81
     82 -class InterfaceClass(object):
     83 -    def __init__(self, name, bases = (), attrs = None, __doc__ = None, __module__ = None):
     84          if __module__ is None:
     85              if (attrs is not None and ('__module__' in attrs) and isinstance(attrs['__module__'], str)):
     86                  __module__ = attrs['__module__']
     87                  del attrs['__module__']
     88              else:
     89                  __module__ = sys._getframe(1).f_globals['__name__']
     90          if __doc__ is not None:
     91              self.__doc__ = __doc__
     92          if attrs is not None and "__doc__" in attrs:
     93              del attrs["__doc__"]
     94          self.__module__ = __module__
     95          for base in bases:
     96              if not isinstance(base, InterfaceClass):
     97                  raise TypeError, 'Interface bases must be Interfaces'
     98          if attrs is not None:
     99              for aname, attr in attrs.items():
    100                  if not isinstance(attr, Attribute) and type(attr) is not FunctionType:
    101                      raise TypeError, 'Interface attributes must be Attributes o functions (%r found in %s)' % (attr, aname)
    102          self.__bases__ = bases
    103          self.__attrs = attrs
    104          self.__name__ = name
    105          self.__identifier__ = "%s.%s" % (self.__module__, self.__name__)
    106
    107 -    def providedBy(self, ob):
    108          """Is the interface implemented by an object"""
    109          if self in providedBy(ob):
    110              return True
    111          return False
    112
    113 -    def implementedBy(self, cls):
    114          """Do instances of the given class implement the interface?"""
    115          return self in implementedBy(cls)
    116
    117 -    def __repr__(self):
    118          name = self.__name__
    119          module = self.__module__
    120          if module and module != "__main__":
    121              name = "%s.%s" % (module, name)
    122          return "<%s %s>" % (self.__class__.__name__, name)
    123
    124 -class Attribute(object):
    125 -    def __init__(self, doc):
    126          self.__doc__ = doc
    127
    128  Interface = InterfaceClass("Interface", __module__ = "pyxmpp.inteface_micro_impl")
    129
    130  # vi: sts=4 et sw=4
    131