Commit 0fba4893 authored by Aron Helser's avatar Aron Helser

Merge branch 'upstream-ZopeInterface' into webserver_update

* upstream-ZopeInterface:
  ZopeInterface 2017-07-25 (f4530aaf)
parents c6c46864 e1153907
# zope.interface fork for vtk/ParaView
zope.interface is a dependency of Twisted. This branch contains changes required to embed zope.interface into vtk/ParaView. This includes choosing a sub-set without documentation or testing, and adding CMake build files.
zope.interface is a dependency of Twisted. This branch contains changes required to embed zope.interface into vtk/ParaView. This includes a readme and .gitattributes file. A subset is chosen on import to vtk using update.sh.
......@@ -16,7 +16,7 @@
import sys
import types
if sys.version_info[0] < 3: #pragma NO COVER
if sys.version_info[0] < 3:
def _normalize_name(name):
if isinstance(name, basestring):
......@@ -31,7 +31,7 @@ if sys.version_info[0] < 3: #pragma NO COVER
PYTHON3 = False
PYTHON2 = True
else: #pragma NO COVER
else:
def _normalize_name(name):
if isinstance(name, bytes):
......@@ -48,16 +48,11 @@ else: #pragma NO COVER
PYTHON3 = True
PYTHON2 = False
def _skip_under_py3k(test_method): #pragma NO COVER
if sys.version_info[0] < 3:
return test_method
def _dummy(*args):
pass
return _dummy
def _skip_under_py2(test_method): #pragma NO COVER
if sys.version_info[0] > 2:
return test_method
def _dummy(*args):
pass
return _dummy
def _skip_under_py3k(test_method):
import unittest
return unittest.skipIf(sys.version_info[0] >= 3, "Only on Python 2")(test_method)
def _skip_under_py2(test_method):
import unittest
return unittest.skipIf(sys.version_info[0] < 3, "Only on Python 3")(test_method)
......@@ -22,6 +22,7 @@ from zope.interface import ro
from zope.interface.interfaces import IAdapterRegistry
from zope.interface._compat import _normalize_name
from zope.interface._compat import STRING_TYPES
_BLANK = u''
......@@ -102,6 +103,8 @@ class BaseAdapterRegistry(object):
self._v_lookup.changed(originally_changed)
def register(self, required, provided, name, value):
if not isinstance(name, STRING_TYPES):
raise ValueError('name is not a string')
if value is None:
self.unregister(required, provided, name, value)
return
......@@ -249,7 +252,7 @@ class BaseAdapterRegistry(object):
old = components.get(_BLANK)
if not old:
# this is belt-and-suspenders against the failure of cleanup below
return #pragma NO COVERAGE
return # pragma: no cover
if value is None:
new = ()
......@@ -288,7 +291,7 @@ class BaseAdapterRegistry(object):
# XXX hack to fake out twisted's use of a private api. We need to get them
# to use the new registed method.
def get(self, _): #pragma NO COVER
def get(self, _): # pragma: no cover
class XXXTwistedFakeOut:
selfImplied = {}
return XXXTwistedFakeOut
......@@ -321,6 +324,8 @@ class LookupBaseFallback(object):
return cache
def lookup(self, required, provided, name=_BLANK, default=None):
if not isinstance(name, STRING_TYPES):
raise ValueError('name is not a string')
cache = self._getcache(provided, name)
required = tuple(required)
if len(required) == 1:
......@@ -341,6 +346,8 @@ class LookupBaseFallback(object):
return result
def lookup1(self, required, provided, name=_BLANK, default=None):
if not isinstance(name, STRING_TYPES):
raise ValueError('name is not a string')
cache = self._getcache(provided, name)
result = cache.get(required, _not_in_mapping)
if result is _not_in_mapping:
......@@ -355,6 +362,8 @@ class LookupBaseFallback(object):
return self.adapter_hook(provided, object, name, default)
def adapter_hook(self, provided, object, name=_BLANK, default=None):
if not isinstance(name, STRING_TYPES):
raise ValueError('name is not a string')
required = providedBy(object)
cache = self._getcache(provided, name)
factory = cache.get(required, _not_in_mapping)
......@@ -401,14 +410,14 @@ LookupBasePy = LookupBaseFallback # BBB
try:
from zope.interface._zope_interface_coptimizations import LookupBase
except ImportError: #pragma NO COVER
except ImportError:
LookupBase = LookupBaseFallback
class VerifyingBaseFallback(LookupBaseFallback):
# Mixin for lookups against registries which "chain" upwards, and
# whose lookups invalidate their own caches whenever a parent registry
# bumps its own '_generation' counter. E.g., used by
# bumps its own '_generation' counter. E.g., used by
# zope.component.persistentregistry
def changed(self, originally_changed):
......@@ -437,7 +446,7 @@ VerifyingBasePy = VerifyingBaseFallback #BBB
try:
from zope.interface._zope_interface_coptimizations import VerifyingBase
except ImportError: #pragma NO COVER
except ImportError:
VerifyingBase = VerifyingBaseFallback
......
......@@ -28,11 +28,11 @@ Visit the PEAK home page at http://peak.telecommunity.com for more information.
from types import FunctionType
try:
from types import ClassType
except ImportError: #pragma NO COVER Python > 3.x
except ImportError:
__python3 = True
else: #pragma NO COVER Python < 3.x
else:
__python3 = False
import sys
def getFrameInfo(frame):
......@@ -96,7 +96,7 @@ def addClassAdvisor(callback, depth=2):
declare any '__metaclass__' *first*, to ensure all callbacks are run."""
# This entire approach is invalid under Py3K. Don't even try to fix
# the coverage for this block there. :(
if __python3: #pragma NO COVER
if __python3: # pragma: no cover
raise TypeError('Class advice impossible in Python3')
frame = sys._getframe(depth)
......@@ -172,7 +172,7 @@ def determineMetaclass(bases, explicit_mc=None):
candidates = minimalBases(meta) # minimal set of metaclasses
if not candidates: #pragma NO COVER
if not candidates: # pragma: no cover
# they're all "classic" classes
assert(not __python3) # This should not happen under Python 3
return ClassType
......@@ -188,7 +188,7 @@ def determineMetaclass(bases, explicit_mc=None):
def minimalBases(classes):
"""Reduce a list of base classes to its ordered minimum equivalent"""
if not __python3: #pragma NO COVER
if not __python3: # pragma: no cover
classes = [c for c in classes if c is not ClassType]
candidates = []
......@@ -203,4 +203,3 @@ def minimalBases(classes):
candidates.append(m)
return candidates
......@@ -436,8 +436,6 @@ class implementer_only:
def _implements(name, interfaces, classImplements):
# This entire approach is invalid under Py3K. Don't even try to fix
# the coverage for this block there. :(
if PYTHON3: #pragma NO COVER
raise TypeError('Class advice impossible in Python3')
frame = sys._getframe(2)
locals = frame.f_locals
......@@ -481,7 +479,7 @@ def implements(*interfaces):
"""
# This entire approach is invalid under Py3K. Don't even try to fix
# the coverage for this block there. :(
if PYTHON3: #pragma NO COVER
if PYTHON3:
raise TypeError(_ADVICE_ERROR % 'implementer')
_implements("implements", interfaces, classImplements)
......@@ -509,7 +507,7 @@ def implementsOnly(*interfaces):
"""
# This entire approach is invalid under Py3K. Don't even try to fix
# the coverage for this block there. :(
if PYTHON3: #pragma NO COVER
if PYTHON3:
raise TypeError(_ADVICE_ERROR % 'implementer_only')
_implements("implementsOnly", interfaces, classImplementsOnly)
......@@ -581,7 +579,7 @@ def directlyProvides(object, *interfaces):
# Note that we can't get here from Py3k tests: there is no normal
# class which isn't descriptor aware.
if not isinstance(object,
DescriptorAwareMetaClasses): #pragma NO COVER Py3k
DescriptorAwareMetaClasses):
raise TypeError("Attempt to make an interface declaration on a "
"non-descriptor-aware class")
......@@ -641,9 +639,9 @@ ClassProvidesBase = ClassProvidesBaseFallback
# Try to get C base:
try:
import zope.interface._zope_interface_coptimizations
except ImportError: #pragma NO COVERAGE
except ImportError:
pass
else: #pragma NO COVERAGE
else:
from zope.interface._zope_interface_coptimizations import ClassProvidesBase
......@@ -715,7 +713,7 @@ def classProvides(*interfaces):
# This entire approach is invalid under Py3K. Don't even try to fix
# the coverage for this block there. :(
if PYTHON3: #pragma NO COVER
if PYTHON3:
raise TypeError(_ADVICE_ERROR % 'provider')
frame = sys._getframe(1)
......@@ -801,7 +799,7 @@ def ObjectSpecification(direct, cls):
These combine information for the object and for it's classes.
"""
return Provides(cls, direct) #pragma NO COVER fossil
return Provides(cls, direct) # pragma: no cover fossil
def getObjectSpecificationFallback(ob):
......@@ -918,9 +916,9 @@ _empty = Declaration()
try:
import zope.interface._zope_interface_coptimizations
except ImportError: #pragma NO COVER
except ImportError:
pass
else: #pragma NO COVER PyPy
else:
from zope.interface._zope_interface_coptimizations import implementedBy
from zope.interface._zope_interface_coptimizations import providedBy
from zope.interface._zope_interface_coptimizations import (
......
......@@ -115,7 +115,7 @@ class SpecificationBasePy(object):
SpecificationBase = SpecificationBasePy
try:
from zope.interface._zope_interface_coptimizations import SpecificationBase
except ImportError: #pragma NO COVER
except ImportError:
pass
_marker = object()
......@@ -156,14 +156,14 @@ class InterfaceBasePy(object):
InterfaceBase = InterfaceBasePy
try:
from zope.interface._zope_interface_coptimizations import InterfaceBase
except ImportError: #pragma NO COVER
except ImportError:
pass
adapter_hooks = []
try:
from zope.interface._zope_interface_coptimizations import adapter_hooks
except ImportError: #pragma NO COVER
except ImportError:
pass
......@@ -321,7 +321,7 @@ class InterfaceClass(Element, InterfaceBase, Specification):
# This is how cPython figures out the module of
# a class, but of course it does it in C. :-/
__module__ = sys._getframe(1).f_globals['__name__']
except (AttributeError, KeyError): #pragma NO COVERAGE
except (AttributeError, KeyError): # pragma: no cover
pass
self.__module__ = __module__
......@@ -465,7 +465,7 @@ class InterfaceClass(Element, InterfaceBase, Specification):
def _call_conform(self, conform):
try:
return conform(self)
except TypeError: #pragma NO COVER
except TypeError: # pragma: no cover
# We got a TypeError. It might be an error raised by
# the __conform__ implementation, or *we* may have
# made the TypeError by calling an unbound method
......@@ -479,7 +479,7 @@ class InterfaceClass(Element, InterfaceBase, Specification):
raise
# This clever trick is from Phillip Eby
return None #pragma NO COVER
return None # pragma: no cover
def __reduce__(self):
return self.__name__
......@@ -517,7 +517,7 @@ class InterfaceClass(Element, InterfaceBase, Specification):
def __hash__(self):
d = self.__dict__
if '__module__' not in d or '__name__' not in d: #pragma NO COVER
if '__module__' not in d or '__name__' not in d: # pragma: no cover
warnings.warn('Hashing uninitialized InterfaceClass instance')
return 1
return hash((self.__name__, self.__module__))
......
......@@ -676,12 +676,14 @@ class IAdapterRegistry(Interface):
"""Register a value
A value is registered for a *sequence* of required specifications, a
provided interface, and a name.
provided interface, and a name, which must be text.
"""
def registered(required, provided, name=_BLANK):
"""Return the component registered for the given interfaces and name
name must be text.
Unlike the lookup method, this methods won't retrieve
components registered for more specific required interfaces or
less specific provided interfaces.
......@@ -695,7 +697,8 @@ class IAdapterRegistry(Interface):
"""Lookup a value
A value is looked up based on a *sequence* of required
specifications, a provided interface, and a name.
specifications, a provided interface, and a name, which must be
text.
"""
def queryMultiAdapter(objects, provided, name=_BLANK, default=None):
......@@ -706,7 +709,8 @@ class IAdapterRegistry(Interface):
"""Lookup a value using a single required interface
A value is looked up based on a single required
specifications, a provided interface, and a name.
specifications, a provided interface, and a name, which must be
text.
"""
def queryAdapter(object, provided, name=_BLANK, default=None):
......@@ -715,6 +719,8 @@ class IAdapterRegistry(Interface):
def adapter_hook(provided, object, name=_BLANK, default=None):
"""Adapt an object using a registered adapter factory.
name must be text.
"""
def lookupAll(required, provided):
......
......@@ -14,7 +14,6 @@
"""Basic components support
"""
from collections import defaultdict
import weakref
try:
from zope.event import notify
......@@ -68,50 +67,14 @@ class _UnhashableComponentCounter(object):
return
raise KeyError(component) # pragma: no cover
def _defaultdict_int():
return defaultdict(int)
class _UtilityRegistrations(object):
_regs_for_components = {}
_weakrefs_for_components = {}
@classmethod
def for_components(cls, components):
# We manage these utility/subscription registrations as associated
# objects with a weakref to avoid making any changes to
# the pickle format. They are keyed off the id of the component because
# Components subclasses are not guaranteed to be hashable.
key = id(components)
try:
regs = cls._regs_for_components[key]
except KeyError:
regs = None
else:
# In case the components have been re-initted, clear the cache
# (zope.component.testing does this between tests)
if (regs._utilities is not components.utilities
or regs._utility_registrations is not components._utility_registrations):
regs = None
if regs is None:
regs = cls(components.utilities, components._utility_registrations)
cls._regs_for_components[key] = regs
if key not in cls._weakrefs_for_components:
def _cleanup(r):
cls._weakrefs_for_components.pop(key)
cls._regs_for_components.pop(key)
cls._weakrefs_for_components[key] = weakref.ref(components, _cleanup)
return regs
@classmethod
def clear_cache(cls):
cls._regs_for_components.clear()
def __init__(self, utilities, utility_registrations):
# {provided -> {component: count}}
self._cache = defaultdict(lambda: defaultdict(int))
self._cache = defaultdict(_defaultdict_int)
self._utilities = utilities
self._utility_registrations = utility_registrations
......@@ -177,17 +140,39 @@ class _UtilityRegistrations(object):
@implementer(IComponents)
class Components(object):
_v_utility_registrations_cache = None
def __init__(self, name='', bases=()):
# __init__ is used for test cleanup as well as initialization.
# XXX add a separate API for test cleanup.
assert isinstance(name, STRING_TYPES)
self.__name__ = name
self._init_registries()
self._init_registrations()
self.__bases__ = tuple(bases)
self._v_utility_registrations_cache = None
def __repr__(self):
return "<%s %s>" % (self.__class__.__name__, self.__name__)
def __reduce__(self):
# Mimic what a persistent.Persistent object does and elide
# _v_ attributes so that they don't get saved in ZODB.
# This allows us to store things that cannot be pickled in such
# attributes.
reduction = super(Components, self).__reduce__()
# (callable, args, state, listiter, dictiter)
# We assume the state is always a dict; the last three items
# are technically optional and can be missing or None.
filtered_state = {k: v for k, v in reduction[2].items()
if not k.startswith('_v_')}
reduction = list(reduction)
reduction[2] = filtered_state
return tuple(reduction)
def _init_registries(self):
# Subclasses have never been required to call this method
# if they override it, merely to fill in these two attributes.
self.adapters = AdapterRegistry()
self.utilities = AdapterRegistry()
......@@ -197,6 +182,19 @@ class Components(object):
self._subscription_registrations = []
self._handler_registrations = []
@property
def _utility_registrations_cache(self):
# We use a _v_ attribute internally so that data aren't saved in ZODB,
# because this object cannot be pickled.
cache = self._v_utility_registrations_cache
if (cache is None
or cache._utilities is not self.utilities
or cache._utility_registrations is not self._utility_registrations):
cache = self._v_utility_registrations_cache = _UtilityRegistrations(
self.utilities,
self._utility_registrations)
return cache
def _getBases(self):
# Subclasses might override
return self.__dict__.get('__bases__', ())
......@@ -234,7 +232,8 @@ class Components(object):
return
self.unregisterUtility(reg[0], provided, name)
_UtilityRegistrations.for_components(self).registerUtility(provided, name, component, info, factory)
self._utility_registrations_cache.registerUtility(
provided, name, component, info, factory)
if event:
notify(Registered(
......@@ -264,7 +263,8 @@ class Components(object):
component = old[0]
# Note that component is now the old thing registered
_UtilityRegistrations.for_components(self).unregisterUtility(provided, name, component)
self._utility_registrations_cache.unregisterUtility(
provided, name, component)
notify(Unregistered(
UtilityRegistration(self, provided, name, component, *old[1:])
......
......@@ -66,10 +66,10 @@ def _verify(iface, candidate, tentative=0, vtype=None):
continue
if isinstance(attr, FunctionType):
if sys.version[0] == '3' and isinstance(candidate, type):
if sys.version_info[0] >= 3 and isinstance(candidate, type):
# This is an "unbound method" in Python 3.
meth = fromFunction(attr, iface, name=name,
imlevel=1) #pragma NO COVERAGE
imlevel=1)
else:
# Nope, just a normal function
meth = fromFunction(attr, iface, name=name)
......@@ -85,7 +85,7 @@ def _verify(iface, candidate, tentative=0, vtype=None):
raise BrokenMethodImplementation(name, "Not a method")
# sigh, it's callable, but we don't know how to introspect it, so
# we have to give it a pass.
continue #pragma NO COVERAGE
continue
# Make sure that the required and implemented method signatures are
# the same.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment