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):

Reply via email to