Skip to content

Commit 429d1d1

Browse files
authored
Merge pull request RustPython#4876 from Phosphorescentt/4845
Update collections from Python 3.11.2
2 parents 9d44f93 + 04749c1 commit 429d1d1

File tree

2 files changed

+75
-51
lines changed

2 files changed

+75
-51
lines changed

Lib/collections/__init__.py

Lines changed: 66 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -240,11 +240,19 @@ def pop(self, key, default=__marker):
240240
is raised.
241241
242242
'''
243-
if key in self:
244-
result = self[key]
245-
del self[key]
243+
marker = self.__marker
244+
result = dict.pop(self, key, marker)
245+
if result is not marker:
246+
# The same as in __delitem__().
247+
link = self.__map.pop(key)
248+
link_prev = link.prev
249+
link_next = link.next
250+
link_prev.next = link_next
251+
link_next.prev = link_prev
252+
link.prev = None
253+
link.next = None
246254
return result
247-
if default is self.__marker:
255+
if default is marker:
248256
raise KeyError(key)
249257
return default
250258

@@ -267,10 +275,22 @@ def __repr__(self):
267275

268276
def __reduce__(self):
269277
'Return state information for pickling'
270-
inst_dict = vars(self).copy()
271-
for k in vars(OrderedDict()):
272-
inst_dict.pop(k, None)
273-
return self.__class__, (), inst_dict or None, None, iter(self.items())
278+
state = self.__getstate__()
279+
if state:
280+
if isinstance(state, tuple):
281+
state, slots = state
282+
else:
283+
slots = {}
284+
state = state.copy()
285+
slots = slots.copy()
286+
for k in vars(OrderedDict()):
287+
state.pop(k, None)
288+
slots.pop(k, None)
289+
if slots:
290+
state = state, slots
291+
else:
292+
state = state or None
293+
return self.__class__, (), state, None, iter(self.items())
274294

275295
def copy(self):
276296
'od.copy() -> a shallow copy of od'
@@ -613,11 +633,9 @@ def elements(self):
613633
['A', 'A', 'B', 'B', 'C', 'C']
614634
615635
# Knuth's example for prime factors of 1836: 2**2 * 3**3 * 17**1
636+
>>> import math
616637
>>> prime_factors = Counter({2: 2, 3: 3, 17: 1})
617-
>>> product = 1
618-
>>> for factor in prime_factors.elements(): # loop over factors
619-
... product *= factor # and multiply them
620-
>>> product
638+
>>> math.prod(prime_factors.elements())
621639
1836
622640
623641
Note, if an element's count has been set to zero or is a negative
@@ -714,42 +732,6 @@ def __delitem__(self, elem):
714732
if elem in self:
715733
super().__delitem__(elem)
716734

717-
def __eq__(self, other):
718-
'True if all counts agree. Missing counts are treated as zero.'
719-
if not isinstance(other, Counter):
720-
return NotImplemented
721-
return all(self[e] == other[e] for c in (self, other) for e in c)
722-
723-
def __ne__(self, other):
724-
'True if any counts disagree. Missing counts are treated as zero.'
725-
if not isinstance(other, Counter):
726-
return NotImplemented
727-
return not self == other
728-
729-
def __le__(self, other):
730-
'True if all counts in self are a subset of those in other.'
731-
if not isinstance(other, Counter):
732-
return NotImplemented
733-
return all(self[e] <= other[e] for c in (self, other) for e in c)
734-
735-
def __lt__(self, other):
736-
'True if all counts in self are a proper subset of those in other.'
737-
if not isinstance(other, Counter):
738-
return NotImplemented
739-
return self <= other and self != other
740-
741-
def __ge__(self, other):
742-
'True if all counts in self are a superset of those in other.'
743-
if not isinstance(other, Counter):
744-
return NotImplemented
745-
return all(self[e] >= other[e] for c in (self, other) for e in c)
746-
747-
def __gt__(self, other):
748-
'True if all counts in self are a proper superset of those in other.'
749-
if not isinstance(other, Counter):
750-
return NotImplemented
751-
return self >= other and self != other
752-
753735
def __repr__(self):
754736
if not self:
755737
return f'{self.__class__.__name__}()'
@@ -795,6 +777,42 @@ def __repr__(self):
795777
# (cp >= cq) == (sp >= sq)
796778
# (cp > cq) == (sp > sq)
797779

780+
def __eq__(self, other):
781+
'True if all counts agree. Missing counts are treated as zero.'
782+
if not isinstance(other, Counter):
783+
return NotImplemented
784+
return all(self[e] == other[e] for c in (self, other) for e in c)
785+
786+
def __ne__(self, other):
787+
'True if any counts disagree. Missing counts are treated as zero.'
788+
if not isinstance(other, Counter):
789+
return NotImplemented
790+
return not self == other
791+
792+
def __le__(self, other):
793+
'True if all counts in self are a subset of those in other.'
794+
if not isinstance(other, Counter):
795+
return NotImplemented
796+
return all(self[e] <= other[e] for c in (self, other) for e in c)
797+
798+
def __lt__(self, other):
799+
'True if all counts in self are a proper subset of those in other.'
800+
if not isinstance(other, Counter):
801+
return NotImplemented
802+
return self <= other and self != other
803+
804+
def __ge__(self, other):
805+
'True if all counts in self are a superset of those in other.'
806+
if not isinstance(other, Counter):
807+
return NotImplemented
808+
return all(self[e] >= other[e] for c in (self, other) for e in c)
809+
810+
def __gt__(self, other):
811+
'True if all counts in self are a proper superset of those in other.'
812+
if not isinstance(other, Counter):
813+
return NotImplemented
814+
return self >= other and self != other
815+
798816
def __add__(self, other):
799817
'''Add counts from two counters.
800818

Lib/test/test_ordered_dict.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,8 @@ def test_equality(self):
281281
# different length implied inequality
282282
self.assertNotEqual(od1, OrderedDict(pairs[:-1]))
283283

284+
# TODO: RUSTPYTHON
285+
@unittest.expectedFailure
284286
def test_copying(self):
285287
OrderedDict = self.OrderedDict
286288
# Check that ordered dicts are copyable, deepcopyable, picklable,
@@ -324,6 +326,8 @@ def check(dup):
324326
check(update_test)
325327
check(OrderedDict(od))
326328

329+
@unittest.expectedFailure
330+
# TODO: RUSTPYTHON
327331
def test_yaml_linkage(self):
328332
OrderedDict = self.OrderedDict
329333
# Verify that __reduce__ is setup in a way that supports PyYAML's dump() feature.
@@ -334,6 +338,8 @@ def test_yaml_linkage(self):
334338
# '!!python/object/apply:__main__.OrderedDict\n- - [a, 1]\n - [b, 2]\n'
335339
self.assertTrue(all(type(pair)==list for pair in od.__reduce__()[1]))
336340

341+
# TODO: RUSTPYTHON
342+
@unittest.expectedFailure
337343
def test_reduce_not_too_fat(self):
338344
OrderedDict = self.OrderedDict
339345
# do not save instance dictionary if not needed
@@ -345,6 +351,8 @@ def test_reduce_not_too_fat(self):
345351
self.assertEqual(od.__dict__['x'], 10)
346352
self.assertEqual(od.__reduce__()[2], {'x': 10})
347353

354+
# TODO: RUSTPYTHON
355+
@unittest.expectedFailure
348356
def test_pickle_recursive(self):
349357
OrderedDict = self.OrderedDict
350358
od = OrderedDict()
@@ -983,8 +991,6 @@ def test_popitem(self):
983991
self.assertEqual(c.popitem(last=True), (3, 3))
984992
self.assertEqual(c.counts, {'get': 0, 'set': 3, 'del': 0})
985993

986-
# TODO: RUSTPYTHON
987-
@unittest.expectedFailure
988994
def test_pop(self):
989995
c = self.type2test(3)
990996
for i in range(1, 4):
@@ -1013,7 +1019,7 @@ class PySimpleLRUCacheTests(SimpleLRUCacheTests, unittest.TestCase):
10131019
class type2test(SimpleLRUCache, py_coll.OrderedDict):
10141020
pass
10151021

1016-
@unittest.skip("TODO: RUSTPYTHON")
1022+
10171023
@unittest.skipUnless(c_coll, 'requires the C version of the collections module')
10181024
class CSimpleLRUCacheTests(SimpleLRUCacheTests, unittest.TestCase):
10191025

0 commit comments

Comments
 (0)