From 1a89df2b4bdc39b8197e4950eaa698e984087885 Mon Sep 17 00:00:00 2001 From: Jason Madden Date: Mon, 13 Aug 2018 10:05:46 -0500 Subject: [PATCH 1/5] Add Python 3.7 - Use latest pypy and pypy3 on travis. - Normalize headings in CHANGES.rst and README.rst - Add badge for supported Python versions to README.rst - Run tox's coverage on Python 3 and have it actually report. Not failing yet because I think we can do better. --- .travis.yml | 8 +++++- CHANGES.rst | 83 +++++++++++++++++++++++++++-------------------------- README.rst | 24 +++++++++++----- setup.py | 7 +++-- tox.ini | 11 +++---- 5 files changed, 74 insertions(+), 59 deletions(-) diff --git a/.travis.yml b/.travis.yml index ce5d214..6e19505 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,13 @@ python: - 3.4 - 3.5 - 3.6 - - pypy-5.6.0 + - pypy + - pypy3 +matrix: + include: + - python: "3.7" + dist: xenial + sudo: true script: - coverage run -m zope.testrunner --test-path=src diff --git a/CHANGES.rst b/CHANGES.rst index 6ab7c79..72abcad 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,8 +1,11 @@ -Changes -======= +========= + Changes +========= 4.5.1 (unreleased) ------------------- +================== + +- Add support for Python 3.7. - ``Object`` instances call their schema's ``validateInvariants`` method by default to collect errors from functions decorated with @@ -19,7 +22,6 @@ Changes compatibility problem. See `issue 36 `_. - - Orderable fields, including ``Int``, ``Float``, ``Decimal``, ``Timedelta``, ``Date`` and ``Time``, can now have a ``missing_value`` without needing to specify concrete ``min`` and @@ -32,9 +34,8 @@ Changes `_ and `PR 6 `_. - 4.5.0 (2017-07-10) ------------------- +================== - Drop support for Python 2.6, 3.2, and 3.3. @@ -44,19 +45,19 @@ Changes 4.4.2 (2014-09-04) ------------------- +================== - Fix description of min max field: max value is included, not excluded. 4.4.1 (2014-03-19) ------------------- +================== - Add support for Python 3.4. 4.4.0 (2014-01-22) ------------------- +================== - Add an event on field properties to notify that a field has been updated. This event enables definition of subscribers based on an event, a context @@ -65,7 +66,7 @@ Changes 4.3.3 (2014-01-06) ------------------- +================== - PEP 8 cleanup. @@ -82,14 +83,14 @@ Changes 4.3.2 (2013-02-24) ------------------- +================== - Fix Python 2.6 support. (Forgot to run tox with all environments before last release.) 4.3.1 (2013-02-24) ------------------- +================== - Make sure that we do not fail during bytes decoding of term token when generated from a bytes value by ignoring all errors. (Another option would @@ -97,7 +98,7 @@ Changes 4.3.0 (2013-02-24) ------------------- +================== - Fix a bug where bytes values were turned into tokens inproperly in Python 3. @@ -106,18 +107,18 @@ Changes maps schema fields into ``FieldProperty`` instances. 4.2.2 (2012-11-21) ------------------- +================== - Add support for Python 3.3. 4.2.1 (2012-11-09) ------------------- +================== - Fix the default property of fields that have no defaultFactory attribute. 4.2.0 (2012-05-12) ------------------- +================== - Automate build of Sphinx HTML docs and running doctest snippets via tox. @@ -149,13 +150,13 @@ Changes 4.1.1 (2012-03-23) ------------------- +================== - Remove trailing slash in MANIFEST.in, it causes Winbot to crash. 4.1.0 (2012-03-23) ------------------- +================== - Add TreeVocabulary for nested tree-like vocabularies. @@ -167,13 +168,13 @@ Changes IContextSourceBinder is still missing. 4.0.1 (2011-11-14) ------------------- +================== - Fix bug in ``fromUnicode`` method of ``DottedName`` which would fail validation on being given unicode. Introduced in 4.0.0. 4.0.0 (2011-11-09) ------------------- +================== - Fix deprecated unittest methods. @@ -181,14 +182,14 @@ Changes Python 2.5. 3.8.1 (2011-09-23) ------------------- +================== - Fix broken Object field validation. Previous version was using a volatile property on object field values which ends in a ForbiddenAttribute error on security proxied objects. 3.8.0 (2011-03-18) ------------------- +================== - Implement a ``defaultFactory`` attribute for all fields. It is a callable that can be used to compute default values. The simplest case is:: @@ -205,7 +206,7 @@ Changes Date(defaultFactory=today) 3.7.1 (2010-12-25) ------------------- +================== - Rename the validation token, used in the validation of schema with Object Field to avoid infinite recursion: @@ -217,31 +218,31 @@ Changes https://bugs.launchpad.net/zope.schema/+bug/191236 3.7.0 (2010-09-12) ------------------- +================== - Improve error messages when term tokens or values are duplicates. - Fix the buildout so the tests run. 3.6.4 (2010-06-08) ------------------- +================== - fix validation of schema with Object Field that specify Interface schema. 3.6.3 (2010-04-30) ------------------- +================== - Prefer the standard libraries doctest module to the one from zope.testing. 3.6.2 (2010-04-30) ------------------- +================== - Avoid maximum recursion when validating Object field that points to cycles - Make the dependency on ``zope.i18nmessageid`` optional. 3.6.1 (2010-01-05) ------------------- +================== - Allow "setup.py test" to run at least a subset of the tests runnable via ``bin/test`` (227 for ``setup.py test`` vs. 258. for @@ -253,7 +254,7 @@ Changes - Make "setup.py test" tests pass on Jython. 3.6.0 (2009-12-22) ------------------- +================== - Prefer zope.testing.doctest over doctestunit. @@ -263,7 +264,7 @@ Changes instead of storing directly on the instance __dict__. 3.5.4 (2009-03-25) ------------------- +================== - Don't fail trying to validate default value for Choice fields with IContextSourceBinder object given as a source. See @@ -281,7 +282,7 @@ Changes 3.5.3 (2009-03-10) ------------------- +================== - Make Choice and Bool fields implement IFromUnicode interface, because they do provide the ``fromUnicode`` method. @@ -296,7 +297,7 @@ Changes - Remove zpkg-related file. 3.5.2 (2009-02-04) ------------------- +================== - Made validation tests compatible with Python 2.5 again (hopefully not breaking Python 2.4) @@ -304,7 +305,7 @@ Changes - Add an __all__ package attribute to expose documentation. 3.5.1 (2009-01-31) ------------------- +================== - Stop using the old old set type. @@ -318,7 +319,7 @@ Changes much more sense for debugging for developers. 3.5.0a2 (2008-12-11) --------------------- +==================== - Move zope.testing to "test" extras_require, as it is not needed for zope.schema itself. @@ -329,7 +330,7 @@ Changes example is z3c.form's converter. 3.5.0a1 (2008-10-10) --------------------- +==================== - Add the doctests to the long description. @@ -345,19 +346,19 @@ Changes - zope.schema now works on Python2.5 3.4.0 (2007-09-28) ------------------- +================== Add BeforeObjectAssignedEvent that is triggered before the object field sets a value. 3.3.0 (2007-03-15) ------------------- +================== Corresponds to the version of the zope.schema package shipped as part of the Zope 3.3.0 release. 3.2.1 (2006-03-26) ------------------- +================== Corresponds to the version of the zope.schema package shipped as part of the Zope 3.2.1 release. @@ -366,7 +367,7 @@ Fix missing import of 'VocabularyRegistryError'. See http://www.zope.org/Collectors/Zope3-dev/544 . 3.2.0 (2006-01-05) ------------------- +================== Corresponds to the version of the zope.schema package shipped as part of the Zope 3.2.0 release. @@ -375,7 +376,7 @@ Add "iterable" sources to replace vocabularies, which are now deprecated and scheduled for removal in Zope 3.3. 3.1.0 (2005-10-03) ------------------- +================== Corresponds to the version of the zope.schema package shipped as part of the Zope 3.1.0 release. @@ -386,7 +387,7 @@ argument (sources are a simpler implementation). Add 'TimeDelta' and 'ASCIILine' field types. 3.0.0 (2004-11-07) ------------------- +================== Corresponds to the version of the zope.schema package shipped as part of the Zope X3.0.0 release. diff --git a/README.rst b/README.rst index 06fe54c..2a32586 100644 --- a/README.rst +++ b/README.rst @@ -1,16 +1,26 @@ -``zope.schema`` -=============== +============= + zope.schema +============= .. image:: https://img.shields.io/pypi/v/zope.schema.svg - :target: https://pypi.python.org/pypi/zope.schema/ - :alt: Latest Version + :target: https://pypi.python.org/pypi/zope.schema/ + :alt: Latest Version + +.. image:: https://img.shields.io/pypi/pyversions/zope.schema.svg + :target: https://pypi.org/project/zope.schema/ + :alt: Supported Python versions .. image:: https://travis-ci.org/zopefoundation/zope.schema.svg?branch=master - :target: https://travis-ci.org/zopefoundation/zope.schema + :target: https://travis-ci.org/zopefoundation/zope.schema + :alt: Build Status .. image:: https://readthedocs.org/projects/zopeschema/badge/?version=latest - :target: http://zopeschema.readthedocs.org/en/latest/ - :alt: Documentation Status + :target: http://zopeschema.readthedocs.org/en/latest/ + :alt: Documentation Status + +.. image:: https://coveralls.io/repos/github/zopefoundation/zope.schema/badge.svg + :target: https://coveralls.io/github/zopefoundation/zope.schema + :alt: Code Coverage Schemas extend the notion of interfaces to detailed descriptions of Attributes (but not methods). Every schema is an interface and diff --git a/setup.py b/setup.py index 60ab19a..e14fb6e 100644 --- a/setup.py +++ b/setup.py @@ -50,7 +50,7 @@ def read(*rnames): author_email='zope-dev@zope.org', long_description=(read('README.rst') + '\n\n' + read('CHANGES.rst')), packages=find_packages('src'), - package_dir = {'': 'src'}, + package_dir={'': 'src'}, namespace_packages=['zope', ], #extras_require={'docs': ['z3c.recipe.sphinxdoc']}, install_requires=REQUIRES, @@ -66,13 +66,14 @@ def read(*rnames): "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Framework :: Zope3", "Topic :: Software Development :: Libraries :: Python Modules", ], - include_package_data = True, - zip_safe = False, + include_package_data=True, + zip_safe=False, tests_require=TESTS_REQUIRE, extras_require={ 'docs': [ diff --git a/tox.ini b/tox.ini index 043e2c0..604820d 100644 --- a/tox.ini +++ b/tox.ini @@ -3,7 +3,7 @@ envlist = # Jython support pending 2.7 support, due 2012-07-15 or so. See: # http://fwierzbicki.blogspot.com/2012/03/adconion-to-fund-jython-27.html # py27,jython,pypy,coverage - py27,py34,py35,py36,pypy,pypy3,coverage,docs + py27,py34,py35,py36,py37,pypy,pypy3,coverage,docs [testenv] deps = @@ -12,15 +12,12 @@ commands = zope-testrunner --test-path=src [testenv:coverage] +usedevelop = true basepython = - python2.7 + python3.6 commands = -# The installed version messes up nose's test discovery / coverage reporting -# So, we uninstall that from the environment, and then install the editable -# version, before running nosetests. - pip uninstall -y zope.schema - pip install -e . coverage run -m zope.testrunner --test-path=src + coverage report deps = .[test] coverage From aea680ac046c184d5cabf870cfe060235b1711af Mon Sep 17 00:00:00 2001 From: Jason Madden Date: Mon, 13 Aug 2018 10:33:29 -0500 Subject: [PATCH 2/5] 100% test coverage on Python 3 - Fix sorting ValidationError on Python 3 to work like Python 2. - Fix DottedName and Id to raise the same exception for invalid unicode characters on Python 2 and Python 3. --- CHANGES.rst | 9 ++++ src/zope/schema/_bootstrapinterfaces.py | 13 +++--- src/zope/schema/_field.py | 42 +++++++++++-------- src/zope/schema/tests/__init__.py | 2 +- .../schema/tests/test__bootstrapinterfaces.py | 21 ++++------ src/zope/schema/tests/test__field.py | 3 +- tox.ini | 2 +- 7 files changed, 55 insertions(+), 37 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 72abcad..efe42c6 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -13,6 +13,14 @@ ``validate_invariants=False`` to the ``Object`` constructor. See `issue 10 `_. +- ``ValidationError`` can be sorted on Python 3. + +- ``DottedName`` and ``Id`` consistently handle non-ASCII unicode + values on Python 2 and 3 by raising ``InvalidDottedName`` and + ``InvalidId`` in ``fromUnicode`` respectively. Previously, a + ``UnicodeEncodeError`` would be raised on Python 2 while Python 3 + would raise the descriptive exception. + - ``Field`` instances are hashable on Python 3, and use a defined hashing algorithm that matches what equality does on all versions of Python. Previously, on Python 2, fields were hashed based on their @@ -34,6 +42,7 @@ `_ and `PR 6 `_. + 4.5.0 (2017-07-10) ================== diff --git a/src/zope/schema/_bootstrapinterfaces.py b/src/zope/schema/_bootstrapinterfaces.py index acb9a23..e249744 100644 --- a/src/zope/schema/_bootstrapinterfaces.py +++ b/src/zope/schema/_bootstrapinterfaces.py @@ -13,8 +13,10 @@ ############################################################################## """Bootstrap schema interfaces and exceptions """ +from functools import total_ordering import zope.interface + from zope.schema._messageid import _ @@ -25,17 +27,17 @@ class StopValidation(Exception): a way for the validator to save time. """ - +@total_ordering class ValidationError(zope.interface.Invalid): """Raised if the Validation process fails.""" def doc(self): return self.__class__.__doc__ - def __cmp__(self, other): + def __lt__(self, other): if not hasattr(other, 'args'): return -1 - return cmp(self.args, other.args) + return self.args < other.args def __eq__(self, other): if not hasattr(other, 'args'): @@ -45,8 +47,9 @@ def __eq__(self, other): __hash__ = zope.interface.Invalid.__hash__ # python3 def __repr__(self): # pragma: no cover - return '%s(%s)' % (self.__class__.__name__, - ', '.join(repr(arg) for arg in self.args)) + return '%s(%s)' % ( + self.__class__.__name__, + ', '.join(repr(arg) for arg in self.args)) class RequiredMissing(ValidationError): diff --git a/src/zope/schema/_field.py b/src/zope/schema/_field.py index 0d02e40..3857a54 100644 --- a/src/zope/schema/_field.py +++ b/src/zope/schema/_field.py @@ -370,14 +370,35 @@ def fromUnicode(self, value): # use the whole line r"$").match +class _StrippedNativeStringLine(NativeStringLine): + + _invalid_exc_type = None + + def fromUnicode(self, value): + v = value.strip() + # On Python 2, self._type is bytes, so we need to encode + # unicode down to ASCII bytes. On Python 3, self._type is + # unicode, but we don't want to allow non-ASCII values, to match + # Python 2 (our regexs would reject that anyway.) + try: + v = v.encode('ascii') # bytes + except UnicodeEncodeError: + raise self._invalid_exc_type(value) + if not isinstance(v, self._type): + v = v.decode('ascii') + self.validate(v) + return v + @implementer(IDottedName) -class DottedName(NativeStringLine): +class DottedName(_StrippedNativeStringLine): """Dotted name field. Values of DottedName fields must be Python-style dotted names. """ + _invalid_exc_type = InvalidDottedName + def __init__(self, *args, **kw): self.min_dots = int(kw.pop("min_dots", 0)) if self.min_dots < 0: @@ -405,21 +426,17 @@ def _validate(self, value): raise InvalidDottedName("too many dots; no more than %d allowed" % self.max_dots, value) - def fromUnicode(self, value): - v = value.strip() - if not isinstance(v, self._type): - v = v.encode('ascii') - self.validate(v) - return v @implementer(IId, IFromUnicode) -class Id(NativeStringLine): +class Id(_StrippedNativeStringLine): """Id field Values of id fields must be either uris or dotted names. """ + _invalid_exc_type = InvalidId + def _validate(self, value): super(Id, self)._validate(value) if _isuri(value): @@ -429,15 +446,6 @@ def _validate(self, value): raise InvalidId(value) - def fromUnicode(self, value): - """ See IFromUnicode. - """ - v = value.strip() - if not isinstance(v, self._type): - v = v.encode('ascii') - self.validate(v) - return v - @implementer(IInterfaceField) class InterfaceField(Field): diff --git a/src/zope/schema/tests/__init__.py b/src/zope/schema/tests/__init__.py index 58ecb2c..b7d1a56 100644 --- a/src/zope/schema/tests/__init__.py +++ b/src/zope/schema/tests/__init__.py @@ -42,7 +42,7 @@ (re.compile(r"zope.schema._bootstrapinterfaces.WrongType:"), r"WrongType:"), ]) -else: +else: # pragma: no cover py3_checker = renormalizing.RENormalizing([ (re.compile(r"([^'])b'([^']*)'"), r"\1'\2'"), diff --git a/src/zope/schema/tests/test__bootstrapinterfaces.py b/src/zope/schema/tests/test__bootstrapinterfaces.py index 6d11334..52c8c8c 100644 --- a/src/zope/schema/tests/test__bootstrapinterfaces.py +++ b/src/zope/schema/tests/test__bootstrapinterfaces.py @@ -13,10 +13,11 @@ ############################################################################## import unittest - -def _skip_under_py3(testcase): - from zope.schema._compat import PY3 - return unittest.skipIf(PY3, "Not under Python 3")(testcase) +try: + compare = cmp +except NameError: + def compare(a, b): + return -1 if a < b else (0 if a == b else 1) class ValidationErrorTests(unittest.TestCase): @@ -33,20 +34,16 @@ class Derived(self._getTargetClass()): inst = Derived() self.assertEqual(inst.doc(), 'DERIVED') - @_skip_under_py3 def test___cmp___no_args(self): - # Py3k?? ve = self._makeOne() - self.assertEqual(cmp(ve, object()), -1) + self.assertEqual(compare(ve, object()), -1) - @_skip_under_py3 def test___cmp___hit(self): - # Py3k?? left = self._makeOne('abc') right = self._makeOne('def') - self.assertEqual(cmp(left, right), -1) - self.assertEqual(cmp(left, left), 0) - self.assertEqual(cmp(right, left), 1) + self.assertEqual(compare(left, right), -1) + self.assertEqual(compare(left, left), 0) + self.assertEqual(compare(right, left), 1) def test___eq___no_args(self): ve = self._makeOne() diff --git a/src/zope/schema/tests/test__field.py b/src/zope/schema/tests/test__field.py index 7ce5ab4..09456fc 100644 --- a/src/zope/schema/tests/test__field.py +++ b/src/zope/schema/tests/test__field.py @@ -1152,7 +1152,6 @@ def test_validate_not_a_dotted_name(self): field.validate, 'http://example.com/\nDAV:') def test_fromUnicode_dotted_name_ok(self): - field = self._makeOne() self.assertEqual(field.fromUnicode(u'dotted.name'), 'dotted.name') @@ -1162,6 +1161,7 @@ def test_fromUnicode_invalid(self): field = self._makeOne() self.assertRaises(InvalidDottedName, field.fromUnicode, u'') + self.assertRaises(InvalidDottedName, field.fromUnicode, u'\u2603') self.assertRaises(ConstraintNotSatisfied, field.fromUnicode, u'http://example.com/\nDAV:') @@ -1240,6 +1240,7 @@ def test_fromUnicode_invalid(self): field = self._makeOne() self.assertRaises(InvalidId, field.fromUnicode, u'') self.assertRaises(InvalidId, field.fromUnicode, u'abc') + self.assertRaises(InvalidId, field.fromUnicode, u'\u2603') self.assertRaises(ConstraintNotSatisfied, field.fromUnicode, u'http://example.com/\nDAV:') diff --git a/tox.ini b/tox.ini index 604820d..8012429 100644 --- a/tox.ini +++ b/tox.ini @@ -17,7 +17,7 @@ basepython = python3.6 commands = coverage run -m zope.testrunner --test-path=src - coverage report + coverage report --fail-under=100 deps = .[test] coverage From 13ea755216b21119bebe74415c7135fd5ee8f6cb Mon Sep 17 00:00:00 2001 From: Jason Madden Date: Tue, 14 Aug 2018 07:33:07 -0500 Subject: [PATCH 3/5] Whitespace and URLs. --- README.rst | 4 ++-- src/zope/schema/_bootstrapinterfaces.py | 3 ++- src/zope/schema/_field.py | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index 2a32586..5fe5acd 100644 --- a/README.rst +++ b/README.rst @@ -3,7 +3,7 @@ ============= .. image:: https://img.shields.io/pypi/v/zope.schema.svg - :target: https://pypi.python.org/pypi/zope.schema/ + :target: https://pypi.org/project/zope.schema/ :alt: Latest Version .. image:: https://img.shields.io/pypi/pyversions/zope.schema.svg @@ -15,7 +15,7 @@ :alt: Build Status .. image:: https://readthedocs.org/projects/zopeschema/badge/?version=latest - :target: http://zopeschema.readthedocs.org/en/latest/ + :target: https://zopeschema.readthedocs.org/en/latest/ :alt: Documentation Status .. image:: https://coveralls.io/repos/github/zopefoundation/zope.schema/badge.svg diff --git a/src/zope/schema/_bootstrapinterfaces.py b/src/zope/schema/_bootstrapinterfaces.py index e249744..c0cc64e 100644 --- a/src/zope/schema/_bootstrapinterfaces.py +++ b/src/zope/schema/_bootstrapinterfaces.py @@ -14,8 +14,8 @@ """Bootstrap schema interfaces and exceptions """ from functools import total_ordering -import zope.interface +import zope.interface from zope.schema._messageid import _ @@ -27,6 +27,7 @@ class StopValidation(Exception): a way for the validator to save time. """ + @total_ordering class ValidationError(zope.interface.Invalid): """Raised if the Validation process fails.""" diff --git a/src/zope/schema/_field.py b/src/zope/schema/_field.py index 3857a54..67d4210 100644 --- a/src/zope/schema/_field.py +++ b/src/zope/schema/_field.py @@ -370,6 +370,7 @@ def fromUnicode(self, value): # use the whole line r"$").match + class _StrippedNativeStringLine(NativeStringLine): _invalid_exc_type = None From 3daaadbe400c63a2977f7e3382da6a9da8c15705 Mon Sep 17 00:00:00 2001 From: Jason Madden Date: Tue, 14 Aug 2018 07:39:44 -0500 Subject: [PATCH 4/5] Make ValidationError sorting make a bit more sense. It is clearly defined to be greater than anything that doesn't have 'args' on both 2 and 3. --- src/zope/schema/_bootstrapinterfaces.py | 2 +- src/zope/schema/tests/test__bootstrapinterfaces.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/zope/schema/_bootstrapinterfaces.py b/src/zope/schema/_bootstrapinterfaces.py index c0cc64e..383a3c5 100644 --- a/src/zope/schema/_bootstrapinterfaces.py +++ b/src/zope/schema/_bootstrapinterfaces.py @@ -37,7 +37,7 @@ def doc(self): def __lt__(self, other): if not hasattr(other, 'args'): - return -1 + return True return self.args < other.args def __eq__(self, other): diff --git a/src/zope/schema/tests/test__bootstrapinterfaces.py b/src/zope/schema/tests/test__bootstrapinterfaces.py index 52c8c8c..73e4dd1 100644 --- a/src/zope/schema/tests/test__bootstrapinterfaces.py +++ b/src/zope/schema/tests/test__bootstrapinterfaces.py @@ -37,6 +37,7 @@ class Derived(self._getTargetClass()): def test___cmp___no_args(self): ve = self._makeOne() self.assertEqual(compare(ve, object()), -1) + self.assertEqual(compare(object(), ve), 1) def test___cmp___hit(self): left = self._makeOne('abc') From 5f6aab268944c080fe4c3770a46f5040ce4517fa Mon Sep 17 00:00:00 2001 From: Jason Madden Date: Tue, 14 Aug 2018 09:42:46 -0500 Subject: [PATCH 5/5] Add comments per review [skip ci] --- CHANGES.rst | 2 +- src/zope/schema/_bootstrapinterfaces.py | 4 ++++ version.txt | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index efe42c6..de05167 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,7 +2,7 @@ Changes ========= -4.5.1 (unreleased) +4.6.0 (unreleased) ================== - Add support for Python 3.7. diff --git a/src/zope/schema/_bootstrapinterfaces.py b/src/zope/schema/_bootstrapinterfaces.py index 383a3c5..60f265f 100644 --- a/src/zope/schema/_bootstrapinterfaces.py +++ b/src/zope/schema/_bootstrapinterfaces.py @@ -36,6 +36,8 @@ def doc(self): return self.__class__.__doc__ def __lt__(self, other): + # There's no particular reason we choose to sort this way, + # it's just the way we used to do it with __cmp__. if not hasattr(other, 'args'): return True return self.args < other.args @@ -45,6 +47,8 @@ def __eq__(self, other): return False return self.args == other.args + # XXX : This is probably inconsistent with __eq__, which is + # a violation of the language spec. __hash__ = zope.interface.Invalid.__hash__ # python3 def __repr__(self): # pragma: no cover diff --git a/version.txt b/version.txt index ed70cbb..4643863 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -4.5.1.dev0 +4.6.0.dev0