Index: CHANGES.txt =================================================================== --- CHANGES.txt (.../trunk) (revision 125127) +++ CHANGES.txt (.../branches/jinty-native_string) (revision 125127) @@ -2,12 +2,16 @@ CHANGES ======= -4.1.2 (unreleased) +4.2.0 (unreleased) ------------------ -- Nothing changed yet. +- Introduce NativeString and NativeStringLine which are equal to Bytes and + BytesLine on Python 2 and Text and TextLine on Python 3. +- Change IURI from a Bytes string to a "native" string. This is a backwards + incompatibility which only affects Python 3. + 4.1.1 (2012-03-23) ------------------ Index: src/zope/schema/__init__.py =================================================================== --- src/zope/schema/__init__.py (.../trunk) (revision 125127) +++ src/zope/schema/__init__.py (.../branches/jinty-native_string) (revision 125127) @@ -17,6 +17,7 @@ from zope.schema._field import MinMaxLen, Choice from zope.schema._field import Bytes, ASCII, BytesLine, ASCIILine from zope.schema._field import Text, TextLine, Bool, Int, Float, Decimal +from zope.schema._field import NativeString, NativeStringLine from zope.schema._field import Tuple, List, Set, FrozenSet from zope.schema._field import Password, Dict, Datetime, Date, Timedelta from zope.schema._field import Time, SourceText Index: src/zope/schema/tests/test_uri.py =================================================================== --- src/zope/schema/tests/test_uri.py (.../trunk) (revision 0) +++ src/zope/schema/tests/test_uri.py (.../branches/jinty-native_string) (revision 125127) @@ -0,0 +1,67 @@ +############################################################################## +# +# Copyright (c) 2012 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""URI field tests +""" +from unittest import main, makeSuite + +from six import u +from zope.schema import URI +from zope.schema.tests.test_field import FieldTestBase +from zope.schema.interfaces import RequiredMissing +from zope.schema.interfaces import InvalidURI, WrongType + +class URITest(FieldTestBase): + """Test the URI Field.""" + + _Field_Factory = URI + + def testValidate(self): + field = self._Field_Factory( + title=u('Not required field'), description=u(''), + readonly=False, required=False) + field.validate(None) + field.validate('http://www.example.com') + self.assertRaises(WrongType, field.validate, 2) + + def testValidateRequired(self): + field = self._Field_Factory( + title=u('Required field'), description=u(''), + readonly=False, required=True) + field.validate('http://www.example.com') + self.assertRaises(RequiredMissing, field.validate, None) + + def testFromUnicode(self): + field = self._Field_Factory() + # result is a native string + self.assertEqual( + field.fromUnicode(u("http://www.python.org/foo/bar")), + 'http://www.python.org/foo/bar') + # leading/trailing whitespace is stripped + self.assertEqual( + field.fromUnicode(u(" http://www.python.org/foo/bar")), + 'http://www.python.org/foo/bar') + self.assertEqual( + field.fromUnicode(u(" \n http://www.python.org/foo/bar\n")), + 'http://www.python.org/foo/bar') + # but not in the middle + self.assertRaises(InvalidURI, + field.fromUnicode, + u("http://www.python.org/ foo/bar")) + +def test_suite(): + suite = makeSuite(URITest) + return suite + +if __name__ == '__main__': + main(defaultTest='test_suite') Property changes on: src/zope/schema/tests/test_uri.py ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: src/zope/schema/tests/test_native_string.py =================================================================== --- src/zope/schema/tests/test_native_string.py (.../trunk) (revision 0) +++ src/zope/schema/tests/test_native_string.py (.../branches/jinty-native_string) (revision 125127) @@ -0,0 +1,38 @@ +############################################################################## +# +# Copyright (c) 2012 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +import unittest + +import six + +from zope.schema import Text, Bytes, NativeString +from zope.schema import TextLine, BytesLine, NativeStringLine + +class TestNativeString(unittest.TestCase): + + def test_string_py2(self): + if six.PY3: + return + self.assertTrue(NativeString is Bytes) + self.assertTrue(NativeStringLine is BytesLine) + + def test_string_py3(self): + if not six.PY3: + return + self.assertTrue(NativeString is Text) + self.assertTrue(NativeStringLine is TextLine) + +def test_suite(): + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(TestNativeString)) + return suite Property changes on: src/zope/schema/tests/test_native_string.py ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: src/zope/schema/_field.py =================================================================== --- src/zope/schema/_field.py (.../trunk) (revision 125127) +++ src/zope/schema/_field.py (.../branches/jinty-native_string) (revision 125127) @@ -107,12 +107,12 @@ # for things which are of the str type on both Python 2 and 3 if PY3: - _Str = Text + NativeString = Text else: - _Str = Bytes + NativeString = Bytes @implementer(IASCII) -class ASCII(_Str): +class ASCII(NativeString): __doc__ = IASCII.__doc__ def _validate(self, value): @@ -152,9 +152,9 @@ # for things which are of the str type on both Python 2 and 3 if PY3: - _StrLine = TextLine + NativeStringLine = TextLine else: - _StrLine = BytesLine + NativeStringLine = BytesLine @implementer(IASCIILine) class ASCIILine(ASCII): @@ -602,46 +602,32 @@ _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): +class URI(NativeStringLine): """URI schema field """ def _validate(self, value): """ >>> uri = URI(__name__='test') - >>> uri.validate(b("http://www.python.org/foo/bar")) - >>> uri.validate(b("DAV:")) - >>> uri.validate(b("www.python.org/foo/bar")) + >>> uri.validate("http://www.python.org/foo/bar") + >>> uri.validate("DAV:") + >>> uri.validate("www.python.org/foo/bar") Traceback (most recent call last): ... InvalidURI: www.python.org/foo/bar """ super(URI, self)._validate(value) - if _isuri_bytes(value): + if _isuri(value): return raise InvalidURI(value) def fromUnicode(self, value): - """ - >>> uri = URI(__name__='test') - >>> uri.fromUnicode("http://www.python.org/foo/bar") - 'http://www.python.org/foo/bar' - >>> uri.fromUnicode(" http://www.python.org/foo/bar") - 'http://www.python.org/foo/bar' - >>> uri.fromUnicode(" \\n http://www.python.org/foo/bar\\n") - 'http://www.python.org/foo/bar' - >>> uri.fromUnicode("http://www.python.org/ foo/bar") - Traceback (most recent call last): - ... - InvalidURI: http://www.python.org/ foo/bar - """ - v = value.strip().encode('ascii') + v = str(value.strip()) self.validate(v) return v @@ -654,7 +640,7 @@ @implementer(IId, IFromUnicode) -class Id(_StrLine): +class Id(NativeStringLine): """Id field Values of id fields must be either uris or dotted names. @@ -705,7 +691,7 @@ @implementer(IDottedName) -class DottedName(_StrLine): +class DottedName(NativeStringLine): """Dotted name field. Values of DottedName fields must be Python-style dotted names. Index: src/zope/schema/interfaces.py =================================================================== --- src/zope/schema/interfaces.py (.../trunk) (revision 125127) +++ src/zope/schema/interfaces.py (.../branches/jinty-native_string) (revision 125127) @@ -373,7 +373,7 @@ return True -class IURI(IBytesLine): +class IURI(_IStrLine): """A field containing an absolute URI """ Index: src/zope/schema/README.txt =================================================================== --- src/zope/schema/README.txt (.../trunk) (revision 125127) +++ src/zope/schema/README.txt (.../branches/jinty-native_string) (revision 125127) @@ -65,7 +65,7 @@ is to define some data: >>> title = u('Zope 3 Website') - >>> url = b('http://dev.zope.org/Zope3') + >>> url = 'http://dev.zope.org/Zope3' Now we, get the fields from the interface: @@ -86,14 +86,9 @@ If the validation is successful, ``None`` is returned. If a validation error occurs a ``ValidationError`` will be raised; for example: - >>> url_bound.validate(u('http://zope.org/foo')) + >>> url_bound.validate('foo.bar') Traceback (most recent call last): ... - WrongType: (u'http://zope.org/foo', , 'url') - - >>> url_bound.validate(b('foo.bar')) - Traceback (most recent call last): - ... InvalidURI: foo.bar Now that the data has been successfully validated, we can set it on the