Products.validation/master: Python 3 compatibilty
Tom Gross <jenkins-z4DKO/[email protected]> Tue, 01 Aug 2017 02:10:55 -0700 (PDT)
| Newsgroups | gmane.comp.web.zope.plone.cvs |
|---|---|
| Message-ID | <[email protected]> |
Repository: Products.validation Branch: refs/heads/master Date: 2017-07-30T21:37:26Z Author: Tom Gross (tomgross) <[email protected]> Commit: https://github.com/plone/Products.validation/commit/6035de491b1bcd84bcbe540d96fa2d7418f50f4c Python 3 compatibilty Files changed: M CHANGES.txt M Products/validation/__init__.py M Products/validation/chain.py M Products/validation/i18n.py M Products/validation/interfaces/__init__.py M Products/validation/service.py M Products/validation/tests/test_validation.py M Products/validation/validators/BaseValidators.py M Products/validation/validators/ExpressionValidator.py M Products/validation/validators/IdValidator.py M Products/validation/validators/RegexValidator.py M Products/validation/validators/__init__.py M setup.py diff --git a/CHANGES.txt b/CHANGES.txt index 4b0f3f8..4055927 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -10,7 +10,8 @@ Breaking changes: New features: -- *add item here* +- Python 3 compatibility + [tomgross] Bug fixes: diff --git a/Products/validation/__init__.py b/Products/validation/__init__.py index eb584bb..f32bf23 100644 --- a/Products/validation/__init__.py +++ b/Products/validation/__init__.py @@ -1,3 +1,7 @@ -from config import validation -from chain import ValidationChain, V_REQUIRED, V_SUFFICIENT -from exceptions import UnknowValidatorError, FalseValidatorError, AlreadyRegisteredValidatorError +from Products.validation.config import validation +from Products.validation.chain import ValidationChain +from Products.validation.chain import V_REQUIRED +from Products.validation.chain import V_SUFFICIENT +from Products.validation.exceptions import UnknowValidatorError +from Products.validation.exceptions import FalseValidatorError +from Products.validation.exceptions import AlreadyRegisteredValidatorError diff --git a/Products/validation/chain.py b/Products/validation/chain.py index 966359a..6319feb 100644 --- a/Products/validation/chain.py +++ b/Products/validation/chain.py @@ -1,12 +1,13 @@ +from Products.validation.config import validation as validationService +from Products.validation.exceptions import ValidatorError from Products.validation.interfaces.IValidator import IValidationChain from zope.interface import implementer -from types import TupleType, ListType -from config import validation as validationService -from exceptions import ValidatorError V_REQUIRED = 1 V_SUFFICIENT = 2 +TupleType = type((0,1)) +ListType = type([]) @implementer(IValidationChain) @@ -140,7 +141,7 @@ def __call__(self, value, *args, **kwargs): elif mode == V_REQUIRED: continue # go on else: - raise ValidatorError, 'Unknown mode %s' % mode + raise ValidatorError('Unknown mode {0}'.format(mode)) else: if mode == V_SUFFICIENT: if isinstance(result, basestring): @@ -154,7 +155,7 @@ def __call__(self, value, *args, **kwargs): failed = True break # fatal error, stop and fail else: - raise ValidatorError, 'Unknown mode %s' % mode + raise ValidatorError('Unknown mode {0}'.format(mode)) if failed: return '\n'.join([ diff --git a/Products/validation/i18n.py b/Products/validation/i18n.py index 6c931d6..f01953c 100644 --- a/Products/validation/i18n.py +++ b/Products/validation/i18n.py @@ -2,18 +2,24 @@ from zope.i18n import translate from zope.i18nmessageid import Message +import six + PloneMessageFactory = MessageFactory('plone') -def safe_unicode(value): - if isinstance(value, unicode): +if six.PY2: + def safe_unicode(value): + if isinstance(value, unicode): + return value + elif isinstance(value, str): + try: + return unicode(value, 'utf-8') + except UnicodeDecodeError: + return unicode(value, 'utf-8', 'ignore') + return str(value) +else: + def safe_unicode(value): return value - elif isinstance(value, str): - try: - return unicode(value, 'utf-8') - except UnicodeDecodeError: - return unicode(value, 'utf-8', 'ignore') - return str(value) def recursiveTranslate(message, **kwargs): diff --git a/Products/validation/interfaces/__init__.py b/Products/validation/interfaces/__init__.py index 47a8423..28454b5 100644 --- a/Products/validation/interfaces/__init__.py +++ b/Products/validation/interfaces/__init__.py @@ -1,3 +1,3 @@ # backward compatibility -from IValidator import IValidator as ivalidator -from IValidationService import IValidationService as ivalidationService +from Products.validation.interfaces.IValidator import IValidator as ivalidator +from Products.validation.interfaces.IValidationService import IValidationService as ivalidationService diff --git a/Products/validation/service.py b/Products/validation/service.py index eb86f18..898fdd6 100644 --- a/Products/validation/service.py +++ b/Products/validation/service.py @@ -1,9 +1,12 @@ +from Products.validation.exceptions import FalseValidatorError +from Products.validation.exceptions import UnknowValidatorError +from Products.validation.exceptions import AlreadyRegisteredValidatorError from Products.validation.interfaces.IValidationService import IValidationService from Products.validation.interfaces.IValidator import IValidator from zope.interface import implementer -from exceptions import UnknowValidatorError, FalseValidatorError, AlreadyRegisteredValidatorError -from types import StringType, StringTypes +import six + @implementer(IValidationService) class Service: @@ -18,19 +21,19 @@ def validate(self, name_or_validator, value, *args, **kwargs): __call__ = validate def validatorFor(self, name_or_validator): - if type(name_or_validator) in StringTypes: + if isinstance(name_or_validator, str): try: return self._validator[name_or_validator] except KeyError: - raise UnknowValidatorError, name_or_validator + raise UnknowValidatorError(name_or_validator) elif IValidator.providedBy(name_or_validator): return name_or_validator else: - raise FalseValidatorError, name_or_validator + raise FalseValidatorError(name_or_validator) def register(self, validator): #XXX if not IValidator.providedBy(validator): - raise FalseValidatorError, validator + raise FalseValidatorError(validator) name = validator.name # The following code prevents refreshing ##if self._validator.has_key(name): @@ -47,7 +50,7 @@ def values(self): return [v for k, v in self.items()] def unregister(self, name_or_validator): - if type(name_or_validator) is StringType: + if isinstance(name_or_validator, str): name = name_or_validator elif IValidator.implementedBy(name_or_validator): name = name_or_validator.name diff --git a/Products/validation/tests/test_validation.py b/Products/validation/tests/test_validation.py index 5c67230..245e924 100644 --- a/Products/validation/tests/test_validation.py +++ b/Products/validation/tests/test_validation.py @@ -1,7 +1,10 @@ -import unittest +# -*- coding: utf-8 -*- +from Products.validation import validation + import doctest +import six +import unittest -from Products.validation import validation class TestValidation(unittest.TestCase): @@ -20,8 +23,18 @@ def test_isDecimal(self): def test_isPrintable(self): v = validation.validatorFor('isPrintable') self.assertEqual(v('text'), 1) - self.assertEqual(v('\u203'), u"Validation failed(isPrintable): '\\u203' contains unprintable characters") - self.assertEqual(v(10), u"Validation failed(isPrintable): 10 of type <type 'int'>, expected 'string'") + self.assertEqual( + v('\\u203'), + u"Validation failed(isPrintable): '\\u203' contains unprintable characters" + ) + if six.PY3: + int_type = "<class 'int'>" + else: + int_type = "<type 'int'>" + self.assertEqual( + v(10), + u"Validation failed(isPrintable): 10 of type {0}, expected 'string'".format(int_type) + ) def test_isSSN(self): v = validation.validatorFor('isSSN') @@ -67,7 +80,7 @@ def test_isMailto(self): def test_isUnixLikeName(self): v = validation.validatorFor('isUnixLikeName') self.assertEqual(v('abcd'), 1) - self.failUnless(v('a_123456'), 1) + self.assertTrue(v('a_123456'), 1) self.assertNotEqual(v('123'), 1) self.assertNotEqual(v('ab.c'), 1) self.assertEqual(v('ab,c'), u"Validation failed(isUnixLikeName): 'ab,c' this name is not a valid identifier") diff --git a/Products/validation/validators/BaseValidators.py b/Products/validation/validators/BaseValidators.py index 5fbd093..c956e0c 100644 --- a/Products/validation/validators/BaseValidators.py +++ b/Products/validation/validators/BaseValidators.py @@ -1,5 +1,5 @@ -from RegexValidator import RegexValidator -from RangeValidator import RangeValidator +from Products.validation.validators.RegexValidator import RegexValidator +from Products.validation.validators.RangeValidator import RangeValidator from Products.validation.i18n import PloneMessageFactory as _ # protocols for isURL validator, the secure (*s) variants are automagically diff --git a/Products/validation/validators/ExpressionValidator.py b/Products/validation/validators/ExpressionValidator.py index ccf1d92..b92a595 100644 --- a/Products/validation/validators/ExpressionValidator.py +++ b/Products/validation/validators/ExpressionValidator.py @@ -45,8 +45,8 @@ class ExpressionValidator: True now lets fail a test - >>> val(4,c) - u'validation failed, expr was:python: int(value) == 5' + >>> str(val(4,c)) + 'validation failed, expr was:python: int(value) == 5' It is also possible to specify the error string diff --git a/Products/validation/validators/IdValidator.py b/Products/validation/validators/IdValidator.py index f98181d..0fb1f75 100644 --- a/Products/validation/validators/IdValidator.py +++ b/Products/validation/validators/IdValidator.py @@ -40,11 +40,11 @@ def __call__(self, id, instance, *args, **kwargs): mapping = {'id': safe_unicode(id)}) return recursiveTranslate(msg, **kwargs) - # objet manager test + # object manager test # XXX: This is f***ed try: ObjectManager.checkValidId(self, id, allow_dup=1) - except BadRequest, m: + except BadRequest as m: return str(m) return 1 diff --git a/Products/validation/validators/RegexValidator.py b/Products/validation/validators/RegexValidator.py index 148e6f7..62923b3 100644 --- a/Products/validation/validators/RegexValidator.py +++ b/Products/validation/validators/RegexValidator.py @@ -1,15 +1,18 @@ from Products.validation.interfaces.IValidator import IValidator -from zope.interface import implementer from Products.validation.i18n import PloneMessageFactory as _ from Products.validation.i18n import recursiveTranslate from Products.validation.i18n import safe_unicode +from zope.interface import implementer + import re -from types import StringType +import six + def ignoreRE(value, expression): ignore = re.compile(expression) return ignore.sub('', value) + @implementer(IValidator) class RegexValidator: @@ -40,7 +43,7 @@ def __setstate__(self, dict): self.compileRegex() def __call__(self, value, *args, **kwargs): - if type(value) != StringType: + if not isinstance(value, str): msg = _(u"Validation failed($name): $value of type $type, expected 'string'", mapping = { 'name' : safe_unicode(self.name), diff --git a/Products/validation/validators/__init__.py b/Products/validation/validators/__init__.py index f9e3033..f6abbfa 100644 --- a/Products/validation/validators/__init__.py +++ b/Products/validation/validators/__init__.py @@ -1,19 +1,19 @@ -from RegexValidator import RegexValidator -from RangeValidator import RangeValidator -from ExpressionValidator import ExpressionValidator +from Products.validation.validators.RegexValidator import RegexValidator +from Products.validation.validators.RangeValidator import RangeValidator +from Products.validation.validators.ExpressionValidator import ExpressionValidator validators = [] -from BaseValidators import baseValidators +from Products.validation.validators.BaseValidators import baseValidators validators.extend(baseValidators) -from EmptyValidator import validatorList +from Products.validation.validators.EmptyValidator import validatorList validators.extend(validatorList) -from SupplValidators import validatorList +from Products.validation.validators.SupplValidators import validatorList validators.extend(validatorList) -from IdValidator import validatorList +from Products.validation.validators.IdValidator import validatorList validators.extend(validatorList) diff --git a/setup.py b/setup.py index 17434c0..ae81845 100644 --- a/setup.py +++ b/setup.py @@ -1,24 +1,26 @@ from setuptools import setup, find_packages -version = '2.0.3.dev0' +version = '2.1.dev0' setup( name='Products.validation', version=version, - description="Data validation package for Archetypes", + description="Data validation package for Zope", long_description=(open("README.txt").read() + "\n" + open("CHANGES.txt").read()), classifiers=[ "Framework :: Zope2", "Operating System :: OS Independent", + "Framework :: Plone", "Framework :: Plone :: 4.3", "Framework :: Plone :: 5.0", "Framework :: Plone :: 5.1", "Programming Language :: Python", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3.5", ], - keywords='Zope catalog index', + keywords='Zope validation regex email', author='Benjamin Saller', author_email='plone-developers-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org', url='https://pypi.python.org/pypi/Products.validation', @@ -30,6 +32,7 @@ extras_require={}, install_requires=[ 'setuptools', + 'six', 'zope.i18n', 'zope.i18nmessageid', 'zope.interface', ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot