[Checkins] SVN: zope.configuration/branches/jinty-python3/ Some Python 3.3 support.

Brian Sutherland cvs-admin at zope.org
Mon Apr 9 16:31:07 UTC 2012


Log message for revision 125120:
  Some Python 3.3 support.
  
  Checkpoint commit. Seems like almost everything works. Some doctests need to be
  re-written as unittests to cope with Python 2/3 doctest changes.
  
  Also pending approval of zope.schema.NativeStringLine on zope-dev.
  

Changed:
  U   zope.configuration/branches/jinty-python3/CHANGES.txt
  A   zope.configuration/branches/jinty-python3/MANIFEST.in
  U   zope.configuration/branches/jinty-python3/setup.py
  U   zope.configuration/branches/jinty-python3/src/zope/configuration/config.py
  U   zope.configuration/branches/jinty-python3/src/zope/configuration/docutils.py
  U   zope.configuration/branches/jinty-python3/src/zope/configuration/fields.py
  U   zope.configuration/branches/jinty-python3/src/zope/configuration/stxdocs.py
  U   zope.configuration/branches/jinty-python3/src/zope/configuration/tests/directives.py
  U   zope.configuration/branches/jinty-python3/src/zope/configuration/tests/samplepackage/foo.py
  U   zope.configuration/branches/jinty-python3/src/zope/configuration/tests/test_config.py
  U   zope.configuration/branches/jinty-python3/src/zope/configuration/tests/test_nested.py
  U   zope.configuration/branches/jinty-python3/src/zope/configuration/tests/test_simple.py
  U   zope.configuration/branches/jinty-python3/src/zope/configuration/tests/test_xmlconfig.py
  U   zope.configuration/branches/jinty-python3/src/zope/configuration/tests/victim.py
  U   zope.configuration/branches/jinty-python3/src/zope/configuration/xmlconfig.py

-=-
Modified: zope.configuration/branches/jinty-python3/CHANGES.txt
===================================================================
--- zope.configuration/branches/jinty-python3/CHANGES.txt	2012-04-09 16:30:40 UTC (rev 125119)
+++ zope.configuration/branches/jinty-python3/CHANGES.txt	2012-04-09 16:31:04 UTC (rev 125120)
@@ -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)
 ------------------

Added: zope.configuration/branches/jinty-python3/MANIFEST.in
===================================================================
--- zope.configuration/branches/jinty-python3/MANIFEST.in	                        (rev 0)
+++ zope.configuration/branches/jinty-python3/MANIFEST.in	2012-04-09 16:31:04 UTC (rev 125120)
@@ -0,0 +1,2 @@
+include *.txt
+recursive-include src/zope/configuration *.txt *.zcml *.zcml.in

Modified: zope.configuration/branches/jinty-python3/setup.py
===================================================================
--- zope.configuration/branches/jinty-python3/setup.py	2012-04-09 16:30:40 UTC (rev 125119)
+++ zope.configuration/branches/jinty-python3/setup.py	2012-04-09 16:31:04 UTC (rev 125120)
@@ -89,7 +89,8 @@
       namespace_packages=['zope'],
       extras_require=dict(
           test=['zope.testing']),
-      install_requires=['zope.i18nmessageid',
+      install_requires=['six',
+                        'zope.i18nmessageid',
                         'zope.interface',
                         'zope.schema',
                         'setuptools',

Modified: zope.configuration/branches/jinty-python3/src/zope/configuration/config.py
===================================================================
--- zope.configuration/branches/jinty-python3/src/zope/configuration/config.py	2012-04-09 16:30:40 UTC (rev 125119)
+++ zope.configuration/branches/jinty-python3/src/zope/configuration/config.py	2012-04-09 16:31:04 UTC (rev 125120)
@@ -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')
-        <type '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
 
+ at 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,9 +663,8 @@
         ...   ]
         >>> try:
         ...    v = context.execute_actions()
-        ... except ConfigurationExecutionError, v:
-        ...    pass
-        >>> print v
+        ... except ConfigurationExecutionError as v:
+        ...    six.print_(v)
         exceptions.AttributeError: 'function' object has no attribute 'xxx'
           in:
           oops
@@ -696,7 +695,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 +743,7 @@
         """Finish processing a directive
         """
 
+ at implementer(IStackItem)
 class SimpleStackItem(object):
     """Simple stack item
 
@@ -752,8 +755,6 @@
     has been reached.
     """
 
-    implements(IStackItem)
-
     def __init__(self, context, handler, info, *argdata):
         newcontext = GroupingContextDecorator(context)
         newcontext.info = info
@@ -800,6 +801,7 @@
     def finish(self):
         pass
 
+ at implementer(IStackItem)
 class GroupingStackItem(RootStackItem):
     """Stack item for a grouping directive
 
@@ -950,8 +952,6 @@
       'order': 0}]
     """
 
-    implements(IStackItem)
-
     def __init__(self, context):
         super(GroupingStackItem, self).__init__(context)
 
@@ -980,6 +980,7 @@
 def noop():
     pass
 
+ at implementer(IStackItem)
 class ComplexStackItem(object):
     """Complex stack item
 
@@ -1109,8 +1110,6 @@
       'order': 0}]
     """
 
-    implements(IStackItem)
-
     def __init__(self, meta, context, data, info):
         newcontext = GroupingContextDecorator(context)
         newcontext.info = info
@@ -1142,7 +1141,7 @@
 
         try:
             actions = self.handler()
-        except AttributeError, v:
+        except AttributeError as v:
             if v[0] == '__call__':
                 return # noncallable
             raise
@@ -1159,14 +1158,13 @@
 ##############################################################################
 # Helper classes
 
+ at 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 +1202,7 @@
 class IDirectivesContext(IDirectivesInfo, IConfigurationContext):
     pass
 
+ at implementer(IDirectivesContext)
 class DirectivesHandler(GroupingContextDecorator):
     """Handler for the directives directive
 
@@ -1211,9 +1210,7 @@
     to the normal directive context.
 
     """
-    implements(IDirectivesContext)
 
-
 class IDirectiveInfo(Interface):
     """Information common to all directive definitions have
     """
@@ -1377,14 +1374,13 @@
 class IComplexDirectiveContext(IFullInfo, IConfigurationContext):
     pass
 
+ at 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 +1553,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 +1695,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)

Modified: zope.configuration/branches/jinty-python3/src/zope/configuration/docutils.py
===================================================================
--- zope.configuration/branches/jinty-python3/src/zope/configuration/docutils.py	2012-04-09 16:30:40 UTC (rev 125119)
+++ zope.configuration/branches/jinty-python3/src/zope/configuration/docutils.py	2012-04-09 16:31:04 UTC (rev 125120)
@@ -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

Modified: zope.configuration/branches/jinty-python3/src/zope/configuration/fields.py
===================================================================
--- zope.configuration/branches/jinty-python3/src/zope/configuration/fields.py	2012-04-09 16:30:40 UTC (rev 125119)
+++ zope.configuration/branches/jinty-python3/src/zope/configuration/fields.py	2012-04-09 16:31:04 UTC (rev 125120)
@@ -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)
 
+ at 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)
 
+ at 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)
 
+ at 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
 
+ at 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)
 
 
+ at 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
 
+ at implementer(IFromUnicode)
 class MessageID(schema.Text):
     """Text string that should be translated.
 
@@ -385,7 +384,7 @@
                                    ('file location', 8)]}}
 
     >>> 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 +402,6 @@
     True
     """
 
-    implements(IFromUnicode)
-
     __factories = {}
 
     def fromUnicode(self, u):

Modified: zope.configuration/branches/jinty-python3/src/zope/configuration/stxdocs.py
===================================================================
--- zope.configuration/branches/jinty-python3/src/zope/configuration/stxdocs.py	2012-04-09 16:30:40 UTC (rev 125119)
+++ zope.configuration/branches/jinty-python3/src/zope/configuration/stxdocs.py	2012-04-09 16:31:04 UTC (rev 125120)
@@ -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

Modified: zope.configuration/branches/jinty-python3/src/zope/configuration/tests/directives.py
===================================================================
--- zope.configuration/branches/jinty-python3/src/zope/configuration/tests/directives.py	2012-04-09 16:30:40 UTC (rev 125119)
+++ zope.configuration/branches/jinty-python3/src/zope/configuration/tests/directives.py	2012-04-09 16:31:04 UTC (rev 125120)
@@ -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
 
+ at implementer(IPackagedContext)
 class Packaged(GroupingContextDecorator):
+    pass
 
-    implements(IPackagedContext)
 
-
 class IFactory(Interface):
 
     factory = GlobalObject()

Modified: zope.configuration/branches/jinty-python3/src/zope/configuration/tests/samplepackage/foo.py
===================================================================
--- zope.configuration/branches/jinty-python3/src/zope/configuration/tests/samplepackage/foo.py	2012-04-09 16:30:40 UTC (rev 125119)
+++ zope.configuration/branches/jinty-python3/src/zope/configuration/tests/samplepackage/foo.py	2012-04-09 16:31:04 UTC (rev 125120)
@@ -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,

Modified: zope.configuration/branches/jinty-python3/src/zope/configuration/tests/test_config.py
===================================================================
--- zope.configuration/branches/jinty-python3/src/zope/configuration/tests/test_config.py	2012-04-09 16:30:40 UTC (rev 125119)
+++ zope.configuration/branches/jinty-python3/src/zope/configuration/tests/test_config.py	2012-04-09 16:31:04 UTC (rev 125120)
@@ -17,6 +17,7 @@
 import sys
 import unittest
 import re
+import six
 from doctest import DocTestSuite
 from zope.testing import renormalizing
 from zope.configuration.config import metans, ConfigurationMachine
@@ -382,7 +383,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 +418,36 @@
     """
 
 def test_suite():
-    checker = renormalizing.RENormalizing([
+    checkers = [
         (re.compile(r"<type 'exceptions.(\w+)Error'>:"),
                     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"\(<class 'int'>,\)"),
+                    r"(<type 'int'>, <type 'long'>)"),
+        (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(),
+        DocTestSuite('zope.configuration.fields', checker=checker),
+        DocTestSuite('zope.configuration.config', checker=checker),
+        DocTestSuite(checker=checker),
         ))
 
 if __name__ == '__main__': unittest.main()

Modified: zope.configuration/branches/jinty-python3/src/zope/configuration/tests/test_nested.py
===================================================================
--- zope.configuration/branches/jinty-python3/src/zope/configuration/tests/test_nested.py	2012-04-09 16:30:40 UTC (rev 125119)
+++ zope.configuration/branches/jinty-python3/src/zope/configuration/tests/test_nested.py	2012-04-09 16:31:04 UTC (rev 125120)
@@ -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']
 
@@ -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(
 ...      '<text xmlns="http://sample.namespaces.zope.org/schema" name="x" />',
 ...      context)
-... except xmlconfig.ZopeXMLConfigurationError, v:
-...   pass
->>> print v
+... except xmlconfig.ZopeXMLConfigurationError as v:
+...   print_(v)
 File "<string>", line 1.0
     ConfigurationError: The directive """ \
         """(u'http://sample.namespaces.zope.org/schema', u'text') """ \
@@ -175,16 +175,20 @@
 ...      </schema>
 ...      ''',
 ...      context)
-... except xmlconfig.ZopeXMLConfigurationError, v:
-...   pass
->>> print v
+... except xmlconfig.ZopeXMLConfigurationError as v:
+...   print_(v)
 File "<string>", 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"
         )
     
+ at 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()

Modified: zope.configuration/branches/jinty-python3/src/zope/configuration/tests/test_simple.py
===================================================================
--- zope.configuration/branches/jinty-python3/src/zope/configuration/tests/test_simple.py	2012-04-09 16:30:40 UTC (rev 125119)
+++ zope.configuration/branches/jinty-python3/src/zope/configuration/tests/test_simple.py	2012-04-09 16:31:04 UTC (rev 125120)
@@ -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

Modified: zope.configuration/branches/jinty-python3/src/zope/configuration/tests/test_xmlconfig.py
===================================================================
--- zope.configuration/branches/jinty-python3/src/zope/configuration/tests/test_xmlconfig.py	2012-04-09 16:30:40 UTC (rev 125119)
+++ zope.configuration/branches/jinty-python3/src/zope/configuration/tests/test_xmlconfig.py	2012-04-09 16:31:04 UTC (rev 125120)
@@ -17,6 +17,8 @@
 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
@@ -97,9 +99,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 +127,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 +165,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
         <test:foo x="blah" y="0" />
 
@@ -187,15 +187,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
         <test:foo x="blah" y="0" />
 
     >>> data.package
-    >>> print clean_path(data.basepath)
+    >>> print_(clean_path(data.basepath))
     tests/samplepackage
     """
 
@@ -212,10 +212,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
         <test:foo x="blah" y="0" />
 
@@ -255,10 +255,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
         <test:foo x="foo" y="2" />
 
@@ -284,10 +284,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
         <test:foo x="foo" y="3" />
 
@@ -303,10 +303,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
         <test:foo x="foo" y="2" />
 
@@ -322,7 +322,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 +330,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 +404,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 +474,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 +552,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 +596,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 +620,28 @@
 
 
 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(),
+        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__':

Modified: zope.configuration/branches/jinty-python3/src/zope/configuration/tests/victim.py
===================================================================
--- zope.configuration/branches/jinty-python3/src/zope/configuration/tests/victim.py	2012-04-09 16:30:40 UTC (rev 125119)
+++ zope.configuration/branches/jinty-python3/src/zope/configuration/tests/victim.py	2012-04-09 16:31:04 UTC (rev 125120)
@@ -1 +1 @@
-import bad
+from . import bad

Modified: zope.configuration/branches/jinty-python3/src/zope/configuration/xmlconfig.py
===================================================================
--- zope.configuration/branches/jinty-python3/src/zope/configuration/xmlconfig.py	2012-04-09 16:30:40 UTC (rev 125119)
+++ zope.configuration/branches/jinty-python3/src/zope/configuration/xmlconfig.py	2012-04-09 16:31:04 UTC (rev 125120)
@@ -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
       <configure xmlns='http://namespaces.zope.org/zope'>
         <!-- zope.configure -->
@@ -177,7 +178,7 @@
                 # unicode won't be printable, at least on my console
                 src = src.encode('ascii','replace')
 
-        return "%s\n%s" % (`self`, src)
+        return "%s\n%s" % (repr(self), src)
 
     def characters(self, characters):
         self.text += characters
@@ -235,8 +236,10 @@
         except:
             if self.testing:
                 raise
-            raise ZopeXMLConfigurationError(info, sys.exc_info()[0],
-                sys.exc_info()[1]), None, sys.exc_info()[2]
+            six.reraise(
+                    ZopeXMLConfigurationError,
+                    ZopeXMLConfigurationError(info, sys.exc_info()[0], sys.exc_info()[1]),
+                    sys.exc_info()[2])
 
         self.context.setInfo(info)
 
@@ -362,8 +365,9 @@
         except:
             if self.testing:
                 raise
-            raise ZopeXMLConfigurationError(info, sys.exc_info()[0],
-                sys.exc_info()[1]), None, sys.exc_info()[2]
+            six.reraise(ZopeXMLConfigurationError,
+                    ZopeXMLConfigurationError(info, sys.exc_info()[0], sys.exc_info()[1]),
+                    sys.exc_info()[2])
 
 
 def processxmlfile(file, context, testing=False):
@@ -379,7 +383,10 @@
     try:
         parser.parse(src)
     except SAXParseException:
-        raise ZopeSAXParseException(sys.exc_info()[1]), None, sys.exc_info()[2]
+        six.reraise(
+                ZopeSAXParseException,
+                ZopeSAXParseException(sys.exc_info()[1]),
+                sys.exc_info()[2])
 
 
 def openInOrPlain(filename):
@@ -418,17 +425,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 +453,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 +461,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,8 +537,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)]
@@ -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="<string>", execute=True):
     """Execute a zcml string
     """
-    from StringIO import StringIO
+    from six import StringIO
 
     if context is None:
         context = config.ConfigurationMachine()



More information about the checkins mailing list