summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Madden <jason+github@nextthought.com>2018-10-19 14:56:58 -0500
committerGitHub <noreply@github.com>2018-10-19 14:56:58 -0500
commit6cb7a6c9c3a05192695299d9847a4637b0533e7e (patch)
treedb1ad825a718240d00f97e766a1cffeaec49f780
parent027263ea0001517edf901178a8eb2bb2ba3bec17 (diff)
parenta2c0e413df1fd389de57578672e1415121ff9b09 (diff)
downloadzope-i18nmessageid-6cb7a6c9c3a05192695299d9847a4637b0533e7e.tar.gz
Merge pull request #15 from zopefoundation/issue14
Fix copying Message in pure-python.
-rw-r--r--CHANGES.rst53
-rw-r--r--setup.py4
-rw-r--r--src/zope/i18nmessageid/_zope_i18nmessageid_message.c37
-rw-r--r--src/zope/i18nmessageid/message.py60
-rw-r--r--src/zope/i18nmessageid/tests.py36
5 files changed, 96 insertions, 94 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index f21f4aa..ec19279 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -1,21 +1,24 @@
-Changes
-=======
+=========
+ Changes
+=========
-4.4 (unreleased)
-----------------
+4.3.1 (unreleased)
+==================
-- Nothing changed yet.
+- Fix a regression copying Message objects in the Python
+ implementation. See `issue 14
+ <https://github.com/zopefoundation/zope.i18nmessageid/issues/14>`_.
-4.3 (2018-10-18)
-----------------
+4.3.0 (2018-10-18)
+==================
- Add attributes to support pluralization on a Message and update the
MessageFactory accordingly.
-4.2 (2018-10-05)
-----------------
+4.2.0 (2018-10-05)
+==================
- Fix the possibility of a rare crash in the C extension when
deallocating items. See `issue 7
@@ -27,7 +30,7 @@ Changes
4.1.0 (2017-05-02)
-------------------
+==================
- Drop support for Python 2.6 and 3.2.
@@ -42,24 +45,24 @@ Changes
<https://github.com/zopefoundation/zope.i18nmessageid/issues/5>`_.
4.0.3 (2014-03-19)
-------------------
+==================
- Add support for Python 3.4.
- Update ``boostrap.py`` to version 2.2.
4.0.2 (2012-12-31)
-------------------
+==================
- Flesh out PyPI Trove classifiers.
4.0.1 (2012-11-21)
-------------------
+==================
- Add support for Python 3.3.
4.0.0 (2012-05-16)
-------------------
+==================
- Automate generation of Sphinx HTML docs and running doctest snippets via tox.
@@ -83,12 +86,12 @@ Changes
3.6.1 (2011-07-20)
-------------------
+==================
- Correct metadata in this file for release date.
3.6.0 (2011-07-20)
-------------------
+==================
- Python 3 support.
@@ -98,7 +101,7 @@ Changes
automated testing.
3.5.3 (2010-08-10)
-------------------
+==================
- Make compilation of C extension optional again; 3.5.1 broke this
inasmuch as this package become unusable on non-CPython platforms.
@@ -112,12 +115,12 @@ Changes
compiled. This also makes the tests pass on Jython.
3.5.2 (2010-04-30)
-------------------
+==================
- Remove use of 'zope.testing.doctestunit' in favor of stdlib's 'doctest.
3.5.1 (2010-04-10)
-------------------
+==================
- LP #257657 / 489529: Fix memory leak in C extension.
@@ -125,7 +128,7 @@ Changes
setuptools Feature.
3.5.0 (2009-06-27)
-------------------
+==================
- Make compilation of C extension optional.
@@ -141,24 +144,24 @@ Changes
- Remove old .cfg files for zpkg.
3.4.3 (2007-09-26)
-------------------
+==================
- Make PyPI the home URL.
3.4.2 (2007-09-25)
-------------------
+==================
- Move the ``ZopeMessageFactory`` from ``zope.app.i18n`` to this package.
3.4.0 (2007-07-19)
-------------------
+==================
- Remove incorrect dependency.
- Create final release to reflect package status.
3.2.0 (2006-01-05)
-------------------
+==================
- Corresponds to the verison of the zope.i18nmessageid package shipped as
part of the Zope 3.2.0 release.
@@ -171,7 +174,7 @@ Changes
in Zope 3.3.
3.0.0 (2004-11-07)
-------------------
+==================
- Corresponds to the verison of the zope.i18nmessageid package shipped as
part of the Zope X3.0.0 release.
diff --git a/setup.py b/setup.py
index eb7eb87..3256913 100644
--- a/setup.py
+++ b/setup.py
@@ -101,7 +101,7 @@ class optional_build_ext(build_ext):
setup(
name='zope.i18nmessageid',
- version='4.4.dev0',
+ version='4.3.1.dev0',
author='Zope Foundation and Contributors',
author_email='zope-dev@zope.org',
description='Message Identifiers for internationalization',
@@ -132,7 +132,7 @@ setup(
'Framework :: Zope :: 3',
],
license='ZPL 2.1',
- url='http://pypi.python.org/pypi/zope.i18nmessageid',
+ url='https://github.com/zopefoundation/zope.i18nmessageid',
packages=find_packages('src'),
package_dir={'': 'src'},
namespace_packages=['zope'],
diff --git a/src/zope/i18nmessageid/_zope_i18nmessageid_message.c b/src/zope/i18nmessageid/_zope_i18nmessageid_message.c
index c0107e1..66cd93d 100644
--- a/src/zope/i18nmessageid/_zope_i18nmessageid_message.c
+++ b/src/zope/i18nmessageid/_zope_i18nmessageid_message.c
@@ -14,16 +14,6 @@
#include "Python.h"
-/* Support for Python < 2.6: */
-
-#ifndef Py_TYPE
- #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
-#endif
-
-#ifndef PyVarObject_HEAD_INIT
- #define PyVarObject_HEAD_INIT(type, size) \
- PyObject_HEAD_INIT(type) size,
-#endif
#if PY_MAJOR_VERSION >= 3
#define MOD_ERROR_VAL NULL
@@ -31,33 +21,6 @@
#define MOD_ERROR_VAL
#endif
-/* these macros make gc support easier; they are only available in
- Python 2.4 and borrowed from there */
-
-#ifndef Py_CLEAR
-#define Py_CLEAR(op) \
- do { \
- if (op) { \
- PyObject *tmp = (op); \
- (op) = NULL; \
- Py_DECREF(tmp); \
- } \
- } while (0)
-#endif
-
-#ifndef Py_VISIT
-#define Py_VISIT(op) \
- do { \
- if (op) { \
- int vret = visit((op), arg); \
- if (vret) \
- return vret; \
- } \
- } while (0)
-#endif
-
-/* ----------------------------------------------------- */
-
typedef struct {
PyUnicodeObject base;
PyObject *domain;
diff --git a/src/zope/i18nmessageid/message.py b/src/zope/i18nmessageid/message.py
index 4bfcb19..70a5053 100644
--- a/src/zope/i18nmessageid/message.py
+++ b/src/zope/i18nmessageid/message.py
@@ -13,11 +13,11 @@
##############################################################################
"""I18n Messages and factories.
"""
+import six
+
__docformat__ = "reStructuredText"
_marker = object()
-import six
-
class Message(six.text_type):
"""Message (Python implementation)
@@ -37,37 +37,37 @@ class Message(six.text_type):
msgid_plural=_marker, default_plural=_marker, number=_marker):
self = six.text_type.__new__(cls, ustr)
if isinstance(ustr, self.__class__):
- domain = ustr.domain[:] if domain is _marker else domain
- default = ustr.default[:] if default is _marker else default
- mapping = ustr.mapping.copy() if mapping is _marker else mapping
- msgid_plural = (
- ustr.msgid_plural[:] if msgid_plural is _marker else
- msgid_plural)
- default_plural = (
- ustr.default_plural[:] if default_plural is _marker else
- default_plural)
- number = ustr.number if number is _marker else number
- ustr = six.text_type(ustr)
+ self.domain = ustr.domain
+ self.default = ustr.default
+ self.mapping = ustr.mapping
+ self.msgid_plural = ustr.msgid_plural
+ self.default_plural = ustr.default_plural
+ self.number = ustr.number
else:
- domain = None if domain is _marker else domain
- default = None if default is _marker else default
- mapping = None if mapping is _marker else mapping
- msgid_plural = None if msgid_plural is _marker else msgid_plural
- default_plural = (None if default_plural is _marker else
- default_plural)
- number = None if number is _marker else number
-
- self.domain = domain
- self.default = default
- self.mapping = mapping
- self.msgid_plural = msgid_plural
- self.default_plural = default_plural
-
- if number is not None and not isinstance(
- number, six.integer_types + (float,)):
+ self.domain = None
+ self.default = None
+ self.mapping = None
+ self.msgid_plural = None
+ self.default_plural = None
+ self.number = None
+
+ if domain is not _marker:
+ self.domain = domain
+ if default is not _marker:
+ self.default = default
+ if mapping is not _marker:
+ self.mapping = mapping
+ if msgid_plural is not _marker:
+ self.msgid_plural = msgid_plural
+ if default_plural is not _marker:
+ self.default_plural = default_plural
+ if number is not _marker:
+ self.number = number
+
+ if self.number is not None and not isinstance(
+ self.number, six.integer_types + (float,)):
raise TypeError('`number` should be an integer or a float')
- self.number = number
self._readonly = True
return self
diff --git a/src/zope/i18nmessageid/tests.py b/src/zope/i18nmessageid/tests.py
index 56074c1..89ed869 100644
--- a/src/zope/i18nmessageid/tests.py
+++ b/src/zope/i18nmessageid/tests.py
@@ -113,6 +113,19 @@ class PyMessageTests(unittest.TestCase):
self.assertEqual(message.msgid_plural, 'testings')
self.assertEqual(message.default_plural, 'defaults')
self.assertEqual(message.number, 0)
+
+ # Besides just being equal, they maintain their identity
+ for attr in (
+ 'domain',
+ 'default',
+ 'mapping',
+ 'msgid_plural',
+ 'default_plural',
+ 'number',
+ ):
+ self.assertIs(getattr(source, attr),
+ getattr(message, attr))
+
if self._TEST_READONLY:
self.assertTrue(message._readonly)
@@ -133,6 +146,29 @@ class PyMessageTests(unittest.TestCase):
if self._TEST_READONLY:
self.assertTrue(message._readonly)
+ def test_copy_no_default(self):
+ # https://github.com/zopefoundation/zope.i18nmessageid/issues/14
+ pref_msg = self._makeOne("${name} Preferences")
+ self.assertIsNone(pref_msg.default)
+ copy = self._makeOne(pref_msg, mapping={u'name': u'name'})
+ self.assertIsNone(copy.default)
+
+ def test_copy_no_overrides(self):
+ # https://github.com/zopefoundation/zope.i18nmessageid/issues/14
+ pref_msg = self._makeOne("${name} Preferences")
+
+ copy = self._makeOne(pref_msg)
+ for attr in (
+ 'domain',
+ 'default',
+ 'mapping',
+ 'msgid_plural',
+ 'default_plural',
+ 'number',
+ ):
+ self.assertIsNone(getattr(pref_msg, attr))
+ self.assertIsNone(getattr(copy, attr))
+
def test_domain_immutable(self):
message = self._makeOne('testing')
with self.assertRaises((TypeError, AttributeError)):