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 c15a6b4
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 45 deletions.
6 changes: 6 additions & 0 deletions .coveragerc
@@ -0,0 +1,6 @@
[run]
source = src

[report]
exclude_lines =
pragma: no cover
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -13,3 +13,4 @@ docs/_build
nosetests.xml
coverage.xml
.coverage
htmlcov/
32 changes: 22 additions & 10 deletions .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
10 changes: 9 additions & 1 deletion CHANGES.rst
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
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
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
)

8 changes: 2 additions & 6 deletions src/zope/i18nmessageid/message.py
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
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

if 'java' not in sys.platform and not hasattr(sys, 'pypy_version_info'):

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
@@ -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 c15a6b4

Please sign in to comment.