Skip to content

Commit

Permalink
Fix: add Text.unicode_normalization = 'NFC' as default
Browse files Browse the repository at this point in the history
  • Loading branch information
agroszer committed Mar 6, 2020
1 parent 6a3e0db commit 3c61968
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 4 deletions.
8 changes: 5 additions & 3 deletions CHANGES.rst
Expand Up @@ -2,10 +2,12 @@
Changes
=========

5.1 (unreleased)
================
5.0.1 (unreleased)
==================

- Nothing changed yet.
- Fix: add ``Text.unicode_normalization = 'NFC'`` as default, because some are
persisting schema fields. Setting that attribute only in ``__init__``
breaks loading old objects.


5.0 (2020-03-06)
Expand Down
4 changes: 3 additions & 1 deletion src/zope/schema/_bootstrapfields.py
Expand Up @@ -505,9 +505,11 @@ def _validate(self, value):
class Text(MinMaxLen, Field):
"""A field containing text used for human discourse."""
_type = text_type
unicode_normalization = 'NFC'

def __init__(self, *args, **kw):
self.unicode_normalization = kw.pop('unicode_normalization', 'NFC')
self.unicode_normalization = kw.pop(
'unicode_normalization', self.unicode_normalization)
super(Text, self).__init__(*args, **kw)

def fromUnicode(self, value):
Expand Down
18 changes: 18 additions & 0 deletions src/zope/schema/tests/test__bootstrapfields.py
Expand Up @@ -967,6 +967,7 @@ def test_fromUnicode_hit(self):
def test_normalization(self):
deadbeef = unicodedata.normalize('NFD', b'\xc3\x84\xc3\x96\xc3\x9c'.decode('utf-8'))
txt = self._makeOne()
self.assertEqual(txt.unicode_normalization, 'NFC')
self.assertEqual(
[unicodedata.name(c) for c in txt.fromUnicode(deadbeef)],
[
Expand All @@ -976,6 +977,7 @@ def test_normalization(self):
]
)
txt = self._makeOne(unicode_normalization=None)
self.assertEqual(txt.unicode_normalization, None)
self.assertEqual(
[unicodedata.name(c) for c in txt.fromUnicode(deadbeef)],
[
Expand All @@ -988,6 +990,22 @@ def test_normalization(self):
]
)

def test_normalization_after_pickle(self):
# test an edge case where `Text` is persisted
# see https://github.com/zopefoundation/zope.schema/issues/90
import pickle
orig_makeOne = self._makeOne
def makeOne(**kwargs):
result = orig_makeOne(**kwargs)
if not kwargs:
# We should have no state to preserve
result.__dict__.clear()

result = pickle.loads(pickle.dumps(result))
return result

self._makeOne = makeOne
self.test_normalization()


class TextLineTests(EqualityTestsMixin,
Expand Down

0 comments on commit 3c61968

Please sign in to comment.