Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-cloudpickle for 
openSUSE:Factory checked in at 2025-12-16 15:49:37
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-cloudpickle (Old)
 and      /work/SRC/openSUSE:Factory/.python-cloudpickle.new.1939 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-cloudpickle"

Tue Dec 16 15:49:37 2025 rev:28 rq:1322605 version:3.1.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-cloudpickle/python-cloudpickle.changes    
2025-09-26 22:24:45.734617124 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-cloudpickle.new.1939/python-cloudpickle.changes
  2025-12-16 15:49:47.270373570 +0100
@@ -1,0 +2,8 @@
+Fri Dec 12 11:59:47 UTC 2025 - Daniel Garcia <[email protected]>
+
+- Update to 3.1.2:
+  * Fix pickling of abstract base classes containing type annotations
+    for Python 3.14. (PR#578)
+- Remove upstreamed patch support-python-314.patch
+
+-------------------------------------------------------------------

Old:
----
  cloudpickle-3.1.1-gh.tar.gz
  support-python-314.patch

New:
----
  cloudpickle-3.1.2-gh.tar.gz

----------(Old B)----------
  Old:    for Python 3.14. (PR#578)
- Remove upstreamed patch support-python-314.patch
----------(Old E)----------

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

Other differences:
------------------
++++++ python-cloudpickle.spec ++++++
--- /var/tmp/diff_new_pack.n2LY7u/_old  2025-12-16 15:49:48.478424725 +0100
+++ /var/tmp/diff_new_pack.n2LY7u/_new  2025-12-16 15:49:48.478424725 +0100
@@ -18,14 +18,12 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-cloudpickle
-Version:        3.1.1
+Version:        3.1.2
 Release:        0
 Summary:        Extended pickling support for Python objects
 License:        BSD-3-Clause
 URL:            https://github.com/cloudpipe/cloudpickle
 Source:         
https://github.com/cloudpipe/cloudpickle/archive/refs/tags/v{%version}.tar.gz#/cloudpickle-%{version}-gh.tar.gz
-# PATCH-FIX-UPSTREAM gh#cloudpipe/cloudpickle#570
-Patch0:         support-python-314.patch
 BuildRequires:  %{python_module base >= 3.8}
 BuildRequires:  %{python_module flit-core}
 BuildRequires:  %{python_module pip}

++++++ cloudpickle-3.1.1-gh.tar.gz -> cloudpickle-3.1.2-gh.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/cloudpickle-3.1.1/.github/workflows/publish_to_pypi.yml 
new/cloudpickle-3.1.2/.github/workflows/publish_to_pypi.yml
--- old/cloudpickle-3.1.1/.github/workflows/publish_to_pypi.yml 2025-01-14 
17:59:46.000000000 +0100
+++ new/cloudpickle-3.1.2/.github/workflows/publish_to_pypi.yml 2025-11-03 
10:12:44.000000000 +0100
@@ -1,4 +1,4 @@
-name: Publish Python 🐍 distribution 📦 to PyPI and TestPyPI
+name: Publish cloudpickle 🥒 distribution 📦 to PyPI and TestPyPI
 # Taken from:
 # 
https://packaging.python.org/en/latest/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/
 
@@ -7,6 +7,8 @@
 jobs:
   build:
     name: Build distribution 📦
+    # Don't run on forked repositories
+    if: github.event.repository.fork != true
     runs-on: ubuntu-latest
 
     steps:
@@ -30,10 +32,11 @@
       with:
         name: python-package-distributions
         path: dist/
+        retention-days: 1
 
   publish-to-pypi:
     name: >-
-      Publish Python 🐍 distribution 📦 to PyPI
+      Publish cloudpickle 🥒 distribution 📦 to PyPI
     if: startsWith(github.ref, 'refs/tags/')  # only publish to PyPI on tag 
pushes
     needs:
     - build
@@ -55,7 +58,7 @@
 
   github-release:
     name: >-
-      Sign the Python 🐍 distribution 📦 with Sigstore
+      Sign the cloudpickle 🥒 distribution 📦 with Sigstore
       and upload them to GitHub Release
     needs:
     - publish-to-pypi
@@ -97,9 +100,10 @@
         --repo "$GITHUB_REPOSITORY"
 
   publish-to-testpypi:
-    name: Publish Python 🐍 distribution 📦 to TestPyPI
+    name: Publish cloudpickle 🥒 distribution 📦 to TestPyPI
     needs:
     - build
+    if: github.ref_name == 'master'
     runs-on: ubuntu-latest
 
     environment:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cloudpickle-3.1.1/.pre-commit-config.yaml 
new/cloudpickle-3.1.2/.pre-commit-config.yaml
--- old/cloudpickle-3.1.1/.pre-commit-config.yaml       2025-01-14 
17:59:46.000000000 +0100
+++ new/cloudpickle-3.1.2/.pre-commit-config.yaml       2025-11-03 
10:12:44.000000000 +0100
@@ -1,6 +1,6 @@
 repos:
 -   repo: https://github.com/pre-commit/pre-commit-hooks
-    rev: v4.5.0
+    rev: v6.0.0
     hooks:
     -   id: check-yaml
     -   id: end-of-file-fixer
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cloudpickle-3.1.1/CHANGES.md 
new/cloudpickle-3.1.2/CHANGES.md
--- old/cloudpickle-3.1.1/CHANGES.md    2025-01-14 17:59:46.000000000 +0100
+++ new/cloudpickle-3.1.2/CHANGES.md    2025-11-03 10:12:44.000000000 +0100
@@ -1,6 +1,12 @@
 In development
 ==============
 
+3.1.2
+=====
+
+- Fix pickling of abstract base classes containing type annotations for
+  Python 3.14. ([PR#578](https://github.com/cloudpipe/cloudpickle/pull/578))
+
 3.1.1
 =====
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cloudpickle-3.1.1/cloudpickle/__init__.py 
new/cloudpickle-3.1.2/cloudpickle/__init__.py
--- old/cloudpickle-3.1.1/cloudpickle/__init__.py       2025-01-14 
17:59:46.000000000 +0100
+++ new/cloudpickle-3.1.2/cloudpickle/__init__.py       2025-11-03 
10:12:44.000000000 +0100
@@ -3,7 +3,7 @@
 
 __doc__ = cloudpickle.__doc__
 
-__version__ = "3.1.1"
+__version__ = "3.1.2"
 
 __all__ = [  # noqa
     "__version__",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cloudpickle-3.1.1/cloudpickle/cloudpickle.py 
new/cloudpickle-3.1.2/cloudpickle/cloudpickle.py
--- old/cloudpickle-3.1.1/cloudpickle/cloudpickle.py    2025-01-14 
17:59:46.000000000 +0100
+++ new/cloudpickle-3.1.2/cloudpickle/cloudpickle.py    2025-11-03 
10:12:44.000000000 +0100
@@ -783,6 +783,12 @@
 
     clsdict.pop("__dict__", None)  # unpicklable property object
 
+    if sys.version_info >= (3, 14):
+        # PEP-649/749: __annotate_func__ contains a closure that references 
the class
+        # dict. We need to exclude it from pickling. Python will recreate it 
when
+        # __annotations__ is accessed at unpickling time.
+        clsdict.pop("__annotate_func__", None)
+
     return (clsdict, {})
 
 
@@ -1190,6 +1196,10 @@
         for subclass in registry:
             obj.register(subclass)
 
+    # PEP-649/749: During pickling, we excluded the __annotate_func__ 
attribute but it
+    # will be created by Python. Subsequently, annotations will be recreated 
when
+    # __annotations__ is accessed.
+
     return obj
 
 
@@ -1301,12 +1311,9 @@
     def dump(self, obj):
         try:
             return super().dump(obj)
-        except RuntimeError as e:
-            if len(e.args) > 0 and "recursion" in e.args[0]:
-                msg = "Could not pickle object as excessively deep recursion 
required."
-                raise pickle.PicklingError(msg) from e
-            else:
-                raise
+        except RecursionError as e:
+            msg = "Could not pickle object as excessively deep recursion 
required."
+            raise pickle.PicklingError(msg) from e
 
     def __init__(self, file, protocol=None, buffer_callback=None):
         if protocol is None:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cloudpickle-3.1.1/tests/cloudpickle_test.py 
new/cloudpickle-3.1.2/tests/cloudpickle_test.py
--- old/cloudpickle-3.1.1/tests/cloudpickle_test.py     2025-01-14 
17:59:46.000000000 +0100
+++ new/cloudpickle-3.1.2/tests/cloudpickle_test.py     2025-11-03 
10:12:44.000000000 +0100
@@ -2507,19 +2507,19 @@
         inner_func = depickled_factory()
         assert inner_func() == _TEST_GLOBAL_VARIABLE
 
+    # TODO: remove this xfail when we drop support for Python 3.8. We don't
+    # plan to fix it because Python 3.8 is EOL.
     @pytest.mark.skipif(
         sys.version_info < (3, 9),
         reason="Can cause CPython 3.8 to segfault",
     )
-    # TODO: remove this xfail when we drop support for Python 3.8. We don't
-    # plan to fix it because Python 3.8 is EOL.
     def test_recursion_during_pickling(self):
         class A:
             def __getattribute__(self, name):
                 return getattr(self, name)
 
         a = A()
-        with pytest.raises(pickle.PicklingError, match="recursion"):
+        with pytest.raises(pickle.PicklingError, match="deep recursion"):
             cloudpickle.dumps(a)
 
     def test_out_of_band_buffers(self):
@@ -2652,7 +2652,9 @@
                 MyClass.__annotations__ = {"attribute": type_}
 
                 def check_annotations(obj, expected_type, expected_type_str):
-                    assert obj.__annotations__["attribute"] == expected_type
+                    # On Python 3.14, it's no longer possible to access class
+                    # annotations from an instance, so use type().
+                    assert type(obj).__annotations__["attribute"] == 
expected_type
                     assert obj.method.__annotations__["arg"] == expected_type
                     assert obj.method.__annotations__["return"] == 
expected_type
                     return "ok"
@@ -2670,6 +2672,22 @@
         C1 = pickle_depickle(C, protocol=self.protocol)
         assert C1.__annotations__ == C.__annotations__
 
+    def test_class_annotations_abstractclass(self):
+        # see https://github.com/cloudpipe/cloudpickle/issues/572
+
+        class C(abc.ABC):
+            a: int
+
+        C1 = pickle_depickle(C, protocol=self.protocol)
+        assert C1.__annotations__ == C.__annotations__
+        C2 = pickle_depickle(C1, protocol=self.protocol)
+        if sys.version_info >= (3, 14):
+            # check that __annotate_func__ is created by Python
+            assert hasattr(C2, "__annotate_func__")
+        assert C2.__annotations__ == C1.__annotations__
+        c2 = C2()
+        assert isinstance(c2, C2)
+
     def test_function_annotations(self):
         def f(a: int) -> str:
             pass

Reply via email to