Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-testscenarios for
openSUSE:Factory checked in at 2026-10-27 18:18:04
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-testscenarios (Old)
and /work/SRC/openSUSE:Factory/.python-testscenarios.new.2252680 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-testscenarios"
Tue Oct 27 18:18:04 2026 rev:13 rq:1392539 version:0.7.0
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-testscenarios/python-testscenarios.changes
2026-06-29 17:30:18.613925369 +0200
+++
/work/SRC/openSUSE:Factory/.python-testscenarios.new.2252680/python-testscenarios.changes
2026-10-27 18:18:07.783513867 +0100
@@ -1,0 +2,7 @@
+Sun Oct 25 20:05:52 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 0.7.0:
+ * Add typing (Stephen Finucane).
+ * Re-add tests to sdist (Michał Górny).
+
+-------------------------------------------------------------------
Old:
----
testscenarios-0.6.2-gh.tar.gz
New:
----
testscenarios-0.7.0-gh.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-testscenarios.spec ++++++
--- /var/tmp/diff_new_pack.U4JDhK/_old 2026-10-27 18:18:09.364579808 +0100
+++ /var/tmp/diff_new_pack.U4JDhK/_new 2026-10-27 18:18:09.370580058 +0100
@@ -26,7 +26,7 @@
%endif
%{?sle15_python_module_pythons}
Name: python-testscenarios%{psuffix}
-Version: 0.6.2
+Version: 0.7.0
Release: 0
Summary: A pyunit extension for dependency injection
License: Apache-2.0 OR BSD-3-Clause
++++++ testscenarios-0.6.2-gh.tar.gz -> testscenarios-0.7.0-gh.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/testscenarios-0.6.2/.github/workflows/test.yml
new/testscenarios-0.7.0/.github/workflows/test.yml
--- old/testscenarios-0.6.2/.github/workflows/test.yml 2026-05-22
13:44:11.000000000 +0200
+++ new/testscenarios-0.7.0/.github/workflows/test.yml 2026-08-28
11:10:36.000000000 +0200
@@ -27,13 +27,17 @@
- name: Install dependencies
run: |
python -m pip install --upgrade pip wheel
- python -m pip install ruff
+ python -m pip install ruff mypy ".[test]"
- name: Ruff
run: |
python -m ruff check .
python -m ruff format --check .
+ - name: Mypy
+ run: |
+ python -m mypy -p testscenarios
+
test:
runs-on: ubuntu-latest
strategy:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/testscenarios-0.6.2/NEWS new/testscenarios-0.7.0/NEWS
--- old/testscenarios-0.6.2/NEWS 2026-05-22 13:44:11.000000000 +0200
+++ new/testscenarios-0.7.0/NEWS 2026-08-28 11:10:36.000000000 +0200
@@ -2,6 +2,16 @@
testscenarios release notes
---------------------------
+0.7.0
+~~~~~
+
+IMPROVEMENTS
+------------
+
+* Add typing (Stephen Finucane).
+
+* Re-add tests to sdist (Michał Górny).
+
0.6.2
~~~~~
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/testscenarios-0.6.2/doc/example.py
new/testscenarios-0.7.0/doc/example.py
--- old/testscenarios-0.6.2/doc/example.py 2026-05-22 13:44:11.000000000
+0200
+++ new/testscenarios-0.7.0/doc/example.py 2026-08-28 11:10:36.000000000
+0200
@@ -17,7 +17,6 @@
from testscenarios import TestWithScenarios
-
scenario1 = ("basic", {"attribute": "value"})
scenario2 = ("advanced", {"attribute": "value2"})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/testscenarios-0.6.2/pyproject.toml
new/testscenarios-0.7.0/pyproject.toml
--- old/testscenarios-0.6.2/pyproject.toml 2026-05-22 13:44:11.000000000
+0200
+++ new/testscenarios-0.7.0/pyproject.toml 2026-08-28 11:10:36.000000000
+0200
@@ -21,6 +21,7 @@
"Programming Language :: Python :: 3.14",
"Topic :: Software Development :: Quality Assurance",
"Topic :: Software Development :: Testing",
+ "Typing :: Typed",
]
authors = [{name = "Testing-cabal", email =
"[email protected]"}]
license = {text = "Apache-2.0 OR BSD-3-Clause"}
@@ -33,7 +34,11 @@
"Source Code" = "https://github.com/testing-cabal/testscenarios"
[project.optional-dependencies]
-"test" = ["testtools >= 2.8.7"]
+test = ["testtools >= 2.8.7"]
+dev = [
+ "ruff==0.16.4",
+ "mypy>=1.20.0",
+]
[tool.hatch.version]
source = "vcs"
@@ -59,4 +64,43 @@
"NEWS",
"README.rst",
"doc/*.py",
- ]
+ "tests/*.py",
+]
+
+[tool.hatch.envs.lint]
+features = ["dev", "test"]
+
+[tool.hatch.envs.lint.scripts]
+check = [
+ "ruff check .",
+ "ruff format --check .",
+ "mypy -p testscenarios",
+]
+
+[tool.mypy]
+python_version = "3.10"
+show_column_numbers = true
+show_error_context = true
+strict = true
+disable_error_code = ["import-untyped"]
+exclude = '(?x)(doc)'
+
+[[tool.mypy.overrides]]
+module = ["tests.*"]
+disallow_untyped_calls = false
+disallow_untyped_defs = false
+disallow_subclassing_any = false
+
+[tool.ruff.lint]
+select = [
+ "E",
+ "F",
+ "I",
+ "PIE",
+ "UP",
+ "RSE",
+ "RUF",
+]
+ignore = [
+ "RUF012",
+]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/testscenarios-0.6.2/tests/__init__.py
new/testscenarios-0.7.0/tests/__init__.py
--- old/testscenarios-0.6.2/tests/__init__.py 2026-05-22 13:44:11.000000000
+0200
+++ new/testscenarios-0.7.0/tests/__init__.py 2026-08-28 11:10:36.000000000
+0200
@@ -20,13 +20,17 @@
import testscenarios
-def test_suite():
+def test_suite() -> unittest.TestSuite:
loader = unittest.TestLoader()
standard_tests = unittest.TestSuite()
return load_tests(loader, standard_tests, None)
-def load_tests(loader, standard_tests, pattern):
+def load_tests(
+ loader: unittest.TestLoader,
+ standard_tests: unittest.TestSuite,
+ pattern: str | None,
+) -> unittest.TestSuite:
test_modules = [
"testcase",
"scenarios",
@@ -38,4 +42,4 @@
standard_tests.addTest(
doctest.DocFileSuite("../README.rst", optionflags=doctest.ELLIPSIS)
)
- return loader.suiteClass(testscenarios.generate_scenarios(standard_tests))
+ return
loader.suiteClass(list(testscenarios.generate_scenarios(standard_tests)))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/testscenarios-0.6.2/tests/test_scenarios.py
new/testscenarios-0.7.0/tests/test_scenarios.py
--- old/testscenarios-0.6.2/tests/test_scenarios.py 2026-05-22
13:44:11.000000000 +0200
+++ new/testscenarios-0.7.0/tests/test_scenarios.py 2026-08-28
11:10:36.000000000 +0200
@@ -16,11 +16,10 @@
# limitations under that license.
import unittest
+from typing import cast
import testtools
from testtools.matchers import EndsWith
-from typing import cast
-
import testscenarios
from testscenarios.scenarios import (
@@ -115,7 +114,7 @@
class TestApplyScenario(testtools.TestCase):
def setUp(self):
- super(TestApplyScenario, self).setUp()
+ super().setUp()
self.scenario_name = "demo"
self.scenario_attrs = {"foo": "bar"}
@@ -134,7 +133,6 @@
does nothing but pass unconditionally.
"""
- pass
self.ReferenceTest = ReferenceTest
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/testscenarios-0.6.2/testscenarios/__init__.py
new/testscenarios-0.7.0/testscenarios/__init__.py
--- old/testscenarios-0.6.2/testscenarios/__init__.py 2026-05-22
13:44:11.000000000 +0200
+++ new/testscenarios-0.7.0/testscenarios/__init__.py 2026-08-28
11:10:36.000000000 +0200
@@ -30,17 +30,19 @@
__all__ = [
"TestWithScenarios",
"WithScenarios",
+ "__version__",
"apply_scenario",
"apply_scenarios",
"generate_scenarios",
"load_tests_apply_scenarios",
"multiply_scenarios",
"per_module_scenarios",
- "__version__",
]
-from testscenarios.scenarios import ( # noqa: E402
+import unittest
+
+from testscenarios.scenarios import (
apply_scenario,
apply_scenarios,
generate_scenarios,
@@ -48,21 +50,25 @@
multiply_scenarios,
per_module_scenarios,
)
-from testscenarios.testcase import TestWithScenarios, WithScenarios # noqa:
E402
+from testscenarios.testcase import TestWithScenarios, WithScenarios
-def test_suite():
- import tests # noqa: F401
+def test_suite() -> unittest.TestSuite:
+ import tests
return tests.test_suite()
-def load_tests(loader, standard_tests, pattern):
+def load_tests(
+ loader: unittest.TestLoader,
+ standard_tests: unittest.TestSuite,
+ pattern: str | None,
+) -> unittest.TestSuite:
standard_tests.addTests(loader.loadTestsFromNames(["tests"]))
return standard_tests
-def __get_git_version():
+def __get_git_version() -> str | None:
import os
import subprocess
@@ -99,13 +105,17 @@
# If the releaselevel is 'final', then the tarball will be major.minor.micro.
# Otherwise it is major.minor.micro~$(revno).
+__version__: tuple[int | str, ...]
+
try:
from ._version import __version__, version
except ModuleNotFoundError:
# package is not installed
- if version := __get_git_version():
+ _git_version = __get_git_version()
+ if _git_version:
# we're in a git repo
- __version__ = tuple([int(v) if v.isdigit() else v for v in
version.split(".")])
+ version = _git_version
+ __version__ = tuple(int(v) if v.isdigit() else v for v in
version.split("."))
else:
# we're working with a tarball or similar
version = "0.0.0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/testscenarios-0.6.2/testscenarios/scenarios.py
new/testscenarios-0.7.0/testscenarios/scenarios.py
--- old/testscenarios-0.6.2/testscenarios/scenarios.py 2026-05-22
13:44:11.000000000 +0200
+++ new/testscenarios-0.7.0/testscenarios/scenarios.py 2026-08-28
11:10:36.000000000 +0200
@@ -23,16 +23,23 @@
"multiply_scenarios",
]
+import sys
+import unittest
+from collections.abc import Iterable, Iterator
from itertools import (
product,
)
-import sys
+from typing import Any
-from testtools.testcase import clone_test_with_new_id
from testtools import iterate_tests
+from testtools.testcase import clone_test_with_new_id
+
+# A scenario is a (name, parameters) pair. The parameter values are injected
+# onto test instances as attributes, so they are intentionally arbitrary.
+Scenario = tuple[str, dict[str, Any]]
-def apply_scenario(scenario, test):
+def apply_scenario(scenario: Scenario, test: unittest.TestCase) ->
unittest.TestCase:
"""Apply scenario to test.
:param scenario: A tuple (name, parameters) to apply to the test. The test
@@ -46,14 +53,16 @@
newtest = clone_test_with_new_id(test, test.id() + scenario_suffix)
test_desc = test.shortDescription()
if test_desc is not None:
- newtest_desc = "%(test_desc)s %(scenario_suffix)s" % vars()
- newtest.shortDescription = lambda: newtest_desc
+ newtest_desc = f"{test_desc} {scenario_suffix}"
+ newtest.shortDescription = lambda: newtest_desc # type:
ignore[method-assign]
for key, value in parameters.items():
setattr(newtest, key, value)
return newtest
-def apply_scenarios(scenarios, test):
+def apply_scenarios(
+ scenarios: Iterable[Scenario], test: unittest.TestCase
+) -> Iterator[unittest.TestCase]:
"""Apply many scenarios to a test.
:param scenarios: An iterable of scenarios.
@@ -64,7 +73,9 @@
yield apply_scenario(scenario, test)
-def generate_scenarios(test_or_suite):
+def generate_scenarios(
+ test_or_suite: unittest.TestCase | unittest.TestSuite,
+) -> Iterator[unittest.TestCase]:
"""Yield the tests in test_or_suite with scenario multiplication done.
TestCase objects with no scenarios specified are yielded unaltered. Tests
@@ -78,13 +89,13 @@
scenarios = getattr(test, "scenarios", None)
if scenarios:
for newtest in apply_scenarios(scenarios, test):
- newtest.scenarios = None
+ newtest.scenarios = None # type: ignore[attr-defined]
yield newtest
else:
yield test
-def load_tests_apply_scenarios(*params):
+def load_tests_apply_scenarios(*params: Any) -> unittest.TestSuite:
"""Adapter test runner load hooks to call generate_scenarios.
If this is referenced by the `load_tests` attribute of a module, then
@@ -101,15 +112,15 @@
multiplication.
"""
if getattr(params[0], "suiteClass", None) is not None:
- loader, standard_tests, pattern = params
+ loader, standard_tests, _ = params
else:
- standard_tests, module, loader = params
- result = loader.suiteClass()
+ standard_tests, _, loader = params
+ result: unittest.TestSuite = loader.suiteClass()
result.addTests(generate_scenarios(standard_tests))
return result
-def multiply_scenarios(*scenarios):
+def multiply_scenarios(*scenarios: Iterable[Scenario]) -> list[Scenario]:
"""Multiply two or more iterables of scenarios.
It is safe to pass scenario generators or iterators.
@@ -118,19 +129,21 @@
scenarios, with the names concatenated and the parameters
merged together.
"""
- result = []
+ result: list[Scenario] = []
scenario_lists = map(list, scenarios)
for combination in product(*scenario_lists):
names, parameters = zip(*combination)
scenario_name = ",".join(names)
- scenario_parameters = {}
+ scenario_parameters: dict[str, Any] = {}
for parameter in parameters:
scenario_parameters.update(parameter)
result.append((scenario_name, scenario_parameters))
return result
-def per_module_scenarios(attribute_name, modules):
+def per_module_scenarios(
+ attribute_name: str, modules: Iterable[tuple[str, str]]
+) -> list[Scenario]:
"""Generate scenarios for available implementation modules.
This is typically used when there is a subsystem implemented, for
@@ -152,8 +165,9 @@
scenario name, and the long name is a fully-qualified Python module
name.
"""
- scenarios = []
+ scenarios: list[Scenario] = []
for short_name, module_name in modules:
+ mod: Any
try:
mod = __import__(module_name, {}, {}, [""])
except BaseException:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/testscenarios-0.6.2/testscenarios/testcase.py
new/testscenarios-0.7.0/testscenarios/testcase.py
--- old/testscenarios-0.6.2/testscenarios/testcase.py 2026-05-22
13:44:11.000000000 +0200
+++ new/testscenarios-0.7.0/testscenarios/testcase.py 2026-08-28
11:10:36.000000000 +0200
@@ -20,9 +20,18 @@
]
import unittest
+from typing import TYPE_CHECKING
+from testscenarios.scenarios import Scenario, generate_scenarios
-from testscenarios.scenarios import generate_scenarios
+# WithScenarios is a mixin that is always combined with unittest.TestCase (and
+# calls up to it via super()). At runtime it must subclass ``object`` so it can
+# be mixed in freely, but for type checking we treat the base as TestCase so
+# that ``super()`` calls and inherited attributes resolve correctly.
+if TYPE_CHECKING:
+ _Base = unittest.TestCase
+else:
+ _Base = object
_doc = """
When a test object which inherits from WithScenarios is run, and there is a
@@ -33,39 +42,41 @@
"""
-class WithScenarios(object):
+class WithScenarios(_Base):
__doc__ = (
"""A mixin for TestCase with support for declarative scenarios.
"""
+ _doc
)
- def _get_scenarios(self):
+ def _get_scenarios(self) -> list[Scenario] | None:
return getattr(self, "scenarios", None)
- def countTestCases(self):
+ def countTestCases(self) -> int:
scenarios = self._get_scenarios()
if not scenarios:
return 1
else:
return len(scenarios)
- def debug(self):
+ def debug(self) -> None:
scenarios = self._get_scenarios()
if scenarios:
for test in generate_scenarios(self):
test.debug()
else:
- return super(WithScenarios, self).debug()
+ return super().debug()
- def run(self, result=None):
+ def run(
+ self, result: unittest.TestResult | None = None
+ ) -> unittest.TestResult | None:
scenarios = self._get_scenarios()
if scenarios:
for test in generate_scenarios(self):
test.run(result)
- return
+ return None
else:
- return super(WithScenarios, self).run(result)
+ return super().run(result)
class TestWithScenarios(WithScenarios, unittest.TestCase):