summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/util/_collections.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/util/_collections.py')
-rw-r--r--lib/sqlalchemy/util/_collections.py66
1 files changed, 58 insertions, 8 deletions
diff --git a/lib/sqlalchemy/util/_collections.py b/lib/sqlalchemy/util/_collections.py
index c29b81f6a..ffd3107fa 100644
--- a/lib/sqlalchemy/util/_collections.py
+++ b/lib/sqlalchemy/util/_collections.py
@@ -98,16 +98,42 @@ class KeyedTuple(AbstractKeyedTuple):
def __setattr__(self, key, value):
raise AttributeError("Can't set attribute: %s" % key)
- def _asdict(self):
+ def _asdict(self, impl=dict, recursive=False):
"""Return the contents of this :class:`.KeyedTuple` as a dictionary.
This method provides compatibility with ``collections.namedtuple()``,
- with the exception that the dictionary returned is **not** ordered.
+ with the exception that the dictionary returned is **not** ordered by
+ default.
+
+ :param impl:
+ The implementation to use. Defaults to :class:`dict`.
+
+ :param recursive:
+ Recursively call :meth:`._asdict` on values found that inherit from
+ AbstractKeyedTuple. Defaults to False.
+
.. versionadded:: 0.8
"""
- return dict((key, self.__dict__[key]) for key in self.keys())
+
+ if recursive:
+ return impl(
+ (
+ key,
+ (
+ self.__dict__[key]._asdict(
+ impl=impl,
+ recursive=recursive
+ )
+ if isinstance(self.__dict__[key], AbstractKeyedTuple)
+ else self.__dict__[key]
+ )
+ )
+ for key in self.keys()
+ )
+ else:
+ return impl((key, self.__dict__[key]) for key in self.keys())
class _LW(AbstractKeyedTuple):
@@ -122,10 +148,34 @@ class _LW(AbstractKeyedTuple):
# difficulties
return KeyedTuple, (list(self), self._real_fields)
- def _asdict(self):
- """Return the contents of this :class:`.KeyedTuple` as a dictionary."""
+ def _asdict(self, impl=dict, recursive=False):
+ """Return the contents of this :class:`.KeyedTuple` as a dictionary.
- d = dict(zip(self._real_fields, self))
+ :param impl:
+ The implementation to use. Defaults to :class:`dict`.
+
+ :param recursive:
+ Recursively call :meth:`._asdict` on values found that inherit from
+ AbstractKeyedTuple. Defaults to False.
+
+ """
+
+ if recursive:
+ d = impl(
+ zip(
+ self._real_fields,
+ (
+ (
+ v._asdict(impl=impl, recursive=recursive)
+ if isinstance(v, AbstractKeyedTuple)
+ else v
+ )
+ for v in self
+ )
+ )
+ )
+ else:
+ d = impl(zip(self._real_fields, self))
d.pop(None, None)
return d
@@ -931,7 +981,7 @@ class LRUCache(dict):
_lw_tuples = LRUCache(100)
-def lightweight_named_tuple(name, fields):
+def lightweight_named_tuple(name, fields, **kw):
hash_ = (name, ) + tuple(fields)
tp_cls = _lw_tuples.get(hash_)
if tp_cls:
@@ -942,7 +992,7 @@ def lightweight_named_tuple(name, fields):
dict([
(field, _property_getters[idx])
for idx, field in enumerate(fields) if field is not None
- ] + [('__slots__', ())])
+ ] + [('__slots__', ())], **kw)
)
tp_cls._real_fields = fields