summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy
diff options
context:
space:
mode:
authorFederico Caselli <cfederico87@gmail.com>2020-12-02 23:43:44 +0100
committerMike Bayer <mike_mp@zzzcomputing.com>2020-12-07 15:46:21 -0500
commit93cc9d7e8bcde2feca1ab8e6808124c0d4aae8d4 (patch)
treeb6c3b57b4835c7e8d109ccc0aa28640b7f1dbbc4 /lib/sqlalchemy
parent87d58b6d8188ccff808b3207d5f9398bb9adf9b9 (diff)
downloadsqlalchemy-93cc9d7e8bcde2feca1ab8e6808124c0d4aae8d4.tar.gz
Replace ``OrderedDict`` with a normal ``dict`` in python 3.7+
References: #5735 Change-Id: I0a73f727fb6820d32eca590b1e8afbfe2872adb8
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r--lib/sqlalchemy/orm/decl_base.py4
-rw-r--r--lib/sqlalchemy/util/__init__.py1
-rw-r--r--lib/sqlalchemy/util/_collections.py172
3 files changed, 104 insertions, 73 deletions
diff --git a/lib/sqlalchemy/orm/decl_base.py b/lib/sqlalchemy/orm/decl_base.py
index 0649247a7..8da326b0e 100644
--- a/lib/sqlalchemy/orm/decl_base.py
+++ b/lib/sqlalchemy/orm/decl_base.py
@@ -569,7 +569,9 @@ class _ClassScanMapperConfig(_MapperConfig):
our_stuff = self.properties
# set up attributes in the order they were created
- our_stuff.sort(key=lambda key: our_stuff[key]._creation_order)
+ util.sort_dictionary(
+ our_stuff, key=lambda key: our_stuff[key]._creation_order
+ )
# extract columns from the class dict
declared_columns = self.declared_columns
diff --git a/lib/sqlalchemy/util/__init__.py b/lib/sqlalchemy/util/__init__.py
index d632f7fed..2db1adb8d 100644
--- a/lib/sqlalchemy/util/__init__.py
+++ b/lib/sqlalchemy/util/__init__.py
@@ -35,6 +35,7 @@ from ._collections import OrderedSet # noqa
from ._collections import PopulateDict # noqa
from ._collections import Properties # noqa
from ._collections import ScopedRegistry # noqa
+from ._collections import sort_dictionary # noqa
from ._collections import ThreadLocalRegistry # noqa
from ._collections import to_column_set # noqa
from ._collections import to_list # noqa
diff --git a/lib/sqlalchemy/util/_collections.py b/lib/sqlalchemy/util/_collections.py
index b50d9885d..69457994a 100644
--- a/lib/sqlalchemy/util/_collections.py
+++ b/lib/sqlalchemy/util/_collections.py
@@ -17,6 +17,7 @@ from .compat import binary_types
from .compat import collections_abc
from .compat import itertools_filterfalse
from .compat import py2k
+from .compat import py37
from .compat import string_types
from .compat import threading
@@ -235,101 +236,128 @@ class ImmutableProperties(ImmutableContainer, Properties):
__slots__ = ()
-class OrderedDict(dict):
- """A dict that returns keys/values/items in the order they were added."""
+def _ordered_dictionary_sort(d, key=None):
+ """Sort an OrderedDict in-place."""
- __slots__ = ("_list",)
+ items = [(k, d[k]) for k in sorted(d, key=key)]
- def __reduce__(self):
- return OrderedDict, (self.items(),)
+ d.clear()
- def __init__(self, ____sequence=None, **kwargs):
- self._list = []
- if ____sequence is None:
- if kwargs:
- self.update(**kwargs)
- else:
- self.update(____sequence, **kwargs)
+ d.update(items)
- def clear(self):
- self._list = []
- dict.clear(self)
- def copy(self):
- return self.__copy__()
+if py37:
+ OrderedDict = dict
+ sort_dictionary = _ordered_dictionary_sort
+
+else:
+ # prevent sort_dictionary from being used against a plain dictionary
+ # for Python < 3.7
- def __copy__(self):
- return OrderedDict(self)
+ def sort_dictionary(d, key=None):
+ """Sort an OrderedDict in place."""
- def sort(self, *arg, **kw):
- self._list.sort(*arg, **kw)
+ d._ordered_dictionary_sort(key=key)
+
+ class OrderedDict(dict):
+ """Dictionary that maintains insertion order.
+
+ Superseded by Python dict as of Python 3.7
+
+ """
+
+ __slots__ = ("_list",)
+
+ def _ordered_dictionary_sort(self, key=None):
+ _ordered_dictionary_sort(self, key=key)
+
+ def __reduce__(self):
+ return OrderedDict, (self.items(),)
- def update(self, ____sequence=None, **kwargs):
- if ____sequence is not None:
- if hasattr(____sequence, "keys"):
- for key in ____sequence.keys():
- self.__setitem__(key, ____sequence[key])
+ def __init__(self, ____sequence=None, **kwargs):
+ self._list = []
+ if ____sequence is None:
+ if kwargs:
+ self.update(**kwargs)
else:
- for key, value in ____sequence:
- self[key] = value
- if kwargs:
- self.update(kwargs)
+ self.update(____sequence, **kwargs)
- def setdefault(self, key, value):
- if key not in self:
- self.__setitem__(key, value)
- return value
- else:
- return self.__getitem__(key)
+ def clear(self):
+ self._list = []
+ dict.clear(self)
+
+ def copy(self):
+ return self.__copy__()
+
+ def __copy__(self):
+ return OrderedDict(self)
+
+ def update(self, ____sequence=None, **kwargs):
+ if ____sequence is not None:
+ if hasattr(____sequence, "keys"):
+ for key in ____sequence.keys():
+ self.__setitem__(key, ____sequence[key])
+ else:
+ for key, value in ____sequence:
+ self[key] = value
+ if kwargs:
+ self.update(kwargs)
- def __iter__(self):
- return iter(self._list)
+ def setdefault(self, key, value):
+ if key not in self:
+ self.__setitem__(key, value)
+ return value
+ else:
+ return self.__getitem__(key)
- def keys(self):
- return list(self)
+ def __iter__(self):
+ return iter(self._list)
- def values(self):
- return [self[key] for key in self._list]
+ def keys(self):
+ return list(self)
- def items(self):
- return [(key, self[key]) for key in self._list]
+ def values(self):
+ return [self[key] for key in self._list]
- if py2k:
+ def items(self):
+ return [(key, self[key]) for key in self._list]
- def itervalues(self):
- return iter(self.values())
+ if py2k:
- def iterkeys(self):
- return iter(self)
+ def itervalues(self):
+ return iter(self.values())
- def iteritems(self):
- return iter(self.items())
+ def iterkeys(self):
+ return iter(self)
- def __setitem__(self, key, obj):
- if key not in self:
- try:
- self._list.append(key)
- except AttributeError:
- # work around Python pickle loads() with
- # dict subclass (seems to ignore __setstate__?)
- self._list = [key]
- dict.__setitem__(self, key, obj)
+ def iteritems(self):
+ return iter(self.items())
- def __delitem__(self, key):
- dict.__delitem__(self, key)
- self._list.remove(key)
+ def __setitem__(self, key, obj):
+ if key not in self:
+ try:
+ self._list.append(key)
+ except AttributeError:
+ # work around Python pickle loads() with
+ # dict subclass (seems to ignore __setstate__?)
+ self._list = [key]
+ dict.__setitem__(self, key, obj)
- def pop(self, key, *default):
- present = key in self
- value = dict.pop(self, key, *default)
- if present:
+ def __delitem__(self, key):
+ dict.__delitem__(self, key)
self._list.remove(key)
- return value
- def popitem(self):
- item = dict.popitem(self)
- self._list.remove(item[0])
- return item
+ def pop(self, key, *default):
+ present = key in self
+ value = dict.pop(self, key, *default)
+ if present:
+ self._list.remove(key)
+ return value
+
+ def popitem(self):
+ item = dict.popitem(self)
+ self._list.remove(item[0])
+ return item
class OrderedSet(set):