Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-atom for openSUSE:Factory 
checked in at 2024-09-01 19:21:29
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-atom (Old)
 and      /work/SRC/openSUSE:Factory/.python-atom.new.2698 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-atom"

Sun Sep  1 19:21:29 2024 rev:14 rq:1197801 version:0.10.5

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-atom/python-atom.changes  2024-01-30 
18:26:48.864971056 +0100
+++ /work/SRC/openSUSE:Factory/.python-atom.new.2698/python-atom.changes        
2024-09-01 19:21:44.420785462 +0200
@@ -1,0 +2,9 @@
+Thu Aug 22 10:26:48 UTC 2024 - Frantisek Simorda <frantisek.simo...@suse.com>
+
+- Update to 0.10.5:
+  * fix ruff config 
+  * Merge pull request #209 from nucleic/ruff-fixes
+  * ci: do not build oldest python on macos 
+  * Fix memory leak in pickle creation (#213)  
+
+-------------------------------------------------------------------

Old:
----
  atom-0.10.4.tar.gz

New:
----
  atom-0.10.5.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-atom.spec ++++++
--- /var/tmp/diff_new_pack.3thxjv/_old  2024-09-01 19:21:45.228818544 +0200
+++ /var/tmp/diff_new_pack.3thxjv/_new  2024-09-01 19:21:45.228818544 +0200
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-atom
-Version:        0.10.4
+Version:        0.10.5
 Release:        0
 Summary:        Memory efficient Python objects
 License:        BSD-3-Clause

++++++ atom-0.10.4.tar.gz -> atom-0.10.5.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/atom-0.10.4/.github/workflows/ci.yml 
new/atom-0.10.5/.github/workflows/ci.yml
--- old/atom-0.10.4/.github/workflows/ci.yml    2024-01-23 16:29:13.000000000 
+0100
+++ new/atom-0.10.5/.github/workflows/ci.yml    2024-07-04 08:29:58.000000000 
+0200
@@ -47,7 +47,7 @@
       - name: Linting
         if: always()
         run: |
-          ruff atom examples tests
+          ruff check atom examples tests
       - name: Typing
         if: always()
         run: |
@@ -95,6 +95,11 @@
       matrix:
         os: [ubuntu-latest, windows-latest, macos-latest]
         python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
+        exclude:
+          - python-version: '3.8'
+            os: macos-latest
+          - python-version: '3.9'
+            os: macos-latest
     steps:
       - uses: actions/checkout@v4
       - name: Get history and tags for SCM versioning to work
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/atom-0.10.4/PKG-INFO new/atom-0.10.5/PKG-INFO
--- old/atom-0.10.4/PKG-INFO    2024-01-23 16:29:27.701215700 +0100
+++ new/atom-0.10.5/PKG-INFO    2024-07-04 08:30:05.404321700 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: atom
-Version: 0.10.4
+Version: 0.10.5
 Summary: Memory efficient Python objects
 Author-email: The Nucleic Development Team <sccolb...@gmail.com>
 Maintainer-email: "Matthieu C. Dartiailh" <m.dartia...@gmail.com>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/atom-0.10.4/atom/src/catom.cpp 
new/atom-0.10.5/atom/src/catom.cpp
--- old/atom-0.10.4/atom/src/catom.cpp  2024-01-23 16:29:13.000000000 +0100
+++ new/atom-0.10.5/atom/src/catom.cpp  2024-07-04 08:29:58.000000000 +0200
@@ -375,8 +375,9 @@
 CAtom_getstate( CAtom* self )
 {
     cppy::ptr stateptr = PyDict_New();
-    if ( !stateptr )
+    if ( !stateptr ) {
         return PyErr_NoMemory();  // LCOV_EXCL_LINE
+    }
 
     cppy::ptr selfptr(pyobject_cast(self), true);
 
@@ -391,26 +392,33 @@
     // Copy __slots__ if present. This assumes copyreg._slotnames was called
     // during AtomMeta's initialization
     {
-        cppy::ptr typeptr = PyObject_Type(selfptr.get());
-        if (!typeptr)
-            return 0;
-        cppy::ptr slotnamesptr = typeptr.getattr("__slotnames__");
-        if (!slotnamesptr.get())
+        PyObject* typedict = Py_TYPE(selfptr.get())->tp_dict;
+        cppy::ptr slotnamesptr(PyDict_GetItemString(typedict, 
"__slotnames__"), true);
+        if ( !slotnamesptr ) {
             return 0;
-        if (!PyList_CheckExact(slotnamesptr.get()))
+        }
+        if ( !PyList_CheckExact(slotnamesptr.get()) ) {
             return cppy::system_error( "slot names" );
+        }
         for ( Py_ssize_t i=0; i < PyList_GET_SIZE(slotnamesptr.get()); i++ )
         {
             PyObject *name = PyList_GET_ITEM(slotnamesptr.get(), i);
             cppy::ptr value = selfptr.getattr(name);
-            if (!value || PyDict_SetItem(stateptr.get(), name, value.get()) )
+            if (!value ) {
+                // Following CPython impl it is not an error if the attribute 
is
+                // not present.
+                continue;
+            }
+            else if ( PyDict_SetItem(stateptr.get(), name, value.get()) ) {
                 return  0;
+            }
         }
     }
 
     cppy::ptr membersptr = selfptr.getattr(atom_members);
-    if ( !membersptr || !PyDict_CheckExact( membersptr.get() ) )
+    if ( !membersptr || !PyDict_CheckExact( membersptr.get() ) ) {
         return cppy::system_error( "atom members" );
+    }
 
     PyObject *name, *member;
     Py_ssize_t pos = 0;
@@ -421,9 +429,8 @@
         }
         int test = PyObject_IsTrue( should_gs.get() );
         if ( test == 1) {
-            PyObject *value =  member_cast( member )->getattr( self );
-            if (!value || PyDict_SetItem( stateptr.get(), name, value ) ) {
-                Py_XDECREF( value );
+            cppy::ptr value =  member_cast( member )->getattr( self );
+            if (!value || PyDict_SetItem( stateptr.get(), name, value.get() ) 
) {
                 return  0;
             }
         }
@@ -433,8 +440,9 @@
     }
 
     // Frozen state
-    if ( self->is_frozen() && PyDict_SetItem(stateptr.get(), atom_flags, 
Py_None) )
+    if ( self->is_frozen() && PyDict_SetItem(stateptr.get(), atom_flags, 
Py_None) ) {
         return 0;
+    }
 
     return stateptr.release();
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/atom-0.10.4/atom/version.py 
new/atom-0.10.5/atom/version.py
--- old/atom-0.10.4/atom/version.py     2024-01-23 16:29:27.000000000 +0100
+++ new/atom-0.10.5/atom/version.py     2024-07-04 08:30:05.000000000 +0200
@@ -12,7 +12,7 @@
 #: A namedtuple of the version info for the current release.
 _version_info = namedtuple("_version_info", "major minor micro status")
 
-parts = "0.10.4".split(".", 3)
+parts = "0.10.5".split(".", 3)
 version_info = _version_info(
     int(parts[0]),
     int(parts[1]),
@@ -23,4 +23,4 @@
 # Remove everything but the 'version_info' from this module.
 del namedtuple, _version_info, parts
 
-__version__ = "0.10.4"
+__version__ = "0.10.5"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/atom-0.10.4/atom.egg-info/PKG-INFO 
new/atom-0.10.5/atom.egg-info/PKG-INFO
--- old/atom-0.10.4/atom.egg-info/PKG-INFO      2024-01-23 16:29:27.000000000 
+0100
+++ new/atom-0.10.5/atom.egg-info/PKG-INFO      2024-07-04 08:30:05.000000000 
+0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: atom
-Version: 0.10.4
+Version: 0.10.5
 Summary: Memory efficient Python objects
 Author-email: The Nucleic Development Team <sccolb...@gmail.com>
 Maintainer-email: "Matthieu C. Dartiailh" <m.dartia...@gmail.com>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/atom-0.10.4/docs/source/examples/example_doc_generator.py 
new/atom-0.10.5/docs/source/examples/example_doc_generator.py
--- old/atom-0.10.4/docs/source/examples/example_doc_generator.py       
2024-01-23 16:29:13.000000000 +0100
+++ new/atom-0.10.5/docs/source/examples/example_doc_generator.py       
2024-07-04 08:29:58.000000000 +0200
@@ -87,7 +87,7 @@
 
     # Add the script to the Python Path
     old_python_path = sys.path
-    sys.path = sys.path + [os.path.dirname(script_path)]
+    sys.path = [*sys.path, os.path.dirname(script_path)]
 
     # Restore Python path.
     sys.path = old_python_path
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/atom-0.10.4/pyproject.toml 
new/atom-0.10.5/pyproject.toml
--- old/atom-0.10.4/pyproject.toml      2024-01-23 16:29:13.000000000 +0100
+++ new/atom-0.10.5/pyproject.toml      2024-07-04 08:29:58.000000000 +0200
@@ -74,16 +74,18 @@
 
 [tool.ruff]
   src = ["src"]
-  select = ["C", "E", "F", "W", "I", "C90", "RUF"]
-  extend-ignore = ["E501", "RUF012"]
   line-length = 88
 
-  [tool.ruff.isort]
-    combine-as-imports = true
-    known-first-party = ["atom"]
+  [tool.ruff.lint]
+    select = ["C", "E", "F", "W", "I", "C90", "RUF"]
+    extend-ignore = ["E501", "RUF012"]
 
-  [tool.ruff.mccabe]
-    max-complexity = 20
+    [tool.ruff.lint.isort]
+      combine-as-imports = true
+      known-first-party = ["atom"]
+
+    [tool.ruff.lint.mccabe]
+      max-complexity = 20
 
 [tool.mypy]
   follow_imports = "normal"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/atom-0.10.4/tests/test_atom_from_annotations.py 
new/atom-0.10.5/tests/test_atom_from_annotations.py
--- old/atom-0.10.4/tests/test_atom_from_annotations.py 2024-01-23 
16:29:13.000000000 +0100
+++ new/atom-0.10.5/tests/test_atom_from_annotations.py 2024-07-04 
08:29:58.000000000 +0200
@@ -168,7 +168,7 @@
         assert A.a.validate_mode[1] == (annotation.__origin__,)
     elif member is Subclass:
         if isinstance(annotation.__args__[0], TypeVar):
-            assert A.a.validate_mode[1] == object
+            assert A.a.validate_mode[1] is object
         else:
             assert A.a.validate_mode[1] == annotation.__args__[0]
     else:
@@ -254,9 +254,9 @@
                 assert type(v) is type(mv)
                 assert f(A()) == mf(A())
         else:
-            assert type(A.a.item) is type(member.item)  # noqa: E721
+            assert type(A.a.item) is type(member.item)
             if isinstance(member.item, List):
-                assert type(A.a.item.item) is type(member.item.item)  # noqa: 
E721
+                assert type(A.a.item.item) is type(member.item.item)
 
 
 @pytest.mark.parametrize(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/atom-0.10.4/tests/test_mem.py 
new/atom-0.10.5/tests/test_mem.py
--- old/atom-0.10.4/tests/test_mem.py   2024-01-23 16:29:13.000000000 +0100
+++ new/atom-0.10.5/tests/test_mem.py   2024-07-04 08:29:58.000000000 +0200
@@ -1,5 +1,5 @@
 # 
--------------------------------------------------------------------------------------
-# Copyright (c) 2023, Nucleic Development Team.
+# Copyright (c) 2023-2024, Nucleic Development Team.
 #
 # Distributed under the terms of the Modified BSD License.
 #
@@ -7,8 +7,10 @@
 # 
--------------------------------------------------------------------------------------
 import gc
 import os
+import pickle
 import sys
 import time
+import tracemalloc
 from multiprocessing import Process
 
 import pytest
@@ -53,6 +55,13 @@
     "atomref": RefObj,
 }
 
+PICKLE_MEM_TESTS = {
+    "dict": DictObj,
+    "defaultdict": DefaultDictObj,
+    "list": ListObj,
+    "set": SetObj,
+}
+
 
 def memtest(cls):
     # Create object in a loop
@@ -105,3 +114,34 @@
     finally:
         p.kill()
         p.join()
+
+
+@pytest.mark.parametrize("label", PICKLE_MEM_TESTS.keys())
+def test_pickle_mem_usage(label):
+    TestClass = PICKLE_MEM_TESTS[label]
+
+    obj = TestClass()
+
+    for _ in range(100):
+        pickle.loads(pickle.dumps(obj))
+
+    gc.collect()
+    tracemalloc.start()
+    for i in range(10000):
+        pck = pickle.dumps(obj)
+        pickle.loads(pck)
+        del pck
+    gc.collect()
+    for stat in (
+        tracemalloc.take_snapshot()
+        .filter_traces(
+            [
+                tracemalloc.Filter(True, "*/atom/*"),
+                tracemalloc.Filter(False, "*/tests/*"),
+            ]
+        )
+        .statistics("lineno")
+    ):
+        # not sure why I sometimes see a 2 here but the original buggy version
+        # reported values > 50
+        assert stat.count < 5
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/atom-0.10.4/tests/type_checking/test_subclass.yml 
new/atom-0.10.5/tests/type_checking/test_subclass.yml
--- old/atom-0.10.4/tests/type_checking/test_subclass.yml       2024-01-23 
16:29:13.000000000 +0100
+++ new/atom-0.10.5/tests/type_checking/test_subclass.yml       2024-07-04 
08:29:58.000000000 +0200
@@ -1,60 +1,61 @@
 #------------------------------------------------------------------------------
-# Copyright (c) 2021, Nucleic Development Team.
+# Copyright (c) 2021-2024, Nucleic Development Team.
 #
 # Distributed under the terms of the Modified BSD License.
 #
 # The full license is in the file LICENSE, distributed with this software.
 #------------------------------------------------------------------------------
 - case: subclass
+  skip: sys.version_info < (3, 9)  # 3.8 uses Type[] while 3.9+ uses type[]
   parametrized:
     - member: Subclass
       member_instance: Subclass(A)
-      member_type: atom.subclass.Subclass[Type[main.A]]
-      member_value_type: Type[main.A]
+      member_type: atom.subclass.Subclass[type[main.A]]
+      member_value_type: type[main.A]
     - member: Subclass
       member_instance: Subclass(A, B)
-      member_type: atom.subclass.Subclass[Type[main.A]]
-      member_value_type: Type[main.A]
+      member_type: atom.subclass.Subclass[type[main.A]]
+      member_value_type: type[main.A]
     - member: Subclass
       member_instance: Subclass((A,))
-      member_type: atom.subclass.Subclass[Type[main.A]]
-      member_value_type: Type[main.A]
+      member_type: atom.subclass.Subclass[type[main.A]]
+      member_value_type: type[main.A]
     - member: Subclass
       member_instance: Subclass((A,), B)
-      member_type: atom.subclass.Subclass[Type[main.A]]
-      member_value_type: Type[main.A]
+      member_type: atom.subclass.Subclass[type[main.A]]
+      member_value_type: type[main.A]
     - member: Subclass
       member_instance: Subclass((int, A))
-      member_type: atom.subclass.Subclass[Union[Type[builtins.int], 
Type[main.A]]]
-      member_value_type: Union[Type[builtins.int], Type[main.A]]
+      member_type: atom.subclass.Subclass[Union[type[builtins.int], 
type[main.A]]]
+      member_value_type: Union[type[builtins.int], type[main.A]]
     - member: Subclass
       member_instance: Subclass((int, A), B)
-      member_type: atom.subclass.Subclass[Union[Type[builtins.int], 
Type[main.A]]]
-      member_value_type: Union[Type[builtins.int], Type[main.A]]
+      member_type: atom.subclass.Subclass[Union[type[builtins.int], 
type[main.A]]]
+      member_value_type: Union[type[builtins.int], type[main.A]]
     - member: Subclass
       member_instance: Subclass((int, A, str))
-      member_type: atom.subclass.Subclass[Union[Type[builtins.int], 
Type[main.A], Type[builtins.str]]]
-      member_value_type: Union[Type[builtins.int], Type[main.A], 
Type[builtins.str]]
+      member_type: atom.subclass.Subclass[Union[type[builtins.int], 
type[main.A], type[builtins.str]]]
+      member_value_type: Union[type[builtins.int], type[main.A], 
type[builtins.str]]
     - member: Subclass
       member_instance: Subclass((int, A, str), B)
-      member_type: atom.subclass.Subclass[Union[Type[builtins.int], 
Type[main.A], Type[builtins.str]]]
-      member_value_type: Union[Type[builtins.int], Type[main.A], 
Type[builtins.str]]
+      member_type: atom.subclass.Subclass[Union[type[builtins.int], 
type[main.A], type[builtins.str]]]
+      member_value_type: Union[type[builtins.int], type[main.A], 
type[builtins.str]]
     - member: ForwardSubclass
       member_instance: ForwardSubclass(resolve1)
-      member_type: atom.subclass.ForwardSubclass[Type[main.A]]
-      member_value_type: Type[main.A]
+      member_type: atom.subclass.ForwardSubclass[type[main.A]]
+      member_value_type: type[main.A]
     - member: ForwardSubclass
       member_instance: ForwardSubclass(resolve2)
-      member_type: atom.subclass.ForwardSubclass[Type[main.A]]
-      member_value_type: Type[main.A]
+      member_type: atom.subclass.ForwardSubclass[type[main.A]]
+      member_value_type: type[main.A]
     - member: ForwardSubclass
       member_instance: ForwardSubclass(resolve3)
-      member_type: atom.subclass.ForwardSubclass[Union[Type[builtins.int], 
Type[main.A]]]
-      member_value_type: Union[Type[builtins.int], Type[main.A]]
+      member_type: atom.subclass.ForwardSubclass[Union[type[builtins.int], 
type[main.A]]]
+      member_value_type: Union[type[builtins.int], type[main.A]]
     - member: ForwardSubclass
       member_instance: ForwardSubclass(resolve4)
-      member_type: atom.subclass.ForwardSubclass[Union[Type[builtins.int], 
Type[main.A], Type[builtins.str]]]
-      member_value_type: Union[Type[builtins.int], Type[main.A], 
Type[builtins.str]]
+      member_type: atom.subclass.ForwardSubclass[Union[type[builtins.int], 
type[main.A], type[builtins.str]]]
+      member_value_type: Union[type[builtins.int], type[main.A], 
type[builtins.str]]
   main: |
     import io
     from typing import Tuple, Type

Reply via email to