Beispiel #1
0
 def __get__(self, inst, cls=None):
     global generated
     if inst is None:
         return getObjectSpecification(cls)
     spec = getattr(inst, '__provides__', None)
     if spec is None:
         spec = implementedBy(cls)
     signature = getattr(inst, 'signature', None)
     if signature is None:
         return spec
     if not ismd5hex(signature):
         if not isdottedname(signature):
             return spec
         # not an md5 signature, so perhaps we have a dotted name
         try:
             iface = resolve(signature)
             if not IInterface.providedBy(iface):
                 raise ValueError('Not interface: %s' % signature)
             return Implements(iface, spec)
         except ImportError:
             logger.warning('SignatureAwareDescriptor: '
                            'unabled to resolve interface '
                            '%s by dotted name.')
             return spec
     iface_name = 'I%s' % signature
     dynamic = [getattr(generated, iface_name)]
     dynamic.append(spec)
     spec = Implements(*dynamic)
     return spec
Beispiel #2
0
 def __get__(self, inst, cls=None):
     if inst is None:
         return getObjectSpecification(cls)
     else:
         provided = providedBy(inst._IndexableObjectWrapper__ob)
         cls = type(inst)
         return ObjectSpecification(provided, cls)
Beispiel #3
0
    def __get__(self, inst, cls=None):
        # We're looking at a class - fall back on default
        if inst is None:
            return getObjectSpecification(cls)

        # Find the cached value.
        cache = getattr(inst, "_v__providedBy__", None)

        # Find the data we need to know if our cache needs to be invalidated
        provided = link_provides = getattr(inst._context, "__provides__", None)

        # See if we have a valid cache, and if so return it
        if cache is not None:
            cached_mtime, cached_provides, cached_provided = cache

            if inst._p_mtime == cached_mtime and link_provides is cached_provides:
                return cached_provided

        # If the instance doesn't have a __provides__ attribute, get the
        # interfaces implied by the class as a starting point.
        if provided is None:
            provided = implementedBy(cls)

        # Add the interfaces provided by the target, but ensure that some problematic
        # interfaces are removed
        provided += providedBy(
            inst._context) - IIterateAware - IVersioningSupport
        provided += ISymlinkMarker

        inst._v__providedBy__ = inst._p_mtime, link_provides, provided
        return provided
Beispiel #4
0
 def __get__(self, inst, cls=None):
     if inst is None:
         return getObjectSpecification(cls)
     else:
         obj = inst._IndexableObjectWrapper__ob
         provided = providedBy(obj)
         return Provides(type(obj), implementedBy(cls), provided)
Beispiel #5
0
    def __get__(self, inst, cls=None):
        # We're looking at a class - fall back on default
        if inst is None:
            return getObjectSpecification(cls)

        # Find the data we need to know if our cache needs to be invalidated
        direct_spec = getattr(inst, '__provides__', None)

        # If the draft proxy doesn't have a __provides__ attribute, get the
        # interfaces implied by the class as a starting point.
        if direct_spec is None:
            direct_spec = implementedBy(cls)

        # Get the interfaces provided by the target
        target = aq_base(inst.__dict__.get('_DraftProxy__target'))
        if target is None:
            return direct_spec
        target_spec = providedBy(target)

        # Find the cached value
        cache = inst.__dict__.get('_DraftProxy__providedBy__', None)
        updated = target._p_mtime, direct_spec, target_spec

        # See if we have a valid cache. Reasons to do this include:
        if cache is not None:
            cached_mtime, cached_direct_spec, \
                cached_target_spec, cached_spec = cache

            if cache[:-1] == updated:
                return cached_spec

        spec = direct_spec + target_spec
        inst.__dict__['_DraftProxy__providedBy__'] = updated + (spec,)

        return spec
Beispiel #6
0
 def __get__(self, inst, cls=None):
     global generated
     if inst is None:
         return getObjectSpecification(cls)
     spec = getattr(inst, '__provides__', None)
     if spec is None:
         spec = implementedBy(cls)
     signature = getattr(inst, 'signature', None)
     if signature is None:
         return spec
     if not ismd5hex(signature):
         if not isdottedname(signature):
             return spec
         # not an md5 signature, so perhaps we have a dotted name
         try:
             iface = resolve(signature)
             if not IInterface.providedBy(iface):
                 raise ValueError('Not interface: %s' % signature)
             return Implements(iface, spec)
         except ImportError:
             logger.warning('SignatureAwareDescriptor: '
                            'unabled to resolve interface '
                            '%s by dotted name.')
             return spec
     iface_name = 'I%s' % signature
     dynamic = [getattr(generated, iface_name)]
     dynamic.append(spec)
     spec = Implements(*dynamic)
     return spec
Beispiel #7
0
    def __get__(self, inst, cls=None):
        # We're looking at a class - fall back on default
        if inst is None:
            return getObjectSpecification(cls)

        # Find the data we need to know if our cache needs to be invalidated
        direct_spec = getattr(inst, '__provides__', None)

        # If the draft proxy doesn't have a __provides__ attribute, get the
        # interfaces implied by the class as a starting point.
        if direct_spec is None:
            direct_spec = implementedBy(cls)

        # Get the interfaces provided by the target
        target = aq_base(inst.__dict__.get('_DraftProxy__target'))
        if target is None:
            return direct_spec
        target_spec = providedBy(target)

        # Find the cached value
        cache = inst.__dict__.get('_DraftProxy__providedBy__', None)
        updated = target._p_mtime, direct_spec, target_spec

        # See if we have a valid cache. Reasons to do this include:
        if cache is not None:
            cached_mtime, cached_direct_spec, \
                cached_target_spec, cached_spec = cache

            if cache[:-1] == updated:
                return cached_spec

        spec = direct_spec + target_spec
        inst.__dict__['_DraftProxy__providedBy__'] = updated + (spec, )

        return spec
Beispiel #8
0
 def __get__(self, inst, cls=None):
     if inst is None:
         return getObjectSpecification(cls)
     else:
         provided = providedBy(inst._IndexableObjectWrapper__ob)
         cls = type(inst)
         return ObjectSpecification(provided, cls)
Beispiel #9
0
 def __get__(self, inst, cls=None):
     
     # We're looking at a class - fall back on default
     if inst is None:
         return getObjectSpecification(cls)
     
     # Find the cached value and return it if possible
     cached = getattr(inst, '_v__providedBy__', None)
     if cached is not None:
         return cached
     
     # Get interfaces directly provided by the draft proxy
     provided = getattr(inst, '__provides__', None)
     
     # If the draft proxy doesn't have a __provides__ attribute, get the
     # interfaces implied by the class as a starting point.
     if provided is None:
         provided = implementedBy(cls)
     
     # Add the interfaces provided by the target 
     target = aq_base(inst._DraftProxy__target)
     if target is None:
         return provided
     
     provided += providedBy(target)
     
     inst._v__providedBy__ = provided
     return provided
Beispiel #10
0
    def __get__(self, inst, cls=None):
        if inst is None:
            return getObjectSpecification(cls)

        tp = inst.__type__
        cached = getattr(tp, '_v__providedBy', _marker)
        if cached is not _marker:
            return cached

        provided = [implementedBy(inst.__class__)]
        bhreg = AdapterRegistry()
        for behavior in tp.behaviors:
            behavior = queryBehavior(behavior)
            if behavior is not None:
                bhreg.register((), behavior.spec, '', behavior)
                provided.append(behavior.spec)

        schreg = AdapterRegistry()
        for schId in tp.schemas:
            sch = querySchema(schId)
            if sch is not None and sch.spec not in provided:
                schreg.register((), sch.spec, '', sch)
                provided.append(sch.spec)

        spec = Implements(*provided)

        tp._v__providedBy = spec
        tp._v__bhCache = bhreg
        tp._v__schCache = schreg

        return spec
Beispiel #11
0
 def __get__(self, inst, cls=None):
     if inst is None:
         return getObjectSpecification(cls)
     else:
         obj = inst._IndexableObjectWrapper__ob
         provided = providedBy(obj)
         return Provides(
             type(obj), implementedBy(cls), provided)
Beispiel #12
0
    def __get__(self, inst, cls=None):
        # We're looking at a class - fall back on default
        if inst is None:
            return getObjectSpecification(cls)
        
        # Find the data we need to know if our cache needs to be invalidated
        direct_spec = getattr(inst, '__provides__', None)
        portal_type = getattr(inst, 'portal_type', None)
        
        spec = direct_spec

        # If the instance doesn't have a __provides__ attribute, get the
        # interfaces implied by the class as a starting point.
        if spec is None:
            spec = implementedBy(cls)

        # If the instance has no portal type, then we're done.
        if portal_type is None:
            return spec

        fti = queryUtility(IDexterityFTI, name=portal_type)
        if fti is None:
            return spec

        schema = SCHEMA_CACHE.get(portal_type)
        subtypes = SCHEMA_CACHE.subtypes(portal_type)

        # Find the cached value. This calculation is expensive and called
        # hundreds of times during each request, so we require a fast cache
        cache = getattr(inst, '_v__providedBy__', None)
        updated = inst._p_mtime, schema, subtypes, direct_spec

        # See if we have a valid cache. Reasons to do this include:
        #
        #  - The schema was modified.
        #  - The subtypes were modified.
        #  - The instance was modified and persisted since the cache was built.
        #  - The instance has a different direct specification.
        if cache is not None:
            cached_mtime, cached_schema, cached_subtypes, \
                cached_direct_spec, cached_spec = cache

            if cache[:-1] == updated:
                return cached_spec

        dynamically_provided = [] if schema is None else [schema]
        dynamically_provided.extend(subtypes)

        # If we have neither a schema, nor a subtype, then we're also done.
        if not dynamically_provided:
            return spec

        dynamically_provided.append(spec)
        spec = Implements(*dynamically_provided)
        inst._v__providedBy__ = updated + (spec, )

        return spec
Beispiel #13
0
    def __get__(self, inst, cls=None):
        # We're looking at a class - fall back on default
        if inst is None:
            return getObjectSpecification(cls)

        # Find the data we need to know if our cache needs to be invalidated
        direct_spec = getattr(inst, '__provides__', None)
        portal_type = getattr(inst, 'portal_type', None)

        spec = direct_spec

        # If the instance doesn't have a __provides__ attribute, get the
        # interfaces implied by the class as a starting point.
        if spec is None:
            spec = implementedBy(cls)

        # If the instance has no portal type, then we're done.
        if portal_type is None:
            return spec

        fti = queryUtility(IDexterityFTI, name=portal_type)
        if fti is None:
            return spec

        schema = SCHEMA_CACHE.get(portal_type)
        subtypes = SCHEMA_CACHE.subtypes(portal_type)

        # Find the cached value. This calculation is expensive and called
        # hundreds of times during each request, so we require a fast cache
        cache = getattr(inst, '_v__providedBy__', None)
        updated = inst._p_mtime, schema, subtypes, direct_spec

        # See if we have a valid cache. Reasons to do this include:
        #
        #  - The schema was modified.
        #  - The subtypes were modified.
        #  - The instance was modified and persisted since the cache was built.
        #  - The instance has a different direct specification.
        if cache is not None:
            cached_mtime, cached_schema, cached_subtypes, \
                cached_direct_spec, cached_spec = cache

            if cache[:-1] == updated:
                return cached_spec

        dynamically_provided = [] if schema is None else [schema]
        dynamically_provided.extend(subtypes)

        # If we have neither a schema, nor a subtype, then we're also done.
        if not dynamically_provided:
            return spec

        dynamically_provided.append(spec)
        spec = Implements(*dynamically_provided)
        inst._v__providedBy__ = updated + (spec, )

        return spec
Beispiel #14
0
    def __get__(self, inst, cls=None):
        if inst is None:
            return getObjectSpecification(cls)
        else:
            provided = providedBy(getProxiedObject(inst))

            # Use type rather than __class__ because inst is a proxy and
            # will return the proxied object's class.
            cls = type(inst)
            return ObjectSpecification(provided, cls)
Beispiel #15
0
    def __get__(self, inst, cls=None):
        if inst is None: # pragma: no cover (Not sure how we can get here)
            return getObjectSpecification(cls)

        provided = providedBy(getProxiedObject(inst))

        # Use type rather than __class__ because inst is a proxy and
        # will return the proxied object's class.
        cls = type(inst)
        return ObjectSpecification(provided, cls)
Beispiel #16
0
    def __get__(self, inst, cls=None):
        if inst is None:  # pragma: no cover (Not sure how we can get here)
            return getObjectSpecification(cls)

        provided = providedBy(getProxiedObject(inst))

        # Use type rather than __class__ because inst is a proxy and
        # will return the proxied object's class.
        cls = type(inst)
        return ObjectSpecification(provided, cls)
Beispiel #17
0
    def __get__(self, inst, cls=None):
        if inst is None:
            return getObjectSpecification(cls)
        else:
            provided = providedBy(getProxiedObject(inst))

            # Use type rather than __class__ because inst is a proxy and
            # will return the proxied object's class.
            cls = type(inst)
            return ObjectSpecification(provided, cls)
Beispiel #18
0
    def __get__(self, inst, cls=None):
        if inst is None:
            return getObjectSpecification(cls)

        request = getRequest()
        annotations = IAnnotations(request)

        try:
            digest = inst.schema_digest
        except AttributeError:
            spec = getattr(inst, '__provides__', None)
            if spec is None:
                return implementedBy(cls)
            else:
                return spec

        # Return cached spec from request
        if not getattr(self, '__recursion__', False):
            spec = annotations.get(self.__class__.__name__ + '.' + digest)
            if spec is not None:
                return spec

        spec = getattr(inst, '__provides__', None)
        if spec is None:
            spec = implementedBy(cls)

        model = load_model(inst.schema, cache_key=inst.schema_digest)
        schemata = [
            model.schemata[name] for name in model.schemata
            if name in [u'', u'++add++']
            or IS_TRANSLATION.match(name.split(u'++add++')[0])
        ]
        schemata.append(spec)

        if getattr(self, '__recursion__', False):
            return Implements(*schemata)

        self.__recursion__ = True
        dynamically_provided = []
        try:
            assignable = IBehaviorAssignable(inst, None)
            if assignable is not None:
                for behavior_registration in assignable.enumerateBehaviors():
                    if behavior_registration.marker:
                        dynamically_provided.append(
                            behavior_registration.marker, )
        finally:
            del self.__recursion__

        schemata.extend(dynamically_provided)
        spec = Implements(*schemata)

        # Cache spec into request
        annotations[self.__class__.__name__ + '.' + digest] = spec
        return spec
Beispiel #19
0
    def __get__(self, inst, cls=None):
        if inst is None:
            return getObjectSpecification(cls)

        request = getRequest()
        annotations = IAnnotations(request)

        # Return cached spec from request
        if inst.__parent__ is not None and inst.__name__ is not None:
            digest = inst.__parent__.schema_digest
            key = '.'.join([self.__class__.__name__, digest, inst.__name__])
            spec = annotations.get(key)
            if spec is not None:
                return spec

            spec = getattr(inst, '__provides__', None)
            if spec is None:
                spec = implementedBy(cls)

            model = load_model(
                aq_base(inst.__parent__).schema,
                cache_key=inst.__parent__.schema_digest,
            )
            schemata = []
            for schema in [
                    model.schemata[name] for name in model.schemata
                    if name == u'' or IS_TRANSLATION.match(name)
            ]:
                try:
                    field = schema[inst.__name__]
                except AttributeError:
                    continue
                try:
                    schemata.append(field.schema)
                except AttributeError:
                    schemata.append(field.value_type.schema)
            schemata.append(spec)

            spec = Implements(*schemata)

            # Cache spec into request
            annotations[key] = spec

        else:

            spec = getattr(inst, '__provides__', None)
            if spec is None:
                spec = implementedBy(cls)

            # Set by FlowSubmissionDataFactory
            schemata = [inst._v_initial_schema, spec]

            spec = Implements(*schemata)

        return spec
Beispiel #20
0
    def __get__(self, inst, cls=None):
        if inst is None:  # pragma: no cover (Not sure how we can get here)
            return getObjectSpecification(cls)

        provided = providedBy(getProxiedObject(inst))

        # Use type rather than __class__ because inst is a proxy and
        # will return the proxied object's class.
        cls = type(inst)
        implemented_by_cls = implementedBy(cls)
        for iface in list(provided):
            if implemented_by_cls.isOrExtends(iface):
                provided = provided - iface
        return Provides(cls, provided)
    def __get__(self, inst, cls=None):

        # We're looking at a class - fall back on default
        if inst is None:
            return getObjectSpecification(cls)

        # Find the cached value.
        cache = getattr(inst, '_v__providedBy__', None)

        # Find the data we need to know if our cache needs to be invalidated
        provided = alias_provides = getattr(inst, '__provides__', None)

        # See if we have a valid cache, and if so return it
        if cache is not None:
            cached_mtime, cached_provides, cached_provided = cache

            if (
                inst._p_mtime == cached_mtime and
                alias_provides is cached_provides
            ):
                return cached_provided

        # If the instance doesn't have a __provides__ attribute, get the
        # interfaces implied by the class as a starting point.
        if provided is None:
            assert cls == Alias # XXX: remove
            provided = implementedBy(cls)

        # Add the interfaces provided by the target
        target = aq_base(inst._target)
        if target is None:
            return provided # don't cache yet!

        # Add the interfaces provided by the target, but take away
        # IHasAlias if set
        provided += providedBy(target) - IHasAlias - IIterateAware

        if ITranslatable:
            provided -= ITranslatable

        inst._v__providedBy__ = inst._p_mtime, alias_provides, provided
        return provided
Beispiel #22
0
    def applyChanges(self, changes):

        names = []
        ispec = list(getObjectSpecification(self).interfaces())[0]
        for field, value in changes.items():

            if value is not None:
                setattr(self, field, value)
                names.append(field)
        if names:
            if ispec:
                description = [zope.lifecycleevent.Attributes(ispec, *names)]
                # Send out a detailed object-modified event
                zope.event.notify(
                    zope.lifecycleevent.ObjectModifiedEvent(
                        self, *description))

            if hasattr(self, 'postApply'):
                self.postApply(changes)

            self.put()
Beispiel #23
0
    def __get__(self, inst, cls=None):

        # We're looking at a class - fall back on default
        if inst is None:
            return getObjectSpecification(cls)

        # Find the cached value.
        cache = getattr(inst, '_v__providedBy__', None)

        # Find the data we need to know if our cache needs to be invalidated
        provided = alias_provides = getattr(inst, '__provides__', None)

        # See if we have a valid cache, and if so return it
        if cache is not None:
            cached_mtime, cached_provides, cached_provided = cache

            if (inst._p_mtime == cached_mtime
                    and alias_provides is cached_provides):
                return cached_provided

        # If the instance doesn't have a __provides__ attribute, get the
        # interfaces implied by the class as a starting point.
        if provided is None:
            assert cls == Alias  # XXX: remove
            provided = implementedBy(cls)

        # Add the interfaces provided by the target
        target = aq_base(inst._target)
        if target is None:
            return provided  # don't cache yet!

        # Add the interfaces provided by the target, but take away
        # IHasAlias if set
        provided += providedBy(target) - IHasAlias - IIterateAware

        if ITranslatable:
            provided -= ITranslatable

        inst._v__providedBy__ = inst._p_mtime, alias_provides, provided
        return provided
Beispiel #24
0
    def __get__(self, inst, cls=None):
        # We're looking at a class - fall back on default
        if inst is None:
            return getObjectSpecification(cls)

        # Find the cached value. This calculation is expensive and called
        # hundreds of times during each request, so we require a fast cache
        cache = getattr(inst, '_v__providedBy__', None)

        # Find the data we need to know if our cache needs to be invalidated

        direct_spec = getattr(inst, '__provides__', None)
        portal_type = getattr(inst, 'portal_type', None)

        fti_counter = -1
        if portal_type is not None:
            fti_counter = SCHEMA_CACHE.counter(portal_type)

        # See if we have a valid cache. Reasons to do this include:
        #
        #  - We don't have a portal_type yet, so we can't have found the schema
        #  - The FTI was modified, and the schema cache invalidated globally.
        #    The fti_counter will have advanced.
        #  - The instance was modified and persisted since the cache was built.
        #  - The instance now has a different __provides__, which means that someone
        #    called directlyProvides/alsoProvides on it.

        if cache is not None and portal_type is not None:
            cached_mtime, cached_fti_counter, cached_direct_spec, cached_spec = cache

            if inst._p_mtime == cached_mtime and \
                    fti_counter == cached_fti_counter and \
                    direct_spec is cached_direct_spec:
                return cached_spec

        # We don't have a cache, so we need to build a new spec and maybe cache it

        spec = direct_spec

        # If the instance doesn't have a __provides__ attribute, get the
        # interfaces implied by the class as a starting point.
        if spec is None:
            spec = implementedBy(cls)

        # Add the schema from the FTI and behavior subtypes

        dynamically_provided = []

        if portal_type is not None:
            schema = SCHEMA_CACHE.get(portal_type)
            if schema is not None:
                dynamically_provided.append(schema)

            subtypes = SCHEMA_CACHE.subtypes(portal_type)
            if subtypes:
                dynamically_provided.extend(subtypes)

        # If we have any dynamically provided interface, prepend them to the spec
        # and cache. We can't cache until we have at least the schema, because
        # it's possible that we were called before traversal and so could not
        # find the schema yet.

        if dynamically_provided:
            dynamically_provided.append(spec)
            spec = Implements(*dynamically_provided)

            inst._v__providedBy__ = inst._p_mtime, SCHEMA_CACHE.counter(
                portal_type), direct_spec, spec

        return spec
Beispiel #25
0
    def __get__(self, inst, cls=None):
        # We're looking at a class - fall back on default
        if inst is None:
            return getObjectSpecification(cls)

        direct_spec = getattr(inst, '__provides__', None)

        # avoid recursion - fall back on default
        if getattr(self, '__recursion__', False):
            return direct_spec

        spec = direct_spec

        # If the instance doesn't have a __provides__ attribute, get the
        # interfaces implied by the class as a starting point.
        if spec is None:
            spec = implementedBy(cls)

        # Find the data we need to know if our cache needs to be invalidated
        portal_type = getattr(inst, 'portal_type', None)

        # If the instance has no portal type, then we're done.
        if portal_type is None:
            return spec

        # Find the cached value. This calculation is expensive and called
        # hundreds of times during each request, so we require a fast cache
        cache = getattr(inst, '_v__providedBy__', None)

        # See if we have a current cache. Reasons to do this include:
        #
        #  - The FTI was modified.
        #  - The instance was modified and persisted since the cache was built.
        #  - The instance has a different direct specification.
        updated = (inst._p_mtime, SCHEMA_CACHE.modified(portal_type),
                   SCHEMA_CACHE.invalidations, hash(direct_spec))
        if cache is not None and cache[:-1] == updated:
            if cache[-1] is not None:
                return cache[-1]
            return spec

        main_schema = SCHEMA_CACHE.get(portal_type)
        if main_schema:
            dynamically_provided = [main_schema]
        else:
            dynamically_provided = []

        # block recursion
        self.__recursion__ = True
        try:
            assignable = IBehaviorAssignable(inst, None)
            if assignable is not None:
                for behavior_registration in assignable.enumerateBehaviors():
                    if behavior_registration.marker:
                        dynamically_provided.append(
                            behavior_registration.marker)
        finally:
            del self.__recursion__

        if not dynamically_provided:
            # rare case if no schema nor behaviors with markers are set
            inst._v__providedBy__ = updated + (None, )
            return spec

        dynamically_provided.append(spec)
        all_spec = Implements(*dynamically_provided)
        inst._v__providedBy__ = updated + (all_spec, )

        return all_spec
Beispiel #26
0
    def __get__(self, inst, cls=None):  # noqa
        # We're looking at a class - fall back on default
        if inst is None:
            return getObjectSpecification(cls)

        direct_spec = getattr(inst, '__provides__', None)

        # avoid recursion - fall back on default
        if getattr(self, '__recursion__', False):
            return direct_spec

        spec = direct_spec

        # If the instance doesn't have a __provides__ attribute, get the
        # interfaces implied by the class as a starting point.
        if spec is None:
            spec = implementedBy(cls)

        # Find the data we need to know if our cache needs to be invalidated
        portal_type = getattr(inst, 'portal_type', None)

        # If the instance has no portal type, then we're done.
        if portal_type is None:
            return spec

        # Find the cached value. This calculation is expensive and called
        # hundreds of times during each request, so we require a fast cache
        cache = getattr(inst, '_v__providedBy__', None)

        # See if we have a current cache. Reasons to do this include:
        #
        #  - The FTI was modified.
        #  - The instance was modified and persisted since the cache was built.
        #  - The instance has a different direct specification.
        updated = (
            inst._p_mtime,
            SCHEMA_CACHE.modified(portal_type),
            SCHEMA_CACHE.invalidations,
            hash(direct_spec)
        )
        if cache is not None and cache[:-1] == updated:
            if cache[-1] is not None:
                return cache[-1]
            return spec

        main_schema = SCHEMA_CACHE.get(portal_type)
        if main_schema:
            dynamically_provided = [main_schema]
        else:
            dynamically_provided = []

        # block recursion
        self.__recursion__ = True
        try:
            assignable = IBehaviorAssignable(inst, None)
            if assignable is not None:
                for behavior_registration in assignable.enumerateBehaviors():
                    if behavior_registration.marker:
                        dynamically_provided.append(
                            behavior_registration.marker
                        )
        finally:
            del self.__recursion__

        if not dynamically_provided:
            # rare case if no schema nor behaviors with markers are set
            inst._v__providedBy__ = updated + (None, )
            return spec

        dynamically_provided.append(spec)
        all_spec = Implements(*dynamically_provided)
        inst._v__providedBy__ = updated + (all_spec, )

        return all_spec
Beispiel #27
0
 def __get__(self, inst, cls=None):
     
     # We're looking at a class - fall back on default
     if inst is None:
         return getObjectSpecification(cls)
     
     # Find the cached value. This calculation is expensive and called
     # hundreds of times during each request, so we require a fast cache
     cache = getattr(inst, '_v__providedBy__', None)
     
     # Find the data we need to know if our cache needs to be invalidated
     
     direct_spec = getattr(inst, '__provides__', None)
     portal_type = getattr(inst, 'portal_type', None)
     
     fti_counter = -1
     if portal_type is not None:
         fti_counter = SCHEMA_CACHE.counter(portal_type)
     
     # See if we have a valid cache. Reasons to do this include:
     # 
     #  - We don't have a portal_type yet, so we can't have found the schema
     #  - The FTI was modified, and the schema cache invalidated globally.
     #    The fti_counter will have advanced.
     #  - The instance was modified and persisted since the cache was built.
     #  - The instance now has a different __provides__, which means that someone
     #    called directlyProvides/alsoProvides on it.
     
     if cache is not None and portal_type is not None:
         cached_mtime, cached_fti_counter, cached_direct_spec, cached_spec = cache
         
         if inst._p_mtime == cached_mtime and \
                 fti_counter == cached_fti_counter and \
                 direct_spec is cached_direct_spec:
             return cached_spec
     
     # We don't have a cache, so we need to build a new spec and maybe cache it
     
     spec = direct_spec
     
     # If the instance doesn't have a __provides__ attribute, get the
     # interfaces implied by the class as a starting point.
     if spec is None:
         spec = implementedBy(cls)
     
     # Add the schema from the FTI and behavior subtypes
     
     dynamically_provided = []
     
     if portal_type is not None:
         schema = SCHEMA_CACHE.get(portal_type)
         if schema is not None:
             dynamically_provided.append(schema)
         
         subtypes = SCHEMA_CACHE.subtypes(portal_type)
         if subtypes:
             dynamically_provided.extend(subtypes)
     
     # If we have any dynamically provided interface, prepend them to the spec
     # and cache. We can't cache until we have at least the schema, because
     # it's possible that we were called before traversal and so could not
     # find the schema yet.
     
     if dynamically_provided:
         dynamically_provided.append(spec)
         spec = Implements(*dynamically_provided)
         
         inst._v__providedBy__ = inst._p_mtime, SCHEMA_CACHE.counter(portal_type), direct_spec, spec
     
     return spec
Beispiel #28
0
 def __get__(self, inst, cls=None):
     if inst is None:
         return getObjectSpecification(cls)
     else:
         return inst.__provides__
Beispiel #29
0
 def __get__(self, inst, cls=None):
     if inst is None:
         return getObjectSpecification(cls)
     else:
         return inst.__provides__