[Checkins] SVN: zope.schema/branches/jinty-python3/src/zope/schema/ Make ASCII, ASCIILine, Id and DottedName into 'str' on Python 3

Brian Sutherland jinty at web.de
Tue Oct 11 06:28:01 EST 2011


Log message for revision 123052:
  Make ASCII, ASCIILine, Id and DottedName into 'str' on Python 3
  
  Still unsure whether URI should be str on Python 3, so leaving it as Bytes
  

Changed:
  U   zope.schema/branches/jinty-python3/src/zope/schema/_field.py
  U   zope.schema/branches/jinty-python3/src/zope/schema/interfaces.py
  U   zope.schema/branches/jinty-python3/src/zope/schema/tests/test_dotted_name.py

-=-
Modified: zope.schema/branches/jinty-python3/src/zope/schema/_field.py
===================================================================
--- zope.schema/branches/jinty-python3/src/zope/schema/_field.py	2011-10-10 20:25:45 UTC (rev 123051)
+++ zope.schema/branches/jinty-python3/src/zope/schema/_field.py	2011-10-11 11:28:01 UTC (rev 123052)
@@ -73,26 +73,7 @@
 classImplements(Bool, IFromUnicode)
 classImplements(Int, IInt)
 
-if PY3:
-    def _to_string(str):
-        return str.decode('ascii')
 
-    def _max_string_ord(bytes):
-        return max(bytes)
-else:
-    def _to_string(str):
-        return str
-    
-    def _max_string_ord(bytes):
-        return max(map(ord, bytes))
-
-def _re_on_bytes(re):
-    if PY3:
-        def f(in_bytes):
-            return re(_to_string(in_bytes))
-        return f
-    return re
-
 @implementer(ISourceText)
 class SourceText(Text):
     __doc__ = ISourceText.__doc__
@@ -124,9 +105,14 @@
         self.validate(v)
         return v
 
+# for things which are of the str type on both Python 2 and 3
+if PY3:
+    _Str = Text
+else:
+    _Str = Bytes
 
 @implementer(IASCII)
-class ASCII(Bytes):
+class ASCII(_Str):
     __doc__ = IASCII.__doc__
 
     def _validate(self, value):
@@ -135,15 +121,15 @@
 
         Make sure we accept empty strings:
 
-        >>> empty = b('')
+        >>> empty = ''
         >>> ascii._validate(empty)
 
         and all kinds of alphanumeric strings:
 
-        >>> alphanumeric = b("Bob\'s my 23rd uncle")
+        >>> alphanumeric = "Bob\'s my 23rd uncle"
         >>> ascii._validate(alphanumeric)
 
-        >>> umlauts = b("Köhlerstraße")
+        >>> umlauts = "Köhlerstraße"
         >>> ascii._validate(umlauts)
         Traceback (most recent call last):
         ...
@@ -152,7 +138,7 @@
         super(ASCII, self)._validate(value)
         if not value:
             return
-        if not _max_string_ord(value) < 128:
+        if not max(map(ord, value)) < 128:
             raise InvalidValue
 
 
@@ -164,6 +150,11 @@
         # TODO: we should probably use a more general definition of newlines
         return b('\n') not in value
 
+# for things which are of the str type on both Python 2 and 3
+if PY3:
+    _StrLine = TextLine
+else:
+    _StrLine = BytesLine
 
 @implementer(IASCIILine)
 class ASCIILine(ASCII):
@@ -603,13 +594,12 @@
         return clone
 
 
-_isuri = re.compile(
-    # scheme
-    r"[a-zA-z0-9+.-]+:"
-    # non space (should be pickier)
-    r"\S*$").match
-_isuri = _re_on_bytes(_isuri)
+_isuri = r"[a-zA-z0-9+.-]+:" # scheme
+_isuri += r"\S*$" # non space (should be pickier)
 
+_isuri_bytes = re.compile(_isuri.encode('ascii')).match
+_isuri = re.compile(_isuri).match
+
 @implementer(IURI, IFromUnicode)
 class URI(BytesLine):
     """URI schema field
@@ -627,7 +617,7 @@
         """
 
         super(URI, self)._validate(value)
-        if _isuri(value):
+        if _isuri_bytes(value):
             return
 
         raise InvalidURI(value)
@@ -656,11 +646,10 @@
     r"([.][a-zA-Z][a-zA-Z0-9_]*)*"
     # use the whole line
     r"$").match
-_isdotted = _re_on_bytes(_isdotted)
 
 
 @implementer(IId, IFromUnicode)
-class Id(BytesLine):
+class Id(_StrLine):
     """Id field
 
     Values of id fields must be either uris or dotted names.
@@ -669,13 +658,13 @@
     def _validate(self, value):
         """
         >>> id = Id(__name__='test')
-        >>> id.validate(b("http://www.python.org/foo/bar"))
-        >>> id.validate(b("zope.app.content"))
-        >>> id.validate(b("zope.app.content/a"))
+        >>> id.validate("http://www.python.org/foo/bar")
+        >>> id.validate("zope.app.content")
+        >>> id.validate("zope.app.content/a")
         Traceback (most recent call last):
         ...
         InvalidId: zope.app.content/a
-        >>> id.validate(b("http://zope.app.content x y"))
+        >>> id.validate("http://zope.app.content x y")
         Traceback (most recent call last):
         ...
         InvalidId: http://zope.app.content x y
@@ -683,7 +672,7 @@
         super(Id, self)._validate(value)
         if _isuri(value):
             return
-        if _isdotted(value) and b(".") in value:
+        if _isdotted(value) and "." in value:
             return
 
         raise InvalidId(value)
@@ -711,7 +700,7 @@
 
 
 @implementer(IDottedName)
-class DottedName(BytesLine):
+class DottedName(_StrLine):
     """Dotted name field.
 
     Values of DottedName fields must be Python-style dotted names.
@@ -762,44 +751,44 @@
     def _validate(self, value):
         """
         >>> dotted_name = DottedName(__name__='test')
-        >>> dotted_name.validate(b("a.b.c"))
-        >>> dotted_name.validate(b("a"))
-        >>> dotted_name.validate(b("   a"))
+        >>> dotted_name.validate("a.b.c")
+        >>> dotted_name.validate("a")
+        >>> dotted_name.validate("   a")
         Traceback (most recent call last):
         ...
         InvalidDottedName:    a
 
         >>> dotted_name = DottedName(__name__='test', min_dots=1)
-        >>> dotted_name.validate(b('a.b'))
-        >>> dotted_name.validate(b('a.b.c.d'))
-        >>> dotted_name.validate(b('a'))
+        >>> dotted_name.validate('a.b')
+        >>> dotted_name.validate('a.b.c.d')
+        >>> dotted_name.validate('a')
         Traceback (most recent call last):
         ...
         InvalidDottedName: ('too few dots; 1 required', 'a')
 
         >>> dotted_name = DottedName(__name__='test', max_dots=0)
-        >>> dotted_name.validate(b('a'))
-        >>> dotted_name.validate(b('a.b'))
+        >>> dotted_name.validate('a')
+        >>> dotted_name.validate('a.b')
         Traceback (most recent call last):
         ...
         InvalidDottedName: ('too many dots; no more than 0 allowed', 'a.b')
 
         >>> dotted_name = DottedName(__name__='test', max_dots=2)
-        >>> dotted_name.validate(b('a'))
-        >>> dotted_name.validate(b('a.b'))
-        >>> dotted_name.validate(b('a.b.c'))
-        >>> dotted_name.validate(b('a.b.c.d'))
+        >>> dotted_name.validate('a')
+        >>> dotted_name.validate('a.b')
+        >>> dotted_name.validate('a.b.c')
+        >>> dotted_name.validate('a.b.c.d')
         Traceback (most recent call last):
         ...
         InvalidDottedName: ('too many dots; no more than 2 allowed', 'a.b.c.d')
 
         >>> dotted_name = DottedName(__name__='test', max_dots=1, min_dots=1)
-        >>> dotted_name.validate(b('a.b'))
-        >>> dotted_name.validate(b('a'))
+        >>> dotted_name.validate('a.b')
+        >>> dotted_name.validate('a')
         Traceback (most recent call last):
         ...
         InvalidDottedName: ('too few dots; 1 required', 'a')
-        >>> dotted_name.validate(b('a.b.c'))
+        >>> dotted_name.validate('a.b.c')
         Traceback (most recent call last):
         ...
         InvalidDottedName: ('too many dots; no more than 1 allowed', 'a.b.c')
@@ -808,7 +797,7 @@
         super(DottedName, self)._validate(value)
         if not _isdotted(value):
             raise InvalidDottedName(value)
-        dots = _to_string(value).count(".")
+        dots = value.count(".")
         if dots < self.min_dots:
             raise InvalidDottedName("too few dots; %d required" % self.min_dots,
                                     value)

Modified: zope.schema/branches/jinty-python3/src/zope/schema/interfaces.py
===================================================================
--- zope.schema/branches/jinty-python3/src/zope/schema/interfaces.py	2011-10-10 20:25:45 UTC (rev 123051)
+++ zope.schema/branches/jinty-python3/src/zope/schema/interfaces.py	2011-10-11 11:28:01 UTC (rev 123052)
@@ -16,7 +16,7 @@
 __docformat__ = "reStructuredText"
 
 from zope.interface import Interface, Attribute
-from six import u
+from six import u, PY3
 
 from zope.schema._messageid import _
 
@@ -285,7 +285,16 @@
     The value might be constrained to be with length limits.
     """
 
-class IASCII(IBytes):
+class IText(IMinMaxLen, IIterable, IField):
+    """Field containing a unicode string."""
+
+# for things which are of the str type on both Python 2 and 3
+if PY3:
+    _IStr = IText
+else:
+    _IStr = IBytes
+
+class IASCII(_IStr):
     """Field containing a 7-bit ASCII string. No characters > DEL
     (chr(127)) are allowed
 
@@ -298,15 +307,17 @@
 class IASCIILine(IASCII):
     """Field containing a 7-bit ASCII string without newlines."""
 
-class IText(IMinMaxLen, IIterable, IField):
-    """Field containing a unicode string."""
-
 class ISourceText(IText):
     """Field for source text of object."""
 
 class ITextLine(IText):
     """Field containing a unicode string without newlines."""
 
+if PY3:
+    _IStrLine = ITextLine
+else:
+    _IStrLine = IBytesLine
+
 class IPassword(ITextLine):
     "Field containing a unicode string without newlines that is a password."
 
@@ -365,14 +376,14 @@
     """A field containing an absolute URI
     """
 
-class IId(IBytesLine):
+class IId(_IStrLine):
     """A field containing a unique identifier
 
     A unique identifier is either an absolute URI or a dotted name.
     If it's a dotted name, it should have a module/package name as a prefix.
     """
 
-class IDottedName(IBytesLine):
+class IDottedName(_IStrLine):
     """Dotted name field.
 
     Values of DottedName fields must be Python-style dotted names.

Modified: zope.schema/branches/jinty-python3/src/zope/schema/tests/test_dotted_name.py
===================================================================
--- zope.schema/branches/jinty-python3/src/zope/schema/tests/test_dotted_name.py	2011-10-10 20:25:45 UTC (rev 123051)
+++ zope.schema/branches/jinty-python3/src/zope/schema/tests/test_dotted_name.py	2011-10-11 11:28:01 UTC (rev 123052)
@@ -29,21 +29,21 @@
         field = self._Field_Factory(required=False)
 
         field.validate(None)
-        field.validate(b('foo.bar'))
-        field.validate(b('foo.bar0'))
-        field.validate(b('foo0.bar'))
+        field.validate('foo.bar')
+        field.validate('foo.bar0')
+        field.validate('foo0.bar')
         
         # We used to incorrectly allow ^: https://bugs.launchpad.net/zope.schema/+bug/191236
-        self.assertRaises(InvalidDottedName, field.validate, b('foo.bar^foobar'))
-        self.assertRaises(InvalidDottedName, field.validate, b('foo^foobar.bar'))
+        self.assertRaises(InvalidDottedName, field.validate, 'foo.bar^foobar')
+        self.assertRaises(InvalidDottedName, field.validate, 'foo^foobar.bar')
         # dotted names cannot start with digits
-        self.assertRaises(InvalidDottedName, field.validate, b('foo.0bar'))
-        self.assertRaises(InvalidDottedName, field.validate, b('0foo.bar'))
+        self.assertRaises(InvalidDottedName, field.validate, 'foo.0bar')
+        self.assertRaises(InvalidDottedName, field.validate, '0foo.bar')
 
     def testValidateRequired(self):
         field = self._Field_Factory(required=True)
         
-        field.validate(b('foo.bar'))
+        field.validate('foo.bar')
         
         self.assertRaises(RequiredMissing, field.validate, None)
 



More information about the checkins mailing list