diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index 9a753db71..002e0a6ee 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -1277,3 +1277,9 @@ class UserString(_collections_abc.Sequence): return self.__class__(self.data.translate(*args)) def upper(self): return self.__class__(self.data.upper()) def zfill(self, width): return self.__class__(self.data.zfill(width)) + +# FIXME: try to implement defaultdict in collections.rs rather than in Python +# I (coolreader18) couldn't figure out some class stuff with __new__ and +# __init__ and __missing__ and subclassing built-in types from Rust, so I went +# with this instead. +from ._defaultdict import * diff --git a/Lib/collections/_defaultdict.py b/Lib/collections/_defaultdict.py new file mode 100644 index 000000000..125a74c13 --- /dev/null +++ b/Lib/collections/_defaultdict.py @@ -0,0 +1,20 @@ +class defaultdict(dict): + def __new__(cls, *args, **kwargs): + if len(args) >= 1: + default_factory = args[0] + args = args[1:] + else: + default_factory = None + self = dict.__new__(cls, *args, **kwargs) + self.default_factory = default_factory + return self + + def __missing__(self, key): + if self.default_factory: + return self.default_factory() + else: + raise KeyError(key) + + def __repr__(self): + return f"defaultdict({self.default_factory}, {dict.__repr__(self)})" +