Skip to content

Commit 2102d7d

Browse files
committed
-
1 parent aeba9a1 commit 2102d7d

File tree

6 files changed

+95
-6
lines changed

6 files changed

+95
-6
lines changed

source_py3/python_toolbox/nifty_collections/bagging.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,10 @@ def popitem(self, last=True):
980980
doc='Sort the keys in this bag. (With optional `key` function.)'
981981
)
982982

983+
@property
984+
def reversed(self):
985+
'''Get a version of this `OrderedBag` with key order reversed.'''
986+
return type(self)(self._dict_type(reversed(tuple(self.items()))))
983987

984988

985989
class FrozenBag(_BaseBagMixin, _FrozenBagMixin, FrozenDict):
@@ -1044,6 +1048,14 @@ class FrozenOrderedBag(_OrderedBagMixin, _FrozenBagMixin, _BaseBagMixin,
10441048
'''
10451049
def __hash__(self):
10461050
return hash((type(self), tuple(self.items())))
1051+
1052+
@_BootstrappedCachedProperty
1053+
def reversed(self):
1054+
'''
1055+
Get a version of this `FrozenOrderedBag` with key order reversed.
1056+
'''
1057+
return type(self)(self._dict_type(reversed(tuple(self.items()))))
1058+
10471059

10481060

10491061
Bag._frozen_type = FrozenBag

source_py3/python_toolbox/nifty_collections/frozen_dict_and_frozen_ordered_dict.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,15 @@ def __eq__(self, other):
7979
# (Gotta manually carry `__hash__` over from the base class because setting
8080
# `__eq__` resets it. )
8181

82+
83+
# Poor man's caching because we can't import `CachedProperty` due to import
84+
# loop:
85+
_reversed = None
86+
@property
87+
def reversed(self):
88+
'''
89+
Get a version of this `FrozenOrderedDict` with key order reversed.
90+
'''
91+
if self._reversed is None:
92+
self._reversed = type(self)(reversed(tuple(self.items())))
93+
return self._reversed

source_py3/python_toolbox/nifty_collections/ordered_dict.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,9 @@ def index(self, key):
3535
for i, key_ in enumerate(self):
3636
if key_ == key:
3737
return i
38-
raise RuntimeError
38+
raise RuntimeError
39+
40+
@property
41+
def reversed(self):
42+
'''Get a version of this `OrderedDict` with key order reversed.'''
43+
return type(self)(reversed(tuple(self.items())))

source_py3/test_python_toolbox/test_nifty_collections/test_bagging.py

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,28 @@ def test_clear(self):
682682

683683
class BaseOrderedBagTestCase(BaseBagTestCase):
684684

685+
def test_reversed(self):
686+
bag = self.bag_type('mississippi')
687+
688+
# Cached only for a frozen type:
689+
assert (bag.reversed is bag.reversed) == \
690+
(bag.reversed.reversed is bag.reversed.reversed) == \
691+
isinstance(bag, collections.Hashable)
692+
693+
assert bag.reversed == bag.reversed
694+
assert bag.reversed.reversed == bag.reversed.reversed
695+
696+
assert Bag(bag) == Bag(bag.reversed)
697+
assert OrderedBag(bag) != OrderedBag(bag.reversed)
698+
699+
assert Bag(bag.elements) == Bag(bag.reversed.elements)
700+
assert OrderedBag(bag.elements) != OrderedBag(bag.reversed.elements)
701+
assert OrderedBag(bag.elements) == \
702+
OrderedBag(reversed(tuple(bag.reversed.elements)))
703+
704+
assert set(bag.keys()) == set(bag.reversed.keys())
705+
assert tuple(bag.keys()) == tuple(reversed(tuple(bag.reversed.keys())))
706+
685707
def test_ordering(self):
686708
ordered_bag_0 = self.bag_type('ababb')
687709
ordered_bag_1 = self.bag_type('bbbaa')
@@ -694,10 +716,12 @@ def test_ordering(self):
694716
assert ordered_bag_0 != ordered_bag_1
695717
assert ordered_bag_0 <= ordered_bag_1
696718
assert ordered_bag_0 >= ordered_bag_1
719+
697720

698-
def test_reversed(self):
721+
def test_builtin_reversed(self):
699722
bag = self.bag_type('abracadabra')
700723
assert tuple(reversed(bag)) == tuple(reversed(tuple(bag)))
724+
701725

702726
def test_index(self):
703727
bag = self.bag_type('aaabbc')
@@ -717,6 +741,12 @@ def test_index(self):
717741

718742
class BaseUnorderedBagTestCase(BaseBagTestCase):
719743

744+
def test_reversed(self):
745+
bag = self.bag_type('mississippi')
746+
with cute_testing.RaiseAssertor(AttributeError):
747+
bag.reversed
748+
749+
720750
def test_ordering(self):
721751
bag_0 = self.bag_type('ababb')
722752
bag_1 = self.bag_type('bbbaa')
@@ -725,7 +755,7 @@ def test_ordering(self):
725755
assert hash(bag_0) == hash(bag_1)
726756

727757

728-
def test_reversed(self):
758+
def test_builtin_reversed(self):
729759
bag = self.bag_type('abracadabra')
730760
with cute_testing.RaiseAssertor(TypeError):
731761
reversed(bag)

source_py3/test_python_toolbox/test_nifty_collections/test_frozen_ordered_dict.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,29 @@ def test():
3939
assert repr(frozen_ordered_dict).startswith('FrozenOrderedDict(')
4040

4141
assert pickle.loads(pickle.dumps(frozen_ordered_dict)) == \
42-
frozen_ordered_dict
42+
frozen_ordered_dict
43+
44+
def test_reversed():
45+
46+
frozen_ordered_dict = \
47+
FrozenOrderedDict((('1', 'a'), ('2', 'b'), ('3', 'c')))
48+
49+
assert frozen_ordered_dict.reversed == \
50+
FrozenOrderedDict((('3', 'c'), ('2', 'b'), ('1', 'a')))
51+
52+
assert frozen_ordered_dict.reversed is frozen_ordered_dict.reversed
53+
assert frozen_ordered_dict.reversed == frozen_ordered_dict.reversed
54+
assert frozen_ordered_dict.reversed.reversed is \
55+
frozen_ordered_dict.reversed.reversed
56+
assert frozen_ordered_dict.reversed.reversed == \
57+
frozen_ordered_dict.reversed.reversed
58+
assert frozen_ordered_dict.reversed.reversed == frozen_ordered_dict
59+
assert frozen_ordered_dict.reversed.reversed.reversed == \
60+
frozen_ordered_dict.reversed
61+
62+
assert set(frozen_ordered_dict.items()) == \
63+
set(frozen_ordered_dict.reversed.items())
64+
assert tuple(frozen_ordered_dict.items()) == \
65+
tuple(reversed(tuple(frozen_ordered_dict.reversed.items())))
66+
assert type(frozen_ordered_dict.reversed) is type(frozen_ordered_dict) \
67+
is FrozenOrderedDict

source_py3/test_python_toolbox/test_nifty_collections/test_ordered_dict/test.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,13 @@ def test_index():
6767
ordered_dict.index('Non-existing key')
6868

6969

70-
def test_reversed():
70+
def test_builtin_reversed():
7171
'''Test the `OrderedDict.__reversed__` method.'''
7272

7373
ordered_dict = OrderedDict(((1, 'a'), (2, 'b'), (3, 'c')))
74-
assert list(reversed(ordered_dict)) == [3, 2, 1]
74+
assert list(reversed(ordered_dict)) == [3, 2, 1]
75+
76+
def test_reversed():
77+
ordered_dict = OrderedDict(((1, 'a'), (2, 'b'), (3, 'c')))
78+
assert ordered_dict.reversed == OrderedDict(((3, 'c'), (2, 'b'), (1, 'a')))
79+
assert type(ordered_dict.reversed) is type(ordered_dict) is OrderedDict

0 commit comments

Comments
 (0)