Skip to content

Commit

Permalink
Add Python 3.6, drop Python 3.3
Browse files Browse the repository at this point in the history
- Run doctests on all versions of Python in tox and travis
- Enable coveralls and reach 100% coverage.
- Fix broken badge.
- Whitespace cleanup in setup.py
  • Loading branch information
jamadden committed Jul 26, 2017
1 parent 6981e1e commit ccd7074
Show file tree
Hide file tree
Showing 12 changed files with 111 additions and 68 deletions.
9 changes: 9 additions & 0 deletions .coveragerc
@@ -0,0 +1,9 @@
[run]
source = zope.hookable

[report]
exclude_lines =
pragma: no cover
if __name__ == '__main__':
raise NotImplementedError
self.fail
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -13,3 +13,4 @@ parts
.coverage
coverage.xml
nosetests.xml
htmlcov/
14 changes: 10 additions & 4 deletions .travis.yml
Expand Up @@ -2,14 +2,20 @@ language: python
sudo: false
python:
- 2.7
- 3.3
- 3.4
- 3.5
- 3.6
- pypy
- pypy3
- pypy3.5-5.8.0
install:
- pip install .
- pip install -U pip setuptools
- pip install -U coveralls coverage
- pip install -U -e .[test]
script:
- python setup.py test -q
- coverage run setup.py test -q
- coverage run -a -m sphinx -b doctest -d docs/_build/doctrees docs docs/_build/doctest
after_success:
- coveralls
notifications:
email: false
cache: pip
25 changes: 13 additions & 12 deletions CHANGES.rst
@@ -1,40 +1,41 @@
Changes
-------
=========
Changes
=========

4.1.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.

4.0.4 (2014-03-19)
##################
==================

- Add support for Python 3.4.

4.0.3 (2014-03-17)
##################
==================

- Update ``boostrap.py`` to version 2.2.

- Fix extension compilation on Py3k.

4.0.2 (2012-12-31)
##################
==================

- Flesh out PyPI Trove classifiers.

4.0.1 (2012-11-21)
##################
==================

- Add support for Python 3.3.

- Avoid building the C extension explicitly (use the "feature" indirection
instead). https://bugs.launchpad.net/zope.hookable/+bug/1025470

4.0.0 (2012-06-04)
##################
==================

- Add support for PyPy.

Expand All @@ -58,13 +59,13 @@ Changes
- Add Python 3 support.

3.4.1 (2009-04-05)
##################
==================

- Update for compatibility with Python 2.6 traceback formats.

- Use Jython-compatible ``bootstrap.py``.

3.4.0 (2007-07-20)
##################
==================

- Initial release as a separate project.
2 changes: 2 additions & 0 deletions MANIFEST.in
Expand Up @@ -3,6 +3,8 @@ include *.txt
include *.py
include buildout.cfg
include tox.ini
include .travis.yml
include .coveragerc

recursive-include docs *.bat
recursive-include docs *.py
Expand Down
23 changes: 17 additions & 6 deletions README.rst
@@ -1,21 +1,32 @@
``zope.hookable``
=================
===================
``zope.hookable``
===================

.. image:: https://img.shields.io/pypi/v/zope.hookable.svg
:target: https://pypi.python.org/pypi/zope.hookable/
:alt: Latest Version
:target: https://pypi.python.org/pypi/zope.hookable/
:alt: Latest release

.. image:: https://img.shields.io/pypi/pyversions/zope.hookable.svg
:target: https://pypi.org/project/zope.hookable/
:alt: Supported Python versions

.. image:: https://travis-ci.org/zopefoundation/zope.hookable.png?branch=master
:target: https://travis-ci.org/zopefoundation/zope.hookable

.. image:: https://readthedocs.org/projects/zopehookable/badge/?version=latest
:target: http://zopehookable.readthedocs.org/en/latest/
:target: http://zopehookable.readthedocs.io/en/latest/
:alt: Documentation Status

.. image:: https://coveralls.io/repos/github/zopefoundation/zope.hookable/badge.svg?branch=master
:target: https://coveralls.io/github/zopefoundation/zope.hookable?branch=master


This package supports the efficient creation of "hookable" objects, which
are callable objects that are meant to be optionally replaced.

The idea is you create a function that does some default thing and make it
The idea is that you create a function that does some default thing and make it
hookable. Later, someone can modify what it does by calling its sethook method
and changing its implementation. All users of the function, including those
that imported it, will see the change.

Documentation is hosted at http://zopehookable.readthedocs.io
5 changes: 5 additions & 0 deletions setup.cfg
Expand Up @@ -9,3 +9,8 @@ where=src
dev = develop easy_install zope.hookable[testing]
docs = easy_install zope.hookable[docs]

[bdist_wheel]
universal = 0

[zest-releaser]
create-wheel = no
54 changes: 31 additions & 23 deletions setup.py
Expand Up @@ -24,11 +24,12 @@
from setuptools import setup, find_packages, Extension, Feature

def read(*rnames):
return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
with open(os.path.join(os.path.dirname(__file__), *rnames)) as f:
return f.read()

Cwrapper = Feature(
"C wrapper",
standard = True,
standard=True,
ext_modules=[Extension("zope.hookable._zope_hookable",
[os.path.join('src', 'zope', 'hookable',
"_zope_hookable.c")
Expand All @@ -47,43 +48,50 @@ def read(*rnames):
else:
features = {'Cwrapper': Cwrapper}

TESTS_REQUIRE = [
'zope.testing',
]

setup(name='zope.hookable',
version = '4.1.0.dev0',
url='http://svn.zope.org/zope.hookable',
version='4.1.0.dev0',
url='http://github.com/zopefoundation/zope.hookable',
license='ZPL 2.1',
description='Zope hookable',
keywords='function hook replacement loose coupled',
author='Zope Foundation and Contributors',
author_email='zope-dev@zope.org',
long_description=(read('README.rst') + '\n\n' +
read('CHANGES.rst')),
classifiers=[
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"License :: OSI Approved :: Zope Public License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"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 :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"Framework :: Zope3",
"Topic :: Software Development :: Libraries :: Python Modules",
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"License :: OSI Approved :: Zope Public License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 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",
],
features=features,
packages=find_packages('src'),
package_dir={'': 'src'},
namespace_packages=['zope',],
install_requires=['setuptools'],
install_requires=[
'setuptools',
],
include_package_data=True,
zip_safe=False,
test_suite='zope.hookable.tests.test_hookable.test_suite',
extras_require = {
extras_require={
'docs': ['Sphinx'],
'testing': ['nose', 'coverage'],
'test': ['zope.testing'],
'testing': TESTS_REQUIRE + ['coverage',],
'test': TESTS_REQUIRE,
},
)
2 changes: 1 addition & 1 deletion src/zope/__init__.py
@@ -1 +1 @@
__import__('pkg_resources').declare_namespace(__name__)
__import__('pkg_resources').declare_namespace(__name__) # pragma: no cover
4 changes: 2 additions & 2 deletions src/zope/hookable/__init__.py
Expand Up @@ -16,7 +16,7 @@

class _py_hookable(object):
__slots__ = ('_original', '_implementation')

def __init__(self, *args, **kw):
if len(args) == 0 and 'implementation' in kw:
args = (kw.pop('implementation'),)
Expand All @@ -43,5 +43,5 @@ def __call__(self, *args, **kw):

try:
from ._zope_hookable import hookable
except ImportError: #pragma NO COVER
except ImportError: # pragma: no cover
pass
17 changes: 7 additions & 10 deletions src/zope/hookable/tests/test_hookable.py
Expand Up @@ -31,7 +31,7 @@ def _foo():

def test_after_hook(self):
def _foo():
return 'FOO'
self.fail("This should not be called")
def _bar():
return 'BAR'
hooked = self._callFUT(_foo)
Expand All @@ -45,7 +45,7 @@ def test_after_hook_and_reset(self):
def _foo():
return 'FOO'
def _bar():
return 'BAR'
self.fail("This should not be called")
hooked = self._callFUT(_foo)
old = hooked.sethook(_bar)
hooked.reset()
Expand All @@ -56,15 +56,15 @@ def _bar():

def test_original_cannot_be_deleted(self):
def _foo():
return 'FOO'
self.fail("This should not be called")
hooked = self._callFUT(_foo)
def _try():
del hooked.original
self.assertRaises((TypeError, AttributeError), _try)

def test_implementation_cannot_be_deleted(self):
def _foo():
return 'FOO'
self.fail("This should not be called")
hooked = self._callFUT(_foo)
def _try():
del hooked.implementation
Expand All @@ -75,7 +75,7 @@ def test_no_args(self):

def test_too_many_args(self):
def _foo():
return 'FOO'
self.fail("This should not be called")
self.assertRaises(TypeError, self._callFUT, _foo, _foo)

def test_w_implementation_kwarg(self):
Expand All @@ -88,7 +88,7 @@ def _foo():

def test_w_unknown_kwarg(self):
def _foo():
return 'FOO'
self.fail("This should not be called")
self.assertRaises(TypeError, self._callFUT, nonesuch=_foo)


Expand All @@ -100,7 +100,4 @@ def _callFUT(self, *args, **kw):


def test_suite():
return unittest.TestSuite((
unittest.makeSuite(PyHookableTests),
unittest.makeSuite(HookableTests),
))
return unittest.defaultTestLoader.loadTestsFromName(__name__)
23 changes: 13 additions & 10 deletions tox.ini
@@ -1,27 +1,30 @@
[tox]
envlist =
py27,py33,py34,py35,pypy,pypy3,coverage,docs
envlist =
py27,py34,py35,py36,pypy,pypy3,coverage,docs

[testenv]
commands =
commands =
python setup.py -q test -q
sphinx-build -b doctest -d {envdir}/.cache/doctrees docs {envdir}/.cache/doctest
deps =
.[test,docs]

[testenv:coverage]
usedevelop = true
basepython =
python2.7
commands =
nosetests --with-xunit --with-xcoverage
commands =
coverage run setup.py -q test -q
coverage run -a -m sphinx -b doctest -d {envdir}/.cache/doctrees docs {envdir}/.cache/doctest
coverage report
deps =
nose
{[testenv]deps}
coverage
nosexcover


[testenv:docs]
basepython =
python2.7
commands =
commands =
sphinx-build -b html -d docs/_build/doctrees docs docs/_build/html
sphinx-build -b doctest -d docs/_build/doctrees docs docs/_build/doctest
deps =
Sphinx

0 comments on commit ccd7074

Please sign in to comment.