diff options
author | Jason Madden <jamadden@gmail.com> | 2017-05-01 16:35:14 -0500 |
---|---|---|
committer | Jason Madden <jamadden@gmail.com> | 2017-05-01 16:43:06 -0500 |
commit | 5954f86733df49920427de4a931b23f8c5db9c95 (patch) | |
tree | d4816cc4a225c052e00de1da46f685d8607e2934 | |
parent | ceb5981168a9b5b6c07b307cdf7fa11c96bb8fc7 (diff) | |
download | zope-i18nmessageid-issue4.tar.gz |
Use C extension in Python 3, and make Python version handle ``default`` the sameissue4
Fixes #4 and fixes #5.
Add a specific test case for both of these things.
Enabling the C extension on Python 3 revealed more places where
readonly attributes can raise different exceptions so fix those tests.
Also add Python 3.6 to the supported list, and use zope.testrunner to
workaround the namespace package issue.
-rw-r--r-- | .coveragerc | 6 | ||||
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | .travis.yml | 32 | ||||
-rw-r--r-- | CHANGES.rst | 10 | ||||
-rw-r--r-- | MANIFEST.in | 2 | ||||
-rw-r--r-- | setup.py | 25 | ||||
-rw-r--r-- | src/zope/__init__.py | 2 | ||||
-rw-r--r-- | src/zope/i18nmessageid/message.py | 8 | ||||
-rw-r--r-- | src/zope/i18nmessageid/tests.py | 33 | ||||
-rw-r--r-- | tox.ini | 16 |
10 files changed, 89 insertions, 46 deletions
diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..af40312 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,6 @@ +[run] +source = src + +[report] +exclude_lines = + pragma: no cover @@ -13,3 +13,4 @@ docs/_build nosetests.xml coverage.xml .coverage +htmlcov/ diff --git a/.travis.yml b/.travis.yml index 4847904..b6b3d84 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,15 +1,27 @@ language: python sudo: false python: - - 2.7 - - 3.3 - - 3.4 - - 3.5 - - pypy - - pypy3 -install: - - pip install . + - 2.7 + - 3.3 + - 3.4 + - 3.5 + - 3.6 + - pypy-5.4.1 script: - - python setup.py -q test -q + - coverage run -m zope.testrunner --test-path=src --auto-color --auto-progress + +after_success: + - coveralls notifications: - email: false + email: false + +install: + - pip install -U pip setuptools + - pip install -U coveralls coverage zope.testrunner + - pip install -U -e ".[test]" + + +cache: pip + +before_cache: + - rm -f $HOME/.cache/pip/log/debug.log diff --git a/CHANGES.rst b/CHANGES.rst index eec874a..98064aa 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -6,7 +6,15 @@ Changes - Drop support for Python 2.6 and 3.2. -- Add support for Python 3.5. +- Add support for Python 3.5 and 3.6. + +- Fix the C extension not being used in Python 3. See `issue 4 + <https://github.com/zopefoundation/zope.i18nmessageid/issues/4>`_. + +- Make the Python implementation of Message accept any object for the + ``default`` argument, just as the C extension does. This should be a + unicode or byte string. See `issue 5 + <https://github.com/zopefoundation/zope.i18nmessageid/issues/5>`_. 4.0.3 (2014-03-19) ------------------ diff --git a/MANIFEST.in b/MANIFEST.in index 691124f..6b9b1a2 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -3,6 +3,8 @@ include *.txt include *.py include buildout.cfg include tox.ini +include .travis.yml +include .coveragerc recursive-include docs *.rst *.bat *.py Makefile .gitignore recursive-include src *.zcml @@ -65,7 +65,7 @@ class optional_build_ext(build_ext): def run(self): try: build_ext.run(self) - + except DistutilsPlatformError: # The sys.exc_info()[1] is to preserve compatibility with both # Python 2.5 and 3.x, which is needed in setup.py. @@ -74,7 +74,7 @@ class optional_build_ext(build_ext): def build_extension(self, ext): try: build_ext.build_extension(self, ext) - + except (CCompilerError, DistutilsExecError): # The sys.exc_info()[1] is to preserve compatibility with both # Python 2.5 and 3.x, which is needed in setup.py. @@ -89,13 +89,13 @@ class optional_build_ext(build_ext): An optional code optimization (C extension) could not be compiled. Optimizations for this package will not be available! - + """) sys.stderr.write(str(e) + '\n') sys.stderr.write('*' * 80 + '\n') setup(name='zope.i18nmessageid', - version = '4.1.0.dev0', + version='4.1.0.dev0', author='Zope Foundation and Contributors', author_email='zope-dev@zope.org', description='Message Identifiers for internationalization', @@ -104,8 +104,8 @@ setup(name='zope.i18nmessageid', + '\n\n' + read('CHANGES.rst') ), - keywords = "zope i18n message factory", - classifiers = [ + keywords="zope i18n message factory", + classifiers=[ 'Development Status :: 5 - Production/Stable', 'Environment :: Web Environment', 'Intended Audience :: Developers', @@ -117,22 +117,23 @@ setup(name='zope.i18nmessageid', '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", 'Natural Language :: English', 'Operating System :: OS Independent', 'Topic :: Internet :: WWW/HTTP', - 'Framework :: Zope3'], + 'Framework :: Zope3', + ], license='ZPL 2.1', url='http://pypi.python.org/pypi/zope.i18nmessageid', packages=find_packages('src'), - package_dir = {'': 'src'}, + package_dir={'': 'src'}, namespace_packages=['zope',], install_requires=['setuptools'], - include_package_data = True, + include_package_data=True, test_suite='zope.i18nmessageid.tests.test_suite', - zip_safe = False, - cmdclass = {'build_ext':optional_build_ext}, + zip_safe=False, + cmdclass={'build_ext':optional_build_ext}, **extra ) - diff --git a/src/zope/__init__.py b/src/zope/__init__.py index de40ea7..2cdb0e4 100644 --- a/src/zope/__init__.py +++ b/src/zope/__init__.py @@ -1 +1 @@ -__import__('pkg_resources').declare_namespace(__name__) +__import__('pkg_resources').declare_namespace(__name__) # pragma: no cover diff --git a/src/zope/i18nmessageid/message.py b/src/zope/i18nmessageid/message.py index e46cad6..0e62408 100644 --- a/src/zope/i18nmessageid/message.py +++ b/src/zope/i18nmessageid/message.py @@ -41,11 +41,7 @@ class Message(unicode): mapping = ustr.mapping and ustr.mapping.copy() or mapping ustr = unicode(ustr) self.domain = domain - if default is None: - # MessageID does: self.default = ustr - self.default = default - else: - self.default = unicode(default) + self.default = default self.mapping = mapping self._readonly = True return self @@ -70,7 +66,7 @@ class Message(unicode): pyMessage = Message try: - from _zope_i18nmessageid_message import Message + from ._zope_i18nmessageid_message import Message except ImportError: # pragma: no cover pass diff --git a/src/zope/i18nmessageid/tests.py b/src/zope/i18nmessageid/tests.py index 560750b..0e8f6b4 100644 --- a/src/zope/i18nmessageid/tests.py +++ b/src/zope/i18nmessageid/tests.py @@ -13,15 +13,17 @@ ############################################################################## """Message ID tests. """ +import sys import unittest +from zope.i18nmessageid import message as messageid + class PyMessageTests(unittest.TestCase): _TEST_REAOONLY = True def _getTargetClass(self): - from zope.i18nmessageid.message import pyMessage - return pyMessage + return messageid.pyMessage def _makeOne(self, *args, **kw): return self._getTargetClass()(*args, **kw) @@ -71,20 +73,23 @@ class PyMessageTests(unittest.TestCase): message = self._makeOne('testing') def _try(): message.domain = 'domain' - self.assertRaises(TypeError, _try) + # C version raises AttributeError, Python version TypeError + self.assertRaises((TypeError, AttributeError), _try) def test_default_immutable(self): message = self._makeOne('testing') def _try(): message.default = 'default' - self.assertRaises(TypeError, _try) + # C version raises AttributeError, Python version TypeError + self.assertRaises((TypeError, AttributeError), _try) def test_mapping_immutable(self): mapping = {'key': 'value'} message = self._makeOne('testing') def _try(): message.mapping = mapping - self.assertRaises(TypeError, _try) + # C version raises AttributeError, Python version TypeError + self.assertRaises((TypeError, AttributeError), _try) def test_unknown_immutable(self): message = self._makeOne('testing') @@ -101,15 +106,25 @@ class PyMessageTests(unittest.TestCase): self.assertTrue(klass is self._getTargetClass()) self.assertEqual(state, ('testing', 'domain', 'default', mapping)) + def test_non_unicode_default(self): + message = self._makeOne(u'str', default=123) + self.assertEqual(message.default, 123) +@unittest.skipIf(messageid.Message is messageid.pyMessage, + "Duplicate tests") class MessageTests(PyMessageTests): _TEST_REAOONLY = False def _getTargetClass(self): - from zope.i18nmessageid.message import Message - return Message + return messageid.Message + +@unittest.skipIf('java' in sys.platform or hasattr(sys, 'pypy_version_info'), + "We don't expect the C implementation here") +class OptimizationTests(unittest.TestCase): + def test_optimizations_available(self): + self.assertIsNot(messageid.Message, messageid.pyMessage) class MessageFactoryTests(unittest.TestCase): @@ -144,7 +159,5 @@ class MessageFactoryTests(unittest.TestCase): def test_suite(): return unittest.TestSuite(( - unittest.makeSuite(PyMessageTests), - unittest.makeSuite(MessageTests), - unittest.makeSuite(MessageFactoryTests), + unittest.defaultTestLoader.loadTestsFromName(__name__), )) @@ -1,16 +1,20 @@ [tox] -envlist = - py27,py33,py34,py35,pypy,pypy3,coverage,docs +envlist = + py27,py33,py34,py35,py36,pypy,pypy3,coverage,docs [testenv] -commands = - python setup.py -q test -q +deps = + .[test] + zope.testrunner +commands = + zope-testrunner --test-path=src [] + [testenv:coverage] usedevelop = true basepython = python2.7 -commands = +commands = nosetests --with-xunit --with-xcoverage deps = nose @@ -20,7 +24,7 @@ deps = [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 = |