Index: CHANGES.txt =================================================================== --- CHANGES.txt (.../trunk) (revision 125127) +++ CHANGES.txt (.../branches/jinty-python3) (revision 125127) @@ -2,11 +2,11 @@ Changes ======= -3.8.1 (unreleased) +4.0.0 (unreleased) ------------------ -- Fixed Python 2.4 backwards incompat (itemgetter used with multiple args); - Python 2.4 now works (at least if you use zope.schema == 3.8.1). +- Support Python 3.3. +- Drop support for Python 2.4 and Python 2.5. 3.8.0 (2011-12-06) ------------------ Index: setup.py =================================================================== --- setup.py (.../trunk) (revision 125127) +++ setup.py (.../branches/jinty-python3) (revision 125127) @@ -78,6 +78,10 @@ 'Intended Audience :: Developers', 'License :: OSI Approved :: Zope Public License', 'Programming Language :: Python', + "Programming Language :: Python :: 2.6", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.3", 'Natural Language :: English', 'Operating System :: OS Independent', 'Topic :: Internet :: WWW/HTTP', @@ -89,7 +93,8 @@ namespace_packages=['zope'], extras_require=dict( test=['zope.testing']), - install_requires=['zope.i18nmessageid', + install_requires=['six', + 'zope.i18nmessageid', 'zope.interface', 'zope.schema', 'setuptools', Index: src/zope/configuration/tests/test_simple.py =================================================================== --- src/zope/configuration/tests/test_simple.py (.../trunk) (revision 125127) +++ src/zope/configuration/tests/test_simple.py (.../branches/jinty-python3) (revision 125127) @@ -121,15 +121,16 @@ >>> from zope.configuration.tests.test_xmlconfig import clean_text_w_paths >>> from zope.configuration.tests.test_xmlconfig import clean_path +>>> from six import print_ >>> for i in file_registry: -... print "path:", clean_path(i.path) -... print "title:", i.title -... print "description:", '\n'.join( +... print_("path:", clean_path(i.path)) +... print_("title:", i.title) +... print_("description:", '\n'.join( ... [l.rstrip() ... for l in i.description.strip().split('\n') -... if l.rstrip()]) -... print "info:" -... print clean_text_w_paths(i.info) +... if l.rstrip()])) +... print_("info:") +... print_(clean_text_w_paths(i.info)) path: tests/test_simple.py title: How to create a simple directive description: Describes how to implement a simple directive Index: src/zope/configuration/tests/victim.py =================================================================== --- src/zope/configuration/tests/victim.py (.../trunk) (revision 125127) +++ src/zope/configuration/tests/victim.py (.../branches/jinty-python3) (revision 125127) @@ -1 +1 @@ -import bad +from . import bad Index: src/zope/configuration/tests/directives.py =================================================================== --- src/zope/configuration/tests/directives.py (.../trunk) (revision 125127) +++ src/zope/configuration/tests/directives.py (.../branches/jinty-python3) (revision 125127) @@ -13,7 +13,7 @@ ############################################################################## """Test directives """ -from zope.interface import Interface, implements +from zope.interface import Interface, implementer from zope.schema import Text, BytesLine from zope.configuration.config import GroupingContextDecorator from zope.configuration.interfaces import IConfigurationContext @@ -48,11 +48,11 @@ class IPackagedContext(IPackaged, IConfigurationContext): pass +@implementer(IPackagedContext) class Packaged(GroupingContextDecorator): + pass - implements(IPackagedContext) - class IFactory(Interface): factory = GlobalObject() Index: src/zope/configuration/tests/test_config.py =================================================================== --- src/zope/configuration/tests/test_config.py (.../trunk) (revision 125127) +++ src/zope/configuration/tests/test_config.py (.../branches/jinty-python3) (revision 125127) @@ -17,250 +17,245 @@ import sys import unittest import re +import six from doctest import DocTestSuite from zope.testing import renormalizing from zope.configuration.config import metans, ConfigurationMachine from zope.configuration import config -def test_config_extended_example(): - """Configuration machine +class TestConfig(unittest.TestCase): - Examples: + def test_config_extended_example(self): + from zope.configuration.tests.directives import f + # Examples: - >>> machine = ConfigurationMachine() - >>> ns = "http://www.zope.org/testing" + machine = ConfigurationMachine() + ns = "http://www.zope.org/testing" - Register some test directives: + # Register some test directives: + # Start with a grouping directive that sets a package: - Start with a grouping directive that sets a package: + machine((metans, "groupingDirective"), + name="package", namespace=ns, + schema="zope.configuration.tests.directives.IPackaged", + handler="zope.configuration.tests.directives.Packaged", + ) - >>> machine((metans, "groupingDirective"), - ... name="package", namespace=ns, - ... schema="zope.configuration.tests.directives.IPackaged", - ... handler="zope.configuration.tests.directives.Packaged", - ... ) + # we can set the package: - Now we can set the package: + machine.begin((ns, "package"), + package="zope.configuration.tests.directives", + ) - >>> machine.begin((ns, "package"), - ... package="zope.configuration.tests.directives", - ... ) + # Which makes it easier to define the other directives: + # First, define some simple directives: - Which makes it easier to define the other directives: + machine((metans, "directive"), + namespace=ns, name="simple", + schema=".ISimple", handler=".simple") - First, define some simple directives: + machine((metans, "directive"), + namespace=ns, name="newsimple", + schema=".ISimple", handler=".newsimple") - >>> machine((metans, "directive"), - ... namespace=ns, name="simple", - ... schema=".ISimple", handler=".simple") - >>> machine((metans, "directive"), - ... namespace=ns, name="newsimple", - ... schema=".ISimple", handler=".newsimple") + # try them out: + machine((ns, "simple"), "first", a=u"aa", c=u"cc") + machine((ns, "newsimple"), "second", a=u"naa", c=u"ncc", b=u"nbb") - and try them out: + self.assertEqual(machine.actions, + [{'args': (u'aa', u'xxx', b'cc'), + 'callable': f, + 'discriminator': ('simple', + u'aa', + u'xxx', + b'cc'), + 'includepath': (), + 'info': 'first', + 'kw': {}, + 'order': 0}, + {'args': (u'naa', u'nbb', b'ncc'), + 'callable': f, + 'discriminator': ('newsimple', + u'naa', + u'nbb', + b'ncc'), + 'includepath': (), + 'info': 'second', + 'kw': {}, + 'order': 0}]) - >>> machine((ns, "simple"), "first", a=u"aa", c=u"cc") - >>> machine((ns, "newsimple"), "second", a=u"naa", c=u"ncc", b=u"nbb") + # Define and try a simple directive that uses a component: - >>> from pprint import PrettyPrinter - >>> pprint=PrettyPrinter(width=50).pprint + machine((metans, "directive"), + namespace=ns, name="factory", + schema=".IFactory", handler=".factory") - >>> pprint(machine.actions) - [{'args': (u'aa', u'xxx', 'cc'), - 'callable': f, - 'discriminator': ('simple', - u'aa', - u'xxx', - 'cc'), - 'includepath': (), - 'info': 'first', - 'kw': {}, - 'order': 0}, - {'args': (u'naa', u'nbb', 'ncc'), - 'callable': f, - 'discriminator': ('newsimple', - u'naa', - u'nbb', - 'ncc'), - 'includepath': (), - 'info': 'second', - 'kw': {}, - 'order': 0}] - Define and try a simple directive that uses a component: + machine((ns, "factory"), factory=u".f") - >>> machine((metans, "directive"), - ... namespace=ns, name="factory", - ... schema=".IFactory", handler=".factory") + self.assertEqual(machine.actions[-1:], + [{'args': (), + 'callable': f, + 'discriminator': ('factory', 1, 2), + 'includepath': (), + 'info': None, + 'kw': {}, + 'order': 0}]) + # Define and try a complex directive: - >>> machine((ns, "factory"), factory=u".f") - >>> pprint(machine.actions[-1:]) - [{'args': (), - 'callable': f, - 'discriminator': ('factory', 1, 2), - 'includepath': (), - 'info': None, - 'kw': {}, - 'order': 0}] + machine.begin((metans, "complexDirective"), + namespace=ns, name="testc", + schema=".ISimple", handler=".Complex") - Define and try a complex directive: + machine((metans, "subdirective"), + name="factory", schema=".IFactory") - >>> machine.begin((metans, "complexDirective"), - ... namespace=ns, name="testc", - ... schema=".ISimple", handler=".Complex") + machine.end() - >>> machine((metans, "subdirective"), - ... name="factory", schema=".IFactory") + machine.begin((ns, "testc"), None, "third", a=u'ca', c='cc') + machine((ns, "factory"), "fourth", factory=".f") - >>> machine.end() + # Note that we can't call a complex method unless there is a directive for + # it: - >>> machine.begin((ns, "testc"), None, "third", a=u'ca', c='cc') - >>> machine((ns, "factory"), "fourth", factory=".f") + self.assertRaises(config.ConfigurationError, machine, (ns, "factory2"), factory=".f") + #Traceback (most recent call last): + # ... + #ConfigurationError: ('Invalid directive', 'factory2') - Note that we can't call a complex method unless there is a directive for - it: + machine.end() - >>> machine((ns, "factory2"), factory=".f") - Traceback (most recent call last): - ... - ConfigurationError: ('Invalid directive', 'factory2') + self.assertEqual(machine.actions, + [{'args': (u'aa', u'xxx', b'cc'), + 'callable': f, + 'discriminator': ('simple', + u'aa', + u'xxx', + b'cc'), + 'includepath': (), + 'info': 'first', + 'kw': {}, + 'order': 0}, + {'args': (u'naa', u'nbb', b'ncc'), + 'callable': f, + 'discriminator': ('newsimple', + u'naa', + u'nbb', + b'ncc'), + 'includepath': (), + 'info': 'second', + 'kw': {}, + 'order': 0}, + {'args': (), + 'callable': f, + 'discriminator': ('factory', 1, 2), + 'includepath': (), + 'info': None, + 'kw': {}, + 'order': 0}, + {'args': (), + 'callable': None, + 'discriminator': 'Complex.__init__', + 'includepath': (), + 'info': 'third', + 'kw': {}, + 'order': 0}, + {'args': (u'ca',), + 'callable': f, + 'discriminator': ('Complex.factory', 1, 2), + 'includepath': (), + 'info': 'fourth', + 'kw': {}, + 'order': 0}, + {'args': (u'xxx', b'cc'), + 'callable': f, + 'discriminator': ('Complex', 1, 2), + 'includepath': (), + 'info': 'third', + 'kw': {}, + 'order': 0}]) + # Done with the package - >>> machine.end() - >>> pprint(machine.actions) - [{'args': (u'aa', u'xxx', 'cc'), - 'callable': f, - 'discriminator': ('simple', - u'aa', - u'xxx', - 'cc'), - 'includepath': (), - 'info': 'first', - 'kw': {}, - 'order': 0}, - {'args': (u'naa', u'nbb', 'ncc'), - 'callable': f, - 'discriminator': ('newsimple', - u'naa', - u'nbb', - 'ncc'), - 'includepath': (), - 'info': 'second', - 'kw': {}, - 'order': 0}, - {'args': (), - 'callable': f, - 'discriminator': ('factory', 1, 2), - 'includepath': (), - 'info': None, - 'kw': {}, - 'order': 0}, - {'args': (), - 'callable': None, - 'discriminator': 'Complex.__init__', - 'includepath': (), - 'info': 'third', - 'kw': {}, - 'order': 0}, - {'args': (u'ca',), - 'callable': f, - 'discriminator': ('Complex.factory', 1, 2), - 'includepath': (), - 'info': 'fourth', - 'kw': {}, - 'order': 0}, - {'args': (u'xxx', 'cc'), - 'callable': f, - 'discriminator': ('Complex', 1, 2), - 'includepath': (), - 'info': 'third', - 'kw': {}, - 'order': 0}] + machine.end() - Done with the package + # Verify that we can use a simple directive outside of the package: - >>> machine.end() + machine((ns, "simple"), a=u"oaa", c=u"occ", b=u"obb") + # we can't use the factory directive, because it's only valid + # inside a package directive: - Verify that we can use a simple directive outside of the package: + self.assertRaises(config.ConfigurationError, machine, (ns, "factory"), factory=u".F") + #Traceback (most recent call last): + #... + #ConfigurationError: ('Invalid value for', 'factory',""" \ + # """ "Can't use leading dots in dotted names, no package has been set.") - >>> machine((ns, "simple"), a=u"oaa", c=u"occ", b=u"obb") + self.assertEqual(machine.actions, + [{'args': (u'aa', u'xxx', b'cc'), + 'callable': f, + 'discriminator': ('simple', + u'aa', + u'xxx', + b'cc'), + 'includepath': (), + 'info': 'first', + 'kw': {}, + 'order': 0}, + {'args': (u'naa', u'nbb', b'ncc'), + 'callable': f, + 'discriminator': ('newsimple', + u'naa', + u'nbb', + b'ncc'), + 'includepath': (), + 'info': 'second', + 'kw': {}, + 'order': 0}, + {'args': (), + 'callable': f, + 'discriminator': ('factory', 1, 2), + 'includepath': (), + 'info': None, + 'kw': {}, + 'order': 0}, + {'args': (), + 'callable': None, + 'discriminator': 'Complex.__init__', + 'includepath': (), + 'info': 'third', + 'kw': {}, + 'order': 0}, + {'args': (u'ca',), + 'callable': f, + 'discriminator': ('Complex.factory', 1, 2), + 'includepath': (), + 'info': 'fourth', + 'kw': {}, + 'order': 0}, + {'args': (u'xxx', b'cc'), + 'callable': f, + 'discriminator': ('Complex', 1, 2), + 'includepath': (), + 'info': 'third', + 'kw': {}, + 'order': 0}, + {'args': (u'oaa', u'obb', b'occ'), + 'callable': f, + 'discriminator': ('simple', + u'oaa', + u'obb', + b'occ'), + 'includepath': (), + 'info': None, + 'kw': {}, + 'order': 0}]) - But we can't use the factory directive, because it's only valid - inside a package directive: - >>> machine((ns, "factory"), factory=u".F") - Traceback (most recent call last): - ... - ConfigurationError: ('Invalid value for', 'factory',""" \ - """ "Can't use leading dots in dotted names, no package has been set.") - - >>> pprint(machine.actions) - [{'args': (u'aa', u'xxx', 'cc'), - 'callable': f, - 'discriminator': ('simple', - u'aa', - u'xxx', - 'cc'), - 'includepath': (), - 'info': 'first', - 'kw': {}, - 'order': 0}, - {'args': (u'naa', u'nbb', 'ncc'), - 'callable': f, - 'discriminator': ('newsimple', - u'naa', - u'nbb', - 'ncc'), - 'includepath': (), - 'info': 'second', - 'kw': {}, - 'order': 0}, - {'args': (), - 'callable': f, - 'discriminator': ('factory', 1, 2), - 'includepath': (), - 'info': None, - 'kw': {}, - 'order': 0}, - {'args': (), - 'callable': None, - 'discriminator': 'Complex.__init__', - 'includepath': (), - 'info': 'third', - 'kw': {}, - 'order': 0}, - {'args': (u'ca',), - 'callable': f, - 'discriminator': ('Complex.factory', 1, 2), - 'includepath': (), - 'info': 'fourth', - 'kw': {}, - 'order': 0}, - {'args': (u'xxx', 'cc'), - 'callable': f, - 'discriminator': ('Complex', 1, 2), - 'includepath': (), - 'info': 'third', - 'kw': {}, - 'order': 0}, - {'args': (u'oaa', u'obb', 'occ'), - 'callable': f, - 'discriminator': ('simple', - u'oaa', - u'obb', - 'occ'), - 'includepath': (), - 'info': None, - 'kw': {}, - 'order': 0}] - - """ - #' - def test_keyword_handling(): """ >>> machine = ConfigurationMachine() @@ -382,7 +377,7 @@ >>> c.resolve('zope.configuration.tests.victim') Traceback (most recent call last): ... - File "...bad.py", line 3 in ? + File "...bad.py", line 3 in ... import bad_to_the_bone ImportError: No module named bad_to_the_bone @@ -417,14 +412,37 @@ """ def test_suite(): - checker = renormalizing.RENormalizing([ + checkers = [ (re.compile(r":"), r'exceptions.\1Error:'), + ] + if six.PY3: + checkers.extend([ + (re.compile(r"^zope.schema._bootstrapinterfaces.([a-zA-Z]*):"), + r'\1:'), + (re.compile(r"^zope.configuration.interfaces.([a-zA-Z]*):"), + r'\1:'), + (re.compile(r"^zope.configuration.exceptions.([a-zA-Z]*):"), + r'\1:'), + (re.compile(r"b'([^']*)'"), + r"'\1'"), + (re.compile(r'b"([^"]*)"'), + r'"\1"'), + (re.compile(r"u'([^']*)'"), + r"'\1'"), + (re.compile(r'u"([^"]*)"'), + r'"\1"'), + (re.compile(r"\(,\)"), + r"(, )"), + (re.compile(r"No module named '([^']*)'"), + r'No module named \1'), ]) + checker = renormalizing.RENormalizing(checkers) return unittest.TestSuite(( - DocTestSuite('zope.configuration.fields'), - DocTestSuite('zope.configuration.config',checker=checker), - DocTestSuite(), + unittest.findTestCases(sys.modules[__name__]), + DocTestSuite('zope.configuration.fields', checker=checker), + DocTestSuite('zope.configuration.config', checker=checker), + DocTestSuite(checker=checker), )) if __name__ == '__main__': unittest.main() Index: src/zope/configuration/tests/samplepackage/foo.py =================================================================== --- src/zope/configuration/tests/samplepackage/foo.py (.../trunk) (revision 125127) +++ src/zope/configuration/tests/samplepackage/foo.py (.../branches/jinty-python3) (revision 125127) @@ -28,8 +28,7 @@ ) = args, info, basepath, package, includepath def handler(_context, **kw): - args = kw.items() - args.sort() + args = sorted(kw.items()) args = tuple(args) discriminator = args args = (stuff(args, _context.info, _context.basepath, _context.package, Index: src/zope/configuration/tests/test_nested.py =================================================================== --- src/zope/configuration/tests/test_nested.py (.../trunk) (revision 125127) +++ src/zope/configuration/tests/test_nested.py (.../branches/jinty-python3) (revision 125127) @@ -114,7 +114,7 @@ >>> from pprint import PrettyPrinter >>> pprint=PrettyPrinter(width=70).pprint ->>> pprint(list(schema_registry)) +>>> pprint(sorted(schema_registry)) ['zope.configuration.tests.test_nested.I1', 'zope.configuration.tests.test_nested.I2'] @@ -126,19 +126,19 @@ >>> i1 = schema_registry['zope.configuration.tests.test_nested.I1'] >>> sorted(i1) ['a', 'b'] ->>> i1['a'].__class__.__name__ +>>> i1[b'a'].__class__.__name__ 'Text' ->>> i1['a'].description.strip() +>>> i1[b'a'].description.strip() u'A\n\n Blah blah' ->>> i1['a'].min_length +>>> i1[b'a'].min_length 1 ->>> i1['b'].__class__.__name__ +>>> i1[b'b'].__class__.__name__ 'Int' ->>> i1['b'].description.strip() +>>> i1[b'b'].description.strip() u'B\n\n Not feeling very creative' ->>> i1['b'].min +>>> i1[b'b'].min 1 ->>> i1['b'].max +>>> i1[b'b'].max 10 >>> i2 = schema_registry['zope.configuration.tests.test_nested.I2'] @@ -151,13 +151,13 @@ (Note that we used the context we created above, so we don't have to redefine our directives: +>>> from six import print_ >>> try: ... v = xmlconfig.string( ... '', ... context) -... except xmlconfig.ZopeXMLConfigurationError, v: -... pass ->>> print v +... except xmlconfig.ZopeXMLConfigurationError as v: +... print_(v) File "", line 1.0 ConfigurationError: The directive """ \ """(u'http://sample.namespaces.zope.org/schema', u'text') """ \ @@ -175,16 +175,20 @@ ... ... ''', ... context) -... except xmlconfig.ZopeXMLConfigurationError, v: -... pass ->>> print v +... except xmlconfig.ZopeXMLConfigurationError as v: +... print_(v) File "", line 5.7-5.24 ValueError: ('Duplicate field', 'x') """ +import re import unittest from doctest import DocTestSuite + +import six from zope import interface, schema +from zope.testing import renormalizing + from zope.configuration import config, xmlconfig, fields @@ -210,12 +214,11 @@ fields = interface.Attribute("Dictionary of field definitions" ) +@interface.implementer(config.IConfigurationContext, ISchema) class Schema(config.GroupingContextDecorator): """Handle schema directives """ - interface.implements(config.IConfigurationContext, ISchema) - def __init__(self, context, name, id): self.context, self.name, self.id = context, name, id self.fields = {} @@ -312,8 +315,21 @@ def test_suite(): + checkers = [] + if six.PY3: + checkers.extend([ + (re.compile(r"b'([^']*)'"), + r"'\1'"), + (re.compile(r'b"([^"]*)"'), + r'"\1"'), + (re.compile(r"u'([^']*)'"), + r"'\1'"), + (re.compile(r'u"([^"]*)"'), + r'"\1"'), + ]) + checker = renormalizing.RENormalizing(checkers) return unittest.TestSuite(( - DocTestSuite(), + DocTestSuite(checker=checker), )) if __name__ == '__main__': unittest.main() Index: src/zope/configuration/tests/test_xmlconfig.py =================================================================== --- src/zope/configuration/tests/test_xmlconfig.py (.../trunk) (revision 125127) +++ src/zope/configuration/tests/test_xmlconfig.py (.../branches/jinty-python3) (revision 125127) @@ -14,9 +14,12 @@ """Test XML configuration (ZCML) machinery. """ import unittest +import sys import os import re from doctest import DocTestSuite, DocFileSuite +import six +from six import print_ from zope.testing import renormalizing from zope.configuration import xmlconfig, config from zope.configuration.tests.samplepackage import foo @@ -48,37 +51,34 @@ def path(*p): return os.path.join(os.path.dirname(__file__), *p) -def test_ConfigurationHandler_normal(): - """ - >>> context = FauxContext() - >>> locator = FauxLocator('tests//sample.zcml', 1, 1) - >>> handler = xmlconfig.ConfigurationHandler(context) - >>> handler.setDocumentLocator(locator) - >>> handler.startElementNS((u"ns", u"foo"), u"foo", - ... {(u"xxx", u"splat"): u"splatv", - ... (None, u"a"): u"avalue", - ... (None, u"b"): u"bvalue", - ... }) - >>> context.info - File "tests//sample.zcml", line 1.1 - >>> from pprint import PrettyPrinter - >>> pprint=PrettyPrinter(width=50).pprint - >>> pprint(context.begin_args) - ((u'ns', u'foo'), - {'a': u'avalue', 'b': u'bvalue'}) - >>> getattr(context, "end_called", 0) - 0 +class TestConfigurationHandler(unittest.TestCase): - >>> locator.line, locator.column = 7, 16 - >>> handler.endElementNS((u"ns", u"foo"), u"foo") - >>> context.info - File "tests//sample.zcml", line 1.1-7.16 - >>> context.end_called - 1 + def test_normal(self): + context = FauxContext() + locator = FauxLocator('tests//sample.zcml', 1, 1) + handler = xmlconfig.ConfigurationHandler(context) + handler.setDocumentLocator(locator) - """ + handler.startElementNS((u"ns", u"foo"), + u"foo", + {(u"xxx", u"splat"): u"splatv", + (None, u"a"): u"avalue", + (None, u"b"): u"bvalue", + }) + self.assertEqual(repr(context.info), 'File "tests//sample.zcml", line 1.1') + self.assertEqual(context.begin_args, ((u'ns', u'foo'), + {'a': u'avalue', 'b': u'bvalue'})) + self.assertEqual(getattr(context, "end_called", 0), 0) + + locator.line, locator.column = 7, 16 + handler.endElementNS((u"ns", u"foo"), u"foo") + + self.assertEqual(repr(context.info), 'File "tests//sample.zcml", line 1.1-7.16') + self.assertEqual(context.end_called, 1) + + def test_ConfigurationHandler_err_start(): """ @@ -97,9 +97,8 @@ ... (None, u"a"): u"avalue", ... (None, u"b"): u"bvalue", ... }) - ... except xmlconfig.ZopeXMLConfigurationError, v: - ... pass - >>> print v + ... except xmlconfig.ZopeXMLConfigurationError as v: + ... print_(v) File "tests//sample.zcml", line 1.1 AttributeError: xxx @@ -126,9 +125,8 @@ >>> locator.line, locator.column = 7, 16 >>> try: ... v = handler.endElementNS((u"ns", u"foo"), u"foo") - ... except xmlconfig.ZopeXMLConfigurationError, v: - ... pass - >>> print v + ... except xmlconfig.ZopeXMLConfigurationError as v: + ... print_(v) File "tests//sample.zcml", line 1.1-7.16 AttributeError: xxx @@ -165,10 +163,10 @@ >>> data.args (('x', 'blah'), ('y', 0)) - >>> print clean_info_path(`data.info`) + >>> print_(clean_info_path(repr(data.info))) File "tests/samplepackage/configure.zcml", line 12.2-12.29 - >>> print clean_info_path(str(data.info)) + >>> print_(clean_info_path(str(data.info))) File "tests/samplepackage/configure.zcml", line 12.2-12.29 @@ -187,15 +185,15 @@ >>> data.args (('x', 'blah'), ('y', 0)) - >>> print clean_info_path(`data.info`) + >>> print_(clean_info_path(repr(data.info))) File "tests/samplepackage/configure.zcml", line 12.2-12.29 - >>> print clean_info_path(str(data.info)) + >>> print_(clean_info_path(str(data.info))) File "tests/samplepackage/configure.zcml", line 12.2-12.29 >>> data.package - >>> print clean_path(data.basepath) + >>> print_(clean_path(data.basepath)) tests/samplepackage """ @@ -212,10 +210,10 @@ >>> data.args (('x', 'blah'), ('y', 0)) - >>> print clean_info_path(`data.info`) + >>> print_(clean_info_path(repr(data.info))) File "tests/samplepackage/configure.zcml", line 12.2-12.29 - >>> print clean_info_path(str(data.info)) + >>> print_(clean_info_path(str(data.info))) File "tests/samplepackage/configure.zcml", line 12.2-12.29 @@ -255,10 +253,10 @@ >>> data.args (('x', 'foo'), ('y', 2)) - >>> print clean_info_path(`data.info`) + >>> print_(clean_info_path(repr(data.info))) File "tests/samplepackage/foo.zcml.in", line 12.2-12.28 - >>> print clean_info_path(str(data.info)) + >>> print_(clean_info_path(str(data.info))) File "tests/samplepackage/foo.zcml.in", line 12.2-12.28 @@ -284,10 +282,10 @@ >>> data.args (('x', 'foo'), ('y', 3)) - >>> print clean_info_path(`data.info`) + >>> print_(clean_info_path(repr(data.info))) File "tests/samplepackage/baz3.zcml", line 5.2-5.28 - >>> print clean_info_path(str(data.info)) + >>> print_(clean_info_path(str(data.info))) File "tests/samplepackage/baz3.zcml", line 5.2-5.28 @@ -303,10 +301,10 @@ >>> data.args (('x', 'foo'), ('y', 2)) - >>> print clean_info_path(`data.info`) + >>> print_(clean_info_path(repr(data.info))) File "tests/samplepackage/baz2.zcml", line 5.2-5.28 - >>> print clean_info_path(str(data.info)) + >>> print_(clean_info_path(str(data.info))) File "tests/samplepackage/baz2.zcml", line 5.2-5.28 @@ -322,7 +320,7 @@ def clean_actions(actions): return [ {'discriminator': action['discriminator'], - 'info': clean_info_path(`action['info']`), + 'info': clean_info_path(repr(action['info'])), 'includepath': [clean_path(p) for p in action['includepath']], } for action in actions @@ -330,7 +328,7 @@ def clean_text_w_paths(error): r = [] - for line in unicode(error).split("\n"): + for line in six.text_type(error).split("\n"): line = line.rstrip() if not line: continue @@ -404,9 +402,8 @@ >>> try: ... v = context.execute_actions() - ... except config.ConfigurationConflictError, v: - ... pass - >>> print clean_text_w_paths(str(v)) + ... except config.ConfigurationConflictError as v: + ... print_(clean_text_w_paths(str(v))) Conflicting configuration actions For: (('x', 'blah'), ('y', 0)) File "tests/samplepackage/configure.zcml", line 12.2-12.29 @@ -475,19 +472,19 @@ >>> data = foo.data.pop(0) >>> data.args (('x', 'blah'), ('y', 0)) - >>> print clean_info_path(`data.info`) + >>> print_(clean_info_path(repr(data.info))) File "tests/samplepackage/bar21.zcml", line 3.2-3.24 >>> data = foo.data.pop(0) >>> data.args (('x', 'blah'), ('y', 2)) - >>> print clean_info_path(`data.info`) + >>> print_(clean_info_path(repr(data.info))) File "tests/samplepackage/bar2.zcml", line 5.2-5.24 >>> data = foo.data.pop(0) >>> data.args (('x', 'blah'), ('y', 1)) - >>> print clean_info_path(`data.info`) + >>> print_(clean_info_path(repr(data.info))) File "tests/samplepackage/bar2.zcml", line 6.2-6.24 @@ -553,19 +550,19 @@ >>> data = foo.data.pop(0) >>> data.args (('x', 'blah'), ('y', 0)) - >>> print clean_info_path(`data.info`) + >>> print_(clean_info_path(repr(data.info))) File "tests/samplepackage/bar21.zcml", line 3.2-3.24 >>> data = foo.data.pop(0) >>> data.args (('x', 'blah'), ('y', 2)) - >>> print clean_info_path(`data.info`) + >>> print_(clean_info_path(repr(data.info))) File "tests/samplepackage/bar2.zcml", line 5.2-5.24 >>> data = foo.data.pop(0) >>> data.args (('x', 'blah'), ('y', 1)) - >>> print clean_info_path(`data.info`) + >>> print_(clean_info_path(repr(data.info))) File "tests/samplepackage/bar2.zcml", line 6.2-6.24 Finally, clean up. @@ -597,19 +594,19 @@ >>> data = foo.data.pop(0) >>> data.args (('x', 'blah'), ('y', 0)) - >>> print clean_info_path(`data.info`) + >>> print_(clean_info_path(repr(data.info))) File "tests/samplepackage/bar21.zcml", line 3.2-3.24 >>> data = foo.data.pop(0) >>> data.args (('x', 'blah'), ('y', 2)) - >>> print clean_info_path(`data.info`) + >>> print_(clean_info_path(repr(data.info))) File "tests/samplepackage/bar2.zcml", line 5.2-5.24 >>> data = foo.data.pop(0) >>> data.args (('x', 'blah'), ('y', 1)) - >>> print clean_info_path(`data.info`) + >>> print_(clean_info_path(repr(data.info))) File "tests/samplepackage/bar2.zcml", line 6.2-6.24 Finally, clean up. @@ -621,15 +618,29 @@ def test_suite(): + checkers = [] + if six.PY3: + checkers.extend([ + (re.compile(r"b'([^']*)'"), + r"'\1'"), + (re.compile(r'b"([^"]*)"'), + r'"\1"'), + (re.compile(r"u'([^']*)'"), + r"'\1'"), + (re.compile(r'u"([^"]*)"'), + r'"\1"'), + ]) + checker = renormalizing.RENormalizing(checkers) return unittest.TestSuite(( - DocTestSuite('zope.configuration.xmlconfig'), - DocTestSuite(), + unittest.findTestCases(sys.modules[__name__]), + DocTestSuite('zope.configuration.xmlconfig', checker=checker), + DocTestSuite(checker=checker), DocFileSuite('../exclude.txt', checker=renormalizing.RENormalizing([ (re.compile('include [^\n]+zope.configuration[\S+]'), 'include /zope.configuration\2'), (re.compile(r'\\'), '/'), - ])) + ] + checkers)) )) if __name__ == '__main__': Index: src/zope/configuration/config.py =================================================================== --- src/zope/configuration/config.py (.../trunk) (revision 125127) +++ src/zope/configuration/config.py (.../branches/jinty-python3) (revision 125127) @@ -16,11 +16,12 @@ See README.txt. """ __docformat__ = 'restructuredtext' -import __builtin__ +from six.moves import builtins import operator import os.path import sys +import six import zope.schema from keyword import iskeyword @@ -28,7 +29,7 @@ from zope.configuration.interfaces import IConfigurationContext from zope.configuration.interfaces import IGroupingContext from zope.interface.adapter import AdapterRegistry -from zope.interface import Interface, implements, providedBy +from zope.interface import Interface, implementer, providedBy from zope.configuration import fields @@ -121,8 +122,8 @@ 1 >>> c.resolve('..interface') is zope.interface 1 - >>> c.resolve('unicode') - + >>> c.resolve('str') is str + True """ name = dottedname.strip() @@ -140,7 +141,7 @@ if len(names) == 1: # Check for built-in objects marker = object() - obj = getattr(__builtin__, names[0], marker) + obj = getattr(builtins, names[0], marker) if obj is not marker: return obj @@ -176,7 +177,7 @@ try: mod = __import__(mname, *_import_chickens) - except ImportError, v: + except ImportError as v: if sys.exc_info()[2].tb_next is not None: # ImportError was caused deeper raise @@ -259,7 +260,7 @@ >>> c.checkDuplicate('/foo.zcml') >>> try: ... c.checkDuplicate('/foo.zcml') - ... except ConfigurationError, e: + ... except ConfigurationError as e: ... # On Linux the exact msg has /foo, on Windows \foo. ... str(e).endswith("foo.zcml' included more than once") True @@ -273,7 +274,7 @@ >>> c.checkDuplicate('bar.zcml') >>> try: ... c.checkDuplicate(d + os.path.normpath('/bar.zcml')) - ... except ConfigurationError, e: + ... except ConfigurationError as e: ... str(e).endswith("bar.zcml' included more than once") ... True @@ -542,7 +543,7 @@ r.register([interface], Interface, '', factory) def document(self, name, schema, usedIn, handler, info, parent=None): - if isinstance(name, (str, unicode)): + if isinstance(name, six.string_types): name = ('', name) self._docRegistry.append((name, schema, usedIn, handler, info, parent)) @@ -561,6 +562,7 @@ "The directive %s cannot be used in this context" % (name, )) return f +@implementer(IConfigurationContext) class ConfigurationMachine(ConfigurationAdapterRegistry, ConfigurationContext): """Configuration machine @@ -593,8 +595,6 @@ A more extensive example can be found in the unit tests. """ - implements(IConfigurationContext) - package = None basepath = None includepath = () @@ -663,14 +663,10 @@ ... ] >>> try: ... v = context.execute_actions() - ... except ConfigurationExecutionError, v: - ... pass - >>> print v - exceptions.AttributeError: 'function' object has no attribute 'xxx' - in: - oops + ... except ConfigurationExecutionError as v: + ... six.print_(repr(v)) + ConfigurationExecutionError() - Note that actions executed before the error still have an effect: >>> output @@ -696,7 +692,10 @@ raise t, v, tb = sys.exc_info() try: - raise ConfigurationExecutionError(t, v, info), None, tb + six.reraise( + ConfigurationExecutionError, + ConfigurationExecutionError(t, v, info), + tb) finally: del t, v, tb @@ -741,6 +740,7 @@ """Finish processing a directive """ +@implementer(IStackItem) class SimpleStackItem(object): """Simple stack item @@ -752,8 +752,6 @@ has been reached. """ - implements(IStackItem) - def __init__(self, context, handler, info, *argdata): newcontext = GroupingContextDecorator(context) newcontext.info = info @@ -800,6 +798,7 @@ def finish(self): pass +@implementer(IStackItem) class GroupingStackItem(RootStackItem): """Stack item for a grouping directive @@ -950,8 +949,6 @@ 'order': 0}] """ - implements(IStackItem) - def __init__(self, context): super(GroupingStackItem, self).__init__(context) @@ -980,6 +977,7 @@ def noop(): pass +@implementer(IStackItem) class ComplexStackItem(object): """Complex stack item @@ -1056,25 +1054,22 @@ Note that the name passed to ``contained`` is a 2-part name, consisting of a namespace and a name within the namespace. - >>> from pprint import PrettyPrinter - >>> pprint=PrettyPrinter(width=60).pprint + >>> context.actions == [{'args': (), + ... 'callable': f, + ... 'discriminator': 'init', + ... 'includepath': (), + ... 'info': 'foo', + ... 'kw': {}, + ... 'order': 0}, + ... {'args': (), + ... 'callable': f, + ... 'discriminator': ('sub', u'av', u'bv'), + ... 'includepath': (), + ... 'info': 'baz', + ... 'kw': {}, + ... 'order': 0}] + True - >>> pprint(context.actions) - [{'args': (), - 'callable': f, - 'discriminator': 'init', - 'includepath': (), - 'info': 'foo', - 'kw': {}, - 'order': 0}, - {'args': (), - 'callable': f, - 'discriminator': ('sub', u'av', u'bv'), - 'includepath': (), - 'info': 'baz', - 'kw': {}, - 'order': 0}] - The new stack item returned by contained is one that doesn't allow any more subdirectives, @@ -1085,32 +1080,30 @@ The stack item will call the handler if it is callable. - >>> pprint(context.actions) - [{'args': (), - 'callable': f, - 'discriminator': 'init', - 'includepath': (), - 'info': 'foo', - 'kw': {}, - 'order': 0}, - {'args': (), - 'callable': f, - 'discriminator': ('sub', u'av', u'bv'), - 'includepath': (), - 'info': 'baz', - 'kw': {}, - 'order': 0}, - {'args': (), - 'callable': f, - 'discriminator': ('call', u'xv', u'yv'), - 'includepath': (), - 'info': 'foo', - 'kw': {}, - 'order': 0}] + >>> context.actions == [{'args': (), + ... 'callable': f, + ... 'discriminator': 'init', + ... 'includepath': (), + ... 'info': 'foo', + ... 'kw': {}, + ... 'order': 0}, + ... {'args': (), + ... 'callable': f, + ... 'discriminator': ('sub', u'av', u'bv'), + ... 'includepath': (), + ... 'info': 'baz', + ... 'kw': {}, + ... 'order': 0}, + ... {'args': (), + ... 'callable': f, + ... 'discriminator': ('call', u'xv', u'yv'), + ... 'includepath': (), + ... 'info': 'foo', + ... 'kw': {}, + ... 'order': 0}] + True """ - implements(IStackItem) - def __init__(self, meta, context, data, info): newcontext = GroupingContextDecorator(context) newcontext.info = info @@ -1142,7 +1135,7 @@ try: actions = self.handler() - except AttributeError, v: + except AttributeError as v: if v[0] == '__call__': return # noncallable raise @@ -1159,14 +1152,13 @@ ############################################################################## # Helper classes +@implementer(IConfigurationContext, IGroupingContext) class GroupingContextDecorator(ConfigurationContext): """Helper mix-in class for building grouping directives See the discussion (and test) in GroupingStackItem. """ - implements(IConfigurationContext, IGroupingContext) - def __init__(self, context, **kw): self.context = context for name, v in kw.items(): @@ -1204,6 +1196,7 @@ class IDirectivesContext(IDirectivesInfo, IConfigurationContext): pass +@implementer(IDirectivesContext) class DirectivesHandler(GroupingContextDecorator): """Handler for the directives directive @@ -1211,9 +1204,7 @@ to the normal directive context. """ - implements(IDirectivesContext) - class IDirectiveInfo(Interface): """Information common to all directive definitions have """ @@ -1377,14 +1368,13 @@ class IComplexDirectiveContext(IFullInfo, IConfigurationContext): pass +@implementer(IComplexDirectiveContext) class ComplexDirectiveDefinition(GroupingContextDecorator, dict): """Handler for defining complex directives See the description and tests for ComplexStackItem. """ - implements(IComplexDirectiveContext) - def before(self): def factory(context, data, info): @@ -1557,14 +1547,16 @@ s = data.get(n, data) if s is not data: - s = unicode(s) + s = six.text_type(s) del data[n] try: args[str(name)] = field.fromUnicode(s) - except zope.schema.ValidationError, v: - raise ConfigurationError( - "Invalid value for", n, str(v)), None, sys.exc_info()[2] + except zope.schema.ValidationError as v: + six.reraise( + ConfigurationError, + ConfigurationError("Invalid value for", n, str(v)), + sys.exc_info()[2]) elif field.required: # if the default is valid, we can use that: default = field.default @@ -1697,12 +1689,11 @@ def __str__(self): r = ["Conflicting configuration actions"] - items = self._conflicts.items() - items.sort() + items = sorted(self._conflicts.items()) for discriminator, infos in items: r.append(" For: %s" % (discriminator, )) for info in infos: - for line in unicode(info).rstrip().split(u'\n'): + for line in six.text_type(info).rstrip().split(u'\n'): r.append(u" "+line) return "\n".join(r) Index: src/zope/configuration/docutils.py =================================================================== --- src/zope/configuration/docutils.py (.../trunk) (revision 125127) +++ src/zope/configuration/docutils.py (.../branches/jinty-python3) (revision 125127) @@ -25,15 +25,16 @@ Examples: - >>> print wrap('foo bar')[:-2] + >>> from six import print_ + >>> print_(wrap('foo bar')[:-2]) foo bar - >>> print wrap('foo bar', indent=2)[:-2] + >>> print_(wrap('foo bar', indent=2)[:-2]) foo bar - >>> print wrap('foo bar, more foo bar', 10)[:-2] + >>> print_(wrap('foo bar, more foo bar', 10)[:-2]) foo bar, more foo bar - >>> print wrap('foo bar, more foo bar', 10, 2)[:-2] + >>> print_(wrap('foo bar, more foo bar', 10, 2)[:-2]) foo bar, more foo bar Index: src/zope/configuration/fields.py =================================================================== --- src/zope/configuration/fields.py (.../trunk) (revision 125127) +++ src/zope/configuration/fields.py (.../branches/jinty-python3) (revision 125127) @@ -19,12 +19,13 @@ from zope.schema.interfaces import IFromUnicode from zope.schema.interfaces import ConstraintNotSatisfied from zope.configuration.exceptions import ConfigurationError -from zope.interface import implements +from zope.interface import implementer from zope.configuration.interfaces import InvalidToken PYIDENTIFIER_REGEX = u'\\A[a-zA-Z_]+[a-zA-Z0-9_]*\\Z' pyidentifierPattern = re.compile(PYIDENTIFIER_REGEX) +@implementer(IFromUnicode) class PythonIdentifier(schema.TextLine): r"""This field describes a python identifier, i.e. a variable name. @@ -50,20 +51,19 @@ ... field._validate(value) >>> >>> from zope import schema + >>> from six import print_ >>> >>> for value in (u'3foo', u'foo:', u'\\', u''): ... try: ... field._validate(value) ... except schema.ValidationError: - ... print 'Validation Error' + ... print_('Validation Error') Validation Error Validation Error Validation Error Validation Error """ - implements(IFromUnicode) - def fromUnicode(self, u): return u.strip() @@ -72,6 +72,7 @@ if pyidentifierPattern.match(value) is None: raise schema.ValidationError(value) +@implementer(IFromUnicode) class GlobalObject(schema.Field): """An object that can be accessed as a module global. @@ -115,8 +116,6 @@ """ - implements(IFromUnicode) - def __init__(self, value_type=None, **kw): self.value_type = value_type super(GlobalObject, self).__init__(**kw) @@ -135,7 +134,7 @@ try: value = self.context.resolve(name) - except ConfigurationError, v: + except ConfigurationError as v: raise schema.ValidationError(v) self.validate(value) @@ -175,6 +174,7 @@ def __init__(self, **kw): super(GlobalInterface, self).__init__(schema.InterfaceField(), **kw) +@implementer(IFromUnicode) class Tokens(schema.List): """A list that can be read from a space-separated string @@ -215,7 +215,6 @@ >>> """ - implements(IFromUnicode) def fromUnicode(self, u): u = u.strip() @@ -225,7 +224,7 @@ for s in u.split(): try: v = vt.fromUnicode(s) - except schema.ValidationError, v: + except schema.ValidationError as v: raise InvalidToken("%s in %s" % (v, u)) else: values.append(v) @@ -236,6 +235,7 @@ return values +@implementer(IFromUnicode) class Path(schema.Text): r"""A file path name, which may be input as a relative path @@ -248,6 +248,7 @@ We'll be careful to do this in an os-independent fashion. + >>> import six >>> class FauxContext(object): ... def path(self, p): ... return os.path.join(os.sep, 'faux', 'context', p) @@ -257,7 +258,7 @@ Lets try an absolute path first: - >>> p = unicode(os.path.join(os.sep, 'a', 'b')) + >>> p = six.text_type(os.path.join(os.sep, 'a', 'b')) >>> n = field.fromUnicode(p) >>> n.split(os.sep) [u'', u'a', u'b'] @@ -271,7 +272,7 @@ Now try a relative path: - >>> p = unicode(os.path.join('a', 'b')) + >>> p = six.text_type(os.path.join('a', 'b')) >>> n = field.fromUnicode(p) >>> n.split(os.sep) [u'', u'faux', u'context', u'a', u'b'] @@ -279,8 +280,6 @@ """ - implements(IFromUnicode) - def fromUnicode(self, u): u = u.strip() if os.path.isabs(u): @@ -289,6 +288,7 @@ return self.context.path(u) +@implementer(IFromUnicode) class Bool(schema.Bool): """A boolean value @@ -305,8 +305,6 @@ 0 """ - implements(IFromUnicode) - def fromUnicode(self, u): u = u.lower() if u in ('1', 'true', 'yes', 't', 'y'): @@ -315,6 +313,7 @@ return False raise schema.ValidationError +@implementer(IFromUnicode) class MessageID(schema.Text): """Text string that should be translated. @@ -377,15 +376,13 @@ >>> i = field.fromUnicode(u"Foo Bar") >>> i = field.fromUnicode(u"Hello world!") - >>> from pprint import PrettyPrinter - >>> pprint=PrettyPrinter(width=70).pprint - >>> pprint(context.i18n_strings) - {'testing': {u'Foo Bar': [('file location', 8)], - u'Hello world!': [('file location', 8), - ('file location', 8)]}} + >>> context.i18n_strings == {'testing': {u'Foo Bar': [('file location', 8)], + ... u'Hello world!': [('file location', 8), + ... ('file location', 8)]}} + True >>> from zope.i18nmessageid import Message - >>> isinstance(context.i18n_strings['testing'].keys()[0], Message) + >>> isinstance(list(context.i18n_strings['testing'].keys())[0], Message) 1 Explicit Message IDs @@ -403,8 +400,6 @@ True """ - implements(IFromUnicode) - __factories = {} def fromUnicode(self, u): Index: src/zope/configuration/xmlconfig.py =================================================================== --- src/zope/configuration/xmlconfig.py (.../trunk) (revision 125127) +++ src/zope/configuration/xmlconfig.py (.../branches/jinty-python3) (revision 125127) @@ -25,6 +25,7 @@ import logging import zope.configuration.config as config +import six from glob import glob from xml.sax import make_parser from xml.sax.xmlreader import InputSource @@ -48,7 +49,7 @@ info and the wrapped error type and value: >>> v = ZopeXMLConfigurationError("blah", AttributeError, "xxx") - >>> print v + >>> six.print_(v) 'blah' AttributeError: xxx @@ -61,13 +62,13 @@ # Only use the repr of the info. This is because we expect to # get a parse info and we only want the location information. return "%s\n %s: %s" % ( - `self.info`, self.etype.__name__, self.evalue) + repr(self.info), self.etype.__name__, self.evalue) class ZopeSAXParseException(ConfigurationError): """Sax Parser errors, reformatted in an emacs friendly way >>> v = ZopeSAXParseException("foo.xml:12:3:Not well formed") - >>> print v + >>> six.print_(v) File "foo.xml", line 12.3, Not well formed """ @@ -93,7 +94,7 @@ >>> info File "tests//sample.zcml", line 1.0 - >>> print info + >>> six.print_(info) File "tests//sample.zcml", line 1.0 >>> info.characters("blah\\n") @@ -105,7 +106,7 @@ >>> info File "tests//sample.zcml", line 1.0-7.0 - >>> print info + >>> six.print_(info) File "tests//sample.zcml", line 1.0-7.0 @@ -151,7 +152,8 @@ except IOError: src = " Could not read source." else: - lines = f.readlines()[self.line-1:self.eline] + with f: + lines = f.readlines()[self.line-1:self.eline] ecolumn = self.ecolumn if lines[-1][ecolumn:ecolumn+2] == '>> here = os.path.dirname(__file__) >>> path = os.path.join(here, 'tests', 'samplepackage', 'configure.zcml') - >>> f = openInOrPlain(path) - >>> f.name[-14:] + >>> with openInOrPlain(path) as f: + ... f.name[-14:] 'configure.zcml' But if we open foo.zcml, we'll get foo.zcml.in, since there isn't a foo.zcml: >>> path = os.path.join(here, 'tests', 'samplepackage', 'foo.zcml') - >>> f = openInOrPlain(path) - >>> f.name[-11:] + >>> with openInOrPlain(path) as f: + ... f.name[-11:] 'foo.zcml.in' Make sure other IOErrors are re-raised. We need to do this in a @@ -418,17 +426,17 @@ >>> try: ... f = openInOrPlain('.') ... except IOError: - ... print "passed" + ... six.print_("passed") ... else: - ... print "failed" ... + ... six.print_("failed") passed """ try: fp = open(filename) - except IOError, (code, msg): - if code == errno.ENOENT: + except IOError as e: + if e.errno == errno.ENOENT: fn = filename + ".in" if os.path.exists(fn): fp = open(fn) @@ -446,7 +454,7 @@ files in each package and then link them together. """ - file = schema.BytesLine( + file = schema.NativeStringLine( title=u"Configuration file name", description=u"The name of a configuration file to be included/excluded, " u"relative to the directive containing the " @@ -454,7 +462,7 @@ required=False, ) - files = schema.BytesLine( + files = schema.NativeStringLine( title=u"Configuration file name pattern", description=u""" The names of multiple configuration files to be included/excluded, @@ -530,23 +538,21 @@ if files: paths = glob(context.path(files)) - paths = zip([path.lower() for path in paths], paths) - paths.sort() + paths = sorted(zip([path.lower() for path in paths], paths)) paths = [path for (l, path) in paths] else: paths = [context.path(file)] for path in paths: if context.processFile(path): - f = openInOrPlain(path) - logger.debug("include %s" % f.name) + with openInOrPlain(path) as f: + logger.debug("include %s" % f.name) - context.basepath = os.path.dirname(path) - context.includepath = _context.includepath + (f.name, ) - _context.stack.append(config.GroupingStackItem(context)) + context.basepath = os.path.dirname(path) + context.includepath = _context.includepath + (f.name, ) + _context.stack.append(config.GroupingStackItem(context)) - processxmlfile(f, context) - f.close() + processxmlfile(f, context) assert _context.stack[-1].context is context _context.stack.pop() @@ -571,8 +577,7 @@ if files: paths = glob(context.path(files)) - paths = zip([path.lower() for path in paths], paths) - paths.sort() + paths = sorted(zip([path.lower() for path in paths], paths)) paths = [path for (l, path) in paths] else: paths = [context.path(file)] @@ -652,7 +657,7 @@ def string(s, context=None, name="", execute=True): """Execute a zcml string """ - from StringIO import StringIO + from six import StringIO if context is None: context = config.ConfigurationMachine() Index: src/zope/configuration/stxdocs.py =================================================================== --- src/zope/configuration/stxdocs.py (.../trunk) (revision 125127) +++ src/zope/configuration/stxdocs.py (.../branches/jinty-python3) (revision 125127) @@ -28,6 +28,7 @@ sub-directories with files in them. """ import sys, os, getopt +from six import print_ import zope.configuration from zope.schema import getFieldsInOrder from zope.configuration import config, xmlconfig @@ -35,9 +36,9 @@ def usage(code, msg=''): # Python 2.1 required - print >> sys.stderr, __doc__ + print_(__doc__, file=sys.stderr) if msg: - print >> sys.stderr, msg + print_(msg, file=sys.stderr) sys.exit(code) def _directiveDocs(name, schema, handler, info, indent_offset=0): @@ -88,7 +89,7 @@ def _subDirectiveDocs(subdirs, namespace, name): """Appends a list of sub-directives and their full specification.""" - if subdirs.has_key((namespace, name)): + if (namespace, name) in subdirs: text = '\n Subdirectives\n\n' sub_dirs = [] # Simply walk through all sub-directives here. @@ -127,7 +128,7 @@ if not path == os.path.abspath(path): cwd = os.getcwd() # This is for symlinks. - if os.environ.has_key('PWD'): + if 'PWD' in os.environ: cwd = os.environ['PWD'] path = os.path.normpath(os.path.join(cwd, path)) return path @@ -138,7 +139,7 @@ sys.argv[1:], 'h:f:o:', ['help']) - except getopt.error, msg: + except getopt.error as msg: usage(1, msg) zcml_file = None Index: MANIFEST.in =================================================================== --- MANIFEST.in (.../trunk) (revision 0) +++ MANIFEST.in (.../branches/jinty-python3) (revision 125127) @@ -0,0 +1,2 @@ +include *.txt +recursive-include src/zope/configuration *.txt *.zcml *.zcml.in