Skip to content

Commit

Permalink
Merge pull request #31 from zopefoundation/py36
Browse files Browse the repository at this point in the history
Add Python 3.6, drop Python 3.3, 100% coverage.
  • Loading branch information
jamadden committed Jul 10, 2017
2 parents 38f0933 + fa586c6 commit 911747b
Show file tree
Hide file tree
Showing 23 changed files with 111 additions and 265 deletions.
9 changes: 9 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[run]
source = zope.schema

[report]
exclude_lines =
pragma: no cover
if __name__ == '__main__':
raise NotImplementedError
raise AssertionError
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ parts
*.egg-info
.tox
.coverage
htmlcov/
nosetests.xml
coverage.xml
devel
Expand Down
41 changes: 25 additions & 16 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,20 +1,29 @@
language: python
sudo: false
matrix:
include:
- python: 3.5
env: TOXENV=py35
env:
- TOXENV=py27
- TOXENV=py33
- TOXENV=py34
- TOXENV=pypy
- TOXENV=pypy3
- TOXENV=coverage
- TOXENV=docs
install:
- pip install tox
python:
- 2.7
- 3.4
- 3.5
- 3.6
- pypy-5.6.0

script:
- tox
- coverage run -m zope.testrunner --test-path=src
- sphinx-build -b html -d docs/_build/doctrees docs docs/_build/html
- coverage run -a `which sphinx-build` -b doctest -d docs/_build/doctrees docs docs/_build/doctest

after_success:
- coveralls
notifications:
email: false
email: false

install:
- pip install -U pip setuptools
- pip install -U coveralls coverage
- pip install -U -e ".[test,docs]"


cache: pip

before_cache:
- rm -f $HOME/.cache/pip/log/debug.log
6 changes: 4 additions & 2 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ Changes
4.5.0 (unreleased)
------------------

- Drop support for Python 2.6 and 3.2.
- Drop support for Python 2.6, 3.2, and 3.3.

- Add support for Python 3.5.
- Add support for Python 3.5 and 3.6.

- Drop support for 'setup.py test'. Use zope.testrunner instead.


4.4.2 (2014-09-04)
Expand Down
18 changes: 12 additions & 6 deletions docs/fields.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ Conversion from Unicode:

>>> from zope.schema import Bytes
>>> obj = Bytes(constraint=lambda v: b'x' in v)
>>> obj.fromUnicode(u" foo x.y.z bat")
>>> result = obj.fromUnicode(u" foo x.y.z bat")
>>> isinstance(result, bytes)
True
>>> str(result.decode("ascii"))
' foo x.y.z bat'
>>> obj.fromUnicode(u" foo y.z bat")
Traceback (most recent call last):
Expand Down Expand Up @@ -167,8 +170,11 @@ Conversion from Unicode enforces the constraint:
Traceback (most recent call last):
...
ConstraintNotSatisfied: baz
>>> t.fromUnicode(u"foo")
u'foo'
>>> result = t.fromUnicode(u"foo")
>>> isinstance(result, bytes)
False
>>> print(result)
foo

By default, ValueErrors are thrown if duplicate values or tokens
are passed in. If you are using this vocabulary as part of a form
Expand All @@ -189,9 +195,9 @@ Validation ensures that the pattern is matched:

>>> from zope.schema import URI
>>> 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
Expand Down
6 changes: 3 additions & 3 deletions docs/narr.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ is to define some data:
.. doctest::

>>> 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:

Expand Down Expand Up @@ -168,8 +168,8 @@ Now we want a class that adheres to the ``IContact`` schema:

.. doctest::

>>> class Contact(object):
... zope.interface.implements(IContact)
>>> @zope.interface.implementer(IContact)
... class Contact(object):
...
... def __init__(self, first, last, email, address, pc):
... self.first = first
Expand Down
4 changes: 2 additions & 2 deletions docs/validation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ When we set a valid value for `a` we still get the same error for `b`:
2
>>> errors[0][0]
'a'
>>> errors[0][1].doc()
u'Value is too big'
>>> print(errors[0][1].doc())
Value is too big
>>> errors[0][1].__class__.__name__
'TooBig'
>>> errors[0][1].args
Expand Down
3 changes: 3 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ ignore-files=examples.py
[aliases]
dev = develop easy_install zope.schema[testing]
docs = easy_install zope.schema[docs]

[bdist_wheel]
universal = 1
52 changes: 9 additions & 43 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,52 +27,17 @@ def read(*rnames):
return f.read()


def _modname(path, base, name=''):
if path == base:
return name
dirname, basename = os.path.split(path)
return _modname(dirname, base, basename + '.' + name)


def alltests():
import logging
import pkg_resources
import unittest

class NullHandler(logging.Handler):
level = 50

def emit(self, record):
pass

logging.getLogger().addHandler(NullHandler())

suite = unittest.TestSuite()
base = pkg_resources.working_set.find(
pkg_resources.Requirement.parse('zope.schema')).location
for dirpath, dirnames, filenames in os.walk(base):
if os.path.basename(dirpath) == 'tests':
for filename in filenames:
if filename.endswith('.py') and filename.startswith('test'):
mod = __import__(
_modname(dirpath, base, os.path.splitext(filename)[0]),
{}, {}, ['*'])
suite.addTest(mod.test_suite())
elif 'tests.py' in filenames:
continue
mod = __import__(_modname(dirpath, base, 'tests'), {}, {}, ['*'])
suite.addTest(mod.test_suite())
return suite


REQUIRES = [
'setuptools',
'zope.interface >= 3.6.0',
'zope.event',
]


TESTS_REQUIRE = ['zope.testing']
TESTS_REQUIRE = [
'zope.testing',
'zope.testrunner',
]


setup(
Expand All @@ -98,21 +63,22 @@ def emit(self, record):
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.3",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"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,
test_suite='__main__.alltests',
tests_require=TESTS_REQUIRE,
extras_require={
'docs': ['Sphinx'],
'docs': [
'Sphinx',
'repoze.sphinx.autointerface',
],
'test': TESTS_REQUIRE,
'testing': TESTS_REQUIRE + ['nose', 'coverage'],
},
)
19 changes: 11 additions & 8 deletions src/zope/schema/_bootstrapfields.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,16 +128,16 @@ def __init__(self, title=u'', description=u'', __name__='',
>>> from zope.schema._bootstrapfields import Field
>>> f = Field()
>>> f.__doc__, f.title, f.description
('', u'', u'')
>>> f.__doc__, str(f.title), str(f.description)
('', '', '')
>>> f = Field(title=u'sample')
>>> f.__doc__, f.title, f.description
(u'sample', u'sample', u'')
>>> str(f.__doc__), str(f.title), str(f.description)
('sample', 'sample', '')
>>> f = Field(title=u'sample', description=u'blah blah\\nblah')
>>> f.__doc__, f.title, f.description
(u'sample\\n\\nblah blah\\nblah', u'sample', u'blah blah\\nblah')
>>> str(f.__doc__), str(f.title), str(f.description)
('sample\\n\\nblah blah\\nblah', 'sample', 'blah blah\\nblah')
"""
__doc__ = ''
if title:
Expand Down Expand Up @@ -332,8 +332,11 @@ def fromUnicode(self, str):
Traceback (most recent call last):
...
WrongType: ('foo x spam', <type 'unicode'>, '')
>>> t.fromUnicode(u"foo x spam")
u'foo x spam'
>>> result = t.fromUnicode(u"foo x spam")
>>> isinstance(result, bytes)
False
>>> str(result)
'foo x spam'
>>> t.fromUnicode(u"foo spam")
Traceback (most recent call last):
...
Expand Down
2 changes: 1 addition & 1 deletion src/zope/schema/_bootstrapinterfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ def __call__(context):


class NO_VALUE(object):
def __repr__(self):
def __repr__(self): # pragma: no cover
return '<NO_VALUE>'

NO_VALUE = NO_VALUE()
11 changes: 0 additions & 11 deletions src/zope/schema/tests/states.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,3 @@ def __len__(self):

def getTerm(self, value):
return _states[value]


class StateSelectionField(Choice):

vocabulary = StateVocabulary()

def __init__(self, **kw):
super(StateSelectionField, self).__init__(
vocabulary=StateSelectionField.vocabulary,
**kw)
self.vocabularyName = "states"
37 changes: 6 additions & 31 deletions src/zope/schema/tests/test__bootstrapfields.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,39 +267,31 @@ def test_bind(self):
def test_validate_missing_not_required(self):
missing = object()

def _fail(value):
return False
field = self._makeOne(
required=False, missing_value=missing, constraint=_fail,
required=False, missing_value=missing, constraint=lambda x: False,
)
self.assertEqual(field.validate(missing), None) # doesn't raise

def test_validate_missing_and_required(self):
from zope.schema._bootstrapinterfaces import RequiredMissing
missing = object()

def _fail(value):
return False
field = self._makeOne(
required=True, missing_value=missing, constraint=_fail,
required=True, missing_value=missing, constraint=lambda x: False,
)
self.assertRaises(RequiredMissing, field.validate, missing)

def test_validate_wrong_type(self):
from zope.schema._bootstrapinterfaces import WrongType

def _fail(value):
return False
field = self._makeOne(required=True, constraint=_fail)
field = self._makeOne(required=True, constraint=lambda x: False)
field._type = str
self.assertRaises(WrongType, field.validate, 1)

def test_validate_constraint_fails(self):
from zope.schema._bootstrapinterfaces import ConstraintNotSatisfied

def _fail(value):
return False
field = self._makeOne(required=True, constraint=_fail)
field = self._makeOne(required=True, constraint=lambda x: False)
field._type = int
self.assertRaises(ConstraintNotSatisfied, field.validate, 1)

Expand Down Expand Up @@ -401,7 +393,7 @@ def test__validate_collection_but_not_iterable(self):

class Dummy(object):
def __contains__(self, item):
return False
raise AssertionError("Not called")
cont._validate(Dummy()) # doesn't raise

def test__validate_not_collection_but_iterable(self):
Expand Down Expand Up @@ -432,7 +424,7 @@ def test__validate_collection_but_not_iterable(self):

class Dummy(object):
def __contains__(self, item):
return False
raise AssertionError("Not called")
self.assertRaises(NotAnIterator, itr._validate, Dummy())


Expand Down Expand Up @@ -803,20 +795,3 @@ def __init__(self, exc=None):
def validate(self, value):
if self._exc is not None:
raise self._exc()


def test_suite():
return unittest.TestSuite((
unittest.makeSuite(ValidatedPropertyTests),
unittest.makeSuite(DefaultPropertyTests),
unittest.makeSuite(FieldTests),
unittest.makeSuite(ContainerTests),
unittest.makeSuite(IterableTests),
unittest.makeSuite(OrderableTests),
unittest.makeSuite(MinMaxLenTests),
unittest.makeSuite(TextTests),
unittest.makeSuite(TextLineTests),
unittest.makeSuite(PasswordTests),
unittest.makeSuite(BoolTests),
unittest.makeSuite(IntTests),
))
Loading

0 comments on commit 911747b

Please sign in to comment.