diff --git a/pottery/counter.py b/pottery/counter.py index d58aa03e..27ffae79 100644 --- a/pottery/counter.py +++ b/pottery/counter.py @@ -57,23 +57,31 @@ def _populate(self, # type: ignore sign: int = +1, **kwargs: int, ) -> None: - to_set = {} + dict_ = {} try: - for key, value in cast(Counter[JSONTypes], arg).items(): - to_set[key] = sign * value + items = cast(Counter[JSONTypes], arg).items() + for key, value in items: + dict_[key] = sign * value except AttributeError: for key in arg: - to_set[key] = to_set.get(key, self[key]) + sign + value = dict_.get(key, self[key]) + dict_[key] = value + sign + for key, value in kwargs.items(): - original = self[key] if to_set.get(key, 0) == 0 else to_set[key] - to_set[key] = original + sign * value - to_set = {key: self[key] + value for key, value in to_set.items()} - encoded_to_set = { - self._encode(k): self._encode(v) for k, v in to_set.items() + if dict_.get(key, 0) == 0: + original = self[key] + else: + original = dict_[key] + dict_[key] = original + sign * value + + dict_ = {key: self[key] + value for key, value in dict_.items()} + encoded_dict = { + self._encode(key): self._encode(value) + for key, value in dict_.items() } - if encoded_to_set: + if encoded_dict: pipeline.multi() - pipeline.hset(self.key, mapping=encoded_to_set) # type: ignore + pipeline.hset(self.key, mapping=encoded_dict) # type: ignore # Preserve the Open-Closed Principle with name mangling. # https://youtu.be/miGolgp9xq8?t=2086 @@ -105,7 +113,7 @@ def __delitem__(self, key: JSONTypes) -> None: def __repr__(self) -> str: 'Return the string representation of the RedisCounter. O(n)' - items = self.most_common() + items = self.__most_common() pairs = (f"'{key}': {value}" for key, value in items) repr_ = ', '.join(pairs) return self.__class__.__name__ + '{' + repr_ + '}' @@ -224,16 +232,15 @@ def __iset_op(self, to_del.add(k) if to_set or to_del: pipeline.multi() - if to_set: - encoded_to_set = { - self._encode(k): self._encode(v) - for k, v in to_set.items() - } - pipeline.hset(self.key, mapping=encoded_to_set) # type: ignore - if to_del: - encoded_to_del = {self._encode(k) for k in to_del} - pipeline.hdel(self.key, *encoded_to_del) - return self + if to_set: + encoded_to_set = { + self._encode(k): self._encode(v) for k, v in to_set.items() + } + pipeline.hset(self.key, mapping=encoded_to_set) # type: ignore + if to_del: + encoded_to_del = {self._encode(k) for k in to_del} + pipeline.hdel(self.key, *encoded_to_del) + return self def __ior__(self, other: Counter[JSONTypes]) -> Counter[JSONTypes]: # type: ignore 'Same as __or__(), but in-place. O(n)' @@ -248,3 +255,5 @@ def most_common(self, ) -> List[Tuple[JSONTypes, int]]: counter = self.__to_counter() return counter.most_common(n=n) + + __most_common = most_common diff --git a/pottery/dict.py b/pottery/dict.py index 4899d44b..260f2ee9 100644 --- a/pottery/dict.py +++ b/pottery/dict.py @@ -71,12 +71,12 @@ def _populate(self, ) -> None: with contextlib.suppress(AttributeError): arg = cast(InitMap, arg).items() - decoded_items = itertools.chain(cast(InitIter, arg), kwargs.items()) + items = itertools.chain(cast(InitIter, arg), kwargs.items()) encoded_dict = {} - for decoded_key, decoded_value in decoded_items: - encoded_key = self._encode(decoded_key) - encoded_value = self._encode(decoded_value) + for key, value in items: + encoded_key = self._encode(key) + encoded_value = self._encode(value) encoded_dict[encoded_key] = encoded_value if encoded_dict: