[Checkins] SVN: zope.i18nmessageid/trunk/ Merge tseaver-no_2to3 branch.

Tres Seaver cvs-admin at zope.org
Tue Apr 17 15:51:22 UTC 2012


Log message for revision 125165:
  Merge tseaver-no_2to3 branch.

Changed:
  _U  zope.i18nmessageid/trunk/
  A   zope.i18nmessageid/trunk/.bzrignore
  U   zope.i18nmessageid/trunk/CHANGES.txt
  A   zope.i18nmessageid/trunk/docs/
  U   zope.i18nmessageid/trunk/docs/Makefile
  U   zope.i18nmessageid/trunk/docs/api.rst
  U   zope.i18nmessageid/trunk/docs/conf.py
  U   zope.i18nmessageid/trunk/docs/index.rst
  U   zope.i18nmessageid/trunk/docs/make.bat
  U   zope.i18nmessageid/trunk/docs/narr.rst
  A   zope.i18nmessageid/trunk/setup.cfg
  U   zope.i18nmessageid/trunk/setup.py
  U   zope.i18nmessageid/trunk/src/zope/i18nmessageid/message.py
  D   zope.i18nmessageid/trunk/src/zope/i18nmessageid/messages.txt
  U   zope.i18nmessageid/trunk/src/zope/i18nmessageid/tests.py
  U   zope.i18nmessageid/trunk/tox.ini

-=-

Property changes on: zope.i18nmessageid/trunk
___________________________________________________________________
Added: svn:mergeinfo
   + /zope.i18nmessageid/branches/tseaver-no_2to3:125006,125040-125054,125164

Added: svk:merge
   + 62d5b8a3-27da-0310-9561-8e5933582275:/zope.i18nmessageid/branches/tseaver-no_2to3:125164


Copied: zope.i18nmessageid/trunk/.bzrignore (from rev 125164, zope.i18nmessageid/branches/tseaver-no_2to3/.bzrignore)
===================================================================
--- zope.i18nmessageid/trunk/.bzrignore	                        (rev 0)
+++ zope.i18nmessageid/trunk/.bzrignore	2012-04-17 15:51:19 UTC (rev 125165)
@@ -0,0 +1,4 @@
+*.egg-info
+.coverage
+docs/_build
+__pycache__

Modified: zope.i18nmessageid/trunk/CHANGES.txt
===================================================================
--- zope.i18nmessageid/trunk/CHANGES.txt	2012-04-17 15:49:50 UTC (rev 125164)
+++ zope.i18nmessageid/trunk/CHANGES.txt	2012-04-17 15:51:19 UTC (rev 125165)
@@ -2,10 +2,28 @@
 CHANGES
 =======
 
-3.6.2 (unreleased)
+4.0.0 (unreleased)
 ------------------
 
+- Removed use of '2to3' and associated fixers when installing under Py3k.
+  The code is now in a "compatible subset" which supports Python 2.6, 2.7,
+  and 3.2, including PyPy 1.8 (the version compatible with the 2.7 language
+  spec).
 
+- 100% unit test coverage.
+
+- Move doctest examples into Sphinx documentation.
+
+- Dropped explicit support for Python 2.4 / 2.5 / 3.1.
+
+- Added explicit support for PyPy.
+
+- Added 'setup.py dev' alias (runs ``setup.py develop`` plus installs
+  ``nose`` and ``coverage``).
+
+- Added 'setup.py docs' alias (installs ``Sphinx`` and dependencies).
+
+
 3.6.1 (2011-07-20)
 ------------------
 

Copied: zope.i18nmessageid/trunk/setup.cfg (from rev 125164, zope.i18nmessageid/branches/tseaver-no_2to3/setup.cfg)
===================================================================
--- zope.i18nmessageid/trunk/setup.cfg	                        (rev 0)
+++ zope.i18nmessageid/trunk/setup.cfg	2012-04-17 15:51:19 UTC (rev 125165)
@@ -0,0 +1,11 @@
+[nosetests]
+nocapture=1
+cover-package=zope.i18nmessageid
+cover-erase=1
+with-doctest=0
+where=src
+
+[aliases]
+dev = develop easy_install zope.i18nmessageid[testing]
+docs = easy_install zope.i18nmessageid[docs]
+

Modified: zope.i18nmessageid/trunk/setup.py
===================================================================
--- zope.i18nmessageid/trunk/setup.py	2012-04-17 15:49:50 UTC (rev 125164)
+++ zope.i18nmessageid/trunk/setup.py	2012-04-17 15:51:19 UTC (rev 125165)
@@ -43,22 +43,18 @@
         [os.path.normcase(codeoptimization_c)]
         )])
 
-if is_pypy or is_jython:
+extra = {
+    'extras_require': {'testing': ['nose', 'coverage'],
+                       'docs': ['Sphinx'],
+                      },
+}
+
+if not is_pypy and not is_jython:
     # Jython cannot build the C optimizations, while on PyPy they are
     # anti-optimizations (the C extension compatibility layer is known-slow,
     # and defeats JIT opportunities).
-    extra = {}
-else:
-    extra = {'features':{'codeoptimization':codeoptimization}}
+    extra['features'] = {'codeoptimization':codeoptimization}
 
-if sys.version_info >= (3,):
-    extra.update(dict(use_2to3 = True,
-                 convert_2to3_doctests = [
-                     'src/zope/i18nmessageid/messages.txt',
-                     ],
-                      )
-                 )
-
 def read(*rnames):
     return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
 
@@ -98,16 +94,13 @@
         sys.stderr.write(str(e) + '\n')
         sys.stderr.write('*' * 80 + '\n')
 
-
 setup(name='zope.i18nmessageid',
-    version = '3.6.2dev',
+    version = '4.0.0dev',
     author='Zope Foundation and Contributors',
     author_email='zope-dev at zope.org',
     description='Message Identifiers for internationalization',
     long_description=(
         read('README.txt')
-        + '\n\n.. contents::\n\n' +
-        read('src', 'zope', 'i18nmessageid', 'messages.txt')
         + '\n\n' +
         read('CHANGES.txt')
         ),
@@ -118,13 +111,12 @@
         'Intended Audience :: Developers',
         'License :: OSI Approved :: Zope Public License',
         'Programming Language :: Python',
-        'Programming Language :: Python :: 2.4',
-        'Programming Language :: Python :: 2.5',
         'Programming Language :: Python :: 2.6',
         'Programming Language :: Python :: 2.7',
         'Programming Language :: Python :: 3',
-        'Programming Language :: Python :: 3.1',
         'Programming Language :: Python :: 3.2',
+        "Programming Language :: Python :: Implementation :: CPython",
+        "Programming Language :: Python :: Implementation :: PyPy",
         'Natural Language :: English',
         'Operating System :: OS Independent',
         'Topic :: Internet :: WWW/HTTP',
@@ -140,5 +132,5 @@
     zip_safe = False,
     cmdclass = {'build_ext':optional_build_ext},
     **extra
-    )
+)
 

Modified: zope.i18nmessageid/trunk/src/zope/i18nmessageid/message.py
===================================================================
--- zope.i18nmessageid/trunk/src/zope/i18nmessageid/message.py	2012-04-17 15:49:50 UTC (rev 125164)
+++ zope.i18nmessageid/trunk/src/zope/i18nmessageid/message.py	2012-04-17 15:51:19 UTC (rev 125165)
@@ -11,10 +11,16 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-"""I18n Messages
+"""I18n Messages and factories.
 """
 __docformat__ = "reStructuredText"
 
+try:
+    unicode
+except NameError: #pragma NO COVER Python3
+    unicode = str
+
+
 class Message(unicode):
     """Message (Python implementation)
 
@@ -23,68 +29,6 @@
     display when there is no translation.  domain may be None meaning there is
     no translation domain.  default may also be None, in which case the
     message id itself implicitly serves as the default text.
-
-    These are the doc tests from message.txt. Note that we have to create the
-    message manually since MessageFactory would return the C implementation.
-
-    >>> from zope.i18nmessageid.message import Message
-    >>> robot = Message(u"robot-message", 'futurama', u"${name} is a robot.")
-
-    >>> robot == u'robot-message'
-    True
-    >>> isinstance(robot, unicode)
-    True
-
-    >>> robot.default == u'${name} is a robot.'
-    True
-    >>> robot.mapping
-
-    >>> robot.domain = "planetexpress"
-    Traceback (most recent call last):
-    ...
-    TypeError: readonly attribute
-
-    >>> robot.default = u"${name} is not a robot."
-    Traceback (most recent call last):
-    ...
-    TypeError: readonly attribute
-
-    >>> robot.mapping = {u'name': u'Bender'}
-    Traceback (most recent call last):
-    ...
-    TypeError: readonly attribute
-
-    >>> new_robot = Message(robot, mapping={u'name': u'Bender'})
-    >>> new_robot == u'robot-message'
-    True
-    >>> new_robot.domain == 'futurama'
-    True
-    >>> new_robot.default == u'${name} is a robot.'
-    True
-    >>> new_robot.mapping == {u'name': u'Bender'}
-    True
-
-    >>> callable, args = new_robot.__reduce__()
-    >>> callable is Message
-    True
-    >>> args == (u'robot-message', 'futurama', u'${name} is a robot.', {u'name': u'Bender'})
-    True
-
-    >>> fembot = Message(u'fembot')
-    >>> callable, args = fembot.__reduce__()
-    >>> callable is Message
-    True
-    >>> args == (u'fembot', None, None, None)
-    True
-
-    Check if pickling and unpickling works
-    >>> from pickle import dumps, loads
-    >>> pystate = dumps(new_robot)
-    >>> pickle_bot = loads(pystate)
-    >>> (pickle_bot, pickle_bot.domain, pickle_bot.default, pickle_bot.mapping) == (u'robot-message', 'futurama', u'${name} is a robot.', {u'name': u'Bender'})
-    True
-    >>> pickle_bot.__reduce__()[0] is Message
-    True
     """
 
     __slots__ = ('domain', 'default', 'mapping', '_readonly')
@@ -116,13 +60,13 @@
         else:
             return unicode.__setattr__(self, key, value)
 
-    def __reduce__(self):
-        return self.__class__, self.__getstate__()
-
     def __getstate__(self):
         return unicode(self), self.domain, self.default, self.mapping
 
-# save a copy for the unit tests
+    def __reduce__(self):
+        return self.__class__, self.__getstate__()
+
+# Name the fallback Python implementation to make it easier to test.
 pyMessage = Message
 
 try:

Deleted: zope.i18nmessageid/trunk/src/zope/i18nmessageid/messages.txt
===================================================================
--- zope.i18nmessageid/trunk/src/zope/i18nmessageid/messages.txt	2012-04-17 15:49:50 UTC (rev 125164)
+++ zope.i18nmessageid/trunk/src/zope/i18nmessageid/messages.txt	2012-04-17 15:51:19 UTC (rev 125165)
@@ -1,133 +0,0 @@
-=============
-I18n Messages
-=============
-
-Rationale
----------
-
-To translate any text, we must be able to discover the source domain
-of the text.  A source domain is an identifier that identifies a
-project that produces program source strings.  Source strings occur as
-literals in python programs, text in templates, and some text in XML
-data.  The project implies a source language and an application
-context.
-
-We can think of a source domain as a collection of messages and
-associated translation strings.
-
-We often need to create unicode strings that will be displayed by
-separate views.  The view cannot translate the string without knowing
-its source domain.  A string or unicode literal carries no domain
-information, therefore we use messages.  Messages are unicode strings
-which carry a translation source domain and possibly a default
-translation.  They are created by a message factory. The message
-factory is created by calling ``MessageFactory`` with the source
-domain.
-
-ZopeMessageFactory
-------------------
-
-  >>> from zope.i18nmessageid import ZopeMessageFactory as _z_
-  >>> foo = _z_('foo')
-  >>> foo.domain
-  'zope'
-  
-
-
-Example
--------
-
-In this example, we create a message factory and assign it to _.  By
-convention, we use _ as the name of our factory to be compatible with
-translatable string extraction tools such as xgettext.  We then call _
-with a string that needs to be translatable:
-
-  >>> from zope.i18nmessageid import MessageFactory, Message
-  >>> _ = MessageFactory("futurama")
-  >>> robot = _(u"robot-message", u"${name} is a robot.")
-
-Messages at first seem like they are unicode strings:
-
-  >>> robot == u'robot-message'
-  True
-  >>> isinstance(robot, unicode)
-  True
-
-The additional domain, default and mapping information is available
-through attributes:
-
-  >>> robot.default == u'${name} is a robot.'
-  True
-  >>> robot.mapping
-  >>> robot.domain
-  'futurama'
-
-The message's attributes are considered part of the immutable message
-object.  They cannot be changed once the message id is created:
-
-  >>> robot.domain = "planetexpress"
-  Traceback (most recent call last):
-  ...
-  TypeError: readonly attribute
-
-  >>> robot.default = u"${name} is not a robot."
-  Traceback (most recent call last):
-  ...
-  TypeError: readonly attribute
-
-  >>> robot.mapping = {u'name': u'Bender'}
-  Traceback (most recent call last):
-  ...
-  TypeError: readonly attribute
-
-If you need to change their information, you'll have to make a new
-message id object:
-
-  >>> new_robot = Message(robot, mapping={u'name': u'Bender'})
-  >>> new_robot == u'robot-message'
-  True
-  >>> new_robot.domain
-  'futurama'
-  >>> new_robot.default == u'${name} is a robot.'
-  True
-  >>> new_robot.mapping == {u'name': u'Bender'}
-  True
-
-Last but not least, messages are reduceable for pickling:
-
-  >>> callable, args = new_robot.__reduce__()
-  >>> callable is Message
-  True
-  >>> args == (u'robot-message', 'futurama', u'${name} is a robot.', {u'name': u'Bender'})
-  True
-
-  >>> fembot = Message(u'fembot')
-  >>> callable, args = fembot.__reduce__()
-  >>> callable is Message
-  True
-  >>> args == (u'fembot', None, None, None)
-  True
-
-Message IDs and backward compatability
---------------------------------------
-
-The change to immutability is not a simple refactoring that can be
-coped with backward compatible APIs--it is a change in semantics.
-Because immutability is one of those "you either have it or you don't"
-things (like pregnancy or death), we will not be able to support both
-in one implementation.
-
-The proposed solution for backward compatability is to support both
-implementations in parallel, deprecating the mutable one.  A separate
-factory, ``MessageFactory``, instantiates immutable messages, while
-the deprecated old one continues to work like before.
-
-The roadmap to immutable-only message ids is proposed as follows:
-
-  Zope 3.1: Immutable message ids are introduced.  Security
-  declarations for mutable message ids are provided to make the
-  stripping of security proxies unnecessary.
-
-  Zope 3.2: Mutable message ids are deprecated.
-
-  Zope 3.3: Mutable message ids are removed.

Modified: zope.i18nmessageid/trunk/src/zope/i18nmessageid/tests.py
===================================================================
--- zope.i18nmessageid/trunk/src/zope/i18nmessageid/tests.py	2012-04-17 15:49:50 UTC (rev 125164)
+++ zope.i18nmessageid/trunk/src/zope/i18nmessageid/tests.py	2012-04-17 15:51:19 UTC (rev 125165)
@@ -14,121 +14,137 @@
 """Message ID tests.
 """
 import unittest
-from doctest import DocFileSuite
-from doctest import DocTestSuite
 
-class PickleEqualityTests(unittest.TestCase):
-    def setUp(self):
-        # set the C version up as the used version
-        import zope.i18nmessageid.message
-        self.oldMessage = zope.i18nmessageid.message.Message
+class PyMessageTests(unittest.TestCase):
 
-    def tearDown(self):
-        # set the original version back up as the used version
-        import zope.i18nmessageid.message
-        zope.i18nmessageid.message.Message = self.oldMessage
+    _TEST_REAOONLY = True
 
-    def test_message_pickling(self):
-        from zope.i18nmessageid.message import pyMessage as Message
-        robot = Message(u"robot-message", 'futurama', u"${name} is a robot.")
+    def _getTargetClass(self):
+        from zope.i18nmessageid.message import pyMessage
+        return pyMessage
 
-        self.assertEqual(robot, u'robot-message')
-        self.assertTrue(isinstance(robot, unicode))
-        self.assertEqual(robot.default, u'${name} is a robot.')
-        self.assertEqual(robot.mapping, None)
+    def _makeOne(self, *args, **kw):
+        return self._getTargetClass()(*args, **kw)
 
-        # Only the python implementation has a _readonly attribute
-        self.assertEqual(robot._readonly, True)
-        self.assertRaises(
-            TypeError,
-            robot.__setattr__, 'domain', "planetexpress")
-        self.assertRaises(
-            TypeError,
-            robot.__setattr__, 'default', u"${name} is not a robot.")
-        self.assertRaises(
-            TypeError,
-            robot.__setattr__, 'mapping', {u'name': u'Bender'})
-        
-        new_robot = Message(robot, mapping={u'name': u'Bender'})
-        self.assertEqual(new_robot, u'robot-message')
-        self.assertEqual(new_robot.domain, 'futurama')
-        self.assertEqual(new_robot.default, u'${name} is a robot.')
-        self.assertEqual(new_robot.mapping, {u'name': u'Bender'})
+    def test_ctor_defaults(self):
+        message = self._makeOne('testing')
+        self.assertEqual(message, 'testing')
+        self.assertEqual(message.domain, None)
+        self.assertEqual(message.default, None)
+        self.assertEqual(message.mapping, None)
+        if self._TEST_REAOONLY:
+            self.assertTrue(message._readonly)
 
-        callable, args = new_robot.__reduce__()
-        self.assertTrue(callable is Message)
-        self.assertEqual(
-            args,
-            (u'robot-message', 'futurama', u'${name} is a robot.',
-             {u'name': u'Bender'}))
+    def test_ctor_explicit(self):
+        mapping = {'key': 'value'}
+        message = self._makeOne('testing', 'domain', 'default', mapping)
+        self.assertEqual(message, 'testing')
+        self.assertEqual(message.domain, 'domain')
+        self.assertEqual(message.default, 'default')
+        self.assertEqual(message.mapping, mapping)
+        if self._TEST_REAOONLY:
+            self.assertTrue(message._readonly)
 
-        fembot = Message(u'fembot')
-        callable, args = fembot.__reduce__()
-        self.assertTrue(callable is Message)
-        self.assertEqual(args, (u'fembot', None, None, None))
+    def test_ctor_copy(self):
+        mapping = {'key': 'value'}
+        source = self._makeOne('testing', 'domain', 'default', mapping)
+        message = self._makeOne(source)
+        self.assertEqual(message, 'testing')
+        self.assertEqual(message.domain, 'domain')
+        self.assertEqual(message.default, 'default')
+        self.assertEqual(message.mapping, mapping)
+        if self._TEST_REAOONLY:
+            self.assertTrue(message._readonly)
 
-        import zope.i18nmessageid.message
-        zope.i18nmessageid.message.Message = Message
+    def test_ctor_copy_w_overrides(self):
+        mapping = {'key': 'value'}
+        source = self._makeOne('testing')
+        message = self._makeOne(source, 'domain', 'default', mapping)
+        self.assertEqual(message, 'testing')
+        self.assertEqual(message.domain, 'domain')
+        self.assertEqual(message.default, 'default')
+        self.assertEqual(message.mapping, mapping)
+        if self._TEST_REAOONLY:
+            self.assertTrue(message._readonly)
 
-        # First check if pickling and unpickling from pyMessage to
-        # pyMessage works
-        from pickle import dumps, loads
-        pystate = dumps(new_robot)
-        pickle_bot = loads(pystate)
-        self.assertEqual(pickle_bot, u'robot-message')
-        self.assertEqual(pickle_bot.domain, 'futurama')
-        self.assertEqual(pickle_bot.default, u'${name} is a robot.')
-        self.assertEqual(pickle_bot.mapping, {u'name': u'Bender'})
-        self.assertEqual(pickle_bot._readonly, True)
+    def test_domain_immutable(self):
+        message = self._makeOne('testing')
+        def _try():
+            message.domain = 'domain'
+        self.assertRaises(TypeError, _try)
 
-        from zope.i18nmessageid.message import pyMessage
-        self.assertTrue(pickle_bot.__reduce__()[0] is pyMessage)
-        del pickle_bot
+    def test_default_immutable(self):
+        message = self._makeOne('testing')
+        def _try():
+            message.default = 'default'
+        self.assertRaises(TypeError, _try)
 
-        # Second check if cMessage is able to load the state of a pyMessage
-        from zope.i18nmessageid._zope_i18nmessageid_message import Message
-        zope.i18nmessageid.message.Message = Message
-        c_bot = loads(pystate) 
-        self.assertEqual(c_bot, u'robot-message')
-        self.assertEqual(c_bot.domain, 'futurama')
-        self.assertEqual(c_bot.default, u'${name} is a robot.')
-        self.assertEqual(c_bot.mapping, {u'name': u'Bender'})
-        self.assertFalse(hasattr(c_bot, '_readonly'))
-        from zope.i18nmessageid._zope_i18nmessageid_message import Message as cMessage
-        self.assertTrue(c_bot.__reduce__()[0] is cMessage)
+    def test_mapping_immutable(self):
+        mapping = {'key': 'value'}
+        message = self._makeOne('testing')
+        def _try():
+            message.mapping = mapping
+        self.assertRaises(TypeError, _try)
 
-        # Last check if pyMessage can load a state of cMessage
-        cstate = dumps(c_bot)
-        del c_bot
-        from zope.i18nmessageid.message import pyMessage as Message
-        zope.i18nmessageid.message.Message = Message
-        py_bot = loads(cstate)
-        self.assertEqual(py_bot, u'robot-message')
-        self.assertEqual(py_bot.domain, 'futurama')
-        self.assertEqual(py_bot.default, u'${name} is a robot.')
-        self.assertEqual(py_bot.mapping, {u'name': u'Bender'})
-        self.assertEqual(py_bot._readonly, True)
-        self.assertTrue(py_bot.__reduce__()[0] is pyMessage)
+    def test_unknown_immutable(self):
+        message = self._makeOne('testing')
+        def _try():
+            message.unknown = 'unknown'
+        # C version raises AttributeError, Python version TypeError
+        self.assertRaises((TypeError, AttributeError), _try)
 
-        # Both pickle states should be equal
-        self.assertEqual(pystate, cstate)
+    def test___reduce__(self):
+        mapping = {'key': 'value'}
+        source = self._makeOne('testing')
+        message = self._makeOne(source, 'domain', 'default', mapping)
+        klass, state = message.__reduce__()
+        self.assertTrue(klass is self._getTargetClass())
+        self.assertEqual(state, ('testing', 'domain', 'default', mapping))
 
-try:
-    from zope.i18nmessageid._zope_i18nmessageid_message import Message as import_test
-    def test_suite():
-        return unittest.TestSuite((
-	    DocTestSuite('zope.i18nmessageid.message'),
-	    DocFileSuite('messages.txt', package='zope.i18nmessageid'),
-            unittest.makeSuite(PickleEqualityTests),
-	    ))
-except ImportError, e: # pragma: no cover
-    print '=' * 80
-    print "Could not import C version:"
-    print e
-    print '=' * 80
-    def test_suite():
-        return unittest.TestSuite((
-	    DocTestSuite('zope.i18nmessageid.message'),
-	    DocFileSuite('messages.txt', package='zope.i18nmessageid'),
-	    ))
-    
+
+class MessageTests(PyMessageTests):
+
+    _TEST_REAOONLY = False
+
+    def _getTargetClass(self):
+        from zope.i18nmessageid.message import Message
+        return Message
+
+
+class MessageFactoryTests(unittest.TestCase):
+
+    def _getTargetClass(self):
+        from zope.i18nmessageid.message import MessageFactory
+        return MessageFactory
+
+    def _makeOne(self, *args, **kw):
+        return self._getTargetClass()(*args, **kw)
+
+    def test___call___defaults(self):
+        from zope.i18nmessageid.message import Message
+        factory = self._makeOne('domain')
+        message = factory('testing')
+        self.assertTrue(isinstance(message, Message))
+        self.assertEqual(message, 'testing')
+        self.assertEqual(message.domain, 'domain')
+        self.assertEqual(message.default, None)
+        self.assertEqual(message.mapping, None)
+
+    def test___call___explicit(self):
+        from zope.i18nmessageid.message import Message
+        mapping = {'key': 'value'}
+        factory = self._makeOne('domain')
+        message = factory('testing', 'default', mapping)
+        self.assertTrue(isinstance(message, Message))
+        self.assertEqual(message, 'testing')
+        self.assertEqual(message.domain, 'domain')
+        self.assertEqual(message.default, 'default')
+        self.assertEqual(message.mapping, mapping)
+
+
+def test_suite():
+    return unittest.TestSuite((
+        unittest.makeSuite(PyMessageTests),
+        unittest.makeSuite(MessageTests),
+        unittest.makeSuite(MessageFactoryTests),
+    ))

Modified: zope.i18nmessageid/trunk/tox.ini
===================================================================
--- zope.i18nmessageid/trunk/tox.ini	2012-04-17 15:49:50 UTC (rev 125164)
+++ zope.i18nmessageid/trunk/tox.ini	2012-04-17 15:51:19 UTC (rev 125165)
@@ -1,6 +1,9 @@
 [tox]
 envlist = 
-    py24,py25,py26,py27,py32,jython,pypy
+# Jython support pending 2.7 support, due 2012-07-15 or so.  See:
+# http://fwierzbicki.blogspot.com/2012/03/adconion-to-fund-jython-27.html
+#   py26,py27,py32,jython,pypy,coverage
+    py26,py27,py32,pypy
 
 [testenv]
 commands = 
@@ -9,3 +12,18 @@
 [testenv:jython]
 commands = 
    jython setup.py test -q
+
+[testenv:coverage]
+basepython =
+    python2.6
+commands = 
+#   The installed version messes up nose's test discovery / coverage reporting
+#   So, we uninstall that from the environment, and then install the editable
+#   version, before running nosetests.
+    pip uninstall -y zope.i18nmessageid
+    pip install -e .
+    nosetests --with-xunit --with-xcoverage
+deps =
+    nose
+    coverage
+    nosexcover



More information about the checkins mailing list