Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-immutabledict for
openSUSE:Factory checked in at 2023-12-08 22:32:08
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-immutabledict (Old)
and /work/SRC/openSUSE:Factory/.python-immutabledict.new.25432 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-immutabledict"
Fri Dec 8 22:32:08 2023 rev:4 rq:1131733 version:4.0.0
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-immutabledict/python-immutabledict.changes
2023-08-10 15:35:03.544597330 +0200
+++
/work/SRC/openSUSE:Factory/.python-immutabledict.new.25432/python-immutabledict.changes
2023-12-08 22:32:39.381330942 +0100
@@ -1,0 +2,10 @@
+Thu Dec 7 22:34:25 UTC 2023 - Dirk Müller <[email protected]>
+
+- update to 4.0.0:
+ * Replace `__init__` by `__new__`.
+ * Add explicit items()/keys()/values() methods to speedup these
+ methods.
+ * Add set/delete/update functions.
+ * Add documentation at immutabledict.corenting.fr
+
+-------------------------------------------------------------------
Old:
----
immutabledict-3.0.0.tar.gz
New:
----
immutabledict-4.0.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-immutabledict.spec ++++++
--- /var/tmp/diff_new_pack.poZ2ye/_old 2023-12-08 22:32:39.861348604 +0100
+++ /var/tmp/diff_new_pack.poZ2ye/_new 2023-12-08 22:32:39.865348752 +0100
@@ -27,7 +27,7 @@
%define short_name immutabledict
%{?sle15_python_module_pythons}
Name: python-%{short_name}%{psuffix}
-Version: 3.0.0
+Version: 4.0.0
Release: 0
Summary: Immutable wrapper around dictionaries (a fork of frozendict)
License: MIT
++++++ immutabledict-3.0.0.tar.gz -> immutabledict-4.0.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/immutabledict-3.0.0/PKG-INFO
new/immutabledict-4.0.0/PKG-INFO
--- old/immutabledict-3.0.0/PKG-INFO 1970-01-01 01:00:00.000000000 +0100
+++ new/immutabledict-4.0.0/PKG-INFO 1970-01-01 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: immutabledict
-Version: 3.0.0
+Version: 4.0.0
Summary: Immutable wrapper around dictionaries (a fork of frozendict)
Home-page: https://github.com/corenting/immutabledict
License: MIT
@@ -15,9 +15,12 @@
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Project-URL: Bug Tracker, https://github.com/corenting/immutabledict/issues
Project-URL: Changelog,
https://github.com/corenting/immutabledict/blob/master/CHANGELOG.md
+Project-URL: Documentation, https://immutabledict.corenting.fr
+Project-URL: Donation, https://corenting.fr/donate
Project-URL: Repository, https://github.com/corenting/immutabledict
Description-Content-Type: text/markdown
@@ -27,15 +30,13 @@




-A fork of the original
[frozendict](https://github.com/slezica/python-frozendict), an immutable
wrapper around dictionaries.
-This library is a pure Python, MIT-licensed alternative to the new LGPL-3.0
licensed [frozendict](https://github.com/Marco-Sulla/python-frozendict).
+An immutable wrapper around dictionaries. immutabledict implements the
complete mapping interface and can be used as a drop-in replacement for
dictionaries where immutability is desired.
-It implements the complete mapping interface and can be used as a drop-in
replacement for dictionaries where immutability is desired.
-The immutabledict constructor mimics dict, and all of the expected interfaces
(iter, len, repr, hash, getitem) are provided. Note that an immutabledict does
not guarantee the immutability of its values, so the utility of hash method is
restricted by usage.
+It's a fork of slezica's
[frozendict](https://github.com/slezica/python-frozendict). This library is a
pure Python, MIT-licensed alternative to the new LGPL-3.0 licensed
[frozendict](https://github.com/Marco-Sulla/python-frozendict).
## Installation
-Official release in [on pypy](https://pypi.org/project/immutabledict/) as
`immutabledict`.
+Official release in [on pypi](https://pypi.org/project/immutabledict/) as
`immutabledict`.
**Community-maintained** releases are available:
- On [conda-forge](https://anaconda.org/conda-forge/immutabledict) as
`immutabledict`
@@ -58,3 +59,7 @@
- [PEP 584 union operators](https://www.python.org/dev/peps/pep-0584/)
- Keep the same signature for `copy()` as `dict` (starting with immutabledict
3.0.0), don't accept extra keyword arguments.
+## Donations
+
+If you wish to support the app, donations are possible
[here](https://corenting.fr/donate).
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/immutabledict-3.0.0/README.md
new/immutabledict-4.0.0/README.md
--- old/immutabledict-3.0.0/README.md 2023-07-21 20:13:55.780401200 +0200
+++ new/immutabledict-4.0.0/README.md 2023-11-25 13:34:07.496336700 +0100
@@ -4,15 +4,13 @@




-A fork of the original
[frozendict](https://github.com/slezica/python-frozendict), an immutable
wrapper around dictionaries.
-This library is a pure Python, MIT-licensed alternative to the new LGPL-3.0
licensed [frozendict](https://github.com/Marco-Sulla/python-frozendict).
+An immutable wrapper around dictionaries. immutabledict implements the
complete mapping interface and can be used as a drop-in replacement for
dictionaries where immutability is desired.
-It implements the complete mapping interface and can be used as a drop-in
replacement for dictionaries where immutability is desired.
-The immutabledict constructor mimics dict, and all of the expected interfaces
(iter, len, repr, hash, getitem) are provided. Note that an immutabledict does
not guarantee the immutability of its values, so the utility of hash method is
restricted by usage.
+It's a fork of slezica's
[frozendict](https://github.com/slezica/python-frozendict). This library is a
pure Python, MIT-licensed alternative to the new LGPL-3.0 licensed
[frozendict](https://github.com/Marco-Sulla/python-frozendict).
## Installation
-Official release in [on pypy](https://pypi.org/project/immutabledict/) as
`immutabledict`.
+Official release in [on pypi](https://pypi.org/project/immutabledict/) as
`immutabledict`.
**Community-maintained** releases are available:
- On [conda-forge](https://anaconda.org/conda-forge/immutabledict) as
`immutabledict`
@@ -34,3 +32,7 @@
- Typing
- [PEP 584 union operators](https://www.python.org/dev/peps/pep-0584/)
- Keep the same signature for `copy()` as `dict` (starting with immutabledict
3.0.0), don't accept extra keyword arguments.
+
+## Donations
+
+If you wish to support the app, donations are possible
[here](https://corenting.fr/donate).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/immutabledict-3.0.0/immutabledict/__init__.py
new/immutabledict-4.0.0/immutabledict/__init__.py
--- old/immutabledict-3.0.0/immutabledict/__init__.py 2023-07-21
20:13:55.780401200 +0200
+++ new/immutabledict-4.0.0/immutabledict/__init__.py 2023-11-25
13:34:07.496336700 +0100
@@ -1,33 +1,49 @@
+"""Implementation of the :class:`immutabledict` and
:class:`ImmutableOrderedDict` classes."""
from __future__ import annotations
from collections import OrderedDict
-from typing import Any, Dict, Iterable, Iterator, Mapping, Optional, Type,
TypeVar
+from typing import (
+ Any,
+ Dict,
+ ItemsView,
+ Iterable,
+ Iterator,
+ KeysView,
+ Mapping,
+ Optional,
+ Type,
+ TypeVar,
+ ValuesView,
+)
-__version__ = "3.0.0"
+__version__ = "4.0.0"
_K = TypeVar("_K")
_V = TypeVar("_V", covariant=True)
-class immutabledict(Mapping[_K, _V]):
+class immutabledict(Mapping[_K, _V]): # noqa: N801
"""
- An immutable wrapper around dictionaries that implements
- the complete :py:class:`collections.Mapping` interface.
- It can be used as a drop-in replacement for dictionaries
- where immutability is desired.
+ An immutable wrapper around dictionaries that implements the complete
:py:class:`collections.Mapping` interface.
+
+ It can be used as a drop-in replacement for dictionaries where
immutability is desired.
"""
- dict_cls: Type[Dict[Any, Any]] = dict
+ _dict_cls: Type[Dict[Any, Any]] = dict
+ _dict: Dict[_K, _V]
+ _hash: Optional[int]
@classmethod
- def fromkeys(
+ def fromkeys( # noqa: D102
cls, seq: Iterable[_K], value: Optional[_V] = None
) -> immutabledict[_K, _V]:
- return cls(cls.dict_cls.fromkeys(seq, value))
+ return cls(cls._dict_cls.fromkeys(seq, value))
- def __init__(self, *args: Any, **kwargs: Any) -> None:
- self._dict = self.dict_cls(*args, **kwargs)
- self._hash: Optional[int] = None
+ def __new__(cls, *args: Any, **kwargs: Any) -> immutabledict[_K, _V]: #
noqa: D102
+ inst = super().__new__(cls)
+ setattr(inst, "_dict", cls._dict_cls(*args, **kwargs))
+ setattr(inst, "_hash", None)
+ return inst
def __getitem__(self, key: _K) -> _V:
return self._dict[key]
@@ -35,7 +51,7 @@
def __contains__(self, key: object) -> bool:
return key in self._dict
- def copy(self) -> immutabledict[_K, _V]:
+ def copy(self) -> immutabledict[_K, _V]: # noqa: D102
return self.__class__(self)
def __iter__(self) -> Iterator[_K]:
@@ -45,7 +61,7 @@
return len(self._dict)
def __repr__(self) -> str:
- return "{}({!r})".format(self.__class__.__name__, self._dict)
+ return f"{self.__class__.__name__}({self._dict!r})"
def __hash__(self) -> int:
if self._hash is None:
@@ -73,10 +89,58 @@
def __ior__(self, other: Any) -> immutabledict[_K, _V]:
raise TypeError(f"'{self.__class__.__name__}' object is not mutable")
+ def items(self) -> ItemsView[_K, _V]: # noqa: D102
+ return self._dict.items()
+
+ def keys(self) -> KeysView[_K]: # noqa: D102
+ return self._dict.keys()
+
+ def values(self) -> ValuesView[_V]: # noqa: D102
+ return self._dict.values()
+
+ def set(self, key: _K, value: Any) -> immutabledict[_K, _V]:
+ """
+ Return a new :class:`immutabledict` where the item at the given key is
set to to the given value. If there is already an item at the given key it will
be replaced.
+
+ :param key: the key for which we want to set a value
+ :param value: the value we want to use
+
+ :return: the new :class:`immutabledict` with the key set to the given
value
+ """
+ new = dict(self._dict)
+ new[key] = value
+ return self.__class__(new)
+
+ def delete(self, key: _K) -> immutabledict[_K, _V]:
+ """
+ Return a new :class:`immutabledict` without the item at the given key.
+
+ :param key: the key of the item you want to remove in the returned
:class:`immutabledict`
+
+ :raises [KeyError]: a KeyError is raised if there is no item at the
given key
+
+ :return: the new :class:`immutabledict` without the item at the given
key
+ """
+ new = dict(self._dict)
+ del new[key]
+ return self.__class__(new)
+
+ def update(self, _dict: Dict[_K, _V]) -> immutabledict[_K, _V]:
+ """
+ Similar to :meth:`dict.update` but returning an immutabledict.
+
+ :return: the updated :class:`immutabledict`
+ """
+ new = dict(self._dict)
+ new.update(_dict)
+ return self.__class__(new)
+
class ImmutableOrderedDict(immutabledict[_K, _V]):
"""
An immutabledict subclass that maintains key order.
+
+ Same as :class:`immutabledict` but based on
:class:`collections.OrderedDict`.
"""
dict_cls = OrderedDict
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/immutabledict-3.0.0/pyproject.toml
new/immutabledict-4.0.0/pyproject.toml
--- old/immutabledict-3.0.0/pyproject.toml 2023-07-21 20:13:55.780401200
+0200
+++ new/immutabledict-4.0.0/pyproject.toml 2023-11-25 13:34:07.496336700
+0100
@@ -1,11 +1,12 @@
[tool.poetry]
name = "immutabledict"
-version = "3.0.0"
+version = "4.0.0"
description = "Immutable wrapper around dictionaries (a fork of frozendict)"
authors = ["Corentin Garcia <[email protected]>"]
license = "MIT"
readme = "README.md"
repository = "https://github.com/corenting/immutabledict"
+documentation = "https://immutabledict.corenting.fr"
keywords = ["immutable", "dictionary"]
classifiers = [
"Development Status :: 5 - Production/Stable",
@@ -18,6 +19,7 @@
[tool.poetry.urls]
"Changelog" =
"https://github.com/corenting/immutabledict/blob/master/CHANGELOG.md"
"Bug Tracker" = "https://github.com/corenting/immutabledict/issues"
+"Donation" = "https://corenting.fr/donate"
[tool.poetry.dependencies]
python = "^3.8"
@@ -26,14 +28,30 @@
black = "*"
coverage = "*"
mypy = "*"
-pdbpp = "*"
pytest = "*"
pytest-cov = "*"
ruff = "*"
+sphinx = { version = "^7.2", python = "^3.9" }
tox = "*"
[tool.ruff]
line-length = 88
+target-version = "py38"
+per-file-ignores = {"tests/**" = ["S101", "D"]}
+# Enable pycodestyle (E), Pyflakes (F), flake8-print (T20), ruff rules (RUF),
+# isort (I), pep8-naming (N), pyupgrade (UP), flake8-async (ASYNC),
+# flake8-bandit (S), perflint (PERF) and pydocstyle (D)
+select = ["E", "F", "T20", "RUF", "I", "N", "UP", "ASYNC", "S", "PERF", "D"]
+ignore = [
+ "E501", # line too long as black is used
+ "D203", # one blank line before class
+ "D212", # multiline summary first line
+ "D105" # no docstrings for magic methods
+]
+
+[tool.ruff.pyupgrade]
+# Preserve types, even if a file imports `from __future__ import annotations`.
+keep-runtime-typing = true
[tool.mypy]
ignore_missing_imports = true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/immutabledict-3.0.0/tests/test_immutabledict.py
new/immutabledict-4.0.0/tests/test_immutabledict.py
--- old/immutabledict-3.0.0/tests/test_immutabledict.py 2023-07-21
20:13:55.780401200 +0200
+++ new/immutabledict-4.0.0/tests/test_immutabledict.py 2023-11-25
13:34:07.496336700 +0100
@@ -1,4 +1,5 @@
from typing import Any, Dict, Union
+
import pytest
from immutabledict import ImmutableOrderedDict, immutabledict
@@ -6,8 +7,7 @@
class TestImmutableDict:
def test_covariance(self) -> None:
- """
- Not a real unit test, but test covariance
+ """Not a real unit test, but test covariance
as mypy runs on the tests.
"""
@@ -26,6 +26,10 @@
my_dict = second_dict
assert my_dict == second_dict
+ def test_new_init_methods(self) -> None:
+ assert "__new__" in immutabledict.__dict__
+ assert "__init__" not in immutabledict.__dict__
+
def test_cannot_assign_value(self) -> None:
with pytest.raises(AttributeError):
immutabledict().setitem("key", "value") # type: ignore
@@ -94,7 +98,7 @@
immutable_dict: immutabledict[str, str] = immutabledict(
{"a": "value", "b": "other_value"}
)
- eval_ret = eval(repr(immutable_dict))
+ eval_ret = eval(repr(immutable_dict)) # noqa: S307
assert immutable_dict == eval_ret
def test_hash(self) -> None:
@@ -185,6 +189,54 @@
assert first_dict == {"a": "a", "b": "b"}
assert second_dict == {"a": "A", "c": "c"}
+ @pytest.mark.parametrize(
+ "statement",
+ [
+ "for k, v in d.items(): s += 1",
+ "for v in d.values(): s += 1",
+ "for k in d.keys(): s += 1",
+ ],
+ )
+ def test_performance(self, statement: str) -> None:
+ from timeit import timeit
+
+ time_standard = timeit(
+ statement,
+ number=3,
+ setup="s=0; d = {i:i for i in range(1000000)}",
+ )
+
+ time_immutable = timeit(
+ statement,
+ globals=globals(),
+ number=3,
+ setup="s=0; d = immutabledict({i:i for i in range(1000000)})",
+ )
+
+ assert time_immutable < 1.2 * time_standard
+
+ def test_set_delete_update(self) -> None:
+ d: immutabledict[str, int] = immutabledict(a=1, b=2)
+
+ assert d.set("a", 10) == immutabledict(a=10, b=2) == dict(a=10, b=2)
+ assert d.delete("a") == immutabledict(b=2) == dict(b=2)
+
+ with pytest.raises(KeyError):
+ d.delete("c")
+
+ assert d.update({"a": 3}) == immutabledict(a=3, b=2) == dict(a=3, b=2)
+
+ assert (
+ d.update({"c": 17}) == immutabledict(a=1, b=2, c=17) == dict(a=1,
b=2, c=17)
+ )
+
+ # Make sure d doesn't change
+ assert d == immutabledict(a=1, b=2) == dict(a=1, b=2)
+
+ def test_new_kwargs(self) -> None:
+ immutable_dict: immutabledict[str, int] = immutabledict(a=1, b=2)
+ assert immutable_dict == {"a": 1, "b": 2} == dict(a=1, b=2)
+
class TestImmutableOrderedDict:
def test_ordered(self) -> None: