Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-msgpack for openSUSE:Factory 
checked in at 2026-10-30 18:03:45
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-msgpack (Old)
 and      /work/SRC/openSUSE:Factory/.python-msgpack.new.1255 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-msgpack"

Fri Oct 30 18:03:45 2026 rev:23 rq:1393622 version:1.2.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-msgpack/python-msgpack.changes    
2026-10-06 19:13:43.922742836 +0200
+++ /work/SRC/openSUSE:Factory/.python-msgpack.new.1255/python-msgpack.changes  
2026-10-30 18:04:17.635153909 +0100
@@ -1,0 +2,14 @@
+Wed Oct 28 18:56:51 UTC 2026 - Marcus Rueckert <[email protected]>
+
+- Uppdate to 1.2.4: (GHSA-j586-36cw-2gc2)
+  - fallback: pass object_pairs_hook a list of pairs by @youdie006
+    in #744
+  - fallback: leave the object unread when a header type does not
+    match by @Shaisolaris in #748
+  - Bump the all-dependencies group with 3 updates by
+    @dependabot[bot] in #749
+  - fallback: return bytes from Unpacker.read_bytes by @Cherith1222
+    in #747
+  - Run tracemalloc tests sequentially by @methane in #758
+
+-------------------------------------------------------------------

Old:
----
  msgpack-1.2.3.tar.gz

New:
----
  msgpack-1.2.4.tar.gz

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

Other differences:
------------------
++++++ python-msgpack.spec ++++++
--- /var/tmp/diff_new_pack.dNlQXB/_old  2026-10-30 18:04:22.698365925 +0100
+++ /var/tmp/diff_new_pack.dNlQXB/_new  2026-10-30 18:04:22.705366218 +0100
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-msgpack
-Version:        1.2.3
+Version:        1.2.4
 Release:        0
 Summary:        MessagePack (de)serializer
 License:        Apache-2.0

++++++ msgpack-1.2.3.tar.gz -> msgpack-1.2.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msgpack-1.2.3/PKG-INFO new/msgpack-1.2.4/PKG-INFO
--- old/msgpack-1.2.3/PKG-INFO  2026-09-29 04:30:26.223456900 +0200
+++ new/msgpack-1.2.4/PKG-INFO  2026-10-26 18:09:40.613909700 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: msgpack
-Version: 1.2.3
+Version: 1.2.4
 Summary: MessagePack serializer
 Author-email: Inada Naoki <[email protected]>
 License-Expression: Apache-2.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msgpack-1.2.3/msgpack/__init__.py 
new/msgpack-1.2.4/msgpack/__init__.py
--- old/msgpack-1.2.3/msgpack/__init__.py       2026-09-29 03:41:54.464199800 
+0200
+++ new/msgpack-1.2.4/msgpack/__init__.py       2026-10-26 18:04:34.442975300 
+0100
@@ -4,8 +4,8 @@
 from .exceptions import *  # noqa: F403
 from .ext import ExtType, Timestamp
 
-version = (1, 2, 3)
-__version__ = "1.2.3"
+version = (1, 2, 4)
+__version__ = "1.2.4"
 
 
 if os.environ.get("MSGPACK_PUREPYTHON"):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msgpack-1.2.3/msgpack/fallback.py 
new/msgpack-1.2.4/msgpack/fallback.py
--- old/msgpack-1.2.3/msgpack/fallback.py       2026-09-29 03:41:54.464795800 
+0200
+++ new/msgpack-1.2.4/msgpack/fallback.py       2026-10-26 18:04:34.443244700 
+0100
@@ -356,7 +356,8 @@
     def read_bytes(self, n):
         ret = self._read(n, raise_outofdata=False)
         self._consume()
-        return ret
+        # The C extension returns bytes. A bytearray slice cannot be a dict 
key.
+        return bytes(ret)
 
     def _read(self, n, raise_outofdata=True):
         # (int) -> bytearray
@@ -501,10 +502,13 @@
 
         if execute == EX_READ_ARRAY_HEADER:
             if typ != TYPE_ARRAY:
+                # Leave the object unread, as the C extension does.
+                self._buff_i = self._buf_checkpoint
                 raise ValueError("Expected array")
             return n
         if execute == EX_READ_MAP_HEADER:
             if typ != TYPE_MAP:
+                self._buff_i = self._buf_checkpoint
                 raise ValueError("Expected map")
             return n
         # TODO should we eliminate the recursion?
@@ -514,7 +518,7 @@
                     # TODO check whether we need to call `list_hook`
                     self._unpack(EX_SKIP)
                 return
-            ret = newlist_hint(n)
+            ret = newlist_hint(min(n, 10000))
             for i in range(n):
                 ret.append(self._unpack(EX_CONSTRUCT))
             if self._list_hook is not None:
@@ -529,15 +533,15 @@
                     self._unpack(EX_SKIP)
                 return
             if self._object_pairs_hook is not None:
-
-                def _gen():
-                    for _ in range(n):
-                        key = self._unpack(EX_CONSTRUCT)
-                        if self._strict_map_key and type(key) not in (str, 
bytes):
-                            raise ValueError("%s is not allowed for map key" % 
str(type(key)))
-                        yield key, self._unpack(EX_CONSTRUCT)
-
-                ret = self._object_pairs_hook(_gen())
+                # Pass a list, as the C extension does, so the whole map is
+                # consumed even if the hook does not iterate it.
+                pairs = []
+                for _ in range(n):
+                    key = self._unpack(EX_CONSTRUCT)
+                    if self._strict_map_key and type(key) not in (str, bytes):
+                        raise ValueError("%s is not allowed for map key" % 
str(type(key)))
+                    pairs.append((key, self._unpack(EX_CONSTRUCT)))
+                ret = self._object_pairs_hook(pairs)
             else:
                 ret = {}
                 for _ in range(n):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msgpack-1.2.3/msgpack/unpack.h 
new/msgpack-1.2.4/msgpack/unpack.h
--- old/msgpack-1.2.3/msgpack/unpack.h  2026-09-29 03:41:54.464795800 +0200
+++ new/msgpack-1.2.4/msgpack/unpack.h  2026-10-26 18:04:34.443780700 +0100
@@ -17,6 +17,7 @@
  */
 
 #define MSGPACK_EMBED_STACK_SIZE  (1024)
+#define MSGPACK_MAX_PREALLOC  (10000)
 #include "unpack_define.h"
 
 typedef struct unpack_user {
@@ -131,7 +132,9 @@
         PyErr_Format(PyExc_ValueError, "%u exceeds max_array_len(%zd)", n, 
u->max_array_len);
         return -1;
     }
-    PyObject *p = u->use_list ? PyList_New(n) : PyTuple_New(n);
+    /* Large tuples are built as lists and converted when complete. */
+    PyObject *p = n > MSGPACK_MAX_PREALLOC ? PyList_New(MSGPACK_MAX_PREALLOC) :
+        (u->use_list ? PyList_New(n) : PyTuple_New(n));
 
     if (!p)
         return -1;
@@ -139,13 +142,24 @@
     return 0;
 }
 
+/* Consumes o on both success and failure; borrows the list. */
+static inline int unpack_list_item(PyObject *list, unsigned int current, 
PyObject *o)
+{
+    if (current < MSGPACK_MAX_PREALLOC) {
+        PyList_SET_ITEM(list, current, o);
+        return 0;
+    }
+    int ret = PyList_Append(list, o);
+    Py_DECREF(o);
+    return ret;
+}
+
 /* Consumes o on both success and failure; borrows the container. */
 static inline int unpack_callback_array_item(unpack_user* u, unsigned int 
current, msgpack_unpack_object* c, msgpack_unpack_object o)
 {
-    if (u->use_list)
-        PyList_SET_ITEM(*c, current, o);
-    else
-        PyTuple_SET_ITEM(*c, current, o);
+    if (PyList_CheckExact(*c))
+        return unpack_list_item(*c, current, o);
+    PyTuple_SET_ITEM(*c, current, o);
     return 0;
 }
 
@@ -153,6 +167,13 @@
  * failure. The original reference is consumed in either case. */
 static inline int unpack_callback_array_end(unpack_user* u, 
msgpack_unpack_object* c)
 {
+    if (!u->use_list && PyList_CheckExact(*c)) {
+        PyObject *tuple = PyList_AsTuple(*c);
+        Py_DECREF(*c);
+        *c = tuple;
+        if (!tuple)
+            return -1;
+    }
     if (u->list_hook) {
         PyObject *new_c = PyObject_CallFunctionObjArgs(u->list_hook, *c, NULL);
         Py_DECREF(*c);
@@ -171,7 +192,7 @@
     }
     PyObject *p;
     if (u->has_pairs_hook) {
-        p = PyList_New(n); // Or use tuple?
+        p = PyList_New(n > MSGPACK_MAX_PREALLOC ? MSGPACK_MAX_PREALLOC : n);
     }
     else {
         p = PyDict_New();
@@ -200,8 +221,7 @@
         Py_DECREF(v);
         if (!item)
             return -1;
-        PyList_SET_ITEM(*c, current, item);
-        return 0;
+        return unpack_list_item(*c, current, item);
     }
     int ret = PyDict_SetItem(*c, k, v);
     Py_DECREF(k);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msgpack-1.2.3/msgpack.egg-info/PKG-INFO 
new/msgpack-1.2.4/msgpack.egg-info/PKG-INFO
--- old/msgpack-1.2.3/msgpack.egg-info/PKG-INFO 2026-09-29 04:30:26.199741100 
+0200
+++ new/msgpack-1.2.4/msgpack.egg-info/PKG-INFO 2026-10-26 18:09:40.596446800 
+0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: msgpack
-Version: 1.2.3
+Version: 1.2.4
 Summary: MessagePack serializer
 Author-email: Inada Naoki <[email protected]>
 License-Expression: Apache-2.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msgpack-1.2.3/test/test_except.py 
new/msgpack-1.2.4/test/test_except.py
--- old/msgpack-1.2.3/test/test_except.py       2026-09-29 03:41:54.466057500 
+0200
+++ new/msgpack-1.2.4/test/test_except.py       2026-10-26 18:04:34.444218900 
+0100
@@ -4,7 +4,7 @@
 import gc
 import tracemalloc
 
-from pytest import raises
+from pytest import mark, raises
 
 from msgpack import ExtType, FormatError, OutOfData, StackError, Unpacker, 
packb, unpackb
 
@@ -103,6 +103,7 @@
         unpacker.skip()
 
 
[email protected]_unsafe(reason="tracemalloc changes process-wide state and 
measures all threads")
 def test_no_memory_leak_on_nested_invalid_tag() -> None:
     """Regression test: unpacking nested arrays containing an invalid tag must 
not leak objects."""
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msgpack-1.2.3/test/test_limits.py 
new/msgpack-1.2.4/test/test_limits.py
--- old/msgpack-1.2.3/test/test_limits.py       2026-09-29 03:41:54.466057500 
+0200
+++ new/msgpack-1.2.4/test/test_limits.py       2026-10-26 18:04:34.444218900 
+0100
@@ -1,10 +1,12 @@
 #!/usr/bin/env python
 import sysconfig
+import tracemalloc
 
 import pytest
 
 from msgpack import (
     ExtType,
+    OutOfData,
     Packer,
     PackOverflowError,
     PackValueError,
@@ -118,6 +120,63 @@
         unpacker.unpack()
 
 
[email protected]("size", [9999, 10000, 10001, 20001])
[email protected]("use_list", [False, True])
+def test_array_preallocation_boundary(size, use_list):
+    value = list(range(size))
+    expected = value if use_list else tuple(value)
+    packed = packb(value)
+    assert unpackb(packed, use_list=use_list, list_hook=lambda obj: obj) == 
expected
+
+    unpacker = Unpacker(use_list=use_list)
+    # Suspend after crossing the preallocation boundary.
+    unpacker.feed(packed[:-1])
+    with pytest.raises(OutOfData):
+        unpacker.unpack()
+    unpacker.feed(packed[-1:])
+    assert unpacker.unpack() == expected
+
+
[email protected]("size", [9999, 10000, 10001, 20001])
+def test_pairs_preallocation_boundary(size):
+    value = {str(i): i for i in range(size)}
+    expected = list(value.items())
+    packed = packb(value)
+    assert unpackb(packed, object_pairs_hook=list) == expected
+
+    unpacker = Unpacker(object_pairs_hook=list)
+    unpacker.feed(packed[:-1])
+    with pytest.raises(OutOfData):
+        unpacker.unpack()
+    unpacker.feed(packed[-1:])
+    assert unpacker.unpack() == expected
+
+
[email protected]("kind", ["list", "tuple", "pairs"])
[email protected]_unsafe(reason="tracemalloc changes process-wide state and 
measures all threads")
+def test_nested_headers_preallocation(kind):
+    packer = Packer()
+    header = (
+        packer.pack_map_header(100_000) if kind == "pairs" else 
packer.pack_array_header(100_000)
+    )
+    unpacker = Unpacker(
+        use_list=kind != "tuple", object_pairs_hook=list if kind == "pairs" 
else None
+    )
+    # Map headers nest in key position, so no completed pairs are needed.
+    unpacker.feed(header * 16)
+    already_tracing = tracemalloc.is_tracing()
+    tracemalloc.start()
+    try:
+        before = tracemalloc.get_traced_memory()[0]
+        with pytest.raises(OutOfData):
+            unpacker.unpack()
+        # Full preallocation would retain over 12 MB in the C unpacker.
+        assert tracemalloc.get_traced_memory()[0] - before < 4 * 1024 * 1024
+    finally:
+        if not already_tracing:
+            tracemalloc.stop()
+
+
 def test_max_ext_len():
     d = ExtType(42, b"abc")
     packed = packb(d)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msgpack-1.2.3/test/test_obj.py 
new/msgpack-1.2.4/test/test_obj.py
--- old/msgpack-1.2.3/test/test_obj.py  2026-09-29 03:41:54.466057500 +0200
+++ new/msgpack-1.2.4/test/test_obj.py  2026-10-26 18:04:34.444218900 +0100
@@ -41,6 +41,18 @@
     assert unpacked[1] == prod_sum
 
 
+def test_decode_pairs_hook_receives_list():
+    def reject_duplicate_keys(pairs):
+        keys = [k for k, _ in pairs]
+        assert len(keys) == len(set(keys))
+        return dict(pairs)
+
+    packed = packb([{"a": 1, "b": 2}, 3])
+    assert unpackb(packed, object_pairs_hook=reject_duplicate_keys) == [{"a": 
1, "b": 2}, 3]
+    assert unpackb(packed, object_pairs_hook=lambda pairs: pairs[0]) == [("a", 
1), 3]
+    assert unpackb(packed, object_pairs_hook=lambda pairs: None) == [None, 3]
+
+
 def test_only_one_obj_hook():
     with raises(TypeError):
         unpackb(b"", object_hook=lambda x: x, object_pairs_hook=lambda x: x)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msgpack-1.2.3/test/test_read_size.py 
new/msgpack-1.2.4/test/test_read_size.py
--- old/msgpack-1.2.3/test/test_read_size.py    2026-09-29 03:41:54.466057500 
+0200
+++ new/msgpack-1.2.4/test/test_read_size.py    2026-10-26 18:04:34.444218900 
+0100
@@ -1,5 +1,9 @@
 """Test Unpacker's read_array_header and read_map_header methods"""
 
+from io import BytesIO
+
+from pytest import raises
+
 from msgpack import OutOfData, Unpacker, packb
 
 UnexpectedTypeException = ValueError
@@ -70,3 +74,31 @@
         assert 0, "should raise exception"
     except UnexpectedTypeException:
         assert 1, "okay"
+
+
+def test_incorrect_type_does_not_consume_object():
+    packed = packb(1) + packb("abc") + packb({"a": 1}) + packb([2])
+    unpackers = [Unpacker(), Unpacker(BytesIO(packed))]
+    unpackers[0].feed(packed)
+    for unpacker in unpackers:
+        with raises(UnexpectedTypeException):
+            unpacker.read_array_header()
+        assert unpacker.tell() == 0
+        assert unpacker.unpack() == 1
+
+        with raises(UnexpectedTypeException):
+            unpacker.read_map_header()
+        assert unpacker.unpack() == "abc"
+
+        # A map is not an array: the stream must stay in sync.
+        with raises(UnexpectedTypeException):
+            unpacker.read_array_header()
+        assert unpacker.read_map_header() == 1
+        assert unpacker.unpack() == "a"
+        assert unpacker.unpack() == 1
+
+        with raises(UnexpectedTypeException):
+            unpacker.read_map_header()
+        assert unpacker.read_array_header() == 1
+        assert unpacker.unpack() == 2
+        assert unpacker.tell() == len(packed)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msgpack-1.2.3/test/test_sequnpack.py 
new/msgpack-1.2.4/test/test_sequnpack.py
--- old/msgpack-1.2.3/test/test_sequnpack.py    2026-09-29 03:41:54.466057500 
+0200
+++ new/msgpack-1.2.4/test/test_sequnpack.py    2026-10-26 18:04:34.444218900 
+0100
@@ -112,6 +112,29 @@
     assert next(u) == 1
 
 
+def test_read_bytes_returns_bytes():
+    # Finding 4 of #683: the fallback used to return a bytearray slice.
+    unpacker = Unpacker()
+    unpacker.feed(b"foobar")
+    assert unpacker.unpack() == ord(b"f")
+    got = unpacker.read_bytes(3)
+    assert got == b"oob"
+    assert type(got) is bytes
+    assert {got: 1}[b"oob"] == 1
+    assert unpacker.unpack() == ord(b"a")
+
+    short = Unpacker(io.BytesIO(b"ab")).read_bytes(5)
+    assert short == b"ab"
+    assert type(short) is bytes
+
+    zero = Unpacker()
+    zero.feed(b"z")
+    assert zero.read_bytes(0) == b""
+    got = zero.read_bytes(1)
+    assert got == b"z"
+    assert type(got) is bytes
+
+
 def test_issue124():
     unpacker = Unpacker()
     unpacker.feed(b"\xa1?\xa1!")

Reply via email to