Skip to content
This repository has been archived by the owner on Feb 9, 2023. It is now read-only.

Commit

Permalink
Merge branch 'py3'
Browse files Browse the repository at this point in the history
Conflicts:
	setup.py
  • Loading branch information
strichter committed Mar 1, 2013
2 parents a90bee3 + 52f7fb9 commit 3bcf72a
Show file tree
Hide file tree
Showing 16 changed files with 187 additions and 126 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -9,4 +9,5 @@ src/*.egg-info
bin
build
develop-eggs
dist
parts
10 changes: 10 additions & 0 deletions CHANGES.txt
Expand Up @@ -2,6 +2,16 @@
CHANGES
=======

2.0.0a1 (2013-02-20)
--------------------

- Added support for Python 3.3.

- Replaced deprecated ``zope.interface.implements`` usage with equivalent
``zope.interface.implementer`` decorator.

- Dropped support for Python 2.4 and 2.5.


1.0.1 (unreleased)
------------------
Expand Down
17 changes: 16 additions & 1 deletion buildout.cfg
@@ -1,7 +1,22 @@
[buildout]
develop = .
parts = test
parts = py test
versions = versions

[test]
recipe = zc.recipe.testrunner
eggs = zope.apidoc [test]

[py]
recipe = zc.recipe.egg
eggs = zope.apidoc [test]
interpreter = py

[versions]
zope.container = 4.0.0a2
zope.i18n = 4.0.0a3
zope.publisher = 4.0.0a2
zope.renderer = 4.0.0a1
zope.security = 4.0.0a5
zope.tal = 4.0.0a1
zope.traversing = 4.0.0a2
9 changes: 5 additions & 4 deletions setup.py
Expand Up @@ -26,7 +26,7 @@ def read(*rnames):

setup(
name = 'zope.apidoc',
version='1.0.1.dev0',
version = '2.0.0a1',
author = 'Zope Corporation and Contributors',
author_email = 'zope-dev@zope.org',
description = 'API Documentation and Component Inspection for Zope 3',
Expand Down Expand Up @@ -58,8 +58,8 @@ def read(*rnames):
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
#'Programming Language :: Python :: 3',
#'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: Implementation :: CPython',
'Natural Language :: English',
'Operating System :: OS Independent',
Expand All @@ -71,8 +71,8 @@ def read(*rnames):
namespace_packages = ['zope'],
install_requires = [
'setuptools',
'six',
'zope.annotation',
'zope.app.renderer',
'zope.browserpage',
'zope.browserresource',
'zope.cachedescriptors',
Expand All @@ -82,6 +82,7 @@ def read(*rnames):
'zope.interface',
'zope.location',
'zope.publisher',
'zope.renderer',
'zope.schema',
'zope.security',
'zope.traversing',
Expand Down
28 changes: 28 additions & 0 deletions src/zope/apidoc/_compat.py
@@ -0,0 +1,28 @@
##############################################################################
#
# Copyright (c) 2013 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Python versions compatibility
"""
import sys

PY3 = sys.version_info[0] >= 3

if PY3:

unicode = str
from types import FunctionType as MethodType

else:

unicode = unicode
from types import MethodType
2 changes: 1 addition & 1 deletion src/zope/apidoc/classregistry.py
Expand Up @@ -63,6 +63,6 @@ def safe_import(path, default=None):
return default
# Some software, we cannot control, might raise all sorts of errors;
# thus catch all exceptions and return the default.
except Exception, error:
except Exception as error:
return default
return module
41 changes: 22 additions & 19 deletions src/zope/apidoc/classregistry.txt
Expand Up @@ -17,7 +17,7 @@ any other dictionary:
Let's now add a couple of classes to registry. The classes should implement
some interfaces, so that we can test all methods on the class registry:

>>> from zope.interface import Interface, implements
>>> from zope.interface import Interface, implementer

>>> class IA(Interface):
... pass
Expand All @@ -28,20 +28,24 @@ some interfaces, so that we can test all methods on the class registry:
>>> class ID(Interface):
... pass

>>> class A(object):
... implements(IA)
>>> @implementer(IA)
... class A(object):
... pass
>>> reg['A'] = A

>>> class B:
... implements(IB)
>>> @implementer(IB)
... class B(object):
... pass
>>> reg['B'] = B

>>> class B2(object):
... implements(IB)
>>> @implementer(IB)
... class B2(object):
... pass
>>> reg['B2'] = B2

>>> class C(object):
... implements(IC)
>>> @implementer(IC)
... class C(object):
... pass
>>> reg['C'] = C
>>> class A2(A):
... pass
Expand All @@ -50,8 +54,7 @@ some interfaces, so that we can test all methods on the class registry:
Since the registry is just a dictionary, we can ask for all its keys, which
are the names of the classes:

>>> names = reg.keys()
>>> names.sort()
>>> names = sorted(reg.keys())
>>> names
['A', 'A2', 'B', 'B2', 'C']

Expand All @@ -66,14 +69,14 @@ There are two API methods specific to the class registry:
This method returns all classes that implement the specified interface:

>>> from pprint import pprint
>>> pprint(reg.getClassesThatImplement(IA)) #doctest:+ELLIPSIS
>>> pprint(sorted(reg.getClassesThatImplement(IA))) #doctest:+ELLIPSIS
[('A', <class 'A'>),
('B', <class __builtin__.B at ...>),
('A2', <class 'A2'>),
('B', <class 'B'>),
('B2', <class 'B2'>)]

>>> pprint(reg.getClassesThatImplement(IB)) #doctest:+ELLIPSIS
[('B', <class __builtin__.B at ...>),
>>> pprint(sorted(reg.getClassesThatImplement(IB))) #doctest:+ELLIPSIS
[('B', <class 'B'>),
('B2', <class 'B2'>)]

>>> pprint(reg.getClassesThatImplement(IC))
Expand Down Expand Up @@ -128,9 +131,8 @@ For this example, we'll create a dummy module:
>>> dir = tempfile.mkdtemp()
>>> filename = os.path.join(dir, 'testmodule.py')
>>> sys.path.insert(0, dir)
>>> f = open(filename, 'w')
>>> f.write('# dummy module\n')
>>> f.close()
>>> with open(filename, 'w') as file:
... _ = file.write('# dummy module\n')

The temporary module is not already imported:

Expand Down Expand Up @@ -162,7 +164,8 @@ Importing some code we cannot control, such as twisted, might raise errors
when imported without having a certain environment. In those cases, the safe
import should prevent the error from penetrating:

>>> open(os.path.join(dir, 'alwaysfail.py'), 'w').write('raise ValueError\n')
>>> with open(os.path.join(dir, 'alwaysfail.py'), 'w') as file:
... _ = file.write('raise ValueError\n')
>>> sys.path.insert(0, dir)

>>> safe_import('alwaysfail') is None
Expand Down
7 changes: 4 additions & 3 deletions src/zope/apidoc/component.py
Expand Up @@ -14,6 +14,7 @@
"""Component Inspection Utilities
"""
import base64
import six
import types
import zope.interface.declarations

Expand All @@ -29,6 +30,7 @@
from zope.interface.interface import InterfaceClass
from zope.publisher.interfaces import IRequest

from zope.apidoc._compat import unicode
from zope.apidoc.classregistry import classRegistry
from zope.apidoc.utilities import relativizePath, truncateSysPath
from zope.apidoc.utilities import getPythonPath, isReferencable, renderText
Expand All @@ -38,7 +40,7 @@
GENERIC_INTERFACE_LEVEL = 4

def encodeUtilityName(name):
return base64.urlsafe_b64encode(name.encode('utf-8'))
return base64.urlsafe_b64encode(name.encode('utf-8')).decode()

def _adapterishRegistrations(registry):
for r in registry.registeredAdapters():
Expand Down Expand Up @@ -261,8 +263,7 @@ def getUtilityInfoDictionary(reg):
# TODO: Once we support passive display of instances, this insanity can go
# away.
if not isinstance(component, (types.MethodType, types.FunctionType,
types.ClassType, types.TypeType,
InterfaceClass)):
InterfaceClass)+six.class_types):
component = getattr(component, '__class__', component)

path = getPythonPath(component)
Expand Down
28 changes: 16 additions & 12 deletions src/zope/apidoc/component.txt
Expand Up @@ -135,19 +135,22 @@ that implement the specified interface.

Let's start by creating and registering some classes:

>>> from zope.interface import implements
>>> from zope.interface import implementer
>>> from zope.apidoc.classregistry import classRegistry

>>> class MyFoo(object):
... implements(IFoo)
>>> @implementer(IFoo)
... class MyFoo(object):
... pass
>>> classRegistry['MyFoo'] = MyFoo

>>> class MyBar(object):
... implements(IBar)
>>> @implementer(IBar)
... class MyBar(object):
... pass
>>> classRegistry['MyBar'] = MyBar

>>> class MyFooBar(object):
... implements(IFooBar)
>>> @implementer(IFooBar)
... class MyFooBar(object):
... pass
>>> classRegistry['MyFooBar'] = MyFooBar

Let's now see whether what results we get:
Expand Down Expand Up @@ -364,8 +367,9 @@ data of an adapter registration in an output-friendly format.

Let's first create an adapter registration:

>>> class MyResult(object):
... implements(IResult)
>>> @implementer(IResult)
... class MyResult(object):
... pass

>>> from zope.component.registry import AdapterRegistration
>>> reg = AdapterRegistration(None, (IFoo, IBar), IResult, 'FooToResult',
Expand Down Expand Up @@ -451,7 +455,7 @@ Luckily we have already registered some factories, so we just reuse their
registrations:

>>> pprint(component.getFactoryInfoDictionary(
... component.getFactories(IFooBar).next()))
... next(component.getFactories(IFooBar))))
{'description': u'<p>My Foo Bar</p>\n',
'name': u'MyFooBar',
'title': 'MyFooBar',
Expand All @@ -473,7 +477,7 @@ will be ``None``:
>>> provideUtility(MyFactoryType(), IFactory, 'MyFactory')

>>> pprint(component.getFactoryInfoDictionary(
... component.getFactories(IMine).next()), width=1)
... next(component.getFactories(IMine))), width=1)
{'description': u'',
'name': u'MyFactory',
'title': u'',
Expand All @@ -490,7 +494,7 @@ Luckily we have already registered some utilities, so we just reuse their
registrations:

>>> pprint(component.getUtilityInfoDictionary(
... component.getUtilities(IFooBar).next()))
... next(component.getUtilities(IFooBar))))
{'iface_id': 'zope.apidoc.doctest.IFooBar',
'name': u'<i>no name</i>',
'path': 'zope.apidoc.doctest.MyFooBar',
Expand Down
7 changes: 2 additions & 5 deletions src/zope/apidoc/interface.py
Expand Up @@ -35,12 +35,9 @@ def getElements(iface, type=IElement):
return items


def getFieldsInOrder(iface,
_itemsorter=lambda x, y: cmp(x[1].order, y[1].order)):
def getFieldsInOrder(iface, _itemkey=lambda x: x[1].order):
"""Return a list of (name, field) tuples in native interface order."""
items = getElements(iface, IField).items()
items.sort(_itemsorter)
return items
return sorted(getElements(iface, IField).items(), key=_itemkey)


def getAttributes(iface):
Expand Down

0 comments on commit 3bcf72a

Please sign in to comment.