Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-testtools for
openSUSE:Factory checked in at 2026-04-28 11:53:31
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-testtools (Old)
and /work/SRC/openSUSE:Factory/.python-testtools.new.11940 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-testtools"
Tue Apr 28 11:53:31 2026 rev:40 rq:1349298 version:2.9.1
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-testtools/python-testtools.changes
2026-04-14 17:48:26.219831014 +0200
+++
/work/SRC/openSUSE:Factory/.python-testtools.new.11940/python-testtools.changes
2026-04-28 11:53:49.599168231 +0200
@@ -1,0 +2,8 @@
+Sat Apr 25 21:33:00 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 2.9.1:
+ * Don't leak testtools-specific exception details into
+ * ``unittest.TestResult`` error reports when using a stdlib
+ ``TestResult``.
+
+-------------------------------------------------------------------
Old:
----
testtools-2.9.0.tar.gz
New:
----
testtools-2.9.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-testtools.spec ++++++
--- /var/tmp/diff_new_pack.tvdHGI/_old 2026-04-28 11:53:50.315197798 +0200
+++ /var/tmp/diff_new_pack.tvdHGI/_new 2026-04-28 11:53:50.315197798 +0200
@@ -26,12 +26,13 @@
%endif
%{?sle15_python_module_pythons}
Name: python-testtools%{psuffix}
-Version: 2.9.0
+Version: 2.9.1
Release: 0
Summary: Extensions to the Python Standard Library Unit Testing
Framework
License: MIT
URL: https://github.com/testing-cabal/testtools
Source0:
https://files.pythonhosted.org/packages/source/t/testtools/testtools-%{version}.tar.gz
+BuildRequires: %{python_module base >= 3.10}
BuildRequires: %{python_module hatch_vcs}
BuildRequires: %{python_module hatchling}
BuildRequires: %{python_module pip}
@@ -53,7 +54,8 @@
testtools is a set of extensions to the Python standard library's unit tests
framework. These extensions have been derived from many years of experience
with unit tests in Python and come from many different sources. testtools
-also ports recent unittest changes all the way back to Python 2.4.
+gives you the very latest in unit testing technology in a way that will
+work with Python 3.10+ and PyPy3.
%prep
%autosetup -p1 -n testtools-%{version}
++++++ testtools-2.9.0.tar.gz -> testtools-2.9.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/testtools-2.9.0/NEWS new/testtools-2.9.1/NEWS
--- old/testtools-2.9.0/NEWS 2020-02-02 01:00:00.000000000 +0100
+++ new/testtools-2.9.1/NEWS 2020-02-02 01:00:00.000000000 +0100
@@ -3,8 +3,14 @@
Changes and improvements to testtools_, grouped by release.
-NEXT
-~~~~
+2.9.1
+~~~~~
+
+Improvements
+------------
+* Don't leak testtools-specific exception details into
+ ``unittest.TestResult`` error reports when using a stdlib ``TestResult``.
+ (Jelmer Vernooij, #607)
2.9.0
~~~~~
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/testtools-2.9.0/PKG-INFO new/testtools-2.9.1/PKG-INFO
--- old/testtools-2.9.0/PKG-INFO 2020-02-02 01:00:00.000000000 +0100
+++ new/testtools-2.9.1/PKG-INFO 2020-02-02 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: testtools
-Version: 2.9.0
+Version: 2.9.1
Summary: Extensions to the Python standard library unit testing framework
Project-URL: Homepage, https://github.com/testing-cabal/testtools
Author-email: "Jonathan M. Lange" <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/testtools-2.9.0/tests/test_testresult.py
new/testtools-2.9.1/tests/test_testresult.py
--- old/testtools-2.9.0/tests/test_testresult.py 2020-02-02
01:00:00.000000000 +0100
+++ new/testtools-2.9.1/tests/test_testresult.py 2020-02-02
01:00:00.000000000 +0100
@@ -16,7 +16,15 @@
from itertools import chain, combinations
from queue import Queue
from typing import Any
-from unittest import TestSuite
+from unittest import (
+ TestCase as StdlibTestCase,
+)
+from unittest import (
+ TestResult as StdlibTestResult,
+)
+from unittest import (
+ TestSuite,
+)
from testtools import (
CopyStreamResult,
@@ -2962,9 +2970,11 @@
event_outcome, event_test, event_err = self.result._events[0]
self.assertEqual(expected, event_outcome)
self.assertEqual(self, event_test)
- # Compare exc type and value; traceback objects differ between calls
+ # Compare exc type and value; traceback is always None because the
+ # exception is synthesised, not raised from user code — attaching a
+ # live traceback would leak testtools internals into error reports.
self.assertEqual(expected_err[:2], event_err[:2])
- self.assertIsNotNone(event_err[2])
+ self.assertIsNone(event_err[2])
def check_outcome_details_to_nothing(self, outcome, expected=None):
"""Call an outcome with a details dict to be swallowed."""
@@ -3139,6 +3149,36 @@
outcome = "addFailure"
+class TestExtendedToOriginalDetailsStdlibReport(TestCase):
+ """Regression test: details converted to exc_info for a stdlib TestResult
+ must not cause testtools' own frames to appear in the error report.
+
+ Before the fix for the 2.9.0 regression, ``_details_to_exc_info`` returned
+ a live traceback pointing into ``testresult/real.py`` itself, which
+ ``unittest.TestResult._exc_info_to_string`` then formatted into the
+ user-visible string.
+ """
+
+ def _report_for(self, outcome, events_attr):
+ client = StdlibTestResult()
+ decorator = ExtendedToOriginalDecorator(client)
+ details = {"traceback": text_content("foo.c:53:ERROR invalid state\n")}
+ getattr(decorator, outcome)(StdlibTestCase("run"), details=details)
+ events = getattr(client, events_attr)
+ self.assertEqual(1, len(events))
+ return events[0][1]
+
+ def test_add_error(self):
+ report = self._report_for("addError", "errors")
+ self.assertNotIn("testresult/real.py", report)
+ self.assertNotIn("Traceback (most recent call last)", report)
+
+ def test_add_failure(self):
+ report = self._report_for("addFailure", "failures")
+ self.assertNotIn("testresult/real.py", report)
+ self.assertNotIn("Traceback (most recent call last)", report)
+
+
class TestExtendedToOriginalAddExpectedFailure(TestExtendedToOriginalAddError):
outcome = "addExpectedFailure"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/testtools-2.9.0/testtools/_types.py
new/testtools-2.9.1/testtools/_types.py
--- old/testtools-2.9.0/testtools/_types.py 2020-02-02 01:00:00.000000000
+0100
+++ new/testtools-2.9.1/testtools/_types.py 2020-02-02 01:00:00.000000000
+0100
@@ -4,5 +4,5 @@
from typing import TypeAlias
# Type for exc_info tuples from sys.exc_info()
-ExcInfo: TypeAlias = tuple[type[BaseException], BaseException, TracebackType]
+ExcInfo: TypeAlias = tuple[type[BaseException], BaseException, TracebackType |
None]
OptExcInfo: TypeAlias = ExcInfo | tuple[None, None, None]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/testtools-2.9.0/testtools/_version.py
new/testtools-2.9.1/testtools/_version.py
--- old/testtools-2.9.0/testtools/_version.py 2020-02-02 01:00:00.000000000
+0100
+++ new/testtools-2.9.1/testtools/_version.py 2020-02-02 01:00:00.000000000
+0100
@@ -1,3 +1,3 @@
# This file is automatically generated by hatch.
-version = '2.9.0'
-__version__ = (2, 9, 0)
+version = '2.9.1'
+__version__ = (2, 9, 1)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/testtools-2.9.0/testtools/testresult/real.py
new/testtools-2.9.1/testtools/testresult/real.py
--- old/testtools-2.9.0/testtools/testresult/real.py 2020-02-02
01:00:00.000000000 +0100
+++ new/testtools-2.9.1/testtools/testresult/real.py 2020-02-02
01:00:00.000000000 +0100
@@ -39,7 +39,6 @@
TypeAlias,
TypedDict,
TypeVar,
- cast,
)
if TYPE_CHECKING:
@@ -2113,12 +2112,15 @@
)
def _details_to_exc_info(self, details: DetailsDict) -> ExcInfo:
- """Convert a details dict to an exc_info tuple."""
- try:
- raise _StringException(_details_to_str(details,
special="traceback"))
- except _StringException:
- # we know this won't be null
- return cast(ExcInfo, sys.exc_info())
+ """Convert a details dict to an exc_info tuple.
+
+ The returned tuple has ``tb=None`` on purpose: the exception is
+ synthesised here, not raised by user code, so attaching a live
+ traceback would leak testtools' own internals into the user-visible
+ error report emitted by e.g.
``unittest.TestResult._exc_info_to_string``.
+ """
+ exc = _StringException(_details_to_str(details, special="traceback"))
+ return (_StringException, exc, None)
@property
def current_tags(self) -> set[str]:
@@ -2755,7 +2757,7 @@
subtest: unittest.TestCase,
err: OptExcInfo | None,
) -> None:
- self.decorated.addSubTest(test, subtest, err)
+ self.decorated.addSubTest(test, subtest, err) # type: ignore[arg-type]
def addDuration(self, test: unittest.TestCase, duration: float) -> None:
self.decorated.addDuration(test, duration)