Script 'mail_helper' called by obssrc
Hello community,

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

Package is "python-tomli"

Mon Mar 30 18:30:06 2026 rev:12 rq:1343517 version:2.4.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-tomli/python-tomli.changes        
2026-01-28 15:07:06.977926351 +0100
+++ /work/SRC/openSUSE:Factory/.python-tomli.new.1999/python-tomli.changes      
2026-03-30 18:30:46.317755213 +0200
@@ -1,0 +2,7 @@
+Sun Mar 29 19:02:30 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 2.4.1:
+  * Limit number of parts of a TOML key to address quadratic time
+    complexity
+
+-------------------------------------------------------------------

Old:
----
  tomli-2.4.0.tar.gz

New:
----
  tomli-2.4.1.tar.gz

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

Other differences:
------------------
++++++ python-tomli.spec ++++++
--- /var/tmp/diff_new_pack.Wc8Xgs/_old  2026-03-30 18:30:47.313796610 +0200
+++ /var/tmp/diff_new_pack.Wc8Xgs/_new  2026-03-30 18:30:47.317796776 +0200
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-tomli
-Version:        2.4.0
+Version:        2.4.1
 Release:        0
 Summary:        A lil' TOML parser
 License:        MIT
@@ -30,10 +30,9 @@
 # Avoid build cycles
 # https://flit.readthedocs.io/en/latest/bootstrap.html
 #!BuildIgnore:  python3-tomli
-#!BuildIgnore:  python36-tomli
-#!BuildIgnore:  python38-tomli
-#!BuildIgnore:  python39-tomli
-#!BuildIgnore:  python310-tomli
+#!BuildIgnore:  python311-tomli
+#!BuildIgnore:  python313-tomli
+#!BuildIgnore:  python314-tomli
 #!BuildIgnore:  ca-certificates
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros

++++++ tomli-2.4.0.tar.gz -> tomli-2.4.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tomli-2.4.0/.bumpversion.cfg 
new/tomli-2.4.1/.bumpversion.cfg
--- old/tomli-2.4.0/.bumpversion.cfg    2026-01-11 12:08:32.000000000 +0100
+++ new/tomli-2.4.1/.bumpversion.cfg    2026-03-25 21:11:29.000000000 +0100
@@ -2,7 +2,7 @@
 commit = True
 tag = True
 tag_name = {new_version}
-current_version = 2.4.0
+current_version = 2.4.1
 
 [bumpversion:file:pyproject.toml]
 search = version = "{current_version}"  # DO NOT EDIT THIS LINE MANUALLY. LET 
bump2version UTILITY DO IT
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tomli-2.4.0/.pre-commit-config.yaml 
new/tomli-2.4.1/.pre-commit-config.yaml
--- old/tomli-2.4.0/.pre-commit-config.yaml     2026-01-11 12:08:32.000000000 
+0100
+++ new/tomli-2.4.1/.pre-commit-config.yaml     2026-03-25 21:11:29.000000000 
+0100
@@ -1,6 +1,6 @@
 repos:
 - repo: https://github.com/Lucas-C/pre-commit-hooks
-  rev: a30f0d816e5062a67d87c8de753cfe499672b959  # frozen: v1.5.5
+  rev: ad1b27d73581aa16cca06fc4a0761fc563ffe8e8  # frozen: v1.5.6
   hooks:
   - id: insert-license
     files: '^src/.+\.py$|^tests/.+\.py$'
@@ -28,11 +28,11 @@
     files: '^src/.+\.py$'
     args: ['--never', '--application-directories', 'src']
 - repo: https://github.com/PyCQA/isort
-  rev: 0a09c783808cfe77bb3269250f663ff733d23302  # frozen: 7.0.0
+  rev: 3459bdee0962449aad91235273c3fd1306dfebe5  # frozen: 8.0.0
   hooks:
   - id: isort
 - repo: https://github.com/psf/black-pre-commit-mirror
-  rev: 831207fd435b47aeffdf6af853097e64322b4d44  # frozen: 25.12.0
+  rev: ea488cebbfd88a5f50b8bd95d5c829d0bb76feb8  # frozen: 26.1.0
   hooks:
   - id: black
 - repo: https://github.com/pre-commit/pre-commit-hooks
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tomli-2.4.0/CHANGELOG.md new/tomli-2.4.1/CHANGELOG.md
--- old/tomli-2.4.0/CHANGELOG.md        2026-01-11 12:08:32.000000000 +0100
+++ new/tomli-2.4.1/CHANGELOG.md        2026-03-25 21:11:29.000000000 +0100
@@ -1,5 +1,15 @@
 # Changelog
 
+## 2.3.1
+
+- Fixed
+  - Backport: Limit number of parts of a TOML key to address quadratic time 
complexity
+
+## 2.4.1
+
+- Fixed
+  - Limit number of parts of a TOML key to address quadratic time complexity
+
 ## 2.4.0
 
 - Added
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tomli-2.4.0/README.md new/tomli-2.4.1/README.md
--- old/tomli-2.4.0/README.md   2026-01-11 12:08:32.000000000 +0100
+++ new/tomli-2.4.1/README.md   2026-03-25 21:11:29.000000000 +0100
@@ -24,8 +24,8 @@
   - [Is there a `dumps`, `write` or `encode` 
function?](#is-there-a-dumps-write-or-encode-function)
   - [How do TOML types map into Python 
types?](#how-do-toml-types-map-into-python-types)
 - [Performance](#performance)
-  - [Pure Python](#pure-python)
   - [Mypyc generated wheel](#mypyc-generated-wheel)
+  - [Pure Python](#pure-python)
 
 <!-- mdformat-toc end -->
 
@@ -156,7 +156,7 @@
 - it's lil'
 - pure Python with zero dependencies
 - the fastest pure Python parser [\*](#pure-python):
-  18x as fast as [tomlkit](https://pypi.org/project/tomlkit/),
+  14x as fast as [tomlkit](https://pypi.org/project/tomlkit/),
   2.1x as fast as [toml](https://pypi.org/project/toml/)
 - outputs [basic data types](#how-do-toml-types-map-into-python-types) only
 - 100% spec compliant: passes all tests in
@@ -202,36 +202,32 @@
 
 The `benchmark/` folder in this repository contains a performance benchmark 
for comparing the various Python TOML parsers.
 
-Below are the results for commit 
[0724e2a](https://github.com/hukkin/tomli/tree/0724e2ab1858da7f5e05a9bffdb24c33589d951c).
+Below are the results for commit 
[064e492](https://github.com/hukkin/tomli/tree/064e492919b2338def788753b8c981c9131334c0).
 
-### Pure Python<a name="pure-python"></a>
+### Mypyc generated wheel<a name="mypyc-generated-wheel"></a>
 
 ```console
 foo@bar:~/dev/tomli$ python --version
-Python 3.12.7
+Python 3.14.2
 foo@bar:~/dev/tomli$ pip freeze
-attrs==21.4.0
-click==8.1.7
-pytomlpp==1.0.13
-qtoml==0.3.1
-rtoml==0.11.0
+pytomlpp==1.1.0
+rtoml==0.13.0
 toml==0.10.2
 tomli @ file:///home/foo/dev/tomli
-tomlkit==0.13.2
+tomlkit==0.13.3
 foo@bar:~/dev/tomli$ python benchmark/run.py
 Parsing data.toml 5000 times:
 ------------------------------------------------------
     parser |  exec time | performance (more is better)
 -----------+------------+-----------------------------
-     rtoml |    0.647 s | baseline (100%)
-  pytomlpp |    0.891 s | 72.62%
-     tomli |     3.14 s | 20.56%
-      toml |     6.69 s | 9.67%
-     qtoml |     8.27 s | 7.82%
-   tomlkit |     56.1 s | 1.15%
+     rtoml |    0.328 s | baseline (100%)
+  pytomlpp |    0.365 s | 89.75%
+     tomli |    0.838 s | 39.12%
+      toml |     3.01 s | 10.90%
+   tomlkit |     20.7 s | 1.59%
 ```
 
-### Mypyc generated wheel<a name="mypyc-generated-wheel"></a>
+### Pure Python<a name="pure-python"></a>
 
 ```console
 foo@bar:~/dev/tomli$ python benchmark/run.py
@@ -239,10 +235,9 @@
 ------------------------------------------------------
     parser |  exec time | performance (more is better)
 -----------+------------+-----------------------------
-     rtoml |    0.668 s | baseline (100%)
-  pytomlpp |    0.893 s | 74.81%
-     tomli |     1.96 s | 34.18%
-      toml |     6.64 s | 10.07%
-     qtoml |     8.26 s | 8.09%
-   tomlkit |     52.9 s | 1.26%
+     rtoml |    0.323 s | baseline (100%)
+  pytomlpp |    0.365 s | 88.40%
+     tomli |     1.44 s | 22.36%
+      toml |     3.03 s | 10.65%
+   tomlkit |     20.6 s | 1.57%
 ```
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tomli-2.4.0/benchmark/requirements.txt 
new/tomli-2.4.1/benchmark/requirements.txt
--- old/tomli-2.4.0/benchmark/requirements.txt  2026-01-11 12:08:32.000000000 
+0100
+++ new/tomli-2.4.1/benchmark/requirements.txt  2026-03-25 21:11:29.000000000 
+0100
@@ -5,5 +5,4 @@
 pytomlpp
 toml
 tomlkit
-qtoml
 rtoml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tomli-2.4.0/benchmark/run.py 
new/tomli-2.4.1/benchmark/run.py
--- old/tomli-2.4.0/benchmark/run.py    2026-01-11 12:08:32.000000000 +0100
+++ new/tomli-2.4.1/benchmark/run.py    2026-03-25 21:11:29.000000000 +0100
@@ -5,7 +5,6 @@
 import timeit
 
 import pytomlpp
-import qtoml
 import rtoml
 import toml
 import tomlkit
@@ -22,7 +21,7 @@
 ) -> float:
     placeholder = "Running..."
     print(f"{name:>{col_width[0]}} | {placeholder}", end="", flush=True)
-    time_taken = timeit.timeit(func, number=run_count)
+    time_taken = min(timeit.repeat(func, number=run_count, repeat=5))
     print("\b" * len(placeholder), end="")
     time_suffix = " s"
     print(f"{time_taken:{col_width[1]-len(time_suffix)}.3g}{time_suffix}", 
end="")
@@ -39,9 +38,6 @@
     data_path = Path(__file__).parent / "data.toml"
     test_data = data_path.read_bytes().decode()
 
-    # qtoml has a bug making it crash without this newline normalization
-    test_data = test_data.replace("\r\n", "\n")
-
     col_width = (10, 10, 28)
     col_head = ("parser", "exec time", "performance (more is better)")
     print(f"Parsing data.toml {run_count} times:")
@@ -55,7 +51,6 @@
     benchmark("pytomlpp", run_count, lambda: pytomlpp.loads(test_data), 
col_width, compare_to=baseline)  # noqa: E501
     benchmark("tomli", run_count, lambda: tomli.loads(test_data), col_width, 
compare_to=baseline)  # noqa: E501
     benchmark("toml", run_count, lambda: toml.loads(test_data), col_width, 
compare_to=baseline)  # noqa: E501
-    benchmark("qtoml", run_count, lambda: qtoml.loads(test_data), col_width, 
compare_to=baseline)  # noqa: E501
     benchmark("tomlkit", run_count, lambda: tomlkit.parse(test_data), 
col_width, compare_to=baseline)  # noqa: E501
     # fmt: on
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tomli-2.4.0/pyproject.toml 
new/tomli-2.4.1/pyproject.toml
--- old/tomli-2.4.0/pyproject.toml      2026-01-11 12:08:32.000000000 +0100
+++ new/tomli-2.4.1/pyproject.toml      2026-03-25 21:11:29.000000000 +0100
@@ -4,7 +4,7 @@
 
 [project]
 name = "tomli"
-version = "2.4.0"  # DO NOT EDIT THIS LINE MANUALLY. LET bump2version UTILITY 
DO IT
+version = "2.4.1"  # DO NOT EDIT THIS LINE MANUALLY. LET bump2version UTILITY 
DO IT
 description = "A lil' TOML parser"
 authors = [
     { name = "Taneli Hukkinen", email = "[email protected]" },
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tomli-2.4.0/scripts/mypyc_tox 
new/tomli-2.4.1/scripts/mypyc_tox
--- old/tomli-2.4.0/scripts/mypyc_tox   2026-01-11 12:08:32.000000000 +0100
+++ new/tomli-2.4.1/scripts/mypyc_tox   2026-03-25 21:11:29.000000000 +0100
@@ -9,6 +9,7 @@
 sets the `TOMLI_USE_MYPYC=1` environment variable that setup.py reads to
 enable mypyc.
 """
+
 import os
 from pathlib import Path
 import shutil
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tomli-2.4.0/src/tomli/__init__.py 
new/tomli-2.4.1/src/tomli/__init__.py
--- old/tomli-2.4.0/src/tomli/__init__.py       2026-01-11 12:08:32.000000000 
+0100
+++ new/tomli-2.4.1/src/tomli/__init__.py       2026-03-25 21:11:29.000000000 
+0100
@@ -3,6 +3,6 @@
 # Licensed to PSF under a Contributor Agreement.
 
 __all__ = ("loads", "load", "TOMLDecodeError")
-__version__ = "2.4.0"  # DO NOT EDIT THIS LINE MANUALLY. LET bump2version 
UTILITY DO IT
+__version__ = "2.4.1"  # DO NOT EDIT THIS LINE MANUALLY. LET bump2version 
UTILITY DO IT
 
 from ._parser import TOMLDecodeError, load, loads
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tomli-2.4.0/src/tomli/_parser.py 
new/tomli-2.4.1/src/tomli/_parser.py
--- old/tomli-2.4.0/src/tomli/_parser.py        2026-01-11 12:08:32.000000000 
+0100
+++ new/tomli-2.4.1/src/tomli/_parser.py        2026-03-25 21:11:29.000000000 
+0100
@@ -34,6 +34,13 @@
 # lower number than where mypyc binaries crash.
 MAX_INLINE_NESTING: Final = sys.getrecursionlimit()
 
+# Pathologically excessive number of parts in a key runs into quadratic
+# behavior (e.g. in Flags.is_).
+# Even if keys aren't currently parsed using recursion, they name a
+# recursive structure, so it makes sense to limit it using getrecursionlimit()
+# and RecursionError.
+MAX_KEY_PARTS: Final = sys.getrecursionlimit()
+
 ASCII_CTRL: Final = frozenset(chr(i) for i in range(32)) | frozenset(chr(127))
 
 # Neither of these sets include quotation mark or backslash. They are
@@ -475,6 +482,10 @@
         pos = skip_chars(src, pos, TOML_WS)
         pos, key_part = parse_key_part(src, pos)
         key += (key_part,)
+        if len(key) > MAX_KEY_PARTS:
+            raise RecursionError(
+                f"TOML key has more than the allowed {MAX_KEY_PARTS} parts"
+            )
         pos = skip_chars(src, pos, TOML_WS)
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tomli-2.4.0/tests/test_misc.py 
new/tomli-2.4.1/tests/test_misc.py
--- old/tomli-2.4.0/tests/test_misc.py  2026-01-11 12:08:32.000000000 +0100
+++ new/tomli-2.4.1/tests/test_misc.py  2026-03-25 21:11:29.000000000 +0100
@@ -130,6 +130,23 @@
         ):
             tomllib.loads(recursive_table_toml)
 
+    def test_key_recursion_limit(self):
+        nest_count = 310
+        nested_key_toml = "a." * nest_count + "a = 1"
+        tomllib.loads(nested_key_toml)
+
+        nest_count = sys.getrecursionlimit() - 2
+        nested_key_toml = "a." * nest_count + "a = 1"
+        tomllib.loads(nested_key_toml)
+
+        nest_count = sys.getrecursionlimit() + 2
+        nested_key_toml = "a." * nest_count + "a = 1"
+        with self.assertRaisesRegex(
+            RecursionError,
+            r"TOML key has more than the allowed [0-9]+ parts",
+        ):
+            tomllib.loads(nested_key_toml)
+
     def test_types_import(self):
         """Test that `_types` module runs.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tomli-2.4.0/tomllib.md new/tomli-2.4.1/tomllib.md
--- old/tomli-2.4.0/tomllib.md  2026-01-11 12:08:32.000000000 +0100
+++ new/tomli-2.4.1/tomllib.md  2026-03-25 21:11:29.000000000 +0100
@@ -35,7 +35,6 @@
 
   from . import load_tests
 
-
   unittest.main()
   ```
 

Reply via email to