Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-oslotest for openSUSE:Factory 
checked in at 2026-03-09 16:11:17
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-oslotest (Old)
 and      /work/SRC/openSUSE:Factory/.python-oslotest.new.8177 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-oslotest"

Mon Mar  9 16:11:17 2026 rev:28 rq:1337527 version:6.0.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-oslotest/python-oslotest.changes  
2025-11-10 19:18:30.747292817 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-oslotest.new.8177/python-oslotest.changes    
    2026-03-09 16:11:42.757846863 +0100
@@ -1,0 +2,12 @@
+Sun Mar  8 21:05:00 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 6.0.0:
+  * Add ruff
+  * Remove cross-testing functionality
+  * Bump pyupgrade target to 3.10+
+  * pre-commit: Bump dependencies
+  * Migrate setup configuration to pyproject.toml
+  * Drop Python 3.8, 3.9 support
+  * add pyproject.toml to support pip 23.1
+
+-------------------------------------------------------------------

Old:
----
  oslotest-5.0.1.tar.gz

New:
----
  oslotest-6.0.0.tar.gz

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

Other differences:
------------------
++++++ python-oslotest.spec ++++++
--- /var/tmp/diff_new_pack.MmiXj4/_old  2026-03-09 16:11:43.305869517 +0100
+++ /var/tmp/diff_new_pack.MmiXj4/_new  2026-03-09 16:11:43.305869517 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-oslotest
 #
-# Copyright (c) 2025 SUSE LLC and contributors
+# Copyright (c) 2026 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
 
 
 Name:           python-oslotest
-Version:        5.0.1
+Version:        6.0.0
 Release:        0
 Summary:        OpenStack test framework
 License:        Apache-2.0
@@ -62,24 +62,16 @@
 %install
 %pyproject_install
 %python_clone -a %{buildroot}%{_bindir}/oslo_debug_helper
-%python_clone -a %{buildroot}%{_bindir}/oslo_run_cross_tests
-%python_clone -a %{buildroot}%{_bindir}/oslo_run_pre_release_tests
 
 %pre
 # If libalternatives is used: Removing old update-alternatives entries.
 %python_libalternatives_reset_alternative oslo_debug_helper
-%python_libalternatives_reset_alternative oslo_run_cross_tests
-%python_libalternatives_reset_alternative oslo_run_pre_release_tests
 
 %post
 %python_install_alternative oslo_debug_helper
-%python_install_alternative oslo_run_cross_tests
-%python_install_alternative oslo_run_pre_release_tests
 
 %postun
 %python_uninstall_alternative oslo_debug_helper
-%python_uninstall_alternative oslo_run_cross_tests
-%python_uninstall_alternative oslo_run_pre_release_tests
 
 %check
 %{openstack_stestr_run}
@@ -88,8 +80,6 @@
 %license LICENSE
 %doc ChangeLog README.rst
 %python_alternative %{_bindir}/oslo_debug_helper
-%python_alternative %{_bindir}/oslo_run_cross_tests
-%python_alternative %{_bindir}/oslo_run_pre_release_tests
 %{python_sitelib}/oslotest
 %{python_sitelib}/oslotest-%{version}.dist-info
 

++++++ oslotest-5.0.1.tar.gz -> oslotest-6.0.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslotest-5.0.1/.pre-commit-config.yaml 
new/oslotest-6.0.0/.pre-commit-config.yaml
--- old/oslotest-5.0.1/.pre-commit-config.yaml  2025-05-06 14:46:34.000000000 
+0200
+++ new/oslotest-6.0.0/.pre-commit-config.yaml  2025-11-11 14:30:30.000000000 
+0100
@@ -1,30 +1,25 @@
 repos:
   - repo: https://github.com/pre-commit/pre-commit-hooks
-    rev: v5.0.0
+    rev: v6.0.0
     hooks:
       - id: trailing-whitespace
-      # Replaces or checks mixed line ending
       - id: mixed-line-ending
         args: ['--fix', 'lf']
         exclude: '.*\.(svg)$'
-      # Forbid files which have a UTF-8 byte-order marker
-      - id: check-byte-order-marker
-      # Checks that non-binary executables have a proper shebang
+      - id: fix-byte-order-marker
       - id: check-executables-have-shebangs
-      # Check for files that contain merge conflict strings.
       - id: check-merge-conflict
-      # Check for debugger imports and py37+ breakpoint()
-      # calls in python source
       - id: debug-statements
       - id: check-yaml
         files: .*\.(yaml|yml)$
+  - repo: https://github.com/astral-sh/ruff-pre-commit
+    rev: v0.12.12
+    hooks:
+      - id: ruff-check
+        args: ['--fix', '--unsafe-fixes']
+      - id: ruff-format
   - repo: https://opendev.org/openstack/hacking
     rev: 7.0.0
     hooks:
       - id: hacking
         additional_dependencies: []
-  - repo: https://github.com/asottile/pyupgrade
-    rev: v3.18.0
-    hooks:
-      - id: pyupgrade
-        args: [--py3-only]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslotest-5.0.1/ChangeLog new/oslotest-6.0.0/ChangeLog
--- old/oslotest-5.0.1/ChangeLog        2025-05-06 14:47:21.000000000 +0200
+++ new/oslotest-6.0.0/ChangeLog        2025-11-11 14:31:15.000000000 +0100
@@ -1,6 +1,17 @@
 CHANGES
 =======
 
+6.0.0
+-----
+
+* Add ruff
+* Remove cross-testing functionality
+* Bump pyupgrade target to 3.10+
+* pre-commit: Bump dependencies
+* Migrate setup configuration to pyproject.toml
+* Drop Python 3.8, 3.9 support
+* add pyproject.toml to support pip 23.1
+
 5.0.1
 -----
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslotest-5.0.1/PKG-INFO new/oslotest-6.0.0/PKG-INFO
--- old/oslotest-5.0.1/PKG-INFO 2025-05-06 14:47:21.724126000 +0200
+++ new/oslotest-6.0.0/PKG-INFO 2025-11-11 14:31:15.673163400 +0100
@@ -1,10 +1,10 @@
 Metadata-Version: 2.1
 Name: oslotest
-Version: 5.0.1
+Version: 6.0.0
 Summary: Oslo test framework
-Home-page: https://docs.openstack.org/oslotest/latest/
-Author: OpenStack
-Author-email: [email protected]
+Author-email: OpenStack <[email protected]>
+Project-URL: Homepage, https://docs.openstack.org/oslotest
+Project-URL: Repository, https://opendev.org/openstack/oslotest
 Classifier: Environment :: OpenStack
 Classifier: Intended Audience :: Developers
 Classifier: Intended Audience :: Information Technology
@@ -12,14 +12,14 @@
 Classifier: Operating System :: POSIX :: Linux
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.8
-Classifier: Programming Language :: Python :: 3.9
 Classifier: Programming Language :: Python :: 3.10
 Classifier: Programming Language :: Python :: 3.11
 Classifier: Programming Language :: Python :: 3.12
+Classifier: Programming Language :: Python :: 3.13
 Classifier: Programming Language :: Python :: 3 :: Only
 Classifier: Programming Language :: Python :: Implementation :: CPython
-Requires-Python: >=3.8
+Requires-Python: >=3.10
+Description-Content-Type: text/x-rst
 License-File: LICENSE
 Requires-Dist: fixtures>=3.0.0
 Requires-Dist: python-subunit>=1.0.0
@@ -46,4 +46,3 @@
 * Source: https://opendev.org/openstack/oslotest
 * Bugs: https://bugs.launchpad.net/oslotest
 * Release notes: https://docs.openstack.org/releasenotes/oslotest
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslotest-5.0.1/doc/source/conf.py 
new/oslotest-6.0.0/doc/source/conf.py
--- old/oslotest-5.0.1/doc/source/conf.py       2025-05-06 14:46:34.000000000 
+0200
+++ new/oslotest-6.0.0/doc/source/conf.py       2025-11-11 14:30:30.000000000 
+0100
@@ -57,7 +57,5 @@
 # sphinxcontrib.apidoc options
 apidoc_module_dir = '../../oslotest'
 apidoc_output_dir = 'reference/api'
-apidoc_excluded_paths = [
-    'tests/*',
-    'tests']
+apidoc_excluded_paths = ['tests/*', 'tests']
 apidoc_separate_modules = True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslotest-5.0.1/doc/source/user/cross-testing.rst 
new/oslotest-6.0.0/doc/source/user/cross-testing.rst
--- old/oslotest-5.0.1/doc/source/user/cross-testing.rst        2025-05-06 
14:46:34.000000000 +0200
+++ new/oslotest-6.0.0/doc/source/user/cross-testing.rst        1970-01-01 
01:00:00.000000000 +0100
@@ -1,102 +0,0 @@
-==========================
-Cross-project Unit Testing
-==========================
-
-Libraries in OpenStack have an unusual ability to introduce breaking
-changes. All of the projects are run together from source in one form
-or another during the integration tests, but they are not combined
-from source when unit tests are run. The server applications do not
-generally import code from other projects, so their unit tests are
-isolated. The libraries, however, are fundamentally intended to be
-used during unit tests as well as integration tests. Testing the full
-cross-product of libraries and consuming projects would consume all
-available test servers, and so we cannot run all of the tests on all
-patches to the libraries. As an alternative, we have a few scripts in
-``oslotest`` for running the unit tests in serial. The result takes
-far too long (usually overnight) to run in the OpenStack
-infrastructure. Instead, they are usually run by hand on a dedicated
-system. A cloud VM works well for this purpose, especially considering
-how much of it is now automated.
-
-Check Out OpenStack Source
-==========================
-
-The first step for all of the cross-project unit tests tools is to
-ensure that you have a full copy of the OpenStack source checked
-out. You can do this yourself through gerrit's ssh API, or you can use
-the ``clone_openstack.sh`` command in the tools directory of the
-``openstack/oslo-incubator`` repository.
-
-For example::
-
-  $ mkdir -p ~/repos/openstack
-  $ cd ~/repos/openstack
-  $ git clone https://opendev.org/openstack/oslo-incubator
-  $ cd ~/repos
-  $ ./openstack/oslo-incubator/tools/clone_openstack.sh
-
-The first time the script runs it will take quite some time, since it
-has to download the entire history of every OpenStack project.
-
-Testing One Project
-===================
-
-``oslo_run_cross_tests`` runs one set of unit tests for one library
-against all of the consuming projects. It should be run from the
-directory with the library to be tested, and passed arguments telling
-it about another project whose tests should be run.
-
-For example, to run the ``py27`` test suite from nova using the
-currently checked out sources for ``oslo.config``, run::
-
-  $ cd ~/repos/openstack/oslo.config
-  $ tox -e venv -- oslo_run_cross_tests ~/repos/openstack/nova py27
-
-Testing All Consumers
-=====================
-
-``oslo_run_pre_release_tests`` builds on ``oslo_run_cross_tests`` to
-find all of the consuming projects and run their tests
-automatically. The pre-release script needs to know where the source
-has been checked out, so the first step is to create its configuration
-file.
-
-Edit ``~/.oslo.conf`` to contain::
-
-  [DEFAULT]
-  repo_root = /path/to/repos
-
-Replace ``/path/to/repos`` with the full, expanded, absolute path to
-the location where the source code was checked out. For example, if
-you followed the instructions above using ``clone_openstack.sh`` in
-``~/repos`` and your user name is ``theuser`` the path would be
-``/home/theuser/repos``.
-
-Returning to the earlier example, to test ``oslo.config`` with all of
-the projects that use it, go to the ``oslo.config`` source directory
-and run ``oslo_run_pre_release_tests``.
-
-::
-
-  $ cd ~/repos/openstack/oslo.config
-  $ tox -e venv -- oslo_run_pre_release_tests
-
-The output for each test set is logged to a separate file in the
-current directory, to make them easy to examine.
-
-Use the ``--update`` or ``-u`` option to force a ``git pull`` for each
-consuming projects before running its tests (useful for maintaining a
-long-running system to host these tests).
-
-Use the ``--verbose`` or ``-v`` option to report more verbosely about
-what is happening, including the number of projects being tested.
-
-Use ``--env`` or ``-e`` to add a tox environment to test. By default
-the ``py27`` and ``pep8`` environments are used because those have
-been shown to provide a good balance between finding problems and
-running the tests quickly.
-
-Use the ``--ref`` option to test a specific commit reference of the
-library under test. The default is to leave the source directory
-untouched, but if this option is specified ``git checkout`` is used to
-force the source tree to the specified reference.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslotest-5.0.1/doc/source/user/index.rst 
new/oslotest-6.0.0/doc/source/user/index.rst
--- old/oslotest-5.0.1/doc/source/user/index.rst        2025-05-06 
14:46:34.000000000 +0200
+++ new/oslotest-6.0.0/doc/source/user/index.rst        2025-11-11 
14:30:30.000000000 +0100
@@ -9,6 +9,5 @@
    debugging
    testing
    mock-autospec
-   cross-testing
    resources
-   history
\ No newline at end of file
+   history
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslotest-5.0.1/doc/source/user/testing.rst 
new/oslotest-6.0.0/doc/source/user/testing.rst
--- old/oslotest-5.0.1/doc/source/user/testing.rst      2025-05-06 
14:46:34.000000000 +0200
+++ new/oslotest-6.0.0/doc/source/user/testing.rst      2025-11-11 
14:30:30.000000000 +0100
@@ -2,29 +2,8 @@
 Testing
 =======
 
-Cross-testing With Other Projects
-=================================
+oslotest can be tested via ``tox``, like any other OpenStack project:
 
-The oslotest package can be cross-tested against its consuming
-projects to ensure that no changes to the library break the tests in
-those other projects.
-
-In the Gate
------------
-
-Refer to the instructions in
-https://wiki.openstack.org/wiki/Oslo/UsingALibrary for setting up
-cross-test jobs in the gate.
-
-Locally
--------
-
-To run the cross-tests locally, invoke the script directly, passing
-the path to the other source repository and the tox environment name
-to use:
-
-::
-
-  $ cd oslo.test
-  $ ./tools/oslo_run_cross_tests ~/repos/openstack/oslo.config py27
+.. code-block:: shell
 
+    tox -e py3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslotest-5.0.1/oslotest/base.py 
new/oslotest-6.0.0/oslotest/base.py
--- old/oslotest-5.0.1/oslotest/base.py 2025-05-06 14:46:34.000000000 +0200
+++ new/oslotest-6.0.0/oslotest/base.py 2025-11-11 14:30:30.000000000 +0100
@@ -84,6 +84,7 @@
     .. _fixtures: https://pypi.org/project/fixtures
 
     """
+
     DEFAULT_TIMEOUT = 0
     TIMEOUT_SCALING_FACTOR = 1
 
@@ -100,8 +101,7 @@
         # NOTE(dims): This is a hack for Mitaka. We'll need to undo this as
         # early as possible in Newton and advertise that this hack will not
         # be supported anymore.
-        if (hasattr(self, '_cleanups') and
-                isinstance(self._cleanups, list)):
+        if hasattr(self, '_cleanups') and isinstance(self._cleanups, list):
             if not self._cleanups:
                 # Ensure that the mock.patch.stopall cleanup is registered
                 # before any addCleanup() methods have a chance to register
@@ -110,8 +110,10 @@
                 # method so those mocks are not included in the stopall set.
                 super().addCleanup(mock.patch.stopall)
         else:
-            LOG.error('Unable to patch test case. '
-                      'mock.patch.stopall cleanup was not registered.')
+            LOG.error(
+                'Unable to patch test case. '
+                'mock.patch.stopall cleanup was not registered.'
+            )
         super().addCleanup(function, *args, **kwargs)
 
     def setUp(self):
@@ -123,10 +125,12 @@
         self.useFixture(fixtures.TempHomeDir())
 
     def _set_timeout(self):
-        self.useFixture(timeout.Timeout(
-            default_timeout=self.DEFAULT_TIMEOUT,
-            scaling_factor=self.TIMEOUT_SCALING_FACTOR,
-        ))
+        self.useFixture(
+            timeout.Timeout(
+                default_timeout=self.DEFAULT_TIMEOUT,
+                scaling_factor=self.TIMEOUT_SCALING_FACTOR,
+            )
+        )
 
     def _fake_output(self):
         self.output_fixture = self.useFixture(output.CaptureOutput())
@@ -155,11 +159,13 @@
             else:
                 basename, contents = f
                 encoding = default_encoding
-            fix = self.useFixture(createfile.CreateFileWithContent(
-                filename=basename,
-                contents=contents,
-                ext=ext,
-                encoding=encoding,
-            ))
+            fix = self.useFixture(
+                createfile.CreateFileWithContent(
+                    filename=basename,
+                    contents=contents,
+                    ext=ext,
+                    encoding=encoding,
+                )
+            )
             tempfiles.append(fix.path)
         return tempfiles
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslotest-5.0.1/oslotest/createfile.py 
new/oslotest-6.0.0/oslotest/createfile.py
--- old/oslotest-5.0.1/oslotest/createfile.py   2025-05-06 14:46:34.000000000 
+0200
+++ new/oslotest-6.0.0/oslotest/createfile.py   2025-11-11 14:30:30.000000000 
+0100
@@ -58,8 +58,9 @@
         if isinstance(contents, str):
             contents = contents.encode(self._encoding)
         if not os.path.isabs(self._filename):
-            (fd, self.path) = tempfile.mkstemp(prefix=self._filename,
-                                               suffix=self._ext)
+            fd, self.path = tempfile.mkstemp(
+                prefix=self._filename, suffix=self._ext
+            )
         else:
             self.path = self._filename + self._ext
             fd = os.open(self.path, os.O_CREAT | os.O_WRONLY)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslotest-5.0.1/oslotest/log.py 
new/oslotest-6.0.0/oslotest/log.py
--- old/oslotest-5.0.1/oslotest/log.py  2025-05-06 14:46:34.000000000 +0200
+++ new/oslotest-6.0.0/oslotest/log.py  2025-11-11 14:30:30.000000000 +0100
@@ -19,9 +19,11 @@
 _FALSE_VALUES = ('False', 'false', '0', 'no')
 _BASE_LOG_LEVELS = ('DEBUG', 'INFO', 'WARN', 'WARNING', 'ERROR', 'CRITICAL')
 _LOG_LEVELS = {n: getattr(logging, n) for n in _BASE_LOG_LEVELS}
-_LOG_LEVELS.update({
-    'TRACE': 5,
-})
+_LOG_LEVELS.update(
+    {
+        'TRACE': 5,
+    }
+)
 
 
 def _try_int(value):
@@ -73,7 +75,7 @@
         elif _os_debug in _LOG_LEVELS:
             self.level = _LOG_LEVELS[_os_debug]
         elif _os_debug and _os_debug not in _FALSE_VALUES:
-            raise ValueError('OS_DEBUG=%s is invalid.' % (_os_debug))
+            raise ValueError(f'OS_DEBUG={_os_debug} is invalid.')
         self.capture_logs = os.environ.get('OS_LOG_CAPTURE') in _TRUE_VALUES
         self.logger = None
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslotest-5.0.1/oslotest/mock_fixture.py 
new/oslotest-6.0.0/oslotest/mock_fixture.py
--- old/oslotest-5.0.1/oslotest/mock_fixture.py 2025-05-06 14:46:34.000000000 
+0200
+++ new/oslotest-6.0.0/oslotest/mock_fixture.py 2025-11-11 14:30:30.000000000 
+0100
@@ -72,8 +72,7 @@
         if callable(original_attr):
             # lazily autospec callable attribute.
             eat_self = mock._must_skip(
-                original_spec, name,
-                isinstance(original_spec, type)
+                original_spec, name, isinstance(original_spec, type)
             )
 
             _lazy_autospec_method(attr, original_attr, eat_self)
@@ -112,13 +111,11 @@
 
         # patch both external and internal usage of Mock / MagicMock.
         self.useFixture(
-            fixtures.MonkeyPatch(
-                'unittest.mock.Mock',
-                _AutospecMock))
+            fixtures.MonkeyPatch('unittest.mock.Mock', _AutospecMock)
+        )
         self.useFixture(
-            fixtures.MonkeyPatch(
-                'unittest.mock.MagicMock',
-                _AutospecMagicMock))
+            fixtures.MonkeyPatch('unittest.mock.MagicMock', _AutospecMagicMock)
+        )
 
 
 class _patch(mock._patch):
@@ -140,8 +137,9 @@
         autospec = True if self.autospec is None else self.autospec
 
         # in some cases, autospec cannot be set to True.
-        skip_autospec = (getattr(self, attr) for attr in
-                         ['new_callable', 'create', 'spec'])
+        skip_autospec = (
+            getattr(self, attr) for attr in ['new_callable', 'create', 'spec']
+        )
         # NOTE(claudiub): The "new" argument is always mock.DEFAULT, unless
         # explicitly set otherwise.
         if self.new is not mock.DEFAULT or any(skip_autospec):
@@ -163,17 +161,16 @@
             target = self.getter()
             original_attr = getattr(target, self.attribute)
             eat_self = mock._must_skip(
-                target,
-                self.attribute,
-                isinstance(target, type)
+                target, self.attribute, isinstance(target, type)
             )
 
             new = super().__enter__()
 
             # NOTE(claudiub): mock.patch.multiple will cause new to be a
             # dict.
-            mocked_method = (new[self.attribute] if isinstance(new, dict)
-                             else new)
+            mocked_method = (
+                new[self.attribute] if isinstance(new, dict) else new
+            )
             _lazy_autospec_method(mocked_method, original_attr, eat_self)
             return new
         else:
@@ -199,4 +196,5 @@
     # as it will try to copy the partial function's __name__ (which they do
     # not have).
     mock._copy_func_details = _safe_attribute_error_wrapper(
-        mock._copy_func_details)
+        mock._copy_func_details
+    )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslotest-5.0.1/oslotest/output.py 
new/oslotest-6.0.0/oslotest/output.py
--- old/oslotest-5.0.1/oslotest/output.py       2025-05-06 14:46:34.000000000 
+0200
+++ new/oslotest-6.0.0/oslotest/output.py       2025-11-11 14:30:30.000000000 
+0100
@@ -47,13 +47,15 @@
     def __init__(self, do_stdout=None, do_stderr=None):
         super().__init__()
         if do_stdout is None:
-            self.do_stdout = (os.environ.get('OS_STDOUT_CAPTURE')
-                              in _TRUE_VALUES)
+            self.do_stdout = (
+                os.environ.get('OS_STDOUT_CAPTURE') in _TRUE_VALUES
+            )
         else:
             self.do_stdout = do_stdout
         if do_stderr is None:
-            self.do_stderr = (os.environ.get('OS_STDERR_CAPTURE')
-                              in _TRUE_VALUES)
+            self.do_stderr = (
+                os.environ.get('OS_STDERR_CAPTURE') in _TRUE_VALUES
+            )
         else:
             self.do_stderr = do_stderr
         self.stdout = None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslotest-5.0.1/oslotest/tests/unit/test_base.py 
new/oslotest-6.0.0/oslotest/tests/unit/test_base.py
--- old/oslotest-5.0.1/oslotest/tests/unit/test_base.py 2025-05-06 
14:46:34.000000000 +0200
+++ new/oslotest-6.0.0/oslotest/tests/unit/test_base.py 2025-11-11 
14:30:30.000000000 +0100
@@ -24,7 +24,6 @@
 
 
 class TestBaseTestCase(testtools.TestCase):
-
     class FakeTestCase(base.BaseTestCase):
         def test_fake_test(self):
             pass
@@ -44,7 +43,9 @@
     def test_fake_logs_default(self, env_get_mock):
         # without debug and log capture
         env_get_mock.side_effect = lambda value, default=None: {
-            'OS_DEBUG': 0, 'OS_LOG_CAPTURE': 0}.get(value, default)
+            'OS_DEBUG': 0,
+            'OS_LOG_CAPTURE': 0,
+        }.get(value, default)
         tc = self.FakeTestCase("test_fake_test")
         tc.setUp()
         env_get_mock.assert_any_call('OS_LOG_CAPTURE')
@@ -56,20 +57,24 @@
     @mock.patch('logging.basicConfig')
     def test_fake_logs_with_debug(self, basic_logger_mock, env_get_mock):
         env_get_mock.side_effect = lambda value, default=None: {
-            'OS_DEBUG': 'True', 'OS_LOG_CAPTURE': 0}.get(value, default)
+            'OS_DEBUG': 'True',
+            'OS_LOG_CAPTURE': 0,
+        }.get(value, default)
         tc = self.FakeTestCase("test_fake_test")
         tc.setUp()
         env_get_mock.assert_any_call('OS_LOG_CAPTURE')
         env_get_mock.assert_any_call('OS_DEBUG')
-        basic_logger_mock.assert_called_once_with(format=base._LOG_FORMAT,
-                                                  level=logging.DEBUG)
+        basic_logger_mock.assert_called_once_with(
+            format=base._LOG_FORMAT, level=logging.DEBUG
+        )
 
     @mock.patch('os.environ.get')
     @mock.patch.object(FakeTestCase, 'useFixture')
     def test_fake_logs_with_log_cap(self, fixture_mock, env_get_mock):
-        env_get_mock.side_effect = lambda value: {'OS_DEBUG': 0,
-                                                  'OS_LOG_CAPTURE': 'True'
-                                                  }.get(value)
+        env_get_mock.side_effect = lambda value: {
+            'OS_DEBUG': 0,
+            'OS_LOG_CAPTURE': 'True',
+        }.get(value)
         tc = self.FakeTestCase("test_fake_test")
         tc.setUp()
         env_get_mock.assert_any_call('OS_LOG_CAPTURE')
@@ -114,7 +119,6 @@
 
 
 class TestManualMock(base.BaseTestCase):
-
     def setUp(self):
         # Create a cleanup to undo a patch() call *before* calling the
         # base class version of setup().
@@ -161,8 +165,9 @@
                 contents = f.read()
             if not isinstance(raw_contents, str):
                 raw_contents = str(raw_contents, encoding=raw_encoding)
-            self.assertEqual(str(contents, encoding=raw_encoding),
-                             raw_contents)
+            self.assertEqual(
+                str(contents, encoding=raw_encoding), raw_contents
+            )
 
     def test_create_bad_encoding(self):
         files = [["hrm", 'ಠ~ಠ', 'ascii']]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/oslotest-5.0.1/oslotest/tests/unit/test_createfile.py 
new/oslotest-6.0.0/oslotest/tests/unit/test_createfile.py
--- old/oslotest-5.0.1/oslotest/tests/unit/test_createfile.py   2025-05-06 
14:46:34.000000000 +0200
+++ new/oslotest-6.0.0/oslotest/tests/unit/test_createfile.py   2025-11-11 
14:30:30.000000000 +0100
@@ -19,7 +19,6 @@
 
 
 class CreateFileWithContentTest(base.BaseTestCase):
-
     def test_create_unicode_files(self):
         f = createfile.CreateFileWithContent(
             "no_approve",
@@ -32,7 +31,9 @@
 
     def test_create_unicode_files_encoding(self):
         f = createfile.CreateFileWithContent(
-            "embarrassed", '⊙﹏⊙', encoding='utf-8',
+            "embarrassed",
+            '⊙﹏⊙',
+            encoding='utf-8',
         )
         f.setUp()
         with open(f.path, 'rb') as f:
@@ -41,7 +42,9 @@
 
     def test_create_bad_encoding(self):
         f = createfile.CreateFileWithContent(
-            "hrm", 'ಠ~ಠ', encoding='ascii',
+            "hrm",
+            'ಠ~ಠ',
+            encoding='ascii',
         )
         self.assertRaises(UnicodeError, f.setUp)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslotest-5.0.1/oslotest/tests/unit/test_log.py 
new/oslotest-6.0.0/oslotest/tests/unit/test_log.py
--- old/oslotest-5.0.1/oslotest/tests/unit/test_log.py  2025-05-06 
14:46:34.000000000 +0200
+++ new/oslotest-6.0.0/oslotest/tests/unit/test_log.py  2025-11-11 
14:30:30.000000000 +0100
@@ -21,12 +21,13 @@
 
 
 class ConfigureLoggingTestCase(testtools.TestCase):
-
     @mock.patch('os.environ.get')
     def test_fake_logs_default(self, env_get_mock):
         # without debug and log capture
         env_get_mock.side_effect = lambda value, default=None: {
-            'OS_DEBUG': 0, 'OS_LOG_CAPTURE': 0}.get(value, default)
+            'OS_DEBUG': 0,
+            'OS_LOG_CAPTURE': 0,
+        }.get(value, default)
         f = log.ConfigureLogging()
         f.setUp()
         env_get_mock.assert_any_call('OS_LOG_CAPTURE')
@@ -38,59 +39,68 @@
     @mock.patch('logging.basicConfig')
     def test_fake_logs_with_debug(self, basic_logger_mock, env_get_mock):
         env_get_mock.side_effect = lambda value, default=None: {
-            'OS_DEBUG': 'True', 'OS_LOG_CAPTURE': 0}.get(value, default)
+            'OS_DEBUG': 'True',
+            'OS_LOG_CAPTURE': 0,
+        }.get(value, default)
         f = log.ConfigureLogging()
         f.setUp()
         env_get_mock.assert_any_call('OS_LOG_CAPTURE')
         env_get_mock.assert_any_call('OS_DEBUG')
         basic_logger_mock.assert_called_once_with(
-            format=log.ConfigureLogging.DEFAULT_FORMAT,
-            level=logging.DEBUG)
+            format=log.ConfigureLogging.DEFAULT_FORMAT, level=logging.DEBUG
+        )
 
     @mock.patch('os.environ.get')
     @mock.patch('logging.basicConfig')
     def test_fake_logs_with_warning(self, basic_logger_mock, env_get_mock):
         env_get_mock.side_effect = lambda value, default=None: {
-            'OS_DEBUG': 'WARNING', 'OS_LOG_CAPTURE': 0}.get(value, default)
+            'OS_DEBUG': 'WARNING',
+            'OS_LOG_CAPTURE': 0,
+        }.get(value, default)
         f = log.ConfigureLogging()
         f.setUp()
         env_get_mock.assert_any_call('OS_LOG_CAPTURE')
         env_get_mock.assert_any_call('OS_DEBUG')
         basic_logger_mock.assert_called_once_with(
-            format=log.ConfigureLogging.DEFAULT_FORMAT,
-            level=logging.WARNING)
+            format=log.ConfigureLogging.DEFAULT_FORMAT, level=logging.WARNING
+        )
 
     @mock.patch('os.environ.get')
     @mock.patch('logging.basicConfig')
     def test_fake_logs_with_trace_int(self, basic_logger_mock, env_get_mock):
         env_get_mock.side_effect = lambda value, default=None: {
-            'OS_DEBUG': '5', 'OS_LOG_CAPTURE': 0}.get(value, default)
+            'OS_DEBUG': '5',
+            'OS_LOG_CAPTURE': 0,
+        }.get(value, default)
         f = log.ConfigureLogging()
         f.setUp()
         env_get_mock.assert_any_call('OS_LOG_CAPTURE')
         env_get_mock.assert_any_call('OS_DEBUG')
         basic_logger_mock.assert_called_once_with(
-            format=log.ConfigureLogging.DEFAULT_FORMAT,
-            level=5)
+            format=log.ConfigureLogging.DEFAULT_FORMAT, level=5
+        )
 
     @mock.patch('os.environ.get')
     @mock.patch('logging.basicConfig')
     def test_fake_logs_with_debug_int(self, basic_logger_mock, env_get_mock):
         env_get_mock.side_effect = lambda value, default=None: {
-            'OS_DEBUG': '10', 'OS_LOG_CAPTURE': 0}.get(value, default)
+            'OS_DEBUG': '10',
+            'OS_LOG_CAPTURE': 0,
+        }.get(value, default)
         f = log.ConfigureLogging()
         f.setUp()
         env_get_mock.assert_any_call('OS_LOG_CAPTURE')
         env_get_mock.assert_any_call('OS_DEBUG')
         basic_logger_mock.assert_called_once_with(
-            format=log.ConfigureLogging.DEFAULT_FORMAT,
-            level=logging.DEBUG)
+            format=log.ConfigureLogging.DEFAULT_FORMAT, level=logging.DEBUG
+        )
 
     @mock.patch('os.environ.get')
     def test_fake_logs_with_log_capture(self, env_get_mock):
-        env_get_mock.side_effect = lambda value: {'OS_DEBUG': 0,
-                                                  'OS_LOG_CAPTURE': 'True'
-                                                  }[value]
+        env_get_mock.side_effect = lambda value: {
+            'OS_DEBUG': 0,
+            'OS_LOG_CAPTURE': 'True',
+        }[value]
         f = log.ConfigureLogging()
         f.setUp()
         env_get_mock.assert_any_call('OS_LOG_CAPTURE')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/oslotest-5.0.1/oslotest/tests/unit/test_mock_fixture.py 
new/oslotest-6.0.0/oslotest/tests/unit/test_mock_fixture.py
--- old/oslotest-5.0.1/oslotest/tests/unit/test_mock_fixture.py 2025-05-06 
14:46:34.000000000 +0200
+++ new/oslotest-6.0.0/oslotest/tests/unit/test_mock_fixture.py 2025-11-11 
14:30:30.000000000 +0100
@@ -40,7 +40,6 @@
 
 
 class MockSanityTestCase(testtools.TestCase):
-
     def setUp(self):
         super().setUp()
         self.useFixture(mock_fixture.MockAutospecFixture())
@@ -51,21 +50,39 @@
 
             # check that the methods are callable with correct args.
             mock_method(mock.sentinel.a, mock.sentinel.b, mock.sentinel.c)
-            mock_method(mock.sentinel.a, mock.sentinel.b, mock.sentinel.c,
-                        d=mock.sentinel.d)
-            mock_method.assert_has_calls([
-                mock.call(mock.sentinel.a, mock.sentinel.b, mock.sentinel.c),
-                mock.call(mock.sentinel.a, mock.sentinel.b, mock.sentinel.c,
-                          d=mock.sentinel.d)])
+            mock_method(
+                mock.sentinel.a,
+                mock.sentinel.b,
+                mock.sentinel.c,
+                d=mock.sentinel.d,
+            )
+            mock_method.assert_has_calls(
+                [
+                    mock.call(
+                        mock.sentinel.a, mock.sentinel.b, mock.sentinel.c
+                    ),
+                    mock.call(
+                        mock.sentinel.a,
+                        mock.sentinel.b,
+                        mock.sentinel.c,
+                        d=mock.sentinel.d,
+                    ),
+                ]
+            )
 
             # assert that TypeError is raised if the method signature is not
             # respected.
             self.assertRaises(TypeError, mock_method)
             self.assertRaises(TypeError, mock_method, mock.sentinel.a)
             self.assertRaises(TypeError, mock_method, a=mock.sentinel.a)
-            self.assertRaises(TypeError, mock_method, mock.sentinel.a,
-                              mock.sentinel.b, mock.sentinel.c,
-                              e=mock.sentinel.e)
+            self.assertRaises(
+                TypeError,
+                mock_method,
+                mock.sentinel.a,
+                mock.sentinel.b,
+                mock.sentinel.c,
+                e=mock.sentinel.e,
+            )
 
         # assert that AttributeError is raised if the method does not exist.
         self.assertRaises(AttributeError, getattr, foo, 'lish')
@@ -90,17 +107,21 @@
         self._check_autospeced_foo(foo)
 
     def test_patch_autospec_multiple(self):
-        with mock.patch.multiple(Foo, bar=mock.DEFAULT,
-                                 classic_bar=mock.DEFAULT,
-                                 static_bar=mock.DEFAULT):
+        with mock.patch.multiple(
+            Foo,
+            bar=mock.DEFAULT,
+            classic_bar=mock.DEFAULT,
+            static_bar=mock.DEFAULT,
+        ):
             foo = Foo()
             self._check_autospeced_foo(foo)
 
     @mock.patch.object(Foo, 'static_bar', autospec=False)
     @mock.patch.object(Foo, 'classic_bar', autospec=False)
     @mock.patch.object(Foo, 'bar', autospec=False)
-    def test_patch_autospec_class_false(self, mock_meth, mock_cmeth,
-                                        mock_smeth):
+    def test_patch_autospec_class_false(
+        self, mock_meth, mock_cmeth, mock_smeth
+    ):
         foo = Foo()
         # we're checking that method signature is not enforced.
         foo.bar()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslotest-5.0.1/oslotest/tests/unit/test_modules.py 
new/oslotest-6.0.0/oslotest/tests/unit/test_modules.py
--- old/oslotest-5.0.1/oslotest/tests/unit/test_modules.py      2025-05-06 
14:46:34.000000000 +0200
+++ new/oslotest-6.0.0/oslotest/tests/unit/test_modules.py      2025-11-11 
14:30:30.000000000 +0100
@@ -15,9 +15,7 @@
 
 
 class CreateDisableModuleTest(base.BaseTestCase):
-
     def test_disable_module(self):
-
         s = __import__('sys')
         self.assertTrue(s)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslotest-5.0.1/oslotest/tests/unit/test_output.py 
new/oslotest-6.0.0/oslotest/tests/unit/test_output.py
--- old/oslotest-5.0.1/oslotest/tests/unit/test_output.py       2025-05-06 
14:46:34.000000000 +0200
+++ new/oslotest-6.0.0/oslotest/tests/unit/test_output.py       2025-11-11 
14:30:30.000000000 +0100
@@ -19,7 +19,6 @@
 
 
 class CaptureOutputTest(testtools.TestCase):
-
     @mock.patch('os.environ')
     def test_disabled_env(self, mock_env):
         mock_env.get.return_value = ''
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslotest-5.0.1/oslotest/tests/unit/test_timeout.py 
new/oslotest-6.0.0/oslotest/tests/unit/test_timeout.py
--- old/oslotest-5.0.1/oslotest/tests/unit/test_timeout.py      2025-05-06 
14:46:34.000000000 +0200
+++ new/oslotest-6.0.0/oslotest/tests/unit/test_timeout.py      2025-11-11 
14:30:30.000000000 +0100
@@ -18,7 +18,6 @@
 
 
 class TimeoutTestCase(testtools.TestCase):
-
     @mock.patch('os.environ.get')
     @mock.patch.object(timeout.Timeout, 'useFixture')
     @mock.patch('fixtures.Timeout')
@@ -33,8 +32,9 @@
     @mock.patch('os.environ.get')
     @mock.patch.object(timeout.Timeout, 'useFixture')
     @mock.patch('fixtures.Timeout')
-    def test_no_timeout(self, fixture_timeout_mock, fixture_mock,
-                        env_get_mock):
+    def test_no_timeout(
+        self, fixture_timeout_mock, fixture_mock, env_get_mock
+    ):
         # Returning 0 means we don't install the timeout
         env_get_mock.return_value = 0
         tc = timeout.Timeout()
@@ -47,7 +47,8 @@
     @mock.patch.object(timeout.Timeout, 'useFixture')
     @mock.patch('fixtures.Timeout')
     def test_timeout_default(
-            self, fixture_timeout_mock, fixture_mock, env_get_mock):
+        self, fixture_timeout_mock, fixture_mock, env_get_mock
+    ):
         env_get_mock.return_value = 5
         tc = timeout.Timeout(default_timeout=5)
         tc.setUp()
@@ -59,7 +60,8 @@
     @mock.patch.object(timeout.Timeout, 'useFixture')
     @mock.patch('fixtures.Timeout')
     def test_timeout_bad_default(
-            self, fixture_timeout_mock, fixture_mock, env_get_mock):
+        self, fixture_timeout_mock, fixture_mock, env_get_mock
+    ):
         env_get_mock.return_value = 'invalid'
         tc = timeout.Timeout(default_timeout='invalid')
         tc.setUp()
@@ -71,7 +73,8 @@
     @mock.patch.object(timeout.Timeout, 'useFixture')
     @mock.patch('fixtures.Timeout')
     def test_timeout_scaling(
-            self, fixture_timeout_mock, fixture_mock, env_get_mock):
+        self, fixture_timeout_mock, fixture_mock, env_get_mock
+    ):
         env_get_mock.return_value = 2
         tc = timeout.Timeout(scaling_factor=1.5)
         tc.setUp()
@@ -83,7 +86,8 @@
     @mock.patch.object(timeout.Timeout, 'useFixture')
     @mock.patch('fixtures.Timeout')
     def test_timeout_bad_scaling(
-            self, fixture_timeout_mock, fixture_mock, env_get_mock):
+        self, fixture_timeout_mock, fixture_mock, env_get_mock
+    ):
         env_get_mock.return_value = 2
         tc = timeout.Timeout(scaling_factor='invalid')
         tc.setUp()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslotest-5.0.1/oslotest/tools/config.py 
new/oslotest-6.0.0/oslotest/tools/config.py
--- old/oslotest-5.0.1/oslotest/tools/config.py 2025-05-06 14:46:34.000000000 
+0200
+++ new/oslotest-6.0.0/oslotest/tools/config.py 2025-11-11 14:30:30.000000000 
+0100
@@ -10,8 +10,7 @@
 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 #    License for the specific language governing permissions and limitations
 #    under the License.
-"""Utilities functions for working with oslo.config from the tool scripts.
-"""
+"""Utilities functions for working with oslo.config from the tool scripts."""
 
 import os
 
@@ -38,9 +37,7 @@
 def parse_arguments(conf):
     # Look for a few configuration files, and load the ones we find.
     default_config_files = [
-        f
-        for f in DEFAULT_CONFIG_FILES
-        if os.path.exists(f)
+        f for f in DEFAULT_CONFIG_FILES if os.path.exists(f)
     ]
     return conf(
         project='oslo',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslotest-5.0.1/oslotest.egg-info/PKG-INFO 
new/oslotest-6.0.0/oslotest.egg-info/PKG-INFO
--- old/oslotest-5.0.1/oslotest.egg-info/PKG-INFO       2025-05-06 
14:47:21.000000000 +0200
+++ new/oslotest-6.0.0/oslotest.egg-info/PKG-INFO       2025-11-11 
14:31:15.000000000 +0100
@@ -1,10 +1,10 @@
 Metadata-Version: 2.1
 Name: oslotest
-Version: 5.0.1
+Version: 6.0.0
 Summary: Oslo test framework
-Home-page: https://docs.openstack.org/oslotest/latest/
-Author: OpenStack
-Author-email: [email protected]
+Author-email: OpenStack <[email protected]>
+Project-URL: Homepage, https://docs.openstack.org/oslotest
+Project-URL: Repository, https://opendev.org/openstack/oslotest
 Classifier: Environment :: OpenStack
 Classifier: Intended Audience :: Developers
 Classifier: Intended Audience :: Information Technology
@@ -12,14 +12,14 @@
 Classifier: Operating System :: POSIX :: Linux
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.8
-Classifier: Programming Language :: Python :: 3.9
 Classifier: Programming Language :: Python :: 3.10
 Classifier: Programming Language :: Python :: 3.11
 Classifier: Programming Language :: Python :: 3.12
+Classifier: Programming Language :: Python :: 3.13
 Classifier: Programming Language :: Python :: 3 :: Only
 Classifier: Programming Language :: Python :: Implementation :: CPython
-Requires-Python: >=3.8
+Requires-Python: >=3.10
+Description-Content-Type: text/x-rst
 License-File: LICENSE
 Requires-Dist: fixtures>=3.0.0
 Requires-Dist: python-subunit>=1.0.0
@@ -46,4 +46,3 @@
 * Source: https://opendev.org/openstack/oslotest
 * Bugs: https://bugs.launchpad.net/oslotest
 * Release notes: https://docs.openstack.org/releasenotes/oslotest
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslotest-5.0.1/oslotest.egg-info/SOURCES.txt 
new/oslotest-6.0.0/oslotest.egg-info/SOURCES.txt
--- old/oslotest-5.0.1/oslotest.egg-info/SOURCES.txt    2025-05-06 
14:47:21.000000000 +0200
+++ new/oslotest-6.0.0/oslotest.egg-info/SOURCES.txt    2025-11-11 
14:31:15.000000000 +0100
@@ -9,6 +9,7 @@
 HACKING.rst
 LICENSE
 README.rst
+pyproject.toml
 requirements.txt
 setup.cfg
 setup.py
@@ -20,7 +21,6 @@
 doc/source/contributor/index.rst
 doc/source/install/index.rst
 doc/source/reference/index.rst
-doc/source/user/cross-testing.rst
 doc/source/user/debugging.rst
 doc/source/user/features.rst
 doc/source/user/history.rst
@@ -62,6 +62,7 @@
 releasenotes/notes/mock-autospec-fix-9042c30dbb74032f.yaml
 releasenotes/notes/remove-functional-module-4733bc6eff595683.yaml
 releasenotes/notes/remove-moxstubout-63345dd5d9528e83.yaml
+releasenotes/notes/remove-py38-py39-24a1ab1e4252ee84.yaml
 releasenotes/notes/remove_mockpatch-80fec29f28da5d5c.yaml
 releasenotes/notes/timeout-scaling-52741beadde528e5.yaml
 releasenotes/source/conf.py
@@ -77,6 +78,4 @@
 releasenotes/source/victoria.rst
 releasenotes/source/_static/.placeholder
 releasenotes/source/_templates/.placeholder
-tools/oslo_debug_helper
-tools/oslo_run_cross_tests
-tools/oslo_run_pre_release_tests
\ No newline at end of file
+tools/oslo_debug_helper
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslotest-5.0.1/oslotest.egg-info/pbr.json 
new/oslotest-6.0.0/oslotest.egg-info/pbr.json
--- old/oslotest-5.0.1/oslotest.egg-info/pbr.json       2025-05-06 
14:47:21.000000000 +0200
+++ new/oslotest-6.0.0/oslotest.egg-info/pbr.json       2025-11-11 
14:31:15.000000000 +0100
@@ -1 +1 @@
-{"git_version": "1fe4458", "is_release": true}
\ No newline at end of file
+{"git_version": "b5e4a4c", "is_release": true}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslotest-5.0.1/pyproject.toml 
new/oslotest-6.0.0/pyproject.toml
--- old/oslotest-5.0.1/pyproject.toml   1970-01-01 01:00:00.000000000 +0100
+++ new/oslotest-6.0.0/pyproject.toml   2025-11-11 14:30:30.000000000 +0100
@@ -0,0 +1,54 @@
+[build-system]
+requires = ["pbr>=6.1.1"]
+build-backend = "pbr.build"
+
+[project]
+name = "oslotest"
+description = "Oslo test framework"
+readme = "README.rst"
+authors = [
+    {name = "OpenStack", email = "[email protected]"},
+]
+requires-python = ">=3.10"
+dynamic = ["version", "dependencies"]
+classifiers = [
+    "Environment :: OpenStack",
+    "Intended Audience :: Developers",
+    "Intended Audience :: Information Technology",
+    "License :: OSI Approved :: Apache Software License",
+    "Operating System :: POSIX :: Linux",
+    "Programming Language :: Python",
+    "Programming Language :: Python :: 3",
+    "Programming Language :: Python :: 3.10",
+    "Programming Language :: Python :: 3.11",
+    "Programming Language :: Python :: 3.12",
+    "Programming Language :: Python :: 3.13",
+    "Programming Language :: Python :: 3 :: Only",
+    "Programming Language :: Python :: Implementation :: CPython",
+]
+
+[project.urls]
+Homepage = "https://docs.openstack.org/oslotest";
+Repository = "https://opendev.org/openstack/oslotest";
+
+[tool.setuptools]
+packages = [
+    "oslotest"
+]
+script-files = [
+    "tools/oslo_debug_helper",
+]
+
+[tool.ruff]
+line-length = 79
+
+[tool.ruff.format]
+quote-style = "preserve"
+docstring-code-format = true
+
+[tool.ruff.lint]
+select = ["E4", "E5", "E7", "E9", "F", "S", "U"]
+ignore = [
+    # we only use asserts for type narrowing
+    "S101",
+]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/oslotest-5.0.1/releasenotes/notes/remove-py38-py39-24a1ab1e4252ee84.yaml 
new/oslotest-6.0.0/releasenotes/notes/remove-py38-py39-24a1ab1e4252ee84.yaml
--- 
old/oslotest-5.0.1/releasenotes/notes/remove-py38-py39-24a1ab1e4252ee84.yaml    
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/oslotest-6.0.0/releasenotes/notes/remove-py38-py39-24a1ab1e4252ee84.yaml    
    2025-11-11 14:30:30.000000000 +0100
@@ -0,0 +1,5 @@
+---
+upgrade:
+  - |
+    Support for Python 3.8 and 3.9 has been removed. Now the minimum Python
+    version supported is 3.10.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslotest-5.0.1/setup.cfg new/oslotest-6.0.0/setup.cfg
--- old/oslotest-5.0.1/setup.cfg        2025-05-06 14:47:21.728126300 +0200
+++ new/oslotest-6.0.0/setup.cfg        2025-11-11 14:31:15.673163400 +0100
@@ -1,35 +1,5 @@
 [metadata]
 name = oslotest
-summary = Oslo test framework
-description_file = 
-       README.rst
-author = OpenStack
-author_email = [email protected]
-home_page = https://docs.openstack.org/oslotest/latest/
-python_requires = >=3.8
-classifier = 
-       Environment :: OpenStack
-       Intended Audience :: Developers
-       Intended Audience :: Information Technology
-       License :: OSI Approved :: Apache Software License
-       Operating System :: POSIX :: Linux
-       Programming Language :: Python
-       Programming Language :: Python :: 3
-       Programming Language :: Python :: 3.8
-       Programming Language :: Python :: 3.9
-       Programming Language :: Python :: 3.10
-       Programming Language :: Python :: 3.11
-       Programming Language :: Python :: 3.12
-       Programming Language :: Python :: 3 :: Only
-       Programming Language :: Python :: Implementation :: CPython
-
-[files]
-packages = 
-       oslotest
-scripts = 
-       tools/oslo_debug_helper
-       tools/oslo_run_cross_tests
-       tools/oslo_run_pre_release_tests
 
 [egg_info]
 tag_build = 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslotest-5.0.1/setup.py new/oslotest-6.0.0/setup.py
--- old/oslotest-5.0.1/setup.py 2025-05-06 14:46:34.000000000 +0200
+++ new/oslotest-6.0.0/setup.py 2025-11-11 14:30:30.000000000 +0100
@@ -17,4 +17,5 @@
 
 setuptools.setup(
     setup_requires=['pbr>=2.0.0'],
-    pbr=True)
+    pbr=True,
+)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslotest-5.0.1/tools/oslo_run_cross_tests 
new/oslotest-6.0.0/tools/oslo_run_cross_tests
--- old/oslotest-5.0.1/tools/oslo_run_cross_tests       2025-05-06 
14:46:34.000000000 +0200
+++ new/oslotest-6.0.0/tools/oslo_run_cross_tests       1970-01-01 
01:00:00.000000000 +0100
@@ -1,109 +0,0 @@
-#!/bin/bash
-#
-# Run cross-project tests
-#
-# Usage:
-#
-#   oslo_run_cross_tests project_dir venv
-
-# Fail the build if any command fails
-set -e
-
-PYTHON=${PYTHON:-python3}
-
-function usage {
-    cat - <<EOF
-ERROR: Missing argument(s)
-
-Usage:
-
-  oslo_run_cross_tests PROJECT_DIR VIRTUAL_ENV [POSARGS]
-
-Example, run the python 2.7 tests for python-neutronclient:
-
-  oslo_run_cross_tests /opt/stack/python-neutronclient py27
-  oslo_run_cross_tests /opt/stack/nova py27 xenapi
-
-EOF
-    exit $1
-}
-
-if [[ $# -lt 2 ]]; then
-    usage 1
-fi
-
-project_dir="$1"
-shift
-venv="$1"
-shift
-posargs="$*"
-
-if [ -z "$project_dir" -o -z "$venv" ]
-then
-    usage 2
-fi
-
-# Set up the virtualenv without running the tests
-(cd $project_dir && tox --notest -r -e $venv)
-
-tox_envbin=$project_dir/.tox/$venv/bin
-
-our_name=$(${PYTHON} setup.py --name)
-
-# Build the egg-info, including the source file list,
-# so we install all of the files, even if the package
-# list or name has changed.
-rm -rf $(${PYTHON} setup.py --name).egg-info
-${PYTHON} setup.py egg_info
-
-# Replace the pip-installed package with the version in our source
-# tree. Look to see if we are already installed before trying to
-# uninstall ourselves, to avoid failures from packages that do not use us
-# yet.
-if $tox_envbin/pip freeze | grep -q $our_name
-then
-    $tox_envbin/pip uninstall -y $our_name || echo "Ignoring error"
-fi
-$tox_envbin/pip install -U .
-
-# Run the tests
-(cd $project_dir && tox -e $venv -- $posargs)
-result=$?
-
-
-# The below checks are modified from
-# openstack-infra/config/modules/jenkins/files/slave_scripts/run-unittests.sh.
-
-# They expect to be run in the project being tested.
-cd $project_dir
-
-echo "Begin pip freeze output from test virtualenv:"
-echo "======================================================================"
-.tox/$venv/bin/pip freeze
-echo "======================================================================"
-
-# We only want to run the next check if the tool is installed, so look
-# for it before continuing.
-if [ -f /usr/local/jenkins/slave_scripts/subunit2html.py -a -d 
".testrepository" ] ; then
-    if [ -f ".testrepository/0.2" ] ; then
-        cp .testrepository/0.2 ./subunit_log.txt
-    elif [ -f ".testrepository/0" ] ; then
-        .tox/$venv/bin/subunit-1to2 < .testrepository/0 > ./subunit_log.txt
-    fi
-    .tox/$venv/bin/python /usr/local/jenkins/slave_scripts/subunit2html.py 
./subunit_log.txt testr_results.html
-    gzip -9 ./subunit_log.txt
-    gzip -9 ./testr_results.html
-
-    rancount=$(.tox/$venv/bin/testr last | sed -ne 's/Ran \([0-9]\+\).*tests 
in.*/\1/p')
-    if [ "$rancount" -eq "0" ] ; then
-        echo
-        echo "Zero tests were run. At least one test should have been run."
-        echo "Failing this test as a result"
-        echo
-        exit 1
-    fi
-fi
-
-# If we make it this far, report status based on the tests that were
-# run.
-exit $result
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslotest-5.0.1/tools/oslo_run_pre_release_tests 
new/oslotest-6.0.0/tools/oslo_run_pre_release_tests
--- old/oslotest-5.0.1/tools/oslo_run_pre_release_tests 2025-05-06 
14:46:34.000000000 +0200
+++ new/oslotest-6.0.0/tools/oslo_run_pre_release_tests 1970-01-01 
01:00:00.000000000 +0100
@@ -1,210 +0,0 @@
-#!/usr/bin/env python
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-"""Run unit tests for projects that use a library.
-"""
-
-import glob
-import os
-import subprocess
-import sys
-
-from oslo_config import cfg
-from oslotest.tools import config as tconfig
-from pbr import packaging
-import pkg_resources
-
-
-def find_all_projects(repo_root):
-    """Scan the checked out repositories for all available projects."""
-    pattern = os.path.join(repo_root, 'openstack/*')
-    candidates = glob.glob(pattern)
-    prefix_len = len(repo_root)
-    return [
-        c[prefix_len:].lstrip('/')
-        for c in candidates
-        if os.path.isdir(c)
-    ]
-
-
-def find_consuming_projects(lib_name, repo_root, projects):
-    """Filter the list of projects
-
-    Filter the list of projects to only include entries that use the library.
-    """
-    for p in projects:
-        consumer = False
-        for base in packaging.get_requirements_files():
-            req_file = os.path.join(repo_root, p, base)
-            for req in packaging.parse_requirements([req_file]):
-                try:
-                    parsed_req = pkg_resources.Requirement.parse(req)
-                    req_name = parsed_req.project_name
-                except ValueError:
-                    continue
-                if req_name == lib_name:
-                    consumer = True
-                    yield p
-                    break
-            if consumer:
-                break
-
-
-def main():
-    conf = tconfig.get_config_parser()
-    conf.register_cli_opt(
-        cfg.StrOpt(
-            'library-under-test',
-            short='l',
-            default='',
-            help=('the name of the library being tested; '
-                  'defaults to current dir'),
-        )
-    )
-    conf.register_cli_opt(
-        cfg.BoolOpt(
-            'update',
-            short='u',
-            default=False,
-            help='update consumers before running tests',
-        )
-    )
-    conf.register_cli_opt(
-        cfg.BoolOpt(
-            'verbose',
-            short='v',
-            default=False,
-            help='print verbose output',
-        )
-    )
-    conf.register_cli_opt(
-        cfg.StrOpt(
-            'ref',
-            short='r',
-            default='HEAD',
-            help='the commit reference to test; defaults to HEAD',
-        )
-    )
-    conf.register_cli_opt(
-        cfg.MultiStrOpt(
-            'env',
-            short='e',
-            default=['py27', 'pep8'],
-            help=('the name of the tox environment to test; '
-                  'defaults to py27 and pep8'),
-        )
-    )
-    conf.register_cli_opt(
-        cfg.MultiStrOpt(
-            'consumer',
-            positional=True,
-            default=[],
-            help='the name of a project to test with; may be repeated',
-        )
-    )
-    tconfig.parse_arguments(conf)
-
-    repo_root = os.path.expanduser(conf.repo_root)
-
-    # Figure out which library is being tested
-    lib_name = conf.library_under_test
-    if not lib_name:
-        if conf.verbose:
-            print('finding library name')
-        lib_name = subprocess.check_output(
-            ['python', 'setup.py', '--name']
-        ).strip()
-        lib_dir = os.getcwd()
-    else:
-        lib_dir = os.path.join(repo_root, 'openstack', lib_name)
-    print('testing {} in {}'.format(lib_name, lib_dir))
-
-    projects = set(conf.consumer)
-    if not projects:
-        # TODO(dhellmann): Need to update this to look at gerrit, so
-        # we can check out the projects we want to test with.
-        if conf.verbose:
-            print('defaulting to all projects under %s/openstack' % repo_root)
-        projects = find_all_projects(repo_root)
-
-    # Filter out projects that do not require the library under test
-    before = len(projects)
-    projects = list(find_consuming_projects(lib_name, repo_root, projects))
-    after = len(projects)
-    if (after < before) and conf.verbose:
-        print('ignoring %s projects that do not use %s'
-              % (before - after, lib_name))
-
-    projects = list(sorted(projects))
-    if not projects:
-        print('ERROR: found no projects using %s' % lib_name)
-        return 1
-    if conf.verbose:
-        print('preparing to test %s projects' % after)
-
-    # Make sure the lib being tested is set to the reference intended.
-    if conf.ref != 'HEAD':
-        if conf.verbose:
-            print('ensuring {} is updated to {}'.format(lib_name, conf.ref))
-        subprocess.check_call(
-            ['git', 'checkout', conf.ref],
-            cwd=lib_dir,
-        )
-
-    git_quiet = ['-q'] if not conf.verbose else []
-
-    failures = []
-    for p in projects:
-        if conf.verbose:
-            print()
-        proj_dir = os.path.join(repo_root, p)
-        if conf.update:
-            if conf.verbose:
-                print('updating %s with "git pull"' % p)
-            subprocess.Popen(
-                ['git', 'pull'] + git_quiet,
-                cwd=proj_dir,
-            ).communicate()
-        p_log_name = p.split('/')[-1].replace('.', '-')
-        for e in conf.env:
-            log_name = 'cross-test-{}-{}.log'.format(p_log_name, e)
-            with open(log_name, 'w') as log_file:
-                print('testing {} in {}, logging to {}'.format(e, p, log_name),
-                      end=' ')
-                sys.stdout.flush()
-                command = ['oslo_run_cross_tests', proj_dir, e]
-                log_file.write('running: %s\n' % ' '.join(command))
-                log_file.flush()  # since Popen is going to use the fd directly
-                cmd = subprocess.Popen(
-                    command,
-                    cwd=lib_dir,
-                    stdout=log_file,
-                    stderr=log_file
-                )
-                cmd.communicate()
-                log_file.write('\nexit code: %s\n' % cmd.returncode)
-                if cmd.returncode:
-                    print('FAIL')
-                    failures.append((p, e, cmd.returncode))
-                else:
-                    print('PASS')
-
-    if failures:
-        print('\nFAILED %d jobs' % len(failures))
-        return 1
-    print('\nPASSED all jobs')
-    return 0
-
-
-if __name__ == '__main__':
-    sys.exit(main())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/oslotest-5.0.1/tox.ini new/oslotest-6.0.0/tox.ini
--- old/oslotest-5.0.1/tox.ini  2025-05-06 14:46:34.000000000 +0200
+++ new/oslotest-6.0.0/tox.ini  2025-11-11 14:30:30.000000000 +0100
@@ -34,7 +34,6 @@
 commands =
   sphinx-build -W --keep-going -b html -d doc/build/doctrees doc/source 
doc/build/html
 
-
 [testenv:releasenotes]
 deps =
   {[testenv:docs]deps}
@@ -42,5 +41,9 @@
   sphinx-build -a -E -W -d releasenotes/build/doctrees -b html 
releasenotes/source releasenotes/build/html
 
 [flake8]
+# We only enable the hacking (H) checks
+select = H,O
+# H301 Black will put commas after imports that can't fit on one line
+ignore = H301
 show-source = true
 exclude = .tox,dist,doc,*.egg,build

Reply via email to