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

Reply via email to