Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-frozendict for
openSUSE:Factory checked in at 2026-02-17 18:13:55
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-frozendict (Old)
and /work/SRC/openSUSE:Factory/.python-frozendict.new.1977 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-frozendict"
Tue Feb 17 18:13:55 2026 rev:13 rq:1333414 version:2.4.7
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-frozendict/python-frozendict.changes
2024-10-30 17:37:33.404099853 +0100
+++
/work/SRC/openSUSE:Factory/.python-frozendict.new.1977/python-frozendict.changes
2026-02-17 18:13:58.104486344 +0100
@@ -1,0 +2,7 @@
+Mon Feb 16 17:17:28 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 2.4.7:
+ * Now pickle is only marginally slower than dict for C
+ Extension!
+
+-------------------------------------------------------------------
Old:
----
frozendict-2.4.6.tar.gz
New:
----
frozendict-2.4.7.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-frozendict.spec ++++++
--- /var/tmp/diff_new_pack.BMyPES/_old 2026-02-17 18:13:58.792514957 +0100
+++ /var/tmp/diff_new_pack.BMyPES/_new 2026-02-17 18:13:58.792514957 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-frozendict
#
-# Copyright (c) 2024 SUSE LLC
+# Copyright (c) 2026 SUSE LLC and contributors
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
%{?sle15_python_module_pythons}
Name: python-frozendict
-Version: 2.4.6
+Version: 2.4.7
Release: 0
Summary: An immutable dictionary
License: MIT
++++++ frozendict-2.4.6.tar.gz -> frozendict-2.4.7.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/frozendict-2.4.6/PKG-INFO
new/frozendict-2.4.7/PKG-INFO
--- old/frozendict-2.4.6/PKG-INFO 2024-10-12 16:47:31.267452200 +0200
+++ new/frozendict-2.4.7/PKG-INFO 2025-11-09 05:54:09.273123700 +0100
@@ -1,6 +1,6 @@
-Metadata-Version: 2.1
+Metadata-Version: 2.4
Name: frozendict
-Version: 2.4.6
+Version: 2.4.7
Summary: A simple immutable dictionary
Home-page: https://github.com/Marco-Sulla/python-frozendict
Author: Marco Sulla
@@ -22,6 +22,18 @@
Requires-Python: >=3.6
Description-Content-Type: text/markdown
License-File: LICENSE.txt
+Dynamic: author
+Dynamic: author-email
+Dynamic: classifier
+Dynamic: description
+Dynamic: description-content-type
+Dynamic: home-page
+Dynamic: keywords
+Dynamic: license
+Dynamic: license-file
+Dynamic: project-url
+Dynamic: requires-python
+Dynamic: summary
# frozendict
### Table of Contents
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/frozendict-2.4.6/pyproject.toml
new/frozendict-2.4.7/pyproject.toml
--- old/frozendict-2.4.6/pyproject.toml 2024-10-12 16:47:27.000000000 +0200
+++ new/frozendict-2.4.7/pyproject.toml 1970-01-01 01:00:00.000000000 +0100
@@ -1,2 +0,0 @@
-[tool.cibuildwheel]
-skip=["cp311-*", "cp312-*", "pp*"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/frozendict-2.4.6/setup.py
new/frozendict-2.4.7/setup.py
--- old/frozendict-2.4.6/setup.py 2024-10-12 16:47:27.000000000 +0200
+++ new/frozendict-2.4.7/setup.py 2025-11-09 05:54:04.000000000 +0100
@@ -1,10 +1,11 @@
#!/usr/bin/env python3
-import setuptools
-from pathlib import Path
import sys
-from platform import python_implementation
from os import environ
+from pathlib import Path
+from platform import python_implementation
+
+import setuptools
name = "frozendict"
module1_name = "frozendict"
@@ -30,7 +31,10 @@
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
- "License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
+ (
+ "License :: OSI Approved :: GNU Lesser General Public " +
+ "License v3 (LGPLv3)"
+ ),
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.6",
"Natural Language :: English",
@@ -97,7 +101,10 @@
include_path = c_src_path / include_dir_name
cpython_stringlib_path = cpython_object_path / cpython_stringlib_name
-cpython_objects_clinic_path = cpython_object_path / cpython_objects_clinic_name
+
+cpython_objects_clinic_path = (
+ cpython_object_path / cpython_objects_clinic_name
+)
cpython_include_dirs = [
str(include_path),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/frozendict-2.4.6/src/frozendict/__init__.py
new/frozendict-2.4.7/src/frozendict/__init__.py
--- old/frozendict-2.4.6/src/frozendict/__init__.py 2024-10-12
16:47:27.000000000 +0200
+++ new/frozendict-2.4.7/src/frozendict/__init__.py 2025-11-09
05:54:04.000000000 +0100
@@ -11,10 +11,10 @@
from ._frozendict_py import *
c_ext = False
-from .version import version as __version__
+from . import cool
from . import monkeypatch
from .cool import *
-from . import cool
+from .version import version as __version__
def _getFrozendictJsonEncoder(BaseJsonEncoder = None):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/frozendict-2.4.6/src/frozendict/_frozendict_py.py
new/frozendict-2.4.7/src/frozendict/_frozendict_py.py
--- old/frozendict-2.4.6/src/frozendict/_frozendict_py.py 2024-10-12
16:47:27.000000000 +0200
+++ new/frozendict-2.4.7/src/frozendict/_frozendict_py.py 2025-11-09
05:54:04.000000000 +0100
@@ -23,7 +23,7 @@
The API is the same as `dict`, without methods that can change the
immutability. In addition, it supports __hash__().
"""
-
+
__slots__ = (
"_hash",
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/frozendict-2.4.6/src/frozendict/c_src/3_8/cpython_src/Objects/dictobject_original.c
new/frozendict-2.4.7/src/frozendict/c_src/3_8/cpython_src/Objects/dictobject_original.c
---
old/frozendict-2.4.6/src/frozendict/c_src/3_8/cpython_src/Objects/dictobject_original.c
2024-10-12 16:47:27.000000000 +0200
+++
new/frozendict-2.4.7/src/frozendict/c_src/3_8/cpython_src/Objects/dictobject_original.c
2025-11-09 05:54:04.000000000 +0100
@@ -3769,6 +3769,11 @@
Py_INCREF(result);
Py_DECREF(oldkey);
Py_DECREF(oldvalue);
+ // bpo-42536: The GC may have untracked this result tuple. Since we're
+ // recycling it, make sure it's tracked again:
+ if (!_PyObject_GC_IS_TRACKED(result)) {
+ _PyObject_GC_TRACK(result);
+ }
}
else {
result = PyTuple_New(2);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/frozendict-2.4.6/src/frozendict/cool.py
new/frozendict-2.4.7/src/frozendict/cool.py
--- old/frozendict-2.4.6/src/frozendict/cool.py 2024-10-12 16:47:27.000000000
+0200
+++ new/frozendict-2.4.7/src/frozendict/cool.py 2025-11-09 05:54:04.000000000
+0100
@@ -1,8 +1,9 @@
+from collections.abc import MutableMapping, MutableSequence, MutableSet
+from enum import Enum
from types import MappingProxyType
+
from array import array
from frozendict import frozendict
-from collections.abc import MutableMapping, MutableSequence, MutableSet
-from enum import Enum
# fix for python 3.9-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/frozendict-2.4.6/src/frozendict/monkeypatch.py
new/frozendict-2.4.7/src/frozendict/monkeypatch.py
--- old/frozendict-2.4.6/src/frozendict/monkeypatch.py 2024-10-12
16:47:27.000000000 +0200
+++ new/frozendict-2.4.7/src/frozendict/monkeypatch.py 2025-11-09
05:54:04.000000000 +0100
@@ -140,9 +140,9 @@
"(maybe you already unpatched MutableMapping?)"
)
- oldMutableMappingSubclasshook = MutableMapping.__subclasshook__
+ oldMutableMappingHook = MutableMapping.__subclasshook__
else:
- oldMutableMappingSubclasshook = self._oldMutableMappingSubclasshook
+ oldMutableMappingHook = self._oldMutableMappingSubclasshook
if patch:
# noinspection PyDecorator
@@ -157,7 +157,8 @@
if issubclass(subclass, frozendict):
return False
- return oldMutableMappingSubclasshook(
+ # noinspection PyArgumentList
+ return oldMutableMappingHook(
subclass,
*args,
**kwargs
@@ -165,14 +166,14 @@
return NotImplemented
- defaultMutableMappingSubclasshook =
frozendictMutableMappingSubclasshook
- newOldMutableMappingSubclasshook = oldMutableMappingSubclasshook
+ defaultMutableMappingHook = frozendictMutableMappingSubclasshook
+ newOldMutableMappingHook = oldMutableMappingHook
else:
- defaultMutableMappingSubclasshook = oldMutableMappingSubclasshook
- newOldMutableMappingSubclasshook = None
+ defaultMutableMappingHook = oldMutableMappingHook
+ newOldMutableMappingHook = None
- self._oldMutableMappingSubclasshook = newOldMutableMappingSubclasshook
- MutableMapping.__subclasshook__ = defaultMutableMappingSubclasshook
+ self._oldMutableMappingSubclasshook = newOldMutableMappingHook
+ MutableMapping.__subclasshook__ = defaultMutableMappingHook
try:
# noinspection PyUnresolvedReferences, PyProtectedMember
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/frozendict-2.4.6/src/frozendict/version.py
new/frozendict-2.4.7/src/frozendict/version.py
--- old/frozendict-2.4.6/src/frozendict/version.py 2024-10-12
16:47:27.000000000 +0200
+++ new/frozendict-2.4.7/src/frozendict/version.py 2025-11-09
05:54:04.000000000 +0100
@@ -1 +1 @@
-version = "2.4.6"
+version = "2.4.7"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/frozendict-2.4.6/src/frozendict.egg-info/PKG-INFO
new/frozendict-2.4.7/src/frozendict.egg-info/PKG-INFO
--- old/frozendict-2.4.6/src/frozendict.egg-info/PKG-INFO 2024-10-12
16:47:31.000000000 +0200
+++ new/frozendict-2.4.7/src/frozendict.egg-info/PKG-INFO 2025-11-09
05:54:09.000000000 +0100
@@ -1,6 +1,6 @@
-Metadata-Version: 2.1
+Metadata-Version: 2.4
Name: frozendict
-Version: 2.4.6
+Version: 2.4.7
Summary: A simple immutable dictionary
Home-page: https://github.com/Marco-Sulla/python-frozendict
Author: Marco Sulla
@@ -22,6 +22,18 @@
Requires-Python: >=3.6
Description-Content-Type: text/markdown
License-File: LICENSE.txt
+Dynamic: author
+Dynamic: author-email
+Dynamic: classifier
+Dynamic: description
+Dynamic: description-content-type
+Dynamic: home-page
+Dynamic: keywords
+Dynamic: license
+Dynamic: license-file
+Dynamic: project-url
+Dynamic: requires-python
+Dynamic: summary
# frozendict
### Table of Contents
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/frozendict-2.4.6/src/frozendict.egg-info/SOURCES.txt
new/frozendict-2.4.7/src/frozendict.egg-info/SOURCES.txt
--- old/frozendict-2.4.6/src/frozendict.egg-info/SOURCES.txt 2024-10-12
16:47:31.000000000 +0200
+++ new/frozendict-2.4.7/src/frozendict.egg-info/SOURCES.txt 2025-11-09
05:54:09.000000000 +0100
@@ -1,7 +1,6 @@
LICENSE.txt
MANIFEST.in
README.md
-pyproject.toml
setup.py
src/frozendict/__init__.py
src/frozendict/__init__.pyi
@@ -66,6 +65,7 @@
test/common.py
test/debug.py
test/frozendict_only.py
+test/run_type_checker.py
test/subclass_only.py
test/test_freeze.py
test/test_frozendict.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/frozendict-2.4.6/test/bench.py
new/frozendict-2.4.7/test/bench.py
--- old/frozendict-2.4.6/test/bench.py 2024-10-12 16:47:27.000000000 +0200
+++ new/frozendict-2.4.7/test/bench.py 2025-11-09 05:54:04.000000000 +0100
@@ -1,126 +1,131 @@
#!/usr/bin/env python3
+import timeit
+import uuid
+from copy import copy
+from time import time
+
+import immutables
from frozendict import frozendict
+from math import sqrt
-def main(number):
- import timeit
- import uuid
- from time import time
- from math import sqrt
-
- def mindev(data, xbar = None):
- """
- This function calculates the stdev around the _minimum_ data,
- and not the mean
- """
-
- if not data:
- raise ValueError("No data")
-
- if xbar is None:
- xbar = min(data)
-
- sigma2 = 0
-
- for x in data:
- sigma2 += (x - xbar) ** 2
-
- N = len(data) - 1
-
- if N < 1:
- N = 1
-
- return sqrt(sigma2 / N)
-
- def autorange(
- stmt,
- setup="pass",
- globals=None,
- ratio=1000,
- bench_time=10,
- number=None
- ):
- if setup is None:
- setup = "pass"
-
- t = timeit.Timer(stmt=stmt, setup=setup, globals=globals)
- break_immediately = False
-
- if number is None:
- # get automatically the number of needed loops
- a = t.autorange()
-
- num = a[0]
- # the number of loops
- number = int(num / ratio)
-
- if number < 1:
- number = 1
-
- # the number of repeat of loops
- repeat = int(num / number)
-
- if repeat < 1:
- repeat = 1
+def mindev(data, xbar=None):
+ """
+ This function calculates the stdev around the _minimum_ data,
+ and not the mean
+ """
+
+ if not data:
+ raise ValueError("No data")
+
+ if xbar is None:
+ xbar = min(data)
+
+ sigma2 = 0
+
+ for x in data:
+ sigma2 += (x - xbar) ** 2
+
+ N = len(data) - 1
+
+ if N < 1:
+ N = 1
+
+ return sqrt(sigma2 / N)
+
+
+def autorange(
+ stmt,
+ setup="pass",
+ globals=None,
+ ratio=1000,
+ bench_time=10,
+ number=None
+):
+ if setup is None:
+ setup = "pass"
+
+ t = timeit.Timer(stmt=stmt, setup=setup, globals=globals)
+ break_immediately = False
+
+ if number is None:
+ # get automatically the number of needed loops
+ a = t.autorange()
- else:
- repeat = 1
- break_immediately = True
+ number_temp = a[0]
+ # the number of loops
+ number = int(number_temp / ratio)
- data_tmp = t.repeat(number=number, repeat=repeat)
- min_value = min(data_tmp)
- # I create a list with minimum values
- data_min = [min_value]
-
- bench_start = time()
-
- while 1:
- # I get additional benchs until `bench_time` seconds passes
- data_min.extend(t.repeat(number=number, repeat=repeat))
-
- if break_immediately or time() - bench_start > bench_time:
- break
+ if number < 1:
+ number = 1
- # I sort the data...
- data_min.sort()
- # ... so the minimum is the fist datum
- xbar = data_min[0]
- i = 0
-
- # I repeat until no data is removed
- while i < len(data_min):
- i = len(data_min)
-
- # I calculate the sigma using the minimum as "real" value,
- # and not the mean
- sigma = mindev(data_min, xbar=xbar)
-
- for i2 in range(2, len(data_min)):
- # I thind the point where the data are greater than
- # 3 sigma. Data are sorted...
- if data_min[i2] - xbar > 3 * sigma:
- break
-
- k = i
-
- # do not remove too much data
- if i < 5:
- k = 5
-
- # remove the data with sigma > 3
- del data_min[k:]
-
- # I return the minimum as real value, with the sigma
- # calculated around the minimum
- return (
- min(data_min) / number,
- mindev(data_min, xbar=xbar) / number
- )
-
- def getUuid():
- return str(uuid.uuid4())
+ # the number of repeat of loops
+ repeat = int(number_temp / number)
+
+ if repeat < 1:
+ repeat = 1
+ else:
+ repeat = 1
+ break_immediately = True
+
+ data_tmp = t.repeat(number=number, repeat=repeat)
+ min_value = min(data_tmp)
+ # create a list with minimum values
+ data_min = [min_value]
+
+ bench_start = time()
+
+ while 1:
+ # get additional benchs until `bench_time` seconds passes
+ data_min.extend(t.repeat(number=number, repeat=repeat))
+
+ if break_immediately or time() - bench_start > bench_time:
+ break
+
+ # sort the data...
+ data_min.sort()
+ # ... so the minimum is the fist datum
+ xbar = data_min[0]
+ i = 0
+
+ # repeat until no data is removed
+ while i < len(data_min):
+ i = len(data_min)
+
+ # calculate the sigma using the minimum as "real" value,
+ # and not the mean
+ sigma = mindev(data_min, xbar=xbar)
+
+ for i2 in range(2, len(data_min)):
+ # find the point where the data are greater than
+ # 3 sigma. Data are sorted
+ if data_min[i2] - xbar > 3 * sigma:
+ break
+
+ k = i
+
+ # do not remove too much data
+ if i < 5:
+ k = 5
+
+ # remove the data with sigma > 3
+ del data_min[k:]
+
+ # return the minimum as real value, with the sigma
+ # calculated around the minimum
+ return (
+ min(data_min) / number,
+ mindev(data_min, xbar=xbar) / number
+ )
+
+
+def getUuid():
+ return str(uuid.uuid4())
+
+
+def main(number):
dictionary_sizes = (5, 1000)
print_tpl = (
@@ -133,21 +138,93 @@
if int_key < 0:
int_key = 0
-
+
+ bench_constr_kwargs_name = "constructor(kwargs)"
+ bench_hash_name = "hash"
+ bench_set_name = "set"
+ bench_delete_name = "set"
+ bench_copy_name = "copy"
+ bench_fromkeys_name = "fromkeys"
+
benchmarks = (
- {"name": "constructor(d)", "code": "klass(d)", "setup": "klass =
type(o)", },
- {"name": "constructor(kwargs)", "code": "klass(**d)", "setup": "klass
= type(o)", },
- {"name": "constructor(seq2)", "code": "klass(v)", "setup": "klass =
type(o); v = tuple(d.items())", },
- {"name": "constructor(o)", "code": "klass(o)", "setup": "klass =
type(o)", },
- {"name": "o.copy()", "code": "o.copy()", "setup": "pass", },
- {"name": "o == o", "code": "o == o", "setup": "pass", },
- {"name": "for x in o", "code": "for _ in o: pass", "setup": "pass", },
- {"name": "for x in o.values()", "code": "for _ in values: pass",
"setup": "values = o.values()", },
- {"name": "for x in o.items()", "code": "for _ in items: pass",
"setup": "items = o.items()", },
- {"name": "pickle.dumps(o)", "code": "dumps(o, protocol=-1)", "setup":
"from pickle import dumps", },
- {"name": "pickle.loads(dump)", "code": "loads(dump)", "setup": "from
pickle import loads, dumps; dump = dumps(o, protocol=-1)", },
- {"name": "class.fromkeys()", "code": "fromkeys(keys)", "setup":
"fromkeys = type(o).fromkeys; keys = o.keys()", },
- {"name": "set", "code": None, "setup": "val = getUuid()", },
+ {
+ "name": "constructor(d)",
+ "code": "klass(d)",
+ "setup": "klass = type(o)",
+ },
+ {
+ "name": bench_constr_kwargs_name,
+ "code": "klass(**d)",
+ "setup": "klass = type(o)",
+ },
+ {
+ "name": "constructor(seq2)",
+ "code": "klass(v)",
+ "setup": "klass = type(o); v = tuple(d.items())",
+ },
+ {
+ "name": "constructor(o)",
+ "code": "klass(o)",
+ "setup": "klass = type(o)",
+ },
+ {
+ "name": bench_copy_name,
+ "code": None,
+ "setup": "pass",
+ },
+ {
+ "name": "o == o",
+ "code": "o == o",
+ "setup": "pass",
+ },
+ {
+ "name": "for x in o",
+ "code": "for _ in o: pass",
+ "setup": "pass",
+ },
+ {
+ "name": "for x in o.values()",
+ "code": "for _ in values: pass",
+ "setup": "values = o.values()",
+ },
+ {
+ "name": "for x in o.items()",
+ "code": "for _ in items: pass",
+ "setup": "items = o.items()",
+ },
+ {
+ "name": "pickle.dumps",
+ "code": "dumps(o, protocol=-1)",
+ "setup": "from pickle import dumps",
+ },
+ {
+ "name": "pickle.loads",
+ "code": "loads(dump)",
+ "setup": (
+ "from pickle import loads, dumps; " +
+ "dump = dumps(o, protocol=-1)"
+ ),
+ },
+ {
+ "name": bench_fromkeys_name,
+ "code": "fromkeys(keys)",
+ "setup": "fromkeys = type(o).fromkeys; keys = o.keys()",
+ },
+ {
+ "name": bench_set_name,
+ "code": None,
+ "setup": "val = getUuid()",
+ },
+ {
+ "name": bench_delete_name,
+ "code": None,
+ "setup": "pass",
+ },
+ {
+ "name": bench_hash_name,
+ "code": "hash(o)",
+ "setup": "pass",
+ },
)
dict_collection = []
@@ -165,49 +242,75 @@
fd1 = frozendict(d1)
fd2 = frozendict(d2)
+ m1 = immutables.Map(d1)
+ m2 = immutables.Map(d2)
dict_collection.append({
- "str": ((d1, fd1), str_key),
- "int": ((d2, fd2), int_key)
+ "str": ((d1, fd1, m1), str_key),
+ "int": ((d2, fd2, m2), int_key)
})
-
+
+ sep_n = 72
+ sep_major = "#"
+
for benchmark in benchmarks:
- print("#" * 72)
+ print(sep_major * sep_n)
for dict_entry in dict_collection:
for (dict_keys, (dicts, one_key)) in dict_entry.items():
if (
- benchmark["name"] == "constructor(kwargs)" and
+ benchmark["name"] == bench_constr_kwargs_name and
dict_keys == "int"
):
continue
- print("/" * 72)
+ print("/" * sep_n)
for o in dicts:
if (
- benchmark["name"] == "hash(o)" and
+ benchmark["name"] == bench_hash_name and
type(o) is dict
):
continue
- if benchmark["name"] == "set":
+ if benchmark["name"] == bench_set_name:
if type(o) is dict:
- benchmark["code"] = "o[one_key] = val"
+ benchmark["code"] = (
+ "o.copy()[one_key] = val"
+ )
else:
benchmark["code"] = "o.set(one_key, val)"
-
+
+ if benchmark["name"] == bench_delete_name:
+ if type(o) is dict:
+ benchmark["code"] = "del o.copy()[one_key]"
+ else:
+ benchmark["code"] = "o.delete(one_key)"
+
+ if benchmark["name"] == bench_copy_name:
+ if type(o) is immutables.Map:
+ benchmark["code"] = "copy(o)"
+ else:
+ benchmark["code"] = "o.copy()"
+
+ if (
+ benchmark["name"] == bench_fromkeys_name and
+ type(o) is immutables.Map
+ ):
+ continue
+
d = dicts[0]
bench_res = autorange(
stmt = benchmark["code"],
setup = benchmark["setup"],
globals = {
- "o": o.copy(),
+ "o": copy(o),
"getUuid": getUuid,
"d": d.copy(),
- "one_key": one_key
+ "one_key": one_key,
+ "copy": copy,
},
number = number,
)
@@ -221,13 +324,13 @@
sigma = bench_res[1],
))
- print("#" * 72)
+ print(sep_major * sep_n)
if __name__ == "__main__":
import sys
- number = None
+ num = None
argv = sys.argv
len_argv = len(argv)
max_positional_args = 1
@@ -242,6 +345,6 @@
number_arg_pos = 1
if len_argv == number_arg_pos + 1:
- number = int(argv[number_arg_pos])
+ num = int(argv[number_arg_pos])
- main(number)
+ main(num)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/frozendict-2.4.6/test/common.py
new/frozendict-2.4.7/test/common.py
--- old/frozendict-2.4.6/test/common.py 2024-10-12 16:47:27.000000000 +0200
+++ new/frozendict-2.4.7/test/common.py 2025-11-09 05:54:04.000000000 +0100
@@ -1,10 +1,11 @@
-import pytest
import pickle
-from copy import deepcopy
import sys
from collections.abc import MutableMapping
-from .base import FrozendictTestBase
+from copy import deepcopy
+import pytest
+
+from .base import FrozendictTestBase
pyversion = sys.version_info
pyversion_major = pyversion[0]
@@ -116,6 +117,7 @@
range(pickle.HIGHEST_PROTOCOL + 1)
)
def test_pickle(self, fd, protocol):
+ # noinspection PyTypeChecker
dump = pickle.dumps(fd, protocol=protocol)
assert dump
assert pickle.loads(dump) == fd
@@ -275,6 +277,7 @@
)
def test_pickle_iter_key(self, fd, protocol):
orig = iter(fd.keys())
+ # noinspection PyTypeChecker
dump = pickle.dumps(orig, protocol=protocol)
assert dump
assert tuple(pickle.loads(dump)) == tuple(orig)
@@ -285,6 +288,7 @@
)
def test_pickle_iter_item(self, fd, protocol):
orig = iter(fd.items())
+ # noinspection PyTypeChecker
dump = pickle.dumps(orig, protocol=protocol)
assert dump
assert tuple(pickle.loads(dump)) == tuple(orig)
@@ -295,6 +299,7 @@
)
def test_pickle_iter_value(self, fd, protocol):
orig = iter(fd.values())
+ # noinspection PyTypeChecker
dump = pickle.dumps(orig, protocol=protocol)
assert dump
assert tuple(pickle.loads(dump)) == tuple(orig)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/frozendict-2.4.6/test/debug.py
new/frozendict-2.4.7/test/debug.py
--- old/frozendict-2.4.6/test/debug.py 2024-10-12 16:47:27.000000000 +0200
+++ new/frozendict-2.4.7/test/debug.py 2025-11-09 05:54:04.000000000 +0100
@@ -1,4 +1,5 @@
#!/usr/bin/env python3
+from typing import Callable, Union
import frozendict
@@ -51,7 +52,7 @@
return len(self._dict)
-def print_info(klass, iterations, func):
+def print_info(klass, iterations, func: Union[Callable, str]):
try:
name = func.__name__
except AttributeError:
@@ -133,7 +134,7 @@
functions = []
-@trace(iterations = 300, mult = 1.5)
+@trace(iterations = 400, mult = 1.5)
def func_1():
pickle.loads(pickle.dumps(fd_1))
@@ -141,7 +142,7 @@
functions.append(func_1)
-@trace(iterations = 200, mult = 1.5)
+@trace(iterations = 300, mult = 1.5)
def func_2():
pickle.loads(pickle.dumps(iter(fd_1.keys())))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/frozendict-2.4.6/test/frozendict_only.py
new/frozendict-2.4.7/test/frozendict_only.py
--- old/frozendict-2.4.6/test/frozendict_only.py 2024-10-12
16:47:27.000000000 +0200
+++ new/frozendict-2.4.7/test/frozendict_only.py 2025-11-09
05:54:04.000000000 +0100
@@ -1,7 +1,9 @@
import io
import pickle
-import pytest
from copy import copy, deepcopy
+
+import pytest
+
from .base import FrozendictTestBase
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/frozendict-2.4.6/test/run_type_checker.py
new/frozendict-2.4.7/test/run_type_checker.py
--- old/frozendict-2.4.6/test/run_type_checker.py 1970-01-01
01:00:00.000000000 +0100
+++ new/frozendict-2.4.7/test/run_type_checker.py 2025-11-09
05:54:04.000000000 +0100
@@ -0,0 +1,24 @@
+import subprocess
+import sys
+from pathlib import Path
+
+py_ver_major = sys.version_info.major
+py_ver_minor = sys.version_info.minor
+
+if py_ver_major == 3 and py_ver_minor < 8:
+ print(
+ f"Python is version {py_ver_major}.{py_ver_minor}, not "
+ "running type checker"
+ )
+
+ sys.exit(0)
+
+curr_file = Path(__file__)
+curr_dir = curr_file.parent
+
+subprocess.run(
+ "mypy typed.py",
+ shell=True,
+ check=True,
+ cwd=str(curr_dir)
+)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/frozendict-2.4.6/test/subclass_only.py
new/frozendict-2.4.7/test/subclass_only.py
--- old/frozendict-2.4.6/test/subclass_only.py 2024-10-12 16:47:27.000000000
+0200
+++ new/frozendict-2.4.7/test/subclass_only.py 2025-11-09 05:54:04.000000000
+0100
@@ -1,4 +1,5 @@
from copy import copy, deepcopy
+
from .base import FrozendictTestBase
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/frozendict-2.4.6/test/test_freeze.py
new/frozendict-2.4.7/test/test_freeze.py
--- old/frozendict-2.4.6/test/test_freeze.py 2024-10-12 16:47:27.000000000
+0200
+++ new/frozendict-2.4.7/test/test_freeze.py 2025-11-09 05:54:04.000000000
+0100
@@ -1,12 +1,14 @@
-import pytest
-import frozendict as cool
-from frozendict import frozendict
from collections import OrderedDict
-from collections.abc import MutableSequence, Sequence, Iterable
-from array import array
+from collections.abc import MutableSequence, Sequence
+from enum import Enum
from types import MappingProxyType
+
+import frozendict as cool
+import pytest
+from array import array
from frozendict import FreezeError, FreezeWarning
-from enum import Enum
+from frozendict import cool as _cool
+from frozendict import frozendict
class A:
@@ -137,11 +139,13 @@
def test_register_bad_to_convert():
with pytest.raises(ValueError):
+ # noinspection PyTypeChecker
cool.register(5, 7)
def test_register_bad_converter():
with pytest.raises(ValueError):
+ # noinspection PyTypeChecker
cool.register(frozendict, 7)
@@ -152,21 +156,25 @@
def test_deepfreeze_bad_custom_converters_key(before_cure):
with pytest.raises(ValueError):
+ # noinspection PyTypeChecker
cool.deepfreeze(before_cure, custom_converters={7: 7})
def test_deepfreeze_bad_custom_converters_val(before_cure):
with pytest.raises(ValueError):
+ # noinspection PyTypeChecker
cool.deepfreeze(before_cure, custom_converters={frozendict: 7})
def test_deepfreeze_bad_custom_inverse_converters_key(before_cure):
with pytest.raises(ValueError):
+ # noinspection PyTypeChecker
cool.deepfreeze(before_cure, custom_inverse_converters={7: 7})
def test_deepfreeze_bad_custom_inverse_converters_val(before_cure):
with pytest.raises(ValueError):
+ # noinspection PyTypeChecker
cool.deepfreeze(
before_cure,
custom_inverse_converters = {frozendict: 7}
@@ -241,7 +249,7 @@
def test_get_items():
with pytest.raises(TypeError):
- cool.cool.getItems(5)
+ _cool.getItems(5)
def test_no_dict_and_hash(no_dict_and_hash):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/frozendict-2.4.6/test/test_frozendict.py
new/frozendict-2.4.7/test/test_frozendict.py
--- old/frozendict-2.4.6/test/test_frozendict.py 2024-10-12
16:47:27.000000000 +0200
+++ new/frozendict-2.4.7/test/test_frozendict.py 2025-11-09
05:54:04.000000000 +0100
@@ -1,8 +1,8 @@
-from .common import FrozendictCommonTest
-from .frozendict_only import FrozendictOnlyTest
import frozendict as cool
from frozendict import frozendict as FrozendictClass
+from .common import FrozendictCommonTest
+from .frozendict_only import FrozendictOnlyTest
is_subclass = False
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/frozendict-2.4.6/test/test_frozendict_subclass.py
new/frozendict-2.4.7/test/test_frozendict_subclass.py
--- old/frozendict-2.4.6/test/test_frozendict_subclass.py 2024-10-12
16:47:27.000000000 +0200
+++ new/frozendict-2.4.7/test/test_frozendict_subclass.py 2025-11-09
05:54:04.000000000 +0100
@@ -1,8 +1,8 @@
-from .common import FrozendictCommonTest
-from .subclass_only import FrozendictSubclassOnlyTest
import frozendict as cool
from frozendict import frozendict as FrozendictClass
+from .common import FrozendictCommonTest
+from .subclass_only import FrozendictSubclassOnlyTest
is_subclass = True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/frozendict-2.4.6/test/typed.py
new/frozendict-2.4.7/test/typed.py
--- old/frozendict-2.4.6/test/typed.py 2024-10-12 16:47:27.000000000 +0200
+++ new/frozendict-2.4.7/test/typed.py 2025-11-09 05:54:04.000000000 +0100
@@ -2,48 +2,70 @@
import copy
from collections.abc import Hashable
-from typing import ItemsView, Iterator, KeysView, Mapping, ValuesView
+from typing import (
+ ItemsView,
+ Iterator,
+ KeysView,
+ Mapping,
+ ValuesView,
+ Union,
+ Tuple,
+)
from frozendict import frozendict
-from typing_extensions import assert_type
+from typing_extensions import assert_type, Never
fd = frozendict(a=1, b=2)
-assert_type(frozendict(), frozendict[()])
+assert_type(frozendict(), frozendict[Never, Never])
assert_type(fd, frozendict[str, int])
assert_type(fd["a"], int)
assert_type(iter(fd), Iterator[str])
assert_type(frozendict.fromkeys("abc", 0), frozendict[str, int])
assert_type(fd.copy(), frozendict[str, int])
-assert_type(fd.item(0), tuple[str, int])
-assert_type(fd.item(), tuple[str, int])
+assert_type(fd.item(0), Tuple[str, int])
+assert_type(fd.item(), Tuple[str, int])
assert_type(fd.key(0), str)
assert_type(fd.key(), str)
assert_type(fd.value(0), int)
assert_type(fd.value(), int)
-assert_type(fd.get("a"), int | None)
+assert_type(fd.get("a"), Union[int, None])
assert_type(fd.items(), ItemsView[str, int])
assert_type(fd.keys(), KeysView[str])
assert_type(fd.values(), ValuesView[int])
assert_type(copy.copy(fd), frozendict[str, int])
assert_type(copy.deepcopy(fd), frozendict[str, int])
-assert_type(reversed(fd), reversed)
+# noinspection PyUnresolvedReferences
+assert_type(reversed(fd), reversed[str])
assert_type(fd.delete("a"), frozendict[str, int])
assert_type(fd | {"c": 2}, frozendict[str, int])
-assert_type(fd | {1: 2}, frozendict[str | int, int])
-assert_type(fd | {"c": "c"}, frozendict[str, str | int])
-assert_type(fd | {1: "c"}, frozendict[str | int, str | int])
+assert_type(fd | {1: 2}, frozendict[Union[str, int], int])
+assert_type(fd | {"c": "c"}, frozendict[str, Union[str, int]])
+assert_type(fd | {1: "c"}, frozendict[Union[str, int], Union[str, int]])
assert_type(fd.setdefault("a", 0), frozendict[str, int])
-assert_type(fd.setdefault("a", "a"), frozendict[str, str | int])
-assert_type(fd.setdefault(0, 0), frozendict[str | int, int])
-assert_type(fd.setdefault(0, "a"), frozendict[str | int, str | int])
+assert_type(fd.setdefault("a", "a"), frozendict[str, Union[str, int]])
+assert_type(fd.setdefault(0, 0), frozendict[Union[str, int], int])
+
+assert_type(
+ fd.setdefault(0, "a"),
+ frozendict[Union[str, int], Union[str, int]]
+)
assert_type(fd.set("abc", 1), frozendict[str, int])
-assert_type(fd.set("abc", "abc"), frozendict[str, str | int])
-assert_type(fd.set(1, 1), frozendict[str | int, int])
-assert_type(fd.set(1, "abc"), frozendict[str | int, str | int])
+
+assert_type(
+ fd.set("abc", "abc"),
+ frozendict[str, Union[str, int]]
+)
+
+assert_type(fd.set(1, 1), frozendict[Union[str, int], int])
+
+assert_type(
+ fd.set(1, "abc"),
+ frozendict[Union[str, int], Union[str, int]]
+)
# frozendict implements Mapping[K, V] and is covariant in V
vals: frozendict[str, Hashable] = fd