[Checkins] SVN: zope.interface/trunk/ Merge of regebro-python3 branch, adding Python 3.1 compatibility\!
Lennart Regebro
regebro at gmail.com
Fri Apr 9 04:16:18 EDT 2010
Log message for revision 110699:
Merge of regebro-python3 branch, adding Python 3.1 compatibility\!
Changed:
U zope.interface/trunk/CHANGES.txt
A zope.interface/trunk/build_ext_2.py
A zope.interface/trunk/build_ext_3.py
U zope.interface/trunk/setup.py
U zope.interface/trunk/src/zope/interface/README.ru.txt
U zope.interface/trunk/src/zope/interface/README.txt
U zope.interface/trunk/src/zope/interface/__init__.py
U zope.interface/trunk/src/zope/interface/_zope_interface_coptimizations.c
U zope.interface/trunk/src/zope/interface/adapter.py
U zope.interface/trunk/src/zope/interface/adapter.ru.txt
U zope.interface/trunk/src/zope/interface/adapter.txt
U zope.interface/trunk/src/zope/interface/advice.py
U zope.interface/trunk/src/zope/interface/declarations.py
U zope.interface/trunk/src/zope/interface/interface.py
U zope.interface/trunk/src/zope/interface/interfaces.py
U zope.interface/trunk/src/zope/interface/tests/__init__.py
U zope.interface/trunk/src/zope/interface/tests/odd.py
U zope.interface/trunk/src/zope/interface/tests/test_advice.py
U zope.interface/trunk/src/zope/interface/tests/test_interface.py
U zope.interface/trunk/src/zope/interface/tests/test_odd_declarations.py
U zope.interface/trunk/src/zope/interface/tests/test_sorting.py
U zope.interface/trunk/src/zope/interface/verify.py
U zope.interface/trunk/src/zope/interface/verify.txt
-=-
Modified: zope.interface/trunk/CHANGES.txt
===================================================================
--- zope.interface/trunk/CHANGES.txt 2010-04-09 02:33:49 UTC (rev 110698)
+++ zope.interface/trunk/CHANGES.txt 2010-04-09 08:16:17 UTC (rev 110699)
@@ -2,6 +2,37 @@
*******
==================
+3.6.0 (unreleased)
+==================
+
+- Added support for Python 3.1. Contributors:
+ Lennart Regebro
+ Martin v Löwis
+ Thomas Lotze
+ Wolfgang Schnerring
+
+ The 3.1 support is completely backwards compatible. However, the implements
+ syntax used under Python 2.X does not work under 3.X, since it depends on
+ how metaclasses are implemented and this has changed. Instead it now supports
+ a decorator syntax (also under Python 2.X):
+
+ class Foo:
+ implements(IFoo)
+ ...
+
+ can now also be written
+
+ @implementor(IFoo):
+ class Foo:
+ ...
+
+ There are 2to3 fixers available to do this change automatically in the
+ zope.fixers package.
+
+- Python 2.3 is no longer supported.
+
+
+==================
3.5.4 (2009-12-23)
==================
@@ -9,6 +40,7 @@
has been deprecated.
+==================
3.5.3 (2009-12-08)
==================
Copied: zope.interface/trunk/build_ext_2.py (from rev 110698, zope.interface/branches/regebro-python3/build_ext_2.py)
===================================================================
--- zope.interface/trunk/build_ext_2.py (rev 0)
+++ zope.interface/trunk/build_ext_2.py 2010-04-09 08:16:17 UTC (rev 110699)
@@ -0,0 +1,38 @@
+import sys
+from distutils.errors import (CCompilerError, DistutilsExecError,
+ DistutilsPlatformError)
+try:
+ from setuptools.command.build_ext import build_ext
+except ImportError:
+ from distutils.command.build_ext import build_ext
+
+
+class optional_build_ext(build_ext):
+ """This class subclasses build_ext and allows
+ the building of C extensions to fail.
+ """
+ def run(self):
+ try:
+ build_ext.run(self)
+
+ except DistutilsPlatformError, e:
+ self._unavailable(e)
+
+ def build_extension(self, ext):
+ try:
+ build_ext.build_extension(self, ext)
+
+ except (CCompilerError, DistutilsExecError), e:
+ self._unavailable(e)
+
+ def _unavailable(self, e):
+ print >> sys.stderr, '*' * 80
+ print >> sys.stderr, """WARNING:
+
+ An optional code optimization (C extension) could not be compiled.
+
+ Optimizations for this package will not be available!"""
+ print >> sys.stderr
+ print >> sys.stderr, e
+ print >> sys.stderr, '*' * 80
+
\ No newline at end of file
Copied: zope.interface/trunk/build_ext_3.py (from rev 110698, zope.interface/branches/regebro-python3/build_ext_3.py)
===================================================================
--- zope.interface/trunk/build_ext_3.py (rev 0)
+++ zope.interface/trunk/build_ext_3.py 2010-04-09 08:16:17 UTC (rev 110699)
@@ -0,0 +1,40 @@
+import os
+import sys
+from distutils.errors import (CCompilerError, DistutilsExecError,
+ DistutilsPlatformError)
+try:
+ from setuptools.command.build_ext import build_ext
+ from pkg_resources import (normalize_path, working_set,
+ add_activation_listener, require)
+except ImportError:
+ from distutils.command.build_ext import build_ext
+
+
+class optional_build_ext(build_ext):
+ """This class subclasses build_ext and allows
+ the building of C extensions to fail.
+ """
+ def run(self):
+ try:
+ build_ext.run(self)
+
+ except DistutilsPlatformError as e:
+ self._unavailable(e)
+
+ def build_extension(self, ext):
+ try:
+ build_ext.build_extension(self, ext)
+
+ except (CCompilerError, DistutilsExecError) as e:
+ self._unavailable(e)
+
+ def _unavailable(self, e):
+ print('*' * 80, file=sys.stderr)
+ print("""WARNING:
+
+ An optional code optimization (C extension) could not be compiled.
+
+ Optimizations for this package will not be available!""", file=sys.stderr)
+ print(file=sys.stderr)
+ print(e, file=sys.stderr)
+ print('*' * 80, file=sys.stderr)
Modified: zope.interface/trunk/setup.py
===================================================================
--- zope.interface/trunk/setup.py 2010-04-09 02:33:49 UTC (rev 110698)
+++ zope.interface/trunk/setup.py 2010-04-09 08:16:17 UTC (rev 110699)
@@ -23,17 +23,15 @@
import os, sys
-from distutils.errors import (CCompilerError, DistutilsExecError,
- DistutilsPlatformError)
+from distutils.errors import CCompilerError, DistutilsExecError, \
+ DistutilsPlatformError
try:
from setuptools import setup, Extension, Feature
- from setuptools.command.build_ext import build_ext
-except ImportError, e:
+except ImportError:
# do we need to support plain distutils for building when even
# the package itself requires setuptools for installing?
from distutils.core import setup, Extension
- from distutils.command.build_ext import build_ext
if sys.version_info[:2] >= (2, 4):
extra = dict(
@@ -60,7 +58,7 @@
namespace_packages=["zope"],
include_package_data = True,
zip_safe = False,
- tests_require = ['zope.testing'],
+ tests_require = [],
install_requires = ['setuptools'],
extras_require={'docs': ['z3c.recipe.sphinxdoc']},
features = {'codeoptimization': codeoptimization}
@@ -87,40 +85,29 @@
'********\n'
)
+try: # Zope 3 setuptools versions
+ from build_ext_3 import optional_build_ext
+ # This is Python 3. Setuptools is now required, and so is zope.fixers.
+ extra['install_requires'] = ['setuptools']
+ extra['setup_requires'] = ['zope.fixers']
+ extra['use_2to3'] = True
+ extra['convert_2to3_doctests'] = [
+ 'src/zope/interface/README.ru.txt',
+ 'src/zope/interface/README.txt',
+ 'src/zope/interface/adapter.ru.txt',
+ 'src/zope/interface/adapter.txt',
+ 'src/zope/interface/human.ru.txt',
+ 'src/zope/interface/human.txt',
+ 'src/zope/interface/index.txt',
+ 'src/zope/interface/verify.txt',
+ ]
+ extra['use_2to3_fixers'] = ['zope.fixers']
-class optional_build_ext(build_ext):
- """This class subclasses build_ext and allows
- the building of C extensions to fail.
- """
- def run(self):
- try:
- build_ext.run(self)
-
- except DistutilsPlatformError, e:
- self._unavailable(e)
-
- def build_extension(self, ext):
- try:
- build_ext.build_extension(self, ext)
-
- except (CCompilerError, DistutilsExecError), e:
- self._unavailable(e)
-
- def _unavailable(self, e):
- print >> sys.stderr, '*' * 80
- print >> sys.stderr, """WARNING:
-
- An optional code optimization (C extension) could not be compiled.
-
- Optimizations for this package will not be available!"""
- print >> sys.stderr
- print >> sys.stderr, e
- print >> sys.stderr, '*' * 80
+except (ImportError, SyntaxError):
+ from build_ext_2 import optional_build_ext
-
-
setup(name='zope.interface',
- version = '3.5.4',
+ version = '3.6.0dev',
url='http://pypi.python.org/pypi/zope.interface',
license='ZPL 2.1',
description='Interfaces for Python',
@@ -128,7 +115,9 @@
author_email='zope-dev at zope.org',
long_description=long_description,
- packages = ['zope', 'zope.interface'],
+ packages = ['zope', 'zope.interface', 'zope.interface.tests'],
package_dir = {'': 'src'},
- cmdclass = {'build_ext': optional_build_ext},
+ cmdclass = {'build_ext': optional_build_ext,
+ },
+ test_suite = 'zope.interface.tests',
**extra)
Modified: zope.interface/trunk/src/zope/interface/README.ru.txt
===================================================================
--- zope.interface/trunk/src/zope/interface/README.ru.txt 2010-04-09 02:33:49 UTC (rev 110698)
+++ zope.interface/trunk/src/zope/interface/README.ru.txt 2010-04-09 08:16:17 UTC (rev 110699)
@@ -231,16 +231,19 @@
ÐÑзÑваÑÑÐ°Ñ ÑÑоÑона не должна пÑедполагаÑÑ, ÑÑо вÑегда бÑÐ´ÐµÑ ÑоздаваÑÑÑÑ
новÑй обÑекÑ.
-Также надо оÑмеÑиÑÑ, ÑÑо как минимÑм ÑейÑÐ°Ñ implementer не Ð¼Ð¾Ð¶ÐµÑ Ð¸ÑполÑзоваÑÑÑÑ
-Ð´Ð»Ñ ÐºÐ»Ð°ÑÑов::
+XXX: Double check and update these version numbers, and translate to russian:
- >>> zope.interface.implementer(IFoo)(Foo)
- ... # doctest: +NORMALIZE_WHITESPACE
- Traceback (most recent call last):
- ...
- TypeError: Can't use implementer with classes.
- Use one of the class-declaration functions instead.
+In zope.interface 3.5.1 and lower, the implementor decorator can not
+be used for classes, but in 3.5.2 and higher it can:
+ >>> Foo = zope.interface.implementer(IFoo)(Foo)
+ >>> list(zope.interface.providedBy(Foo()))
+ [<InterfaceClass __main__.IFoo>]
+
+Note that class decorators using the @implementor(IFoo) syntax are only
+supported in Python 2.6 and later.
+
+
ÐбÑÑвление пÑедоÑÑавлÑемÑÑ
инÑеÑÑейÑов
--------------------------------------
@@ -545,12 +548,12 @@
к ÑпеÑиÑикаÑиÑм. ÐбÑÑÐ²Ð»ÐµÐ½Ð¸Ñ ÑакÑиÑеÑки ÑаÑÑиÑÑÑÑ Ð¸Ð½ÑеÑÑейÑÑ ÐºÐ¾ÑоÑÑе они
обÑÑвлÑÑÑ::
- >>> class Baz:
+ >>> class Baz(object):
... zope.interface.implements(IBaz)
>>> baz_implements = zope.interface.implementedBy(Baz)
>>> baz_implements.__bases__
- (<InterfaceClass __main__.IBaz>,)
+ (<InterfaceClass __main__.IBaz>, <implementedBy ...object>)
>>> baz_implements.extends(IFoo)
True
@@ -568,7 +571,8 @@
<InterfaceClass __main__.IBaz>,
<InterfaceClass __main__.IFoo>,
<InterfaceClass __main__.IBlat>,
- <InterfaceClass zope.interface.Interface>)
+ <InterfaceClass zope.interface.Interface>,
+ <implementedBy ...object>)
ÐомеÑеннÑе знаÑениÑ
===================
@@ -657,11 +661,13 @@
бÑÐ´ÐµÑ Ð²ÑкинÑÑо единÑÑвенное иÑклÑÑение `Invalid` Ñо ÑпиÑком иÑклÑÑений
как аÑгÑменÑом::
+ >>> from zope.interface.exceptions import Invalid
>>> errors = []
- >>> IRange.validateInvariants(Range(2,1), errors)
- Traceback (most recent call last):
- ...
- Invalid: [RangeError(Range(2, 1))]
+ >>> try:
+ ... IRange.validateInvariants(Range(2,1), errors)
+ ... except Invalid, e:
+ ... str(e)
+ '[RangeError(Range(2, 1))]'
Ð ÑпиÑок бÑÐ´ÐµÑ Ð·Ð°Ð¿Ð¾Ð»Ð½ÐµÐ½ индивидÑалÑнÑми иÑклÑÑениÑми::
Modified: zope.interface/trunk/src/zope/interface/README.txt
===================================================================
--- zope.interface/trunk/src/zope/interface/README.txt 2010-04-09 02:33:49 UTC (rev 110698)
+++ zope.interface/trunk/src/zope/interface/README.txt 2010-04-09 08:16:17 UTC (rev 110699)
@@ -231,16 +231,33 @@
Note that the implementer decorator may modify it's argument. Callers
should not assume that a new object is created.
-Also note that, at least for now, implementer can't be used with
-classes::
+Using implementer also works on callable objects. This is used by
+zope.formlib, as an example.
- >>> zope.interface.implementer(IFoo)(Foo)
- ... # doctest: +NORMALIZE_WHITESPACE
- Traceback (most recent call last):
- ...
- TypeError: Can't use implementer with classes.
- Use one of the class-declaration functions instead.
+ >>> class yfactory:
+ ... def __call__(self, y):
+ ... foo = Foo()
+ ... foo.y = y
+ ... return foo
+ >>> yfoo = yfactory()
+ >>> yfoo = zope.interface.implementer(IFoo)(yfoo)
+ >>> list(zope.interface.implementedBy(yfoo))
+ [<InterfaceClass __main__.IFoo>]
+
+XXX: Double check and update these version numbers:
+
+In zope.interface 3.5.2 and lower, the implementor decorator can not
+be used for classes, but in 3.6.0 and higher it can:
+
+ >>> Foo = zope.interface.implementer(IFoo)(Foo)
+ >>> list(zope.interface.providedBy(Foo()))
+ [<InterfaceClass __main__.IFoo>]
+
+Note that class decorators using the @implementor(IFoo) syntax are only
+supported in Python 2.6 and later.
+
+
Declaring provided interfaces
-----------------------------
@@ -547,12 +564,12 @@
declarations and specifications. Declarations actually extend the
interfaces that they declare::
- >>> class Baz:
+ >>> class Baz(object):
... zope.interface.implements(IBaz)
>>> baz_implements = zope.interface.implementedBy(Baz)
>>> baz_implements.__bases__
- (<InterfaceClass __main__.IBaz>,)
+ (<InterfaceClass __main__.IBaz>, <implementedBy ...object>)
>>> baz_implements.extends(IFoo)
True
@@ -570,7 +587,8 @@
<InterfaceClass __main__.IBaz>,
<InterfaceClass __main__.IFoo>,
<InterfaceClass __main__.IBlat>,
- <InterfaceClass zope.interface.Interface>)
+ <InterfaceClass zope.interface.Interface>,
+ <implementedBy ...object>)
Tagged Values
@@ -659,12 +677,14 @@
then a single `Invalid` exception will be raised with the list of
exceptions as it's argument::
+ >>> from zope.interface.exceptions import Invalid
>>> errors = []
- >>> IRange.validateInvariants(Range(2,1), errors)
- Traceback (most recent call last):
- ...
- Invalid: [RangeError(Range(2, 1))]
-
+ >>> try:
+ ... IRange.validateInvariants(Range(2,1), errors)
+ ... except Invalid, e:
+ ... str(e)
+ '[RangeError(Range(2, 1))]'
+
And the list will be filled with the individual exceptions::
>>> errors
Modified: zope.interface/trunk/src/zope/interface/__init__.py
===================================================================
--- zope.interface/trunk/src/zope/interface/__init__.py 2010-04-09 02:33:49 UTC (rev 110698)
+++ zope.interface/trunk/src/zope/interface/__init__.py 2010-04-09 08:16:17 UTC (rev 110699)
@@ -63,7 +63,8 @@
from zope.interface.declarations import providedBy, implementedBy
from zope.interface.declarations import classImplements, classImplementsOnly
from zope.interface.declarations import directlyProvidedBy, directlyProvides
-from zope.interface.declarations import alsoProvides, implementer
+from zope.interface.declarations import alsoProvides, provider
+from zope.interface.declarations import implementer, implementer_only
from zope.interface.declarations import implements, implementsOnly
from zope.interface.declarations import classProvides, moduleProvides
from zope.interface.declarations import noLongerProvides, Declaration
Modified: zope.interface/trunk/src/zope/interface/_zope_interface_coptimizations.c
===================================================================
--- zope.interface/trunk/src/zope/interface/_zope_interface_coptimizations.c 2010-04-09 02:33:49 UTC (rev 110698)
+++ zope.interface/trunk/src/zope/interface/_zope_interface_coptimizations.c 2010-04-09 08:16:17 UTC (rev 110699)
@@ -18,6 +18,12 @@
#define TYPE(O) ((PyTypeObject*)(O))
#define OBJECT(O) ((PyObject*)(O))
#define CLASSIC(O) ((PyClassObject*)(O))
+#ifndef PyVarObject_HEAD_INIT
+#define PyVarObject_HEAD_INIT(a, b) PyObject_HEAD_INIT(a) b,
+#endif
+#ifndef Py_TYPE
+#define Py_TYPE(o) ((o)->ob_type)
+#endif
static PyObject *str__dict__, *str__implemented__, *strextends;
static PyObject *BuiltinImplementationSpecifications, *str__provides__;
@@ -366,8 +372,7 @@
};
static PyTypeObject SpecType = {
- PyObject_HEAD_INIT(NULL)
- /* ob_size */ 0,
+ PyVarObject_HEAD_INIT(NULL, 0)
/* tp_name */ "_interface_coptimizations."
"SpecificationBase",
/* tp_basicsize */ 0,
@@ -376,7 +381,7 @@
/* tp_print */ (printfunc)0,
/* tp_getattr */ (getattrfunc)0,
/* tp_setattr */ (setattrfunc)0,
- /* tp_compare */ (cmpfunc)0,
+ /* tp_compare */ 0,
/* tp_repr */ (reprfunc)0,
/* tp_as_number */ 0,
/* tp_as_sequence */ 0,
@@ -414,8 +419,7 @@
}
static PyTypeObject OSDType = {
- PyObject_HEAD_INIT(NULL)
- /* ob_size */ 0,
+ PyVarObject_HEAD_INIT(NULL, 0)
/* tp_name */ "_interface_coptimizations."
"ObjectSpecificationDescriptor",
/* tp_basicsize */ 0,
@@ -424,7 +428,7 @@
/* tp_print */ (printfunc)0,
/* tp_getattr */ (getattrfunc)0,
/* tp_setattr */ (setattrfunc)0,
- /* tp_compare */ (cmpfunc)0,
+ /* tp_compare */ 0,
/* tp_repr */ (reprfunc)0,
/* tp_as_number */ 0,
/* tp_as_sequence */ 0,
@@ -479,8 +483,7 @@
}
static PyTypeObject CPBType = {
- PyObject_HEAD_INIT(NULL)
- /* ob_size */ 0,
+ PyVarObject_HEAD_INIT(NULL, 0)
/* tp_name */ "_interface_coptimizations."
"ClassProvidesBase",
/* tp_basicsize */ 0,
@@ -489,7 +492,7 @@
/* tp_print */ (printfunc)0,
/* tp_getattr */ (getattrfunc)0,
/* tp_setattr */ (setattrfunc)0,
- /* tp_compare */ (cmpfunc)0,
+ /* tp_compare */ 0,
/* tp_repr */ (reprfunc)0,
/* tp_as_number */ 0,
/* tp_as_sequence */ 0,
@@ -670,8 +673,7 @@
}
static PyTypeObject InterfaceBase = {
- PyObject_HEAD_INIT(NULL)
- /* ob_size */ 0,
+ PyVarObject_HEAD_INIT(NULL, 0)
/* tp_name */ "_zope_interface_coptimizations."
"InterfaceBase",
/* tp_basicsize */ 0,
@@ -680,7 +682,7 @@
/* tp_print */ (printfunc)0,
/* tp_getattr */ (getattrfunc)0,
/* tp_setattr */ (setattrfunc)0,
- /* tp_compare */ (cmpfunc)0,
+ /* tp_compare */ 0,
/* tp_repr */ (reprfunc)0,
/* tp_as_number */ 0,
/* tp_as_sequence */ 0,
@@ -764,7 +766,7 @@
lookup_dealloc(lookup *self)
{
lookup_clear(self);
- self->ob_type->tp_free((PyObject*)self);
+ Py_TYPE(self)->tp_free((PyObject*)self);
}
/*
@@ -1222,8 +1224,7 @@
};
static PyTypeObject LookupBase = {
- PyObject_HEAD_INIT(NULL)
- /* ob_size */ 0,
+ PyVarObject_HEAD_INIT(NULL, 0)
/* tp_name */ "_zope_interface_coptimizations."
"LookupBase",
/* tp_basicsize */ sizeof(lookup),
@@ -1232,7 +1233,7 @@
/* tp_print */ (printfunc)0,
/* tp_getattr */ (getattrfunc)0,
/* tp_setattr */ (setattrfunc)0,
- /* tp_compare */ (cmpfunc)0,
+ /* tp_compare */ 0,
/* tp_repr */ (reprfunc)0,
/* tp_as_number */ 0,
/* tp_as_sequence */ 0,
@@ -1293,7 +1294,7 @@
verifying_dealloc(verify *self)
{
verifying_clear(self);
- self->ob_type->tp_free((PyObject*)self);
+ Py_TYPE(self)->tp_free((PyObject*)self);
}
/*
@@ -1383,9 +1384,10 @@
if (generations == NULL)
return -1;
- changed = PyObject_Compare(self->_verify_generations, generations);
+ changed = PyObject_RichCompareBool(self->_verify_generations,
+ generations, Py_NE);
Py_DECREF(generations);
- if (PyErr_Occurred())
+ if (changed == -1)
return -1;
if (changed == 0)
@@ -1509,8 +1511,7 @@
};
static PyTypeObject VerifyingBase = {
- PyObject_HEAD_INIT(NULL)
- /* ob_size */ 0,
+ PyVarObject_HEAD_INIT(NULL, 0)
/* tp_name */ "_zope_interface_coptimizations."
"VerifyingBase",
/* tp_basicsize */ sizeof(verify),
@@ -1519,7 +1520,7 @@
/* tp_print */ (printfunc)0,
/* tp_getattr */ (getattrfunc)0,
/* tp_setattr */ (setattrfunc)0,
- /* tp_compare */ (cmpfunc)0,
+ /* tp_compare */ 0,
/* tp_repr */ (reprfunc)0,
/* tp_as_number */ 0,
/* tp_as_sequence */ 0,
@@ -1563,16 +1564,38 @@
{NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
};
+static char module_doc[] = "C optimizations for zope.interface\n\n"
+ "$Id$";
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef _zic_module = {
+ PyModuleDef_HEAD_INIT,
+ "_zope_interface_coptimizations",
+ module_doc,
+ -1,
+ m_methods,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+#endif
+
#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#endif
-PyMODINIT_FUNC
-init_zope_interface_coptimizations(void)
+static PyObject *
+init(void)
{
PyObject *m;
+#if PY_MAJOR_VERSION < 3
#define DEFINE_STRING(S) \
if(! (str ## S = PyString_FromString(# S))) return
+#else
+#define DEFINE_STRING(S) \
+ if(! (str ## S = PyUnicode_FromString(# S))) return NULL
+#endif
DEFINE_STRING(__dict__);
DEFINE_STRING(__implemented__);
@@ -1595,53 +1618,70 @@
#undef DEFINE_STRING
adapter_hooks = PyList_New(0);
if (adapter_hooks == NULL)
- return;
+ return NULL;
/* Initialize types: */
SpecType.tp_new = PyBaseObject_Type.tp_new;
if (PyType_Ready(&SpecType) < 0)
- return;
+ return NULL;
OSDType.tp_new = PyBaseObject_Type.tp_new;
if (PyType_Ready(&OSDType) < 0)
- return;
+ return NULL;
CPBType.tp_new = PyBaseObject_Type.tp_new;
if (PyType_Ready(&CPBType) < 0)
- return;
+ return NULL;
InterfaceBase.tp_new = PyBaseObject_Type.tp_new;
if (PyType_Ready(&InterfaceBase) < 0)
- return;
+ return NULL;
LookupBase.tp_new = PyBaseObject_Type.tp_new;
if (PyType_Ready(&LookupBase) < 0)
- return;
+ return NULL;
VerifyingBase.tp_new = PyBaseObject_Type.tp_new;
if (PyType_Ready(&VerifyingBase) < 0)
- return;
+ return NULL;
-
+ #if PY_MAJOR_VERSION < 3
/* Create the module and add the functions */
m = Py_InitModule3("_zope_interface_coptimizations", m_methods,
"C optimizations for zope.interface\n\n"
- "$Id$");
+ "$Id$");
+ #else
+ m = PyModule_Create(&_zic_module);
+ #endif
if (m == NULL)
- return;
-
+ return NULL;
+
/* Add types: */
if (PyModule_AddObject(m, "SpecificationBase", OBJECT(&SpecType)) < 0)
- return;
+ return NULL;
if (PyModule_AddObject(m, "ObjectSpecificationDescriptor",
(PyObject *)&OSDType) < 0)
- return;
+ return NULL;
if (PyModule_AddObject(m, "ClassProvidesBase", OBJECT(&CPBType)) < 0)
- return;
+ return NULL;
if (PyModule_AddObject(m, "InterfaceBase", OBJECT(&InterfaceBase)) < 0)
- return;
+ return NULL;
if (PyModule_AddObject(m, "LookupBase", OBJECT(&LookupBase)) < 0)
- return;
+ return NULL;
if (PyModule_AddObject(m, "VerifyingBase", OBJECT(&VerifyingBase)) < 0)
- return;
+ return NULL;
if (PyModule_AddObject(m, "adapter_hooks", adapter_hooks) < 0)
- return;
+ return NULL;
+ return m;
}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC
+init_zope_interface_coptimizations(void)
+{
+ init();
+}
+#else
+PyInit__zope_interface_coptimizations(void)
+{
+ return init();
+}
+#endif
Modified: zope.interface/trunk/src/zope/interface/adapter.py
===================================================================
--- zope.interface/trunk/src/zope/interface/adapter.py 2010-04-09 02:33:49 UTC (rev 110698)
+++ zope.interface/trunk/src/zope/interface/adapter.py 2010-04-09 08:16:17 UTC (rev 110699)
@@ -33,6 +33,10 @@
def __init__(self, bases=()):
+ # The comments here could be improved. Possibly this bit needs
+ # explaining in a separate document, as the comments here can
+ # be quite confusing. /regebro
+
# {order -> {required -> {provided -> {name -> value}}}}
# Here "order" is actually an index in a list, "required" and
# "provided" are interfaces, and "required" is really a nested
@@ -41,6 +45,7 @@
# {provided -> {name -> value}}
# but for order == 2 (that is, self._adapters[2]), we have:
# {r1 -> {r2 -> {provided -> {name -> value}}}}
+ #
self._adapters = []
# {order -> {required -> {provided -> {name -> [value]}}}}
@@ -70,6 +75,7 @@
# Setting the bases causes the registries described above
# to be initialized (self._setBases -> self.changed ->
# self._v_lookup.changed).
+
self.__bases__ = bases
def _setBases(self, bases):
@@ -153,6 +159,8 @@
# Keep track of how we got to `components`:
lookups = []
+ # Keep track of how we got to `components`:
+ lookups = []
for k in key:
d = components.get(k)
if d is None:
@@ -228,6 +236,8 @@
# Keep track of how we got to `components`:
lookups = []
+ # Keep track of how we got to `components`:
+ lookups = []
for k in key:
d = components.get(k)
if d is None:
Modified: zope.interface/trunk/src/zope/interface/adapter.ru.txt
===================================================================
--- zope.interface/trunk/src/zope/interface/adapter.ru.txt 2010-04-09 02:33:49 UTC (rev 110698)
+++ zope.interface/trunk/src/zope/interface/adapter.ru.txt 2010-04-09 08:16:17 UTC (rev 110699)
@@ -384,24 +384,21 @@
>>> adapters = list(registry.lookupAll([IR1], IP1))
>>> adapters.sort()
- >>> adapters
- [(u'', 11), (u'bob', "Bob's 12")]
+ >>> assert adapters == [(u'', 11), (u'bob', "Bob's 12")]
ÐÑо ÑабоÑÐ°ÐµÑ Ñакже и Ð´Ð»Ñ Ð¼ÑлÑÑи-адапÑеÑов::
>>> registry.register([IR1, IQ2], IP2, 'bob', '1q2 for bob')
>>> adapters = list(registry.lookupAll([IR2, IQ2], IP1))
>>> adapters.sort()
- >>> adapters
- [(u'', '1q22'), (u'bob', '1q2 for bob')]
+ >>> assert adapters == [(u'', '1q22'), (u'bob', '1q2 for bob')]
Рдаже Ð´Ð»Ñ Ð½ÑлевÑÑ
адапÑеÑов::
>>> registry.register([], IP2, 'bob', 3)
>>> adapters = list(registry.lookupAll([], IP1))
>>> adapters.sort()
- >>> adapters
- [(u'', 2), (u'bob', 3)]
+ >>> assert adapters == [(u'', 2), (u'bob', 3)]
ÐодпиÑки
========
Modified: zope.interface/trunk/src/zope/interface/adapter.txt
===================================================================
--- zope.interface/trunk/src/zope/interface/adapter.txt 2010-04-09 02:33:49 UTC (rev 110698)
+++ zope.interface/trunk/src/zope/interface/adapter.txt 2010-04-09 08:16:17 UTC (rev 110699)
@@ -386,24 +386,21 @@
>>> adapters = list(registry.lookupAll([IR1], IP1))
>>> adapters.sort()
- >>> adapters
- [(u'', 11), (u'bob', "Bob's 12")]
+ >>> assert adapters == [(u'', 11), (u'bob', "Bob's 12")]
This works for multi-adapters too::
>>> registry.register([IR1, IQ2], IP2, 'bob', '1q2 for bob')
>>> adapters = list(registry.lookupAll([IR2, IQ2], IP1))
>>> adapters.sort()
- >>> adapters
- [(u'', '1q22'), (u'bob', '1q2 for bob')]
+ >>> assert adapters == [(u'', '1q22'), (u'bob', '1q2 for bob')]
And even null adapters::
>>> registry.register([], IP2, 'bob', 3)
>>> adapters = list(registry.lookupAll([], IP1))
>>> adapters.sort()
- >>> adapters
- [(u'', 2), (u'bob', 3)]
+ >>> assert adapters == [(u'', 2), (u'bob', 3)]
Subscriptions
=============
Modified: zope.interface/trunk/src/zope/interface/advice.py
===================================================================
--- zope.interface/trunk/src/zope/interface/advice.py 2010-04-09 02:33:49 UTC (rev 110698)
+++ zope.interface/trunk/src/zope/interface/advice.py 2010-04-09 08:16:17 UTC (rev 110699)
@@ -27,7 +27,13 @@
$Id$
"""
-from types import ClassType, FunctionType
+from types import FunctionType
+try:
+ from types import ClassType
+ __python3 = False
+except ImportError:
+ __python3 = True
+
import sys
def getFrameInfo(frame):
@@ -102,7 +108,10 @@
# )
previousMetaclass = caller_locals.get('__metaclass__')
- defaultMetaclass = caller_globals.get('__metaclass__', ClassType)
+ if __python3:
+ defaultMetaclass = caller_globals.get('__metaclass__', type)
+ else:
+ defaultMetaclass = caller_globals.get('__metaclass__', ClassType)
def advise(name, bases, cdict):
@@ -111,11 +120,11 @@
del cdict['__metaclass__']
if previousMetaclass is None:
- if bases:
- # find best metaclass or use global __metaclass__ if no bases
- meta = determineMetaclass(bases)
- else:
- meta = defaultMetaclass
+ if bases:
+ # find best metaclass or use global __metaclass__ if no bases
+ meta = determineMetaclass(bases)
+ else:
+ meta = defaultMetaclass
elif isClassAdvisor(previousMetaclass):
# special case: we can't compute the "true" metaclass here,
@@ -162,6 +171,7 @@
if not candidates:
# they're all "classic" classes
+ assert(not __python3) # This should not happen under Python 3
return ClassType
elif len(candidates)>1:
@@ -175,7 +185,8 @@
def minimalBases(classes):
"""Reduce a list of base classes to its ordered minimum equivalent"""
- classes = [c for c in classes if c is not ClassType]
+ if not __python3:
+ classes = [c for c in classes if c is not ClassType]
candidates = []
for m in classes:
Modified: zope.interface/trunk/src/zope/interface/declarations.py
===================================================================
--- zope.interface/trunk/src/zope/interface/declarations.py 2010-04-09 02:33:49 UTC (rev 110698)
+++ zope.interface/trunk/src/zope/interface/declarations.py 2010-04-09 08:16:17 UTC (rev 110699)
@@ -33,8 +33,7 @@
from zope.interface.interface import InterfaceClass, Specification
from zope.interface.interface import SpecificationBase
from ro import mergeOrderings, ro
-import exceptions
-from types import ClassType, ModuleType
+from types import ModuleType, MethodType, FunctionType
from zope.interface.advice import addClassAdvisor
# Registry of class-implementation specifications
@@ -97,12 +96,8 @@
>>> spec = Declaration(I2, I3)
>>> spec = Declaration(I4, spec)
>>> i = iter(spec)
- >>> i.next().getName()
- 'I4'
- >>> i.next().getName()
- 'I2'
- >>> i.next().getName()
- 'I3'
+ >>> [x.getName() for x in i]
+ ['I4', 'I2', 'I3']
>>> list(i)
[]
"""
@@ -125,16 +120,8 @@
>>> spec = Declaration(I2, I3)
>>> spec = Declaration(I4, spec)
>>> i = spec.flattened()
- >>> i.next().getName()
- 'I4'
- >>> i.next().getName()
- 'I2'
- >>> i.next().getName()
- 'I1'
- >>> i.next().getName()
- 'I3'
- >>> i.next().getName()
- 'Interface'
+ >>> [x.getName() for x in i]
+ ['I4', 'I2', 'I1', 'I3', 'Interface']
>>> list(i)
[]
@@ -475,7 +462,7 @@
b = implementedBy(c)
if b not in seen:
seen[b] = 1
- bases.append(b)
+ bases.append(b)
spec.__bases__ = tuple(bases)
@@ -493,9 +480,9 @@
def __call__(self, ob):
if isinstance(ob, DescriptorAwareMetaClasses):
- raise TypeError("Can't use implementer with classes. Use one of "
- "the class-declaration functions instead."
- )
+ classImplements(ob, *self.interfaces)
+ return ob
+
spec = Implements(*self.interfaces)
try:
ob.__implemented__ = spec
@@ -503,6 +490,23 @@
raise TypeError("Can't declare implements", ob)
return ob
+class implementer_only:
+
+ def __init__(self, *interfaces):
+ self.interfaces = interfaces
+
+ def __call__(self, ob):
+ if isinstance(ob, (FunctionType, MethodType)):
+ # XXX Does this decorator make sense for anything but classes?
+ # I don't think so. There can be no inheritance of interfaces
+ # on a method pr function....
+ raise ValueError('The implementor_only decorator is not '
+ 'supported for methods or functions.')
+ else:
+ # Assume it's a class:
+ classImplementsOnly(ob, *self.interfaces)
+ return ob
+
def _implements(name, interfaces, classImplements):
frame = sys._getframe(2)
locals = frame.f_locals
@@ -558,10 +562,10 @@
...
>>> class IC(Interface): pass
...
- >>> class A(object): implements(IA1, IA2)
- ...
- >>> class B(object): implements(IB)
- ...
+ >>> class A(object):
+ ... implements(IA1, IA2)
+ >>> class B(object):
+ ... implements(IB)
>>> class C(A, B):
... implements(IC)
@@ -615,10 +619,10 @@
...
>>> class IC(Interface): pass
...
- >>> class A(object): implements(IA1, IA2)
- ...
- >>> class B(object): implements(IB)
- ...
+ >>> class A(object):
+ ... implements(IA1, IA2)
+ >>> class B(object):
+ ... implements(IB)
>>> class C(A, B):
... implementsOnly(IC)
@@ -756,8 +760,12 @@
return spec
Provides.__safe_for_unpickling__ = True
-
-DescriptorAwareMetaClasses = ClassType, type
+try:
+ from types import ClassType
+ DescriptorAwareMetaClasses = ClassType, type
+except ImportError: # Python 3
+ DescriptorAwareMetaClasses = (type,)
+
def directlyProvides(object, *interfaces):
"""Declare interfaces declared directly for an object
@@ -782,10 +790,10 @@
...
>>> class IC(Interface): pass
...
- >>> class A(object): implements(IA1, IA2)
- ...
- >>> class B(object): implements(IB)
- ...
+ >>> class A(object):
+ ... implements(IA1, IA2)
+ >>> class B(object):
+ ... implements(IB)
>>> class C(A, B):
... implements(IC)
@@ -886,10 +894,10 @@
...
>>> class IC(Interface): pass
...
- >>> class A(object): implements(IA1, IA2)
- ...
- >>> class B(object): implements(IB)
- ...
+ >>> class A(object):
+ ... implements(IA1, IA2)
+ >>> class B(object):
+ ... implements(IB)
>>> class C(A, B):
... implements(IC)
@@ -1106,13 +1114,6 @@
>>> [i.getName() for i in C().__providedBy__]
['IFoo']
- If classProvides is called outside of a class definition, it fails.
-
- >>> classProvides(IFooFactory)
- Traceback (most recent call last):
- ...
- TypeError: classProvides can be used only from a class definition.
-
"""
frame = sys._getframe(1)
locals = frame.f_locals
@@ -1135,6 +1136,16 @@
directlyProvides(cls, *interfaces)
return cls
+class provider:
+ """Class decorator version of classProvides"""
+
+ def __init__(self, *interfaces):
+ self.interfaces = interfaces
+
+ def __call__(self, ob):
+ directlyProvides(ob, *self.interfaces)
+ return ob
+
def moduleProvides(*interfaces):
"""Declare interfaces provided by a module
@@ -1197,12 +1208,12 @@
...
>>> class I5(Interface): pass
...
- >>> class A(object): implements(I1)
- ...
+ >>> class A(object):
+ ... implements(I1)
>>> class B(object): __implemented__ = I2
...
- >>> class C(A, B): implements(I31)
- ...
+ >>> class C(A, B):
+ ... implements(I31)
>>> c = C()
>>> directlyProvides(c, I4)
>>> [i.getName() for i in providedBy(c)]
@@ -1219,10 +1230,10 @@
1
>>> int(providedBy(c).extends(I5))
0
- >>> class COnly(A, B): implementsOnly(I31)
- ...
- >>> class D(COnly): implements(I5)
- ...
+ >>> class COnly(A, B):
+ ... implementsOnly(I31)
+ >>> class D(COnly):
+ ... implements(I5)
>>> c = D()
>>> directlyProvides(c, I4)
>>> [i.getName() for i in providedBy(c)]
Modified: zope.interface/trunk/src/zope/interface/interface.py
===================================================================
--- zope.interface/trunk/src/zope/interface/interface.py 2010-04-09 02:33:49 UTC (rev 110698)
+++ zope.interface/trunk/src/zope/interface/interface.py 2010-04-09 08:16:17 UTC (rev 110699)
@@ -340,12 +340,8 @@
>>> spec = Specification((I2, I3))
>>> spec = Specification((I4, spec))
>>> i = spec.interfaces()
- >>> i.next().getName()
- 'I4'
- >>> i.next().getName()
- 'I2'
- >>> i.next().getName()
- 'I3'
+ >>> [x.getName() for x in i]
+ ['I4', 'I2', 'I3']
>>> list(i)
[]
"""
@@ -480,6 +476,9 @@
# Make sure that all recorded attributes (and methods) are of type
# `Attribute` and `Method`
for name, attr in attrs.items():
+ if name == '__locals__':
+ # This happens under Python 3 sometimes, not sure why. /regebro
+ continue
if isinstance(attr, Attribute):
attr.interface = self
if not attr.__name__:
@@ -505,8 +504,8 @@
...
>>>
>>> i = I1.interfaces()
- >>> i.next().getName()
- 'I1'
+ >>> [x.getName() for x in i]
+ ['I1']
>>> list(i)
[]
"""
@@ -574,7 +573,7 @@
exec "class %s: pass" % self.__name__ in klass
klass=klass[self.__name__]
- self.__d(klass.__dict__)
+ self.__d(klass)
self._deferred=klass
@@ -603,14 +602,13 @@
"""Retrieve a named interface."""
return None
- def __d(self, dict):
-
+ def __d(self, klass):
for k, v in self.__attrs.items():
- if isinstance(v, Method) and not (k in dict):
- dict[k]=v
+ if isinstance(v, Method) and not (k in klass.__dict__):
+ setattr(klass, k, v)
for b in self.__bases__:
- b.__d(dict)
+ b.__d(klass)
def __repr__(self):
try:
@@ -681,7 +679,7 @@
n2 = (getattr(o2, '__name__', ''),
getattr(getattr(o2, '__module__', None), '__name__', ''))
- return cmp(n1, n2)
+ return (n1 > n2) - (n1 < n2)
def __lt__(self, other):
c = self.__cmp(self, other)
Modified: zope.interface/trunk/src/zope/interface/interfaces.py
===================================================================
--- zope.interface/trunk/src/zope/interface/interfaces.py 2010-04-09 02:33:49 UTC (rev 110698)
+++ zope.interface/trunk/src/zope/interface/interfaces.py 2010-04-09 08:16:17 UTC (rev 110699)
@@ -446,6 +446,13 @@
Instances of ``C`` provide only ``I1``, ``I2``, and regardless of
whatever interfaces instances of ``A`` and ``B`` implement.
"""
+
+ def implementer_only(*interfaces):
+ """Create a decorator for declaring the only interfaces implemented
+
+ A callable is returned that makes an implements declaration on
+ objects passed to it.
+ """
def directlyProvidedBy(object):
"""Return the interfaces directly provided by the given object
@@ -614,6 +621,8 @@
after the class has been created.
"""
+ def provider(*interfaces):
+ """A class decorator version of classProvides"""
def moduleProvides(*interfaces):
"""Declare interfaces provided by a module
Modified: zope.interface/trunk/src/zope/interface/tests/__init__.py
===================================================================
--- zope.interface/trunk/src/zope/interface/tests/__init__.py 2010-04-09 02:33:49 UTC (rev 110698)
+++ zope.interface/trunk/src/zope/interface/tests/__init__.py 2010-04-09 08:16:17 UTC (rev 110699)
@@ -1,2 +1,13 @@
-#
-# This file is necessary to make this directory a package.
+import os
+import unittest
+
+def additional_tests():
+ suites = unittest.TestSuite()
+ for file in os.listdir(os.path.dirname(__file__)):
+ if file.endswith('.py') and file!='__init__.py':
+ name = os.path.splitext(file)[0]
+ module = __import__('.'.join((__name__, name)), globals(),
+ locals(), [name])
+ if hasattr(module, 'test_suite'):
+ suites.addTests(module.test_suite())
+ return suites
Modified: zope.interface/trunk/src/zope/interface/tests/odd.py
===================================================================
--- zope.interface/trunk/src/zope/interface/tests/odd.py 2010-04-09 02:33:49 UTC (rev 110698)
+++ zope.interface/trunk/src/zope/interface/tests/odd.py 2010-04-09 08:16:17 UTC (rev 110699)
@@ -21,8 +21,8 @@
...
>>> A.__name__
'A'
- >>> A.__bases__
- (<type 'object'>,)
+ >>> A.__bases__ == (object,)
+ True
>>> class B(object):
... __metaclass__ = MetaClass
... b = 1
@@ -55,9 +55,11 @@
>>> C.c = 1
>>> c.c
1
- >>> from types import ClassType
- >>> int(isinstance(C, (type, ClassType)))
- 0
+ >>> import sys
+ >>> if sys.version[0] == '2': # This test only makes sense under Python 2.x
+ ... from types import ClassType
+ ... assert not isinstance(C, (type, ClassType))
+
>>> int(C.__class__.__class__ is C.__class__)
1
Modified: zope.interface/trunk/src/zope/interface/tests/test_advice.py
===================================================================
--- zope.interface/trunk/src/zope/interface/tests/test_advice.py 2010-04-09 02:33:49 UTC (rev 110698)
+++ zope.interface/trunk/src/zope/interface/tests/test_advice.py 2010-04-09 08:16:17 UTC (rev 110699)
@@ -31,7 +31,6 @@
import unittest
from unittest import TestCase, makeSuite, TestSuite
from zope.interface.advice import *
-from types import ClassType
import sys
def ping(log, value):
@@ -42,9 +41,14 @@
addClassAdvisor(pong)
-class ClassicClass:
- __metaclass__ = ClassType
- classLevelFrameInfo = getFrameInfo(sys._getframe())
+try:
+ from types import ClassType
+
+ class ClassicClass:
+ __metaclass__ = ClassType
+ classLevelFrameInfo = getFrameInfo(sys._getframe())
+except ImportError:
+ pass
class NewStyleClass:
__metaclass__ = type
@@ -172,7 +176,11 @@
TestClasses = (AdviceTests, FrameInfoTest)
def test_suite():
- return TestSuite([makeSuite(t,'check') for t in TestClasses])
+ if sys.version[0] == '2':
+ return TestSuite([makeSuite(t,'check') for t in TestClasses])
+ else:
+ # Advise metaclasses doesn't work in Python 3
+ return []
if __name__ == '__main__':
unittest.main(defaultTest='test_suite')
Modified: zope.interface/trunk/src/zope/interface/tests/test_interface.py
===================================================================
--- zope.interface/trunk/src/zope/interface/tests/test_interface.py 2010-04-09 02:33:49 UTC (rev 110698)
+++ zope.interface/trunk/src/zope/interface/tests/test_interface.py 2010-04-09 08:16:17 UTC (rev 110699)
@@ -338,6 +338,9 @@
def testIssue228(self):
from zope.interface import Interface
# Test for http://collector.zope.org/Zope3-dev/228
+ if sys.version[0] == '3':
+ # No old style classes in Python 3, so the test becomes moot.
+ return
class I(Interface):
"xxx"
class Bad:
@@ -373,12 +376,14 @@
... def __init__(self, min, max):
... self.min, self.max = min, max
+ >>> from zope.interface.exceptions import Invalid
>>> IRange.validateInvariants(Range(1,2))
>>> IRange.validateInvariants(Range(1,1))
- >>> IRange.validateInvariants(Range(2,1))
- Traceback (most recent call last):
- ...
- Invalid: max < min
+ >>> try:
+ ... IRange.validateInvariants(Range(2,1))
+ ... except Invalid, e:
+ ... str(e)
+ 'max < min'
"""
@@ -391,11 +396,11 @@
suite.addTest(doctest.DocFileSuite(
'../README.txt',
globs={'__name__': '__main__'},
- optionflags=doctest.NORMALIZE_WHITESPACE,
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
))
suite.addTest(doctest.DocFileSuite(
'../README.ru.txt',
globs={'__name__': '__main__'},
- optionflags=doctest.NORMALIZE_WHITESPACE,
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
))
return suite
Modified: zope.interface/trunk/src/zope/interface/tests/test_odd_declarations.py
===================================================================
--- zope.interface/trunk/src/zope/interface/tests/test_odd_declarations.py 2010-04-09 02:33:49 UTC (rev 110698)
+++ zope.interface/trunk/src/zope/interface/tests/test_odd_declarations.py 2010-04-09 08:16:17 UTC (rev 110699)
@@ -19,9 +19,9 @@
$Id$
"""
import doctest
-import odd
import unittest
+from zope.interface.tests import odd
from zope.interface import Interface, implements, implementsOnly
from zope.interface import directlyProvides, providedBy, directlyProvidedBy
from zope.interface import classImplements, classImplementsOnly, implementedBy
@@ -45,10 +45,12 @@
# from zope.interface import classProvides
class A(Odd):
- implements(I1)
+ pass
+classImplements(A, I1)
class C(A, B):
- implements(I31)
+ pass
+classImplements(C, I31)
class Test(unittest.TestCase):
@@ -69,10 +71,12 @@
self.failIf(providedBy(c).extends(I5))
class COnly(A, B):
- implementsOnly(I31)
+ pass
+ classImplementsOnly(COnly, I31)
class D(COnly):
- implements(I5)
+ pass
+ classImplements(D, I5)
classImplements(D, I5)
@@ -91,7 +95,8 @@
class COnly(A, B): __implemented__ = I31
class D(COnly):
- implements(I5)
+ pass
+ classImplements(D, I5)
classImplements(D, I5)
c = D()
@@ -143,13 +148,16 @@
class IB(Interface): pass
class IC(Interface): pass
class A(Odd):
- implements(IA1, IA2)
+ pass
+ classImplements(A, IA1, IA2)
class B(Odd):
- implements(IB)
+ pass
+ classImplements(B, IB)
class C(A, B):
- implements(IC)
+ pass
+ classImplements(C, IC)
ob = C()
@@ -186,10 +194,12 @@
class I2(I1): pass
class C1(Odd):
- implements(I2)
+ pass
+ classImplements(C1, I2)
class C2(C1):
- implements(I3)
+ pass
+ classImplements(C2, I3)
self.assertEqual([i.getName() for i in implementedBy(C2)],
['I3', 'I2'])
Modified: zope.interface/trunk/src/zope/interface/tests/test_sorting.py
===================================================================
--- zope.interface/trunk/src/zope/interface/tests/test_sorting.py 2010-04-09 02:33:49 UTC (rev 110698)
+++ zope.interface/trunk/src/zope/interface/tests/test_sorting.py 2010-04-09 08:16:17 UTC (rev 110699)
@@ -36,9 +36,9 @@
self.assertEqual(l, [I1, I2, I3, I4, I5, I6])
def test_w_None(self):
- l = [I1, None, I3, I5, None, I6, I4, I2]
+ l = [I1, None, I3, I5, I6, I4, I2]
l.sort()
- self.assertEqual(l, [I1, I2, I3, I4, I5, I6, None, None])
+ self.assertEqual(l, [I1, I2, I3, I4, I5, I6, None])
def test_suite():
return TestSuite((
Modified: zope.interface/trunk/src/zope/interface/verify.py
===================================================================
--- zope.interface/trunk/src/zope/interface/verify.py 2010-04-09 02:33:49 UTC (rev 110698)
+++ zope.interface/trunk/src/zope/interface/verify.py 2010-04-09 08:16:17 UTC (rev 110699)
@@ -19,6 +19,7 @@
from zope.interface.exceptions import BrokenMethodImplementation
from types import FunctionType, MethodType
from zope.interface.interface import fromMethod, fromFunction, Method
+import sys
# This will be monkey-patched when running under Zope 2, so leave this
# here:
@@ -67,8 +68,12 @@
continue
if isinstance(attr, FunctionType):
- # should never get here, since classes should not provide functions
- meth = fromFunction(attr, iface, name=name)
+ if sys.version[0] == '3' and isinstance(candidate, type):
+ # This is an "unbound method" in Python 3.
+ meth = fromFunction(attr, iface, name=name, imlevel=1)
+ else:
+ # Nope, just a normal function
+ meth = fromFunction(attr, iface, name=name)
elif (isinstance(attr, MethodTypes)
and type(attr.im_func) is FunctionType):
meth = fromMethod(attr, iface, name)
Modified: zope.interface/trunk/src/zope/interface/verify.txt
===================================================================
--- zope.interface/trunk/src/zope/interface/verify.txt 2010-04-09 02:33:49 UTC (rev 110698)
+++ zope.interface/trunk/src/zope/interface/verify.txt 2010-04-09 08:16:17 UTC (rev 110699)
@@ -35,6 +35,7 @@
``__init__`` method, will be recognized:
>>> from zope.interface import Interface, Attribute, implements
+>>> from zope.interface.exceptions import BrokenImplementation
>>> class IFoo(Interface):
... x = Attribute("The X attribute")
... y = Attribute("The Y attribute")
@@ -55,20 +56,28 @@
... implements(IFoo)
... x = 1
->>> verifyObject(IFoo, Foo())
-Traceback (most recent call last):
-BrokenImplementation: An object has failed to implement interface <InterfaceClass __builtin__.IFoo>
- The y attribute was not provided.
+>>> try: #doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
+... verifyObject(IFoo, Foo())
+... except BrokenImplementation, e:
+... print str(e)
+An object has failed to implement interface <InterfaceClass ...IFoo>
+<BLANKLINE>
+ The y attribute was not provided.
+<BLANKLINE>
>>> class Foo(object):
... implements(IFoo)
... def __init__(self):
... self.y = 2
->>> verifyObject(IFoo, Foo())
-Traceback (most recent call last):
-BrokenImplementation: An object has failed to implement interface <InterfaceClass __builtin__.IFoo>
- The x attribute was not provided.
+>>> try: #doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
+... verifyObject(IFoo, Foo())
+... except BrokenImplementation, e:
+... print str(e)
+An object has failed to implement interface <InterfaceClass ...IFoo>
+<BLANKLINE>
+ The x attribute was not provided.
+<BLANKLINE>
If an attribute is implemented as a property that raises an AttributeError
when trying to get its value, the attribute is considered missing:
@@ -82,10 +91,14 @@
... def x(self):
... raise AttributeError
->>> verifyObject(IFoo, Foo())
-Traceback (most recent call last):
-BrokenImplementation: An object has failed to implement interface <InterfaceClass __builtin__.IFoo>
- The x attribute was not provided.
+>>> try: #doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
+... verifyObject(IFoo, Foo())
+... except BrokenImplementation, e:
+... print str(e)
+An object has failed to implement interface <InterfaceClass ...IFoo>
+<BLANKLINE>
+ The x attribute was not provided.
+<BLANKLINE>
Any other exception raised by a property will propagate to the caller of
``verifyObject``:
More information about the checkins
mailing list