Skip to content

Commit

Permalink
Merge of regebro-python3 branch, adding Python 3.1 compatibility\!
Browse files Browse the repository at this point in the history
  • Loading branch information
regebro committed Apr 9, 2010
1 parent d052410 commit bc3b946
Show file tree
Hide file tree
Showing 23 changed files with 502 additions and 249 deletions.
32 changes: 32 additions & 0 deletions CHANGES.txt
@@ -1,6 +1,37 @@
CHANGES
*******

==================
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)
==================
Expand All @@ -9,6 +40,7 @@ CHANGES
has been deprecated.


==================
3.5.3 (2009-12-08)
==================

Expand Down
38 changes: 38 additions & 0 deletions build_ext_2.py
@@ -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

40 changes: 40 additions & 0 deletions build_ext_3.py
@@ -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)
69 changes: 29 additions & 40 deletions setup.py
Expand Up @@ -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(
Expand All @@ -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}
Expand All @@ -87,48 +85,39 @@ def read(*rnames):
'********\n'
)


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
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']

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',
author='Zope Foundation and Contributors',
author_email='zope-dev@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)
36 changes: 21 additions & 15 deletions src/zope/interface/README.ru.txt
Expand Up @@ -231,15 +231,18 @@ API для объявления интерфейсов.
Вызывающая сторона не должна предполагать, что всегда будет создаваться
новый объект.

Также надо отметить, что как минимум сейчас implementer не может использоваться
для классов::
XXX: Double check and update these version numbers, and translate to russian:

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.

>>> 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.

Объявление предоставляемых интерфейсов
--------------------------------------
Expand Down Expand Up @@ -545,12 +548,12 @@ IBase::
к спецификациям. Объявления фактически расширяют интерфейсы которые они
объявляют::

>>> 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
Expand All @@ -568,7 +571,8 @@ IBase::
<InterfaceClass __main__.IBaz>,
<InterfaceClass __main__.IFoo>,
<InterfaceClass __main__.IBlat>,
<InterfaceClass zope.interface.Interface>)
<InterfaceClass zope.interface.Interface>,
<implementedBy ...object>)

Помеченные значения
===================
Expand Down Expand Up @@ -657,11 +661,13 @@ IBase::
будет выкинуто единственное исключение `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))]'

И список будет заполнен индивидуальными исключениями::

Expand Down
52 changes: 36 additions & 16 deletions src/zope/interface/README.txt
Expand Up @@ -231,15 +231,32 @@ classes). We do this using a Python-2.4-style decorator named
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.

>>> 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.

>>> 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.

Declaring provided interfaces
-----------------------------
Expand Down Expand Up @@ -547,12 +564,12 @@ What we described above for interface inheritance applies to both
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
Expand All @@ -570,7 +587,8 @@ that lists the specification and all of it's ancestors::
<InterfaceClass __main__.IBaz>,
<InterfaceClass __main__.IFoo>,
<InterfaceClass __main__.IBlat>,
<InterfaceClass zope.interface.Interface>)
<InterfaceClass zope.interface.Interface>,
<implementedBy ...object>)


Tagged Values
Expand Down Expand Up @@ -659,12 +677,14 @@ after the first error. If you pass a list to `validateInvariants`,
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
Expand Down
3 changes: 2 additions & 1 deletion src/zope/interface/__init__.py
Expand Up @@ -63,7 +63,8 @@ def meth(arg1, arg2):
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
Expand Down

0 comments on commit bc3b946

Please sign in to comment.