Home | Trees | Indices | Help |
|
---|
|
1 # -*- coding: utf-8 -*- 2 # 3 # Copyright (c) 2009 Olivier Guilyardi <olivier@samalyse.com> 4 # 5 # This file is part of TimeSide. 6 7 # TimeSide is free software: you can redistribute it and/or modify 8 # it under the terms of the GNU General Public License as published by 9 # the Free Software Foundation, either version 2 of the License, or 10 # (at your option) any later version. 11 12 # TimeSide is distributed in the hope that it will be useful, 13 # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 # GNU General Public License for more details. 16 17 # You should have received a copy of the GNU General Public License 18 # along with TimeSide. If not, see <http://www.gnu.org/licenses/>. 19 20 21 # This file defines a generic object interface mechanism and 22 # a way to determine which components implements a given interface. 23 # 24 # For example, the following defines the Music class as implementing the 25 # listenable interface. 26 # 27 # class Listenable(Interface): 28 # pass 29 # 30 # class Music(Component): 31 # implements(Listenable) 32 # 33 # Several class can implements a such interface, and it is possible to 34 # discover which class implements it with implementations(): 35 # 36 # list_of_classes = implementations(Listenable) 37 # 38 # This mechanism support inheritance of interfaces: a class implementing a given 39 # interface is also considered to implement all the ascendants of this interface. 40 # 41 # However, inheritance is not supported for components. The descendants of a class 42 # implementing a given interface are not automatically considered to implement this 43 # interface too. 44 45 __all__ = ['Component', 'MetaComponent', 'implements', 'abstract', 46 'interfacedoc', 'Interface', 'implementations', 'ComponentError'] 47 5052 """Registers the interfaces implemented by a component when placed in the 53 class header""" 54 MetaComponent.implements.extend(interfaces)5557 """Declare a component as abstract when placed in the class header""" 58 MetaComponent.abstract = True5961 """Returns the components implementing interface, and if recurse, any of 62 the descendants of interface. If abstract is True, also return the 63 abstract implementations.""" 64 result = [] 65 find_implementations(interface, recurse, abstract, result) 66 return result6769 if isinstance(func, staticmethod): 70 raise ComponentError("@interfacedoc can't handle staticmethod (try to put @staticmethod above @interfacedoc)") 71 72 if not func.__doc__: 73 func.__doc__ = "@interfacedoc" 74 func._interfacedoc = True 75 return func7678 """Metaclass of the Component class, used mainly to register the interface 79 declared to be implemented by a component.""" 80 81 implementations = [] 82 implements = [] 83 abstract = False 84116 12086 new_class = type.__new__(cls, name, bases, d) 87 88 # Register implementations 89 if MetaComponent.implements: 90 for i in MetaComponent.implements: 91 MetaComponent.implementations.append({ 92 'interface': i, 93 'class': new_class, 94 'abstract': MetaComponent.abstract}) 95 96 # Propagate @interfacedoc 97 for name in new_class.__dict__: 98 member = new_class.__dict__[name] 99 if isinstance(member, staticmethod): 100 member = getattr(new_class, name) 101 102 if member.__doc__ == "@interfacedoc": 103 if_member = None 104 for i in MetaComponent.implements: 105 if hasattr(i, name): 106 if_member = getattr(i, name) 107 if not if_member: 108 raise ComponentError("@interfacedoc: %s.%s: no such member in implemented interfaces: %s" 109 % (new_class.__name__, name, str(MetaComponent.implements))) 110 member.__doc__ = if_member.__doc__ 111 112 MetaComponent.implements = [] 113 MetaComponent.abstract = False 114 115 return new_class122 """Extend list1 with list2 as list.extend(), but doesn't append duplicates 123 to list1""" 124 for item in list2: 125 if item not in list1: 126 list1.append(item)127129 """Find implementations of an interface or of one of its descendants and 130 extend result with the classes found.""" 131 for item in MetaComponent.implementations: 132 if (item['interface'] == interface and (abstract or not item['abstract'])): 133 extend_unique(result, [item['class']]) 134 135 if recurse: 136 subinterfaces = interface.__subclasses__() 137 if subinterfaces: 138 for i in subinterfaces: 139 find_implementations(i, recurse, abstract, result)140 143
Home | Trees | Indices | Help |
|
---|
Generated by Epydoc 3.0.1 on Sun Dec 15 00:09:37 2013 | http://epydoc.sourceforge.net |