[Checkins] SVN: zope.interface/branches/tseaver-no_2to3/src/zope/interface/ Close Py3k coverage gap to absolute minimum.
Tres Seaver
cvs-admin at zope.org
Fri Apr 6 04:14:36 UTC 2012
Log message for revision 124987:
Close Py3k coverage gap to absolute minimum.
We *can't* test the classAdvice stuff under Py3k. Need to deprecate it
before the 4.0 release.
Changed:
U zope.interface/branches/tseaver-no_2to3/src/zope/interface/_compat.py
U zope.interface/branches/tseaver-no_2to3/src/zope/interface/advice.py
U zope.interface/branches/tseaver-no_2to3/src/zope/interface/declarations.py
U zope.interface/branches/tseaver-no_2to3/src/zope/interface/registry.py
U zope.interface/branches/tseaver-no_2to3/src/zope/interface/tests/test_advice.py
U zope.interface/branches/tseaver-no_2to3/src/zope/interface/tests/test_declarations.py
-=-
Modified: zope.interface/branches/tseaver-no_2to3/src/zope/interface/_compat.py
===================================================================
--- zope.interface/branches/tseaver-no_2to3/src/zope/interface/_compat.py 2012-04-06 04:14:27 UTC (rev 124986)
+++ zope.interface/branches/tseaver-no_2to3/src/zope/interface/_compat.py 2012-04-06 04:14:32 UTC (rev 124987)
@@ -26,8 +26,8 @@
return unicode(name)
raise TypeError("name must be a regular or unicode string")
- class_types = (type, types.ClassType)
- string_types = (basestring,)
+ CLASS_TYPES = (type, types.ClassType)
+ STRING_TYPES = (basestring,)
_FUNC_DEFAULTS = 'func_defaults'
_FUNC_CODE = 'func_code'
@@ -35,6 +35,9 @@
_IM_FUNC = 'im_func'
_BUILTINS = '__builtin__'
+ PYTHON3 = False
+ PYTHON2 = True
+
else: #pragma NO COVER
def _u(s):
@@ -47,8 +50,8 @@
return name
raise TypeError("name must be a string or ASCII-only bytes")
- class_types = type
- string_types = (str,)
+ CLASS_TYPES = (type,)
+ STRING_TYPES = (str,)
_FUNC_DEFAULTS = '__defaults__'
_FUNC_CODE = '__code__'
@@ -56,9 +59,19 @@
_IM_FUNC = '__func__'
_BUILTINS = 'builtins'
+ 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
Modified: zope.interface/branches/tseaver-no_2to3/src/zope/interface/advice.py
===================================================================
--- zope.interface/branches/tseaver-no_2to3/src/zope/interface/advice.py 2012-04-06 04:14:27 UTC (rev 124986)
+++ zope.interface/branches/tseaver-no_2to3/src/zope/interface/advice.py 2012-04-06 04:14:32 UTC (rev 124987)
@@ -94,6 +94,10 @@
callbacks *after* the last '__metaclass__' assignment in the containing
class will be executed. Be sure that classes using "advising" functions
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
+ raise TypeError('Class advice impossible in Python3')
frame = sys._getframe(depth)
kind, module, caller_locals, caller_globals = getFrameInfo(frame)
@@ -184,7 +188,7 @@
def minimalBases(classes):
"""Reduce a list of base classes to its ordered minimum equivalent"""
- if not __python3:
+ if not __python3: #pragma NO COVER
classes = [c for c in classes if c is not ClassType]
candidates = []
Modified: zope.interface/branches/tseaver-no_2to3/src/zope/interface/declarations.py
===================================================================
--- zope.interface/branches/tseaver-no_2to3/src/zope/interface/declarations.py 2012-04-06 04:14:27 UTC (rev 124986)
+++ zope.interface/branches/tseaver-no_2to3/src/zope/interface/declarations.py 2012-04-06 04:14:32 UTC (rev 124987)
@@ -36,6 +36,7 @@
from zope.interface.interface import InterfaceClass
from zope.interface.interface import SpecificationBase
from zope.interface.interface import Specification
+from zope.interface._compat import CLASS_TYPES as DescriptorAwareMetaClasses
# Registry of class-implementation specifications
BuiltinImplementationSpecifications = {}
@@ -249,7 +250,7 @@
b = implementedBy(c)
if b not in seen:
seen[b] = 1
- bases.append(b)
+ bases.append(b)
spec.__bases__ = tuple(bases)
@@ -295,8 +296,8 @@
def __call__(self, ob):
if isinstance(ob, DescriptorAwareMetaClasses):
classImplements(ob, *self.interfaces)
- return ob
-
+ return ob
+
spec = Implements(*self.interfaces)
try:
ob.__implemented__ = spec
@@ -341,9 +342,11 @@
else:
# Assume it's a class:
classImplementsOnly(ob, *self.interfaces)
- return ob
-
+ return ob
+
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 sys.version_info[0] >= 3: #pragma NO COVER
raise TypeError('Class advice impossible in Python3')
frame = sys._getframe(2)
@@ -386,7 +389,9 @@
classImplements(C, I1)
after the class has been created.
- """
+ """
+ # This entire approach is invalid under Py3K. Don't even try to fix
+ # the coverage for this block there. :(
_implements("implements", interfaces, classImplements)
def implementsOnly(*interfaces):
@@ -410,7 +415,9 @@
classImplementsOnly(I1)
after the class has been created.
- """
+ """
+ # This entire approach is invalid under Py3K. Don't even try to fix
+ # the coverage for this block there. :(
_implements("implementsOnly", interfaces, classImplementsOnly)
##############################################################################
@@ -465,12 +472,7 @@
Provides.__safe_for_unpickling__ = True
-try:
- from types import ClassType
- DescriptorAwareMetaClasses = ClassType, type
-except ImportError: #pragma NO COVERAGE (Python 3)
- DescriptorAwareMetaClasses = (type,)
-
+
def directlyProvides(object, *interfaces):
"""Declare interfaces declared directly for an object
@@ -485,7 +487,8 @@
# It's a meta class (well, at least it it could be an extension class)
# 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):
+ if not isinstance(object,
+ DescriptorAwareMetaClasses): #pragma NO COVER Py3k
raise TypeError("Attempt to make an interface declaration on a "
"non-descriptor-aware class")
@@ -616,6 +619,8 @@
after the class has been created.
"""
+ # This entire approach is invalid under Py3K. Don't even try to fix
+ # the coverage for this block there. :(
if sys.version_info[0] >= 3: #pragma NO COVER
raise TypeError('Class advice impossible in Python3')
@@ -636,6 +641,8 @@
addClassAdvisor(_classProvides_advice, depth=2)
def _classProvides_advice(cls):
+ # This entire approach is invalid under Py3K. Don't even try to fix
+ # the coverage for this block there. :(
interfaces = cls.__dict__['__provides__']
del cls.__provides__
directlyProvides(cls, *interfaces)
@@ -649,7 +656,7 @@
def __call__(self, ob):
directlyProvides(ob, *self.interfaces)
- return ob
+ return ob
def moduleProvides(*interfaces):
"""Declare interfaces provided by a module
Modified: zope.interface/branches/tseaver-no_2to3/src/zope/interface/registry.py
===================================================================
--- zope.interface/branches/tseaver-no_2to3/src/zope/interface/registry.py 2012-04-06 04:14:27 UTC (rev 124986)
+++ zope.interface/branches/tseaver-no_2to3/src/zope/interface/registry.py 2012-04-06 04:14:32 UTC (rev 124987)
@@ -35,15 +35,15 @@
from zope.interface.declarations import providedBy
from zope.interface.adapter import AdapterRegistry
from zope.interface._compat import _u
-from zope.interface._compat import class_types
-from zope.interface._compat import string_types
+from zope.interface._compat import CLASS_TYPES
+from zope.interface._compat import STRING_TYPES
@implementer(IComponents)
class Components(object):
def __init__(self, name='', bases=()):
- assert isinstance(name, string_types)
+ assert isinstance(name, STRING_TYPES)
self.__name__ = name
self._init_registries()
self._init_registrations()
@@ -415,7 +415,7 @@
if r is None:
r = Interface
elif not ISpecification.providedBy(r):
- if isinstance(r, class_types):
+ if isinstance(r, CLASS_TYPES):
r = implementedBy(r)
else:
raise TypeError("Required specification must be a "
Modified: zope.interface/branches/tseaver-no_2to3/src/zope/interface/tests/test_advice.py
===================================================================
--- zope.interface/branches/tseaver-no_2to3/src/zope/interface/tests/test_advice.py 2012-04-06 04:14:27 UTC (rev 124986)
+++ zope.interface/branches/tseaver-no_2to3/src/zope/interface/tests/test_advice.py 2012-04-06 04:14:32 UTC (rev 124987)
@@ -28,6 +28,7 @@
import unittest
import sys
+from zope.interface._compat import _skip_under_py2
from zope.interface._compat import _skip_under_py3k
@@ -185,19 +186,141 @@
self.assertEqual(type(klass), ClassType)
+class Test_isClassAdvisor(unittest.TestCase):
+
+ def _callFUT(self, *args, **kw):
+ from zope.interface.advice import isClassAdvisor
+ return isClassAdvisor(*args, **kw)
+
+ def test_w_non_function(self):
+ self.assertEqual(self._callFUT(self), False)
+
+ def test_w_normal_function(self):
+ def foo():
+ pass
+ self.assertEqual(self._callFUT(foo), False)
+
+ def test_w_advisor_function(self):
+ def bar():
+ pass
+ bar.previousMetaclass = object()
+ self.assertEqual(self._callFUT(bar), True)
+
+
+class Test_determineMetaclass(unittest.TestCase):
+
+ def _callFUT(self, *args, **kw):
+ from zope.interface.advice import determineMetaclass
+ return determineMetaclass(*args, **kw)
+
@_skip_under_py3k
+ def test_empty(self):
+ from types import ClassType
+ self.assertEquals(self._callFUT(()), ClassType)
+
+ def test_empty_w_explicit_metatype(self):
+ class Meta(type):
+ pass
+ self.assertEquals(self._callFUT((), Meta), Meta)
+
+ def test_single(self):
+ class Meta(type):
+ pass
+ self.assertEquals(self._callFUT((Meta,)), type)
+
+ @_skip_under_py3k
def test_meta_of_class(self):
- from zope.interface.advice import determineMetaclass
-
class Metameta(type):
pass
class Meta(type):
__metaclass__ = Metameta
- self.assertEquals(determineMetaclass((Meta, type)), Metameta)
+ self.assertEquals(self._callFUT((Meta, type)), Metameta)
+ @_skip_under_py2
+ def test_meta_of_class_py3k(self):
+ # Work around SyntaxError under Python2.
+ EXEC = '\n'.join([
+ 'class Metameta(type):',
+ ' pass',
+ 'class Meta(type, metaclass=Metameta):',
+ ' pass',
+ ])
+ globs = {}
+ exec(EXEC, globs)
+ Meta = globs['Meta']
+ Metameta = globs['Metameta']
+ self.assertEquals(self._callFUT((Meta, type)), Metameta)
+
+ @_skip_under_py3k
+ def test_multiple_in_hierarchy(self):
+ class Meta_A(type):
+ pass
+ class Meta_B(Meta_A):
+ pass
+ class A(type):
+ __metaclass__ = Meta_A
+ class B(type):
+ __metaclass__ = Meta_B
+ self.assertEquals(self._callFUT((A, B,)), Meta_B)
+
+ @_skip_under_py2
+ def test_multiple_in_hierarchy_py3k(self):
+ # Work around SyntaxError under Python2.
+ EXEC = '\n'.join([
+ 'class Meta_A(type):',
+ ' pass',
+ 'class Meta_B(Meta_A):',
+ ' pass',
+ 'class A(type, metaclass=Meta_A):',
+ ' pass',
+ 'class B(type, metaclass=Meta_B):',
+ ' pass',
+ ])
+ globs = {}
+ exec(EXEC, globs)
+ Meta_A = globs['Meta_A']
+ Meta_B = globs['Meta_B']
+ A = globs['A']
+ B = globs['B']
+ self.assertEquals(self._callFUT((A, B)), Meta_B)
+
+ @_skip_under_py3k
+ def test_multiple_not_in_hierarchy(self):
+ class Meta_A(type):
+ pass
+ class Meta_B(type):
+ pass
+ class A(type):
+ __metaclass__ = Meta_A
+ class B(type):
+ __metaclass__ = Meta_B
+ self.assertRaises(TypeError, self._callFUT, (A, B,))
+
+ @_skip_under_py2
+ def test_multiple_not_in_hierarchy_py3k(self):
+ # Work around SyntaxError under Python2.
+ EXEC = '\n'.join([
+ 'class Meta_A(type):',
+ ' pass',
+ 'class Meta_B(type):',
+ ' pass',
+ 'class A(type, metaclass=Meta_A):',
+ ' pass',
+ 'class B(type, metaclass=Meta_B):',
+ ' pass',
+ ])
+ globs = {}
+ exec(EXEC, globs)
+ Meta_A = globs['Meta_A']
+ Meta_B = globs['Meta_B']
+ A = globs['A']
+ B = globs['B']
+ self.assertRaises(TypeError, self._callFUT, (A, B))
+
+
class Test_minimalBases(unittest.TestCase):
def _callFUT(self, klasses):
@@ -252,12 +375,10 @@
def test_suite():
- if sys.version[0] == '2':
- return unittest.TestSuite((
- unittest.makeSuite(FrameInfoTest),
- unittest.makeSuite(AdviceTests),
- unittest.makeSuite(Test_minimalBases),
- ))
- else:
- # Advise metaclasses doesn't work in Python 3
- return unittest.TestSuite([])
+ return unittest.TestSuite((
+ unittest.makeSuite(FrameInfoTest),
+ unittest.makeSuite(AdviceTests),
+ unittest.makeSuite(Test_isClassAdvisor),
+ unittest.makeSuite(Test_determineMetaclass),
+ unittest.makeSuite(Test_minimalBases),
+ ))
Modified: zope.interface/branches/tseaver-no_2to3/src/zope/interface/tests/test_declarations.py
===================================================================
--- zope.interface/branches/tseaver-no_2to3/src/zope/interface/tests/test_declarations.py 2012-04-06 04:14:27 UTC (rev 124986)
+++ zope.interface/branches/tseaver-no_2to3/src/zope/interface/tests/test_declarations.py 2012-04-06 04:14:32 UTC (rev 124987)
@@ -641,6 +641,31 @@
from zope.interface.declarations import implementsOnly
return implementsOnly
+ def test_simple(self):
+ from zope.interface.declarations import implementsOnly
+ from zope.interface._compat import PYTHON3
+ from zope.interface.interface import InterfaceClass
+ IFoo = InterfaceClass("IFoo")
+ globs = {'implementsOnly': implementsOnly,
+ 'IFoo': IFoo,
+ }
+ locs = {}
+ CODE = "\n".join([
+ 'class Foo(object):'
+ ' implementsOnly(IFoo)',
+ ])
+ try:
+ exec(CODE, globs, locs)
+ except TypeError:
+ if not PYTHON3:
+ raise
+ else:
+ if PYTHON3:
+ self.fail("Didn't raise TypeError")
+ Foo = locs['Foo']
+ spec = Foo.__implemented__
+ self.assertEqual(list(spec), [IFoo])
+
def test_called_once_from_class_w_bases(self):
from zope.interface.declarations import implements
from zope.interface.declarations import implementsOnly
More information about the checkins
mailing list