Skip to content

Commit 9d787cf

Browse files
committed
-
1 parent 2102d7d commit 9d787cf

File tree

6 files changed

+92
-5
lines changed

6 files changed

+92
-5
lines changed

source_py2/python_toolbox/nifty_collections/bagging.py

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

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

986990

987991
class FrozenBag(_BaseBagMixin, _FrozenBagMixin, FrozenDict):
@@ -1047,6 +1051,14 @@ class FrozenOrderedBag(_OrderedBagMixin, _FrozenBagMixin, _BaseBagMixin,
10471051
def __hash__(self):
10481052
return hash((type(self), tuple(self.items())))
10491053

1054+
@_BootstrappedCachedProperty
1055+
def reversed(self):
1056+
'''
1057+
Get a version of this `FrozenOrderedBag` with key order reversed.
1058+
'''
1059+
return type(self)(self._dict_type(reversed(tuple(self.items()))))
1060+
1061+
10501062

10511063
Bag._frozen_type = FrozenBag
10521064
OrderedBag._frozen_type = FrozenOrderedBag

source_py2/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_py2/python_toolbox/nifty_collections/ordered_dict.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,8 @@ def index(self, key):
6161
if key_ == key:
6262
return i
6363
raise RuntimeError
64+
65+
@property
66+
def reversed(self):
67+
'''Get a version of this `OrderedDict` with key order reversed.'''
68+
return type(self)(reversed(tuple(self.items())))

source_py2/test_python_toolbox/test_nifty_collections/test_bagging.py

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

684684
class BaseOrderedBagTestCase(BaseBagTestCase):
685685

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

699-
def test_reversed(self):
721+
722+
def test_builtin_reversed(self):
700723
bag = self.bag_type('abracadabra')
701724
assert tuple(reversed(bag)) == tuple(reversed(tuple(bag)))
702725

726+
703727
def test_index(self):
704728
bag = self.bag_type('aaabbc')
705729
if not isinstance(bag, collections.Hashable):
@@ -718,6 +742,12 @@ def test_index(self):
718742

719743
class BaseUnorderedBagTestCase(BaseBagTestCase):
720744

745+
def test_reversed(self):
746+
bag = self.bag_type('mississippi')
747+
with cute_testing.RaiseAssertor(AttributeError):
748+
bag.reversed
749+
750+
721751
def test_ordering(self):
722752
bag_0 = self.bag_type('ababb')
723753
bag_1 = self.bag_type('bbbaa')
@@ -726,7 +756,7 @@ def test_ordering(self):
726756
assert hash(bag_0) == hash(bag_1)
727757

728758

729-
def test_reversed(self):
759+
def test_builtin_reversed(self):
730760
bag = self.bag_type('abracadabra')
731761
with cute_testing.RaiseAssertor(TypeError):
732762
reversed(bag)

source_py2/test_python_toolbox/test_nifty_collections/test_frozen_ordered_dict.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,28 @@ 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+
def test_reversed():
44+
45+
frozen_ordered_dict = \
46+
FrozenOrderedDict((('1', 'a'), ('2', 'b'), ('3', 'c')))
47+
48+
assert frozen_ordered_dict.reversed == \
49+
FrozenOrderedDict((('3', 'c'), ('2', 'b'), ('1', 'a')))
50+
51+
assert frozen_ordered_dict.reversed is frozen_ordered_dict.reversed
52+
assert frozen_ordered_dict.reversed == frozen_ordered_dict.reversed
53+
assert frozen_ordered_dict.reversed.reversed is \
54+
frozen_ordered_dict.reversed.reversed
55+
assert frozen_ordered_dict.reversed.reversed == \
56+
frozen_ordered_dict.reversed.reversed
57+
assert frozen_ordered_dict.reversed.reversed == frozen_ordered_dict
58+
assert frozen_ordered_dict.reversed.reversed.reversed == \
59+
frozen_ordered_dict.reversed
60+
61+
assert set(frozen_ordered_dict.items()) == \
62+
set(frozen_ordered_dict.reversed.items())
63+
assert tuple(frozen_ordered_dict.items()) == \
64+
tuple(reversed(tuple(frozen_ordered_dict.reversed.items())))
65+
assert type(frozen_ordered_dict.reversed) is type(frozen_ordered_dict) \
66+
is FrozenOrderedDict

source_py2/test_python_toolbox/test_nifty_collections/test_ordered_dict/test.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,12 @@ 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+
def test_reversed():
76+
ordered_dict = OrderedDict(((1, 'a'), (2, 'b'), (3, 'c')))
77+
assert ordered_dict.reversed == OrderedDict(((3, 'c'), (2, 'b'), (1, 'a')))
78+
assert type(ordered_dict.reversed) is type(ordered_dict) is OrderedDict

0 commit comments

Comments
 (0)