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  __docformat__="restructuredtext en"
     25
     26  import sys
     27  from types import FunctionType
     28
     29 -def classImplements(cls, *interfaces):
     30      if not isinstance(cls, classobj):
     31          raise TypeError, "%r is not a class"
     32      for interface in interfaces:
     33          if not isinstance(interface, InterfaceClass):
     34              raise TypeError, "Only interfaces may be implemented"
     35      cls.__implemented__ = tuple(interfaces)
     36
     37 -def implements(*interfaces):
     38      for interface in interfaces:
     39          if not isinstance(interface, InterfaceClass):
     40              raise TypeError, "Only interfaces may be implemented"
     41
     42      frame = sys._getframe(1)
     43      locals = frame.f_locals
     44
     45      if (locals is frame.f_globals) or ('__module__' not in locals):
     46          raise TypeError, "implements() may only be used in a class definition"
     47
     48      if "__implemented__" in locals:
     49          raise TypeError, "implements() may be used only once"
     50
     51      locals["__implemented__"] = tuple(interfaces)
     52
     53 -def _whole_tree(cls):
     54      yield cls
     55      for base in cls.__bases__:
     56          for b in _whole_tree(base):
     57              yield b
     58
     59 -def implementedBy(cls):
     60      try:
     61          for interface in cls.__implemented__:
     62              for c in _whole_tree(interface):
     63                  yield c
     64      except AttributeError:
     65          pass
     66      for base in cls.__bases__:
     67          for interface in implementedBy(base):
     68              yield interface
     69
     70 -def providedBy(ob):
     71      try:
     72          for interface in ob.__provides__:
     73              yield interface
     74      except AttributeError:
     75          try:
     76              for interface in implementedBy(ob.__class__):
     77                  yield interface
     78          except AttributeError:
     79              return
     80
     81 -class InterfaceClass(object):
     82 -    def __init__(self, name, bases = (), attrs = None, __doc__ = None, __module__ = None):
     83          if __module__ is None:
     84              if (attrs is not None and ('__module__' in attrs) and isinstance(attrs['__module__'], str)):
     85                  __module__ = attrs['__module__']
     86                  del attrs['__module__']
     87              else:
     88                  __module__ = sys._getframe(1).f_globals['__name__']
     89          if __doc__ is not None:
     90              self.__doc__ = __doc__
     91          if attrs is not None and "__doc__" in attrs:
     92              del attrs["__doc__"]
     93          self.__module__ = __module__
     94          for base in bases:
     95              if not isinstance(base, InterfaceClass):
     96                  raise TypeError, 'Interface bases must be Interfaces'
     97          if attrs is not None:
     98              for aname, attr in attrs.items():
     99                  if not isinstance(attr, Attribute) and type(attr) is not FunctionType:
    100                      raise TypeError, 'Interface attributes must be Attributes o functions (%r found in %s)' % (attr, aname)
    101          self.__bases__ = bases
    102          self.__attrs = attrs
    103          self.__name__ = name
    104          self.__identifier__ = "%s.%s" % (self.__module__, self.__name__)
    105
    106 -    def providedBy(self, ob):
    107          """Is the interface implemented by an object"""
    108          if self in providedBy(ob):
    109              return True
    110          return False
    111
    112 -    def implementedBy(self, cls):
    113          """Do instances of the given class implement the interface?"""
    114          return self in implementedBy(cls)
    115
    116 -    def __repr__(self):
    117          name = self.__name__
    118          module = self.__module__
    119          if module and module != "__main__":
    120              name = "%s.%s" % (module, name)
    121          return "<%s %s>" % (self.__class__.__name__, name)
    122
    123 -class Attribute(object):
    124 -    def __init__(self, doc):
    125          self.__doc__ = doc
    126
    127  Interface = InterfaceClass("Interface", __module__ = "pyxmpp.inteface_micro_impl")
    128
    129  # vi: sts=4 et sw=4
    130