diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index 3d3bbd7a3..803de0c67 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -57,8 +57,7 @@ except ImportError: try: from _collections import defaultdict except ImportError: - # TODO: RUSTPYTHON - implement defaultdict in Rust - from ._defaultdict import defaultdict + pass heapq = None # Lazily imported diff --git a/Lib/collections/_defaultdict.py b/Lib/collections/_defaultdict.py deleted file mode 100644 index b9c6c4961..000000000 --- a/Lib/collections/_defaultdict.py +++ /dev/null @@ -1,58 +0,0 @@ -from reprlib import recursive_repr as _recursive_repr - -class defaultdict(dict): - def __init__(self, *args, **kwargs): - if len(args) >= 1: - default_factory = args[0] - if default_factory is not None and not callable(default_factory): - raise TypeError("first argument must be callable or None") - args = args[1:] - else: - default_factory = None - super().__init__(*args, **kwargs) - self.default_factory = default_factory - - def __missing__(self, key): - if self.default_factory is not None: - val = self.default_factory() - else: - raise KeyError(key) - self[key] = val - return val - - @_recursive_repr() - def __repr_factory(factory): - return repr(factory) - - def __repr__(self): - return f"{type(self).__name__}({defaultdict.__repr_factory(self.default_factory)}, {dict.__repr__(self)})" - - def copy(self): - return type(self)(self.default_factory, self) - - __copy__ = copy - - def __reduce__(self): - if self.default_factory is not None: - args = self.default_factory, - else: - args = () - return type(self), args, None, None, iter(self.items()) - - def __or__(self, other): - if not isinstance(other, dict): - return NotImplemented - - new = defaultdict(self.default_factory, self) - new.update(other) - return new - - def __ror__(self, other): - if not isinstance(other, dict): - return NotImplemented - - new = defaultdict(self.default_factory, other) - new.update(self) - return new - -defaultdict.__module__ = 'collections' diff --git a/Lib/test/mapping_tests.py b/Lib/test/mapping_tests.py index 53f29f605..20306e152 100644 --- a/Lib/test/mapping_tests.py +++ b/Lib/test/mapping_tests.py @@ -1,7 +1,7 @@ # tests common to dict and UserDict import unittest import collections -import sys +from test import support class BasicTestMappingProtocol(unittest.TestCase): @@ -70,8 +70,8 @@ class BasicTestMappingProtocol(unittest.TestCase): if not d: self.fail("Full mapping must compare to True") # keys(), items(), iterkeys() ... def check_iterandlist(iter, lst, ref): - self.assertTrue(hasattr(iter, '__next__')) - self.assertTrue(hasattr(iter, '__iter__')) + self.assertHasAttr(iter, '__next__') + self.assertHasAttr(iter, '__iter__') x = list(iter) self.assertTrue(set(x)==set(lst)==set(ref)) check_iterandlist(iter(d.keys()), list(d.keys()), @@ -448,7 +448,7 @@ class TestMappingProtocol(BasicTestMappingProtocol): class Exc(Exception): pass class baddict1(self.type2test): - def __init__(self): + def __init__(self, *args, **kwargs): raise Exc() self.assertRaises(Exc, baddict1.fromkeys, [1]) @@ -595,12 +595,14 @@ class TestHashMappingProtocol(TestMappingProtocol): d = self._empty_mapping() d[1] = 1 try: + count = 0 for i in d: d[i+1] = 1 + if count >= 1: + self.fail("changing dict size during iteration doesn't raise Error") + count += 1 except RuntimeError: pass - else: - self.fail("changing dict size during iteration doesn't raise Error") def test_repr(self): d = self._empty_mapping() @@ -620,9 +622,12 @@ class TestHashMappingProtocol(TestMappingProtocol): d = self._full_mapping({1: BadRepr()}) self.assertRaises(Exc, repr, d) + @support.skip_wasi_stack_overflow() + @support.skip_emscripten_stack_overflow() + @support.skip_if_sanitizer("requires deep stack", ub=True) def test_repr_deep(self): d = self._empty_mapping() - for i in range(sys.getrecursionlimit() + 100): + for i in range(support.exceeds_recursion_limit()): d0 = d d = self._empty_mapping() d[1] = d0