Skip to content

Commit

Permalink
Use C extension in Python 3, and make Python version handle ``default…
Browse files Browse the repository at this point in the history
…`` the same

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.
  • Loading branch information
jamadden committed May 1, 2017
1 parent ceb5981 commit 5954f86
Show file tree
Hide file tree
Showing 10 changed files with 89 additions and 46 deletions.
6 changes: 6 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[run]
source = src

[report]
exclude_lines =
pragma: no cover
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ docs/_build
nosetests.xml
coverage.xml
.coverage
htmlcov/
32 changes: 22 additions & 10 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -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
10 changes: 9 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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)
------------------
Expand Down
2 changes: 2 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
25 changes: 13 additions & 12 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -74,7 +74,7 @@ def run(self):
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.
Expand All @@ -89,13 +89,13 @@ def _unavailable(self, e):
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',
Expand All @@ -104,8 +104,8 @@ def _unavailable(self, e):
+ '\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',
Expand All @@ -117,22 +117,23 @@ def _unavailable(self, e):
'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
)

2 changes: 1 addition & 1 deletion src/zope/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__import__('pkg_resources').declare_namespace(__name__)
__import__('pkg_resources').declare_namespace(__name__) # pragma: no cover
8 changes: 2 additions & 6 deletions src/zope/i18nmessageid/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,7 @@ def __new__(cls, ustr, domain=None, default=None, mapping=None):
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
Expand All @@ -70,7 +66,7 @@ def __reduce__(self):
pyMessage = Message

try:
from _zope_i18nmessageid_message import Message
from ._zope_i18nmessageid_message import Message
except ImportError: # pragma: no cover
pass

Expand Down
33 changes: 23 additions & 10 deletions src/zope/i18nmessageid/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -71,20 +73,23 @@ def test_domain_immutable(self):
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')
Expand All @@ -101,15 +106,25 @@ def test___reduce__(self):
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):

Expand Down Expand Up @@ -144,7 +159,5 @@ def test___call___explicit(self):

def test_suite():
return unittest.TestSuite((
unittest.makeSuite(PyMessageTests),
unittest.makeSuite(MessageTests),
unittest.makeSuite(MessageFactoryTests),
unittest.defaultTestLoader.loadTestsFromName(__name__),
))
16 changes: 10 additions & 6 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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 =
Expand Down

0 comments on commit 5954f86

Please sign in to comment.