]> git.ipfire.org Git - thirdparty/babel.git/commitdiff
Replace odict with Python's collection.OrderedDict
authorJon Dufresne <jon.dufresne@gmail.com>
Sun, 30 Dec 2018 15:54:34 +0000 (10:54 -0500)
committerAarni Koskela <akx@iki.fi>
Fri, 25 Jan 2019 10:50:05 +0000 (12:50 +0200)
The odict class duplicates collection.OrderedDict from Python's standard
lib. Simplify the code by using builtin Python features.

https://docs.python.org/3/library/collections.html#collections.OrderedDict

CHANGES
babel/messages/catalog.py
babel/messages/frontend.py
babel/util.py
tests/test_util.py

diff --git a/CHANGES b/CHANGES
index 6d9b0e5fa5381859f9fe87c84fc35ffcd2a9cc32..622b4c5737a5668e6cd925f47d04a51f5bb32231 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,19 @@
 Babel Changelog
 ===============
 
+UNRELEASED
+----------
+
+Possibly incompatible changes
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+These may be backward incompatible in some cases, as some more-or-less internal
+APIs have changed. Please feel free to file issues if you bump into anything
+strange and we'll try to help!
+
+* General: Internal uses of ``babel.util.odict`` have been replaced with
+  ``collections.OrderedDict`` from The Python standard library.
+
 Version 2.6.0
 -------------
 
index 6d61a3826bbc7e546e2ff14b1aee77fab2b8301d..649d0e2fe887e8bb1b82df07c890358ede5ee1bd 100644 (file)
@@ -13,6 +13,7 @@ import re
 import time
 
 from cgi import parse_header
+from collections import OrderedDict
 from datetime import datetime, time as time_
 from difflib import get_close_matches
 from email import message_from_string
@@ -22,7 +23,7 @@ from babel import __version__ as VERSION
 from babel.core import Locale, UnknownLocaleError
 from babel.dates import format_datetime
 from babel.messages.plurals import get_plural
-from babel.util import odict, distinct, LOCALTZ, FixedOffsetTimezone
+from babel.util import distinct, LOCALTZ, FixedOffsetTimezone
 from babel._compat import string_types, number_types, PY2, cmp, text_type, force_text
 
 __all__ = ['Message', 'Catalog', 'TranslationError']
@@ -269,7 +270,7 @@ class Catalog(object):
         self.domain = domain
         self.locale = locale
         self._header_comment = header_comment
-        self._messages = odict()
+        self._messages = OrderedDict()
 
         self.project = project or 'PROJECT'
         self.version = version or 'VERSION'
@@ -295,7 +296,7 @@ class Catalog(object):
         self.revision_date = revision_date
         self.fuzzy = fuzzy
 
-        self.obsolete = odict()  # Dictionary of obsolete messages
+        self.obsolete = OrderedDict()  # Dictionary of obsolete messages
         self._num_plurals = None
         self._plural_expr = None
 
@@ -754,7 +755,7 @@ class Catalog(object):
         """
         messages = self._messages
         remaining = messages.copy()
-        self._messages = odict()
+        self._messages = OrderedDict()
 
         # Prepare for fuzzy matching
         fuzzy_candidates = []
index 16cb90054a700c9bddffd734949ac35d62f422a6..9213cca41453a75abac1d29fe70605741d005eab 100644 (file)
@@ -17,6 +17,7 @@ import re
 import shutil
 import sys
 import tempfile
+from collections import OrderedDict
 from datetime import datetime
 from locale import getpreferredencoding
 
@@ -28,7 +29,7 @@ from babel.messages.catalog import Catalog
 from babel.messages.extract import DEFAULT_KEYWORDS, DEFAULT_MAPPING, check_and_call_extract_file, extract_from_dir
 from babel.messages.mofile import write_mo
 from babel.messages.pofile import read_po, write_po
-from babel.util import LOCALTZ, odict
+from babel.util import LOCALTZ
 from distutils import log as distutils_log
 from distutils.cmd import Command as _Command
 from distutils.errors import DistutilsOptionError, DistutilsSetupError
@@ -965,7 +966,7 @@ def parse_mapping(fileobj, filename=None):
     options_map = {}
 
     parser = RawConfigParser()
-    parser._sections = odict(parser._sections)  # We need ordered sections
+    parser._sections = OrderedDict(parser._sections)  # We need ordered sections
 
     if PY2:
         parser.readfp(fileobj, filename)
index fb93f16d5790114011e1fab625f66459eec4858f..c443b6902e52f557958c8a0736e60c8903941869 100644 (file)
@@ -10,6 +10,7 @@
 """
 
 import codecs
+import collections
 from datetime import timedelta, tzinfo
 import os
 import re
@@ -220,77 +221,8 @@ def wraptext(text, width=70, initial_indent='', subsequent_indent=''):
     return wrapper.wrap(text)
 
 
-class odict(dict):
-    """Ordered dict implementation.
-
-    :see: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/107747
-    """
-
-    def __init__(self, data=None):
-        dict.__init__(self, data or {})
-        self._keys = list(dict.keys(self))
-
-    def __delitem__(self, key):
-        dict.__delitem__(self, key)
-        self._keys.remove(key)
-
-    def __setitem__(self, key, item):
-        new_key = key not in self
-        dict.__setitem__(self, key, item)
-        if new_key:
-            self._keys.append(key)
-
-    def __iter__(self):
-        return iter(self._keys)
-    iterkeys = __iter__
-
-    def clear(self):
-        dict.clear(self)
-        self._keys = []
-
-    def copy(self):
-        d = odict()
-        d.update(self)
-        return d
-
-    def items(self):
-        return zip(self._keys, self.values())
-
-    def iteritems(self):
-        return izip(self._keys, self.itervalues())
-
-    def keys(self):
-        return self._keys[:]
-
-    def pop(self, key, default=missing):
-        try:
-            value = dict.pop(self, key)
-            self._keys.remove(key)
-            return value
-        except KeyError as e:
-            if default == missing:
-                raise e
-            else:
-                return default
-
-    def popitem(self, key):
-        self._keys.remove(key)
-        return dict.popitem(key)
-
-    def setdefault(self, key, failobj=None):
-        dict.setdefault(self, key, failobj)
-        if key not in self._keys:
-            self._keys.append(key)
-
-    def update(self, dict):
-        for (key, val) in dict.items():
-            self[key] = val
-
-    def values(self):
-        return map(self.get, self._keys)
-
-    def itervalues(self):
-        return imap(self.get, self._keys)
+# TODO (Babel 3.x): Remove this re-export
+odict = collections.OrderedDict
 
 
 class FixedOffsetTimezone(tzinfo):
index ef591102e8b57e1995a741e9745fbe7068ae7cb3..0fc59e5c48307e11ff9804a8365ec7294ea486c0 100644 (file)
@@ -38,20 +38,6 @@ def test_pathmatch():
     assert not util.pathmatch('./foo/**.py', 'blah/foo/bar/baz.py')
 
 
-def test_odict_pop():
-    odict = util.odict()
-    odict[0] = 1
-    value = odict.pop(0)
-    assert 1 == value
-    assert [] == list(odict.items())
-    assert odict.pop(2, None) is None
-    try:
-        odict.pop(2)
-        assert False
-    except KeyError:
-        assert True
-
-
 class FixedOffsetTimezoneTestCase(unittest.TestCase):
 
     def test_zone_negative_offset(self):