def menuDirective(_context, id=None, class_=BrowserMenu, interface=None, title=u'', description=u''): """Registers a new browser menu.""" if id is None and interface is None: raise ConfigurationError( "You must specify the 'id' or 'interface' attribute.") if interface is None: if id in dir(menus): # reuse existing interfaces for the id, without this we are not # able to override menus. interface = getattr(menus, id) else: interface = InterfaceClass(id, (), __doc__='Menu Item Type: %s' %id, __module__='zope.app.menus') # Add the menu item type to the `menus` module. # Note: We have to do this immediately, so that directives using the # MenuField can find the menu item type. setattr(menus, id, interface) path = 'zope.app.menus.' + id else: path = interface.__module__ + '.' + interface.getName() # If an id was specified, make this menu available under this id. # Note that the menu will be still available under its path, since it # is an adapter, and the `MenuField` can resolve paths as well. if id is None: id = path else: # Make the interface available in the `zope.app.menus` module, so # that other directives can find the interface under the name # before the CA is setup. _context.action( discriminator=('browser', 'MenuItemType', path), callable=provideInterface, args=(path, interface, IMenuItemType, _context.info) ) setattr(menus, id, interface) # Register the layer interface as an interface _context.action( discriminator=('interface', path), callable=provideInterface, args=(path, interface), kw={'info': _context.info} ) # Register the menu item type interface as an IMenuItemType _context.action( discriminator=('browser', 'MenuItemType', id), callable=provideInterface, args=(id, interface, IMenuItemType, _context.info) ) # Register the menu as a utility utility(_context, IBrowserMenu, class_(id, title, description), name=id)
def test__uncached_lookupAll_empty_ro(self): from zope.interface.interface import InterfaceClass IFoo = InterfaceClass('IFoo') IBar = InterfaceClass('IBar', IFoo) registry = self._makeRegistry() alb = self._makeOne(registry) result = alb._uncached_lookupAll((IFoo,), IBar) self.assertEqual(result, ()) self.assertEqual(len(alb._required), 1) self.failUnless(IFoo.weakref() in alb._required)
def __init__(self, *arg, **kw): try: attrs = arg[2] or {} except IndexError: attrs = kw.get("attrs", {}) si = attrs.pop("source_integrity", False) ti = attrs.pop("target_integrity", False) InterfaceClass.__init__(self, *arg, **kw) self.setTaggedValue("source_integrity", si) self.setTaggedValue("target_integrity", ti)
def __init__(self, *arg, **kw): try: attrs = arg[2] or {} except IndexError: attrs = kw.get('attrs', {}) si = attrs.pop('source_integrity', False) ti = attrs.pop('target_integrity', False) so = attrs.pop('source_ordered', False) to = attrs.pop('target_ordered', False) InterfaceClass.__init__(self, *arg, **kw) self.setTaggedValue('source_integrity', si) self.setTaggedValue('target_integrity', ti) self.setTaggedValue('source_ordered', so) self.setTaggedValue('target_ordered', to)
def route_request_iface(name, bases=()): # zope.interface treats the __name__ as the __doc__ and changes __name__ # to None for interfaces that contain spaces if you do not pass a # nonempty __doc__ (insane); see # zope.interface.interface.Element.__init__ and # https://github.com/Pylons/pyramid/issues/232; as a result, always pass # __doc__ to the InterfaceClass constructor. iface = InterfaceClass('%s_IRequest' % name, bases=bases, __doc__="route_request_iface-generated interface") # for exception view lookups iface.combined = InterfaceClass( '%s_combined_IRequest' % name, bases=(iface, IRequest), __doc__ = 'route_request_iface-generated combined interface') return iface
def wrapSchema(self, sch, field, hfields): wschema = InterfaceClass(sch.__name__, (interface.Interface,), __doc__ = sch.__doc__, __module__ = 'memphisttw.schema.schemas') for name, fld in schema.getFieldsInOrder(sch): if name in self.skipFields or name in hfields: continue mfield = self.mapField(name, fld) if mfield is not None: fld = mfield( __name__ = name, title = fld.title, description = fld.description, required = False) if fld.__class__ == schema.Field: continue wschema._InterfaceClass__attrs[name] = fld return wschema
def __init__(self, *arg, **kw): try: attrs = arg[2] or {} except IndexError: attrs = kw.get('attrs', {}) # get class attribute values and remove them si = attrs.pop('source_integrity', False) ti = attrs.pop('target_integrity', False) so = attrs.pop('source_ordered', False) to = attrs.pop('target_ordered', False) sif = attrs.pop('source_isheet', ISheet) sifa = attrs.pop('source_isheet_field', u'') tif = attrs.pop('target_isheet', ISheet) # initialize interface class InterfaceClass.__init__(self, *arg, **kw) # set tagged values based on attribute values self.setTaggedValue('source_integrity', si) self.setTaggedValue('target_integrity', ti) self.setTaggedValue('source_ordered', so) self.setTaggedValue('target_ordered', to) self.setTaggedValue('source_isheet', sif) self.setTaggedValue('source_isheet_field', sifa) self.setTaggedValue('target_isheet', tif)
def __call__(self, other, default=_notag): """ XXX use TypedInterfaceConfigurable as a fallback if this interface doesn't work for some reason """ result = InterfaceClass.__call__(self, other, _notag) if result is not _notag: return result from formless.annotate import TypedInterface if TypedInterface.providedBy(other): from formless.configurable import TypedInterfaceConfigurable return TypedInterfaceConfigurable(other) if default is _notag: raise TypeError('Could not adapt', other, self) return default
def register_settings(name, *fields, **kw): """Register settings group. :param name: Name of settings group :param fields: List of :py:class:`ptah.form.Field` objects """ iname = name for ch in ('.', '-'): iname = iname.replace(ch, '_') category = InterfaceClass('SettingsGroup:%s' % iname.upper(), (), __doc__='Settings group: %s' % name, __module__='ptah.config.settings') for field in fields: field.required = False field.missing = field.default if field.default is form.null: raise StopException( 'Default value is required for "{0}.{1}"'.format( name, field.name)) group = Group(name=name, *fields, **kw) interface.directlyProvides(Group, category) info = config.DirectiveInfo() discr = (ID_SETTINGS_GROUP, name) intr = config.Introspectable(ID_SETTINGS_GROUP, discr, group.__title__, 'ptah-settingsgroup') intr['name'] = name intr['group'] = group intr['codeinfo'] = info.codeinfo info.attach( config.Action( lambda config, group: config.get_cfg_storage(ID_SETTINGS_GROUP)\ .update({group.__name__: group.clone(config.registry)}), (group,), discriminator=discr, introspectables=(intr,)) )
def __call__(self, name, module): if name.startswith('__'): return None global loaded # use schema-saver to get interface signature = name[1:] # "I[md5hex]" -> "[md5hex]" if signature in loaded: return loaded[signature] saver = queryUtility(ISchemaSaver) if signature in saver: schema = saver.load(saver.get(signature)) # schema/iface object loaded[signature] = schema else: # otherwise load a placeholder interface logger.warning('SignatureSchemaFactory: ' 'Unable to obtain dynamic schema from ' 'serialization; using placeholder.') schema = InterfaceClass( name, (Interface), __module__=module.__name__, ) # placeholder (anonymous marker) interface return schema
def create_content_factory(proto_name, proto_definition): parent_interface = import_class( proto_definition.get("inherited_interface", "guillotina.interfaces.content.IFolder")) parent_class = import_class( proto_definition.get("inherited_class", "guillotina.content.Folder")) schema_fields, tags = get_fields( properties=proto_definition.get("properties")) class_interface = InterfaceClass( "I" + proto_name, (parent_interface, ), schema_fields, __module__="guillotina.contrib.dyncontent.interfaces", ) for field_id, tag in tags.items(): for tag_id, tag_metadata in tag.items(): if tag_id in SUPPORTED_DIRECTIVES: if tag_metadata is None: SUPPORTED_DIRECTIVES[tag_id].apply(class_interface, field_id) elif isinstance(tag_metadata, dict): SUPPORTED_DIRECTIVES[tag_id].apply(class_interface, field_id, **tag_metadata) elif isinstance(tag_metadata, list): SUPPORTED_DIRECTIVES[tag_id].apply(class_interface, field_id, *tag_metadata) elif tag_id == "fieldset": SUPPORTED_DIRECTIVES[tag_id].apply(class_interface, field_id, tag_metadata) elif isinstance(tag_metadata, str): SUPPORTED_DIRECTIVES[tag_id].apply( class_interface, **{field_id: tag_metadata}) klass = type(proto_name, (parent_class, ), {}) klass.__module__ = "guillotina.contrib.dyncontent.contents" setattr(contents, proto_name, klass) behaviors = [] for bhr in proto_definition.get("behaviors", []): if bhr in BEHAVIOR_CACHE: behaviors.append(BEHAVIOR_CACHE[bhr]) else: raise Exception(f"Behavior not found {bhr}") contenttype = { "schema": class_interface, "type_name": proto_name, "allowed_types": proto_definition.get("allowed_types", []), "add_permission": proto_definition.get("add_permission", "guillotina.AddContent"), "behaviors": behaviors, } utility = query_utility(IResourceFactory, name=proto_name) if utility is not None: sm = get_global_components() sm.unregisterUtility(utility, IResourceFactory, proto_name) configure.register_configuration(klass, contenttype, "contenttype")
def create(self, cls): name = "I{}".format(cls.__name__) return InterfaceClass(name)
def layer(_context, name=None, interface=None, base=IBrowserRequest): """Provides a new layer. >>> class Context(object): ... info = u'doc' ... def __init__(self): self.actions = [] ... def action(self, **kw): self.actions.append(kw) Possibility 1: The Old Way -------------------------- >>> context = Context() >>> layer(context, u'layer1') >>> iface = context.actions[0]['args'][1] >>> iface.getName() 'layer1' >>> ILayer.providedBy(iface) True >>> hasattr(sys.modules['zope.app.layers'], 'layer1') True >>> del sys.modules['zope.app.layers'].layer1 Possibility 2: Providing a custom base interface ------------------------------------------------ >>> class BaseLayer(IBrowserRequest): ... pass >>> context = Context() >>> layer(context, u'layer1', base=BaseLayer) >>> iface = context.actions[0]['args'][1] >>> iface.getName() 'layer1' >>> iface.__bases__ (<InterfaceClass zope.app.publisher.browser.metaconfigure.BaseLayer>,) >>> hasattr(sys.modules['zope.app.layers'], 'layer1') True >>> del sys.modules['zope.app.layers'].layer1 Possibility 3: Define a Layer just through an Interface ------------------------------------------------------- >>> class layer1(IBrowserRequest): ... pass >>> context = Context() >>> layer(context, interface=layer1) >>> context.actions[0]['args'][1] is layer1 True >>> hasattr(sys.modules['zope.app.layers'], 'layer1') False Possibility 4: Use an Interface and a Name ------------------------------------------ >>> context = Context() >>> layer(context, name='layer1', interface=layer1) >>> context.actions[0]['args'][1] is layer1 True >>> hasattr(sys.modules['zope.app.layers'], 'layer1') True >>> import pprint >>> pprint.pprint([action['discriminator'] for action in context.actions]) [('interface', 'zope.app.publisher.browser.metaconfigure.layer1'), ('layer', 'layer1')] Here are some disallowed configurations. >>> context = Context() >>> layer(context, 'foo,bar') Traceback (most recent call last): ... TypeError: Commas are not allowed in layer names. >>> layer(context) Traceback (most recent call last): ... ConfigurationError: You must specify the 'name' or 'interface' attribute. >>> layer(context, base=BaseLayer) Traceback (most recent call last): ... ConfigurationError: You must specify the 'name' or 'interface' attribute. >>> layer(context, interface=layer1, base=BaseLayer) Traceback (most recent call last): ... ConfigurationError: You cannot specify the 'interface' and 'base' together. """ if name is not None and "," in name: raise TypeError("Commas are not allowed in layer names.") if name is None and interface is None: raise ConfigurationError("You must specify the 'name' or 'interface' attribute.") if interface and not interface.extends(IBrowserRequest): raise ConfigurationError("The layer interface must extend `IBrowserRequest`.") if base is not IBrowserRequest and not base.extends(IBrowserRequest): raise ConfigurationError("The base interface must extend `IBrowserRequest`.") if interface is not None and base is not IBrowserRequest: raise ConfigurationError("You cannot specify the 'interface' and 'base' together.") if interface is None: interface = InterfaceClass(str(name), (base,), __doc__="Layer: %s" % str(name), __module__="zope.app.layers") # Add the layer to the layers module. # Note: We have to do this immediately, so that directives using the # InterfaceField can find the layer. setattr(zope.app.layers, name, interface) path = "zope.app.layers." + name else: path = interface.__module__ + "." + interface.getName() # If a name was specified, make this layer available under this name. # Note that the layer will be still available under its path, since it # is an adapter, and the `LayerField` can resolve paths as well. if name is None: name = path else: # Make the interface available in the `zope.app.layers` module, so # that other directives can find the interface under the name # before the CA is setup. setattr(zope.app.layers, name, interface) # Register the layer interface as an interface _context.action( discriminator=("interface", path), callable=provideInterface, args=(path, interface), kw={"info": _context.info} ) directlyProvides(interface, ILayer) # Register the layer interface as a layer _context.action( discriminator=("layer", name), callable=provideInterface, args=(name, interface, ILayer, _context.info) )
class IMyInterface(Interface): __module__ = 'zodbbrowser.nosuchmodule' class IMyGoodInterface(Interface): pass class NotAnInterface(object): """A stand in for a ZODB Broken object""" __module__ = 'zodbbrowser.nosuchmodule' __name__ = 'NotAnInterface' FixedNotAnInterface = InterfaceClass( 'NotAnInterface', __module__='broken zodbbrowser.nosuchmodule') class CrashOnUnpickling(object): def __getstate__(self): return {} def __setstate__(self, state): raise Exception('oops') class TestFlattenInterfaces(unittest.TestCase): def test(self): self.assertEqual( flatten_interfaces([ IMyGoodInterface, NotAnInterface,
def __init__(self, name, bases=(), attrs=None, __doc__=None, __module__=None): InterfaceClass.__init__(self, name, bases, attrs, __doc__, __module__)
def __init__(self, name): InterfaceClass.__init__(self, name, (Interface,)) Baz.__init__(self, name)
def parse(source, policy=u""): tree = ElementTree.parse(source) root = tree.getroot() model = Model() handlers = {} schema_metadata_handlers = tuple(getUtilitiesFor(ISchemaMetadataHandler)) field_metadata_handlers = tuple(getUtilitiesFor(IFieldMetadataHandler)) policy_util = getUtility(ISchemaPolicy, name=policy) def readField(fieldElement, schemaAttributes, fieldElements, baseFields): # Parse field attributes fieldName = fieldElement.get('name') fieldType = fieldElement.get('type') if fieldName is None or fieldType is None: raise ValueError("The attributes 'name' and 'type' are required for each <field /> element") handler = handlers.get(fieldType, None) if handler is None: handler = handlers[fieldType] = queryUtility(IFieldExportImportHandler, name=fieldType) if handler is None: raise ValueError("Field type %s specified for field %s is not supported" % (fieldType, fieldName, )) field = handler.read(fieldElement) # Preserve order from base interfaces if this field is an override # of a field with the same name in a base interface base_field = baseFields.get(fieldName, None) if base_field is not None: field.order = base_field.order # Save for the schema schemaAttributes[fieldName] = field fieldElements[fieldName] = fieldElement return fieldName for schema_element in root.findall(ns('schema')): schemaAttributes = {} schema_metadata = {} schemaName = schema_element.get('name') if schemaName is None: schemaName = u"" bases = () baseFields = {} based_on = schema_element.get('based-on') if based_on is not None: bases = tuple([resolve(dotted) for dotted in based_on.split()]) for base_schema in bases: baseFields.update(getFields(base_schema)) fieldElements = {} # Read global fields for fieldElement in schema_element.findall(ns('field')): readField(fieldElement, schemaAttributes, fieldElements, baseFields) # Read fieldsets and their fields fieldsets = [] fieldsets_by_name = {} for subelement in schema_element: if subelement.tag == ns('field'): readField(subelement, schemaAttributes, fieldElements, baseFields) elif subelement.tag == ns('fieldset'): fieldset_name = subelement.get('name') if fieldset_name is None: raise ValueError(u"Fieldset in schema %s has no name" % (schemaName)) fieldset = fieldsets_by_name.get(fieldset_name, None) if fieldset is None: fieldset_label = subelement.get('label') fieldset_description = subelement.get('description') fieldset = fieldsets_by_name[fieldset_name] = Fieldset(fieldset_name, label=fieldset_label, description=fieldset_description) fieldsets_by_name[fieldset_name] = fieldset fieldsets.append(fieldset) for fieldElement in subelement.findall(ns('field')): parsed_fieldName = readField(fieldElement, schemaAttributes, fieldElements, baseFields) if parsed_fieldName: fieldset.fields.append(parsed_fieldName) schema = InterfaceClass(name=policy_util.name(schemaName, tree), bases=bases + policy_util.bases(schemaName, tree), __module__=policy_util.module(schemaName, tree), attrs=schemaAttributes) schema.setTaggedValue(FIELDSETS_KEY, fieldsets) # Save fieldsets # Let metadata handlers write metadata for handler_name, metadata_handler in field_metadata_handlers: for fieldName in schema: if fieldName in fieldElements: metadata_handler.read(fieldElements[fieldName], schema, schema[fieldName]) for handler_name, metadata_handler in schema_metadata_handlers: metadata_handler.read(schema_element, schema) model.schemata[schemaName] = schema return model
def create_behaviors_factory(proto_name, proto_definition): if proto_definition.get('for', None) is None: raise Exception('We need a for interface') else: for_ = import_class(proto_definition.get('for')) if for_ is None: raise Exception('Wrong for interface') parent_class = import_class( proto_definition.get( 'inherited_class', 'guillotina.behaviors.instance.AnnotationBehavior')) schema_fields, tags = get_fields( properties=proto_definition.get('properties')) base_interface = proto_definition.get('base_interface', None) if base_interface is None: base_interface = Interface class_interface = InterfaceClass('I' + proto_name, (base_interface, ), schema_fields, __module__='guillotina_cms.interfaces') for field_id, tag in tags.items(): for tag_id, tag_metadata in tag.items(): if tag_id in SUPPORTED_DIRECTIVES: SUPPORTED_DIRECTIVES[tag_id].apply(class_interface, field_id, tag_metadata) klass = type(proto_name, (parent_class, ), {}) klass.__module__ = 'guillotina_cms.behaviors' behavior = { 'for_': for_, 'provides': class_interface, 'data_key': proto_definition.get('data_key', 'default'), 'auto_serialize': proto_definition.get('auto_serialize', True), 'name': proto_name, 'name_only': proto_definition.get('name_only', False), 'title': proto_definition.get('title', ''), 'marker': proto_definition.get('marker', None), 'description': proto_definition.get('description', '') } configure.register_configuration(klass, behavior, 'behavior') root = get_utility(IApplication, name='root') configure.load_configuration(root.app.config, 'guillotina_cms.behaviors', 'behavior') root.app.config.execute_actions() configure.clear() load_cached_schema() # Verify its created interface_name = 'guillotina_cms.interfaces.I' + proto_name utility = get_utility(IBehavior, name=interface_name) interface_name = 'guillotina_cms.interfaces.I' + proto_name utility2 = get_utility(IBehavior, name=proto_name) assert BEHAVIOR_CACHE[interface_name] == class_interface utility.interface == class_interface utility2.interface == class_interface
def create_content_factory(proto_name, proto_definition): parent_interface = import_class( proto_definition.get('inherited_interface', 'guillotina.interfaces.content.IFolder')) parent_class = import_class( proto_definition.get('inherited_class', 'guillotina.content.Folder')) schema_fields, tags = get_fields( properties=proto_definition.get('properties')) for fieldset_id, fieldset_list in proto_definition.get('fieldsets', {}).items(): for field_id in fieldset_list: tags.setdefault(field_id, {})['fieldset'] = fieldset_id class_interface = InterfaceClass('I' + proto_name, (parent_interface, ), schema_fields, __module__='guillotina_cms.interfaces') for field_id, tag in tags.items(): for tag_id, tag_metadata in tag.items(): if tag_id in SUPPORTED_DIRECTIVES: if tag_metadata is None: SUPPORTED_DIRECTIVES[tag_id].apply(class_interface, field_id) elif isinstance(tag_metadata, dict): SUPPORTED_DIRECTIVES[tag_id].apply(class_interface, field_id, **tag_metadata) elif isinstance(tag_metadata, list): SUPPORTED_DIRECTIVES[tag_id].apply(class_interface, field_id, *tag_metadata) elif tag_id == 'fieldset': SUPPORTED_DIRECTIVES[tag_id].apply(class_interface, field_id, tag_metadata) elif isinstance(tag_metadata, str): SUPPORTED_DIRECTIVES[tag_id].apply( class_interface, **{field_id: tag_metadata}) klass = type(proto_name, (parent_class, ), {}) klass.__module__ = 'guillotina_cms.dyncontent' setattr(dyncontent, proto_name, klass) behaviors = [] for bhr in proto_definition.get('behaviors', []): if bhr in BEHAVIOR_CACHE: behaviors.append(BEHAVIOR_CACHE[bhr]) else: raise Exception(f"Behavior not found {bhr}") contenttype = { 'schema': class_interface, 'type_name': proto_name, 'allowed_types': proto_definition.get('allowed_types', []), 'add_permission': proto_definition.get('add_permission', 'guillotina.AddContent'), 'behaviors': behaviors } utility = query_utility(IResourceFactory, name=proto_name) if utility is not None: sm = get_global_components() sm.unregisterUtility(utility, IResourceFactory, proto_name) configure.register_configuration(klass, contenttype, 'contenttype') root = get_utility(IApplication, name='root') configure.load_configuration(root.app.config, 'guillotina_cms.dyncontent', 'contenttype') root.app.config.execute_actions() configure.clear() load_cached_schema() # Verify its created if proto_name in FACTORY_CACHE: del FACTORY_CACHE[proto_name] get_cached_factory(proto_name)
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # ############################################################################## """Test tree item filters. """ import unittest from zope.interface import directlyProvides from zope.interface.interface import InterfaceClass from zope.app.tree.filters import OnlyInterfacesFilter, AllButInterfacesFilter from .test_adapters import SampleContent IRobot = InterfaceClass('IRobot', (), {}) IHuman = InterfaceClass('IHuman', (), {}) IAlien = InterfaceClass('IAlien', (), {}) ISpaceShipCaptain = InterfaceClass('ISpaceShipCaptain', (), {}) IDeliveryBoy = InterfaceClass('IDeliveryBoy', (IHuman, ), {}) IProfessor = InterfaceClass('IProfessor', (IHuman, ), {}) class FilterTestCase(unittest.TestCase): def setUp(self): self.makeObjects() def makeObjects(self): to_be_made = { 'bender': IRobot, 'fry': IDeliveryBoy,
return self.__abc def getRegisteredConformers(self): """ Return an iterable of the classes that are known to conform to the ABC this interface parallels. """ based_on = self.__abc # The registry only contains things that aren't already # known to be subclasses of the ABC. But the ABC is in charge # of checking that, so its quite possible that registrations # are in fact ignored, winding up just in the _abc_cache. try: registered = list(based_on._abc_registry) + list(based_on._abc_cache) except AttributeError: # Rewritten in C in CPython 3.7. # These expose the underlying weakref. from abc import _get_dump data = _get_dump(based_on) registry = data[0] cache = data[1] registered = [x() for x in itertools.chain(registry, cache)] registered = [x for x in registered if x is not None] return set(itertools.chain(registered, self.__extra_classes)) ABCInterface = ABCInterfaceClass.__new__(ABCInterfaceClass, None, None, None) InterfaceClass.__init__(ABCInterface, 'ABCInterface', (Interface,), {})
) for attacher in actionAttachers: attacher.attachActionBindings(possibleActions) methods.sort(key=lambda x: x.id) properties.sort(key=lambda x: x.id) cls.__spec__ = spec = methods + properties spec.sort(key=lambda x: x.id) cls.name = name # because attributes "label" and "description" would become Properties, # check for ones with an underscore prefix. cls.label = dct.get('_label', None) cls.description = dct.get('_description', None) defaultLabel, defaultDescription = labelAndDescriptionFromDocstring(dct.get('__doc__')) if defaultLabel is None: defaultLabel = nameToLabel(name) if cls.label is None: cls.label = defaultLabel if cls.description is None: cls.description = defaultDescription return rv ####################################### ## External API; subclass this to create a TypedInterface ####################################### TypedInterface = MetaTypedInterface('TypedInterface', (InterfaceClass('TypedInterface'), ), {})
def __new__(cls, name, bases, dct): rv = cls = InterfaceClass.__new__(cls) cls.__id__ = nextId() cls.__methods__ = methods = [] cls.__properties__ = properties = [] cls.default = 'DEFAULT' cls.complexType = True possibleActions = [] actionAttachers = [] for key, value in list(dct.items()): if key[0] == '_': continue if isinstance(value, MetaTypedInterface): ## A Nested TypedInterface indicates a GroupBinding properties.append(GroupBinding(key, value, value.__id__)) ## zope.interface doesn't like these del dct[key] setattr(cls, key, value) elif isinstance(value, collections.Callable): names, _, _, typeList = inspect.getargspec(value) _testCallArgs = () if typeList is None: typeList = [] if len(names) == len(typeList) + 1: warnings.warn( "TypeInterface method declarations should not have a 'self' parameter", DeprecationWarning, stacklevel=2) del names[0] _testCallArgs = (_Marker,) if len(names) != len(typeList): ## Allow non-autocallable methods in the interface; ignore them continue argumentTypes = [ Argument(n, argtype, argtype.id) for n, argtype in zip(names[-len(typeList):], typeList) ] result = value(*_testCallArgs) label = None description = None if getattr(value, 'autocallable', None): # autocallables have attributes that can set label and description label = value.attributes.get('label', None) description = value.attributes.get('description', None) adapted = iformless.ITyped(result, None) if adapted is None: adapted = Object(result) # ITyped has label and description we can use if label is None: label = adapted.label if description is None: description = adapted.description defaultLabel, defaultDescription = labelAndDescriptionFromDocstring(value.__doc__) if defaultLabel is None: # docstring had no label, try the action if it is an autocallable if getattr(value, 'autocallable', None): if label is None and value.action is not None: # no explicit label, but autocallable has action we can use defaultLabel = value.action if defaultLabel is None: # final fallback: use the function name as label defaultLabel = nameToLabel(key) if label is None: label = defaultLabel if description is None: description = defaultDescription theMethod = Method( adapted, argumentTypes, label=label, description=description ) if getattr(value, 'autocallable', None): methods.append( MethodBinding( key, theMethod, value.id, value.action, value.attributes)) else: possibleActions.append((value, MethodBinding(key, theMethod))) else: if not value.label: value.label = nameToLabel(key) if iformless.IActionableType.providedBy(value): actionAttachers.append(value) properties.append( Property(key, value, value.id) ) for attacher in actionAttachers: attacher.attachActionBindings(possibleActions) methods.sort(key=_sorter) properties.sort(key=_sorter) cls.__spec__ = spec = methods + properties spec.sort(key=_sorter) cls.name = name # because attributes "label" and "description" would become Properties, # check for ones with an underscore prefix. cls.label = dct.get('_label', None) cls.description = dct.get('_description', None) defaultLabel, defaultDescription = labelAndDescriptionFromDocstring(dct.get('__doc__')) if defaultLabel is None: defaultLabel = nameToLabel(name) if cls.label is None: cls.label = defaultLabel if cls.description is None: cls.description = defaultDescription return rv
def GenerateContainer( ctx, container_name=None, container_iname=None, base_interfaces=() ): """ generate a zope3 container class for a domain model """ # create container container_name = container_name or \ ctx.domain_model.__name__ + 'Container' # allow passing in dotted python path if isinstance( ctx.container_module, (str, unicode) ): ctx.container_module = resolve( ctx.container_module ) # if not present use the domain class's module elif ctx.container_module is None: ctx.container_module = resolve( ctx.domain_model.__module__ ) # sanity check we have a module for the container assert isinstance(ctx.container_module, types.ModuleType ), "Invalid Container" # logging variables msg = ( ctx.domain_model.__name__, ctx.container_module.__name__, container_name ) # if we already have a container class, exit if getattr( ctx.container_module, container_name, None ): if ctx.echo: ctx.logger.debug("%s: found container %s.%s, skipping"%msg ) ctx.container_class = getattr( ctx.container_module, container_name ) return if ctx.echo: ctx.logger.debug("%s: generated container %s.%s"%msg ) # if we already have a container class, exit container_class = type( container_name, (AlchemistContainer,), dict(_class=ctx.domain_model, __module__=ctx.container_module.__name__ ) ) setattr( ctx.container_module, container_name, container_class) # save container class on catalyst context ctx.container_class = container_class # interface for container container_iname = container_iname or "I%s"%container_name # if the interface module is none, then use the nearest one to the domain class if ctx.interface_module is None: ispec = ctx.domain_model.__module__.rsplit('.',1)[0]+'.interfaces' ctx.interface_module = resolve( ispec ) msg = ( ctx.domain_model.__name__, ctx.container_module.__name__, container_iname ) # if we already have a container interface class, skip creation container_interface = getattr( ctx.interface_module, container_iname, None ) if container_interface is not None: assert issubclass( container_interface, IAlchemistContainer ) if ctx.echo: ctx.logger.debug("%s: skipping container interface %s.%s for"%msg ) else: if ctx.echo: ctx.logger.debug("%s: generated container interface %s.%s"%msg ) # ensure that our base interfaces include alchemist container if base_interfaces: assert isinstance( base_interfaces, tuple ) found = False for bi in base_interfaces: found = issubclass( bi, IAlchemistContainer ) if found: break if not found: base_interfaces = base_interfaces + ( IAlchemistContainer,) else: base_interfaces = ( IAlchemistContainer, ) # create interface container_interface = InterfaceClass( container_iname, bases = base_interfaces, __module__ = ctx.interface_module.__name__ ) # store container interface for catalyst ctx.container_interface = container_interface setattr( ctx.interface_module, container_iname, container_interface ) # setup security for n,d in container_interface.namesAndDescriptions(1): protectName( container_class, n, "zope.Public") if not container_interface.implementedBy(container_class): interface.classImplements(container_class, container_interface) ctx.container_interface = container_interface
def route_request_iface(name, bases=()): iface = InterfaceClass('%s_IRequest' % name, bases=bases) # for exception view lookups iface.combined = InterfaceClass('%s_combined_IRequest' % name, bases=(iface, IRequest)) return iface
def __init__(self, name, bases=(), attrs=None, __doc__=None, __module__=None): InterfaceClass.__init__(self, name, bases, attrs, __doc__, __module__) self._SchemaClass_finalize()
def __init__(self, *args, **kw): Persistent.__init__(self) InterfaceClass.__init__(self, *args, **kw) self.dependents = FlexibleWeakKeyDictionary()
def __new__(cls, name, bases, dct): rv = cls = InterfaceClass.__new__(cls) cls.__id__ = nextId() cls.__methods__ = methods = [] cls.__properties__ = properties = [] cls.default = 'DEFAULT' cls.complexType = True possibleActions = [] actionAttachers = [] for key, value in dct.items(): if key[0] == '_': continue if isinstance(value, MetaTypedInterface): ## A Nested TypedInterface indicates a GroupBinding properties.append(GroupBinding(key, value, value.__id__)) ## zope.interface doesn't like these del dct[key] setattr(cls, key, value) elif callable(value): names, _, _, typeList = inspect.getargspec(value) _testCallArgs = () if typeList is None: typeList = [] if len(names) == len(typeList) + 1: warnings.warn( "TypeInterface method declarations should not have a 'self' parameter", DeprecationWarning, stacklevel=2) del names[0] _testCallArgs = (_Marker, ) if len(names) != len(typeList): ## Allow non-autocallable methods in the interface; ignore them continue argumentTypes = [ Argument(n, argtype, argtype.id) for n, argtype in zip(names[-len(typeList):], typeList) ] result = value(*_testCallArgs) label = None description = None if getattr(value, 'autocallable', None): # autocallables have attributes that can set label and description label = value.attributes.get('label', None) description = value.attributes.get('description', None) adapted = iformless.ITyped(result, None) if adapted is None: adapted = Object(result) # ITyped has label and description we can use if label is None: label = adapted.label if description is None: description = adapted.description defaultLabel, defaultDescription = labelAndDescriptionFromDocstring( value.__doc__) if defaultLabel is None: # docstring had no label, try the action if it is an autocallable if getattr(value, 'autocallable', None): if label is None and value.action is not None: # no explicit label, but autocallable has action we can use defaultLabel = value.action if defaultLabel is None: # final fallback: use the function name as label defaultLabel = nameToLabel(key) if label is None: label = defaultLabel if description is None: description = defaultDescription theMethod = Method(adapted, argumentTypes, label=label, description=description) if getattr(value, 'autocallable', None): methods.append( MethodBinding(key, theMethod, value.id, value.action, value.attributes)) else: possibleActions.append( (value, MethodBinding(key, theMethod))) else: if not value.label: value.label = nameToLabel(key) if iformless.IActionableType.providedBy(value): actionAttachers.append(value) properties.append(Property(key, value, value.id)) for attacher in actionAttachers: attacher.attachActionBindings(possibleActions) methods.sort(_sorter) properties.sort(_sorter) cls.__spec__ = spec = methods + properties spec.sort(_sorter) cls.name = name # because attributes "label" and "description" would become Properties, # check for ones with an underscore prefix. cls.label = dct.get('_label', None) cls.description = dct.get('_description', None) defaultLabel, defaultDescription = labelAndDescriptionFromDocstring( dct.get('__doc__')) if defaultLabel is None: defaultLabel = nameToLabel(name) if cls.label is None: cls.label = defaultLabel if cls.description is None: cls.description = defaultDescription return rv
import pyperf from zope.interface import Interface from zope.interface import classImplements from zope.interface import implementedBy from zope.interface.interface import InterfaceClass from zope.interface.registry import Components # Long, mostly similar names are a worst case for equality # comparisons. ifaces = [ InterfaceClass('I' + ('0' * 20) + str(i), (Interface, ), {}) for i in range(100) ] class IWideInheritance(*ifaces): """ Inherits from 100 unrelated interfaces. """ class WideInheritance(object): pass classImplements(WideInheritance, IWideInheritance) def make_deep_inheritance(): children = []
def onDiscovery(self, theme, settings, dependenciesSettings): layer = InterfaceClass(theme, (Interface,), __module__=schemata.__name__) setattr(schemata, theme, layer)
def skin(_context, name=None, interface=None, layers=None): """Provides a new skin. >>> import pprint >>> class Context(object): ... info = u'doc' ... def __init__(self): self.actions = [] ... def action(self, **kw): self.actions.append(kw) >>> class Layer1(ILayer): pass >>> class Layer2(ILayer): pass Possibility 1: The Old Way -------------------------- >>> context = Context() >>> skin(context, u'skin1', layers=[Layer1, Layer2]) >>> iface = context.actions[3]['args'][1] >>> iface.getName() 'skin1' >>> pprint.pprint(iface.__bases__) (<InterfaceClass zope.app.publisher.browser.metaconfigure.Layer1>, <InterfaceClass zope.app.publisher.browser.metaconfigure.Layer2>) >>> hasattr(sys.modules['zope.app.skins'], 'skin1') True >>> del sys.modules['zope.app.skins'].skin1 Possibility 2: Just specify an interface ---------------------------------------- >>> class skin1(Layer1, Layer2): ... pass >>> context = Context() >>> skin(context, interface=skin1) >>> context.actions[0]['args'][1] is skin1 True Possibility 3: Specify an interface and a Name ---------------------------------------------- >>> context = Context() >>> skin(context, name='skin1', interface=skin1) >>> context.actions[0]['args'][1] is skin1 True >>> import pprint >>> pprint.pprint([action['discriminator'] for action in context.actions]) [('skin', 'skin1'), ('interface', 'zope.app.publisher.browser.metaconfigure.skin1'), ('skin', 'zope.app.publisher.browser.metaconfigure.skin1')] Here are some disallowed configurations. >>> context = Context() >>> skin(context) Traceback (most recent call last): ... ConfigurationError: You must specify the 'name' or 'interface' attribute. >>> skin(context, layers=[Layer1]) Traceback (most recent call last): ... ConfigurationError: You must specify the 'name' or 'interface' attribute. """ if name is None and interface is None: raise ConfigurationError("You must specify the 'name' or 'interface' attribute.") if name is not None and layers is not None: interface = InterfaceClass(str(name), layers, __doc__="Skin: %s" % str(name), __module__="zope.app.skins") # Add the layer to the skins module. # Note: We have to do this immediately, so that directives using the # InterfaceField can find the layer. setattr(zope.app.skins, name, interface) path = "zope.app.skins" + name # Register the layers for layer in layers: _context.action( discriminator=None, callable=provideInterface, args=(layer.getName(), layer, ILayer, _context.info) ) else: path = interface.__module__ + "." + interface.getName() # Register the skin interface as a skin using the passed name. if name is not None: _context.action( discriminator=("skin", name), callable=provideInterface, args=(name, interface, ISkin, _context.info) ) name = path # Register the skin interface as an interface _context.action( discriminator=("interface", path), callable=provideInterface, args=(path, interface), kw={"info": _context.info} ) # Register the skin interface as a skin _context.action( discriminator=("skin", name), callable=provideInterface, args=(name, interface, ISkin, _context.info) )
for attacher in actionAttachers: attacher.attachActionBindings(possibleActions) methods.sort(_sorter) properties.sort(_sorter) cls.__spec__ = spec = methods + properties spec.sort(_sorter) cls.name = name # because attributes "label" and "description" would become Properties, # check for ones with an underscore prefix. cls.label = dct.get('_label', None) cls.description = dct.get('_description', None) defaultLabel, defaultDescription = labelAndDescriptionFromDocstring( dct.get('__doc__')) if defaultLabel is None: defaultLabel = nameToLabel(name) if cls.label is None: cls.label = defaultLabel if cls.description is None: cls.description = defaultDescription return rv ####################################### ## External API; subclass this to create a TypedInterface ####################################### TypedInterface = MetaTypedInterface('TypedInterface', (InterfaceClass('TypedInterface'), ), {})
def __init__(self, *args, **kw): Persistent.__init__(self) InterfaceClass.__init__(self, *args, **kw) self.dependents = PersistentDict()