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-04-12 17:52:26
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-oslotest (Old)
and /work/SRC/openSUSE:Factory/.python-oslotest.new.21863 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-oslotest"
Sun Apr 12 17:52:26 2026 rev:29 rq:1345963 version:6.1.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-oslotest/python-oslotest.changes
2026-03-09 16:11:42.757846863 +0100
+++
/work/SRC/openSUSE:Factory/.python-oslotest.new.21863/python-oslotest.changes
2026-04-12 17:52:28.459562295 +0200
@@ -1,0 +2,20 @@
+Fri Apr 10 19:29:17 UTC 2026 - Dirk Müller <[email protected]>
+
+- add multibuild to avoid build cycle
+
+-------------------------------------------------------------------
+Tue Mar 24 17:13:28 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 6.1.0:
+ * ruff: Configure hacking as external linter
+ * mypy: Disabling warnings for untyped imports
+ * Add typing classifier
+ * Add mypy
+ * typing: Add initial types
+ * Remove unused dependency
+ * Enable logging related ruff checks
+ * Delay string interpolations at logging calls
+ * Remove reference to tag framework
+ * ruff: Use more specific name to enable pyupgrade rule
+
+-------------------------------------------------------------------
Old:
----
oslotest-6.0.0.tar.gz
New:
----
_multibuild
oslotest-6.1.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-oslotest.spec ++++++
--- /var/tmp/diff_new_pack.uqj8th/_old 2026-04-12 17:52:29.151590474 +0200
+++ /var/tmp/diff_new_pack.uqj8th/_new 2026-04-12 17:52:29.151590474 +0200
@@ -16,23 +16,34 @@
#
-Name: python-oslotest
-Version: 6.0.0
+%global flavor @BUILD_FLAVOR@%{nil}
+%if "%{flavor}" == "test"
+%define psuffix -test
+%bcond_without test
+%else
+%define psuffix %{nil}
+%bcond_with test
+%endif
+Name: python-oslotest%{psuffix}
+Version: 6.1.0
Release: 0
Summary: OpenStack test framework
License: Apache-2.0
Group: Development/Languages/Python
URL: https://docs.openstack.org/oslotest
Source0:
https://files.pythonhosted.org/packages/source/o/oslotest/oslotest-%{version}.tar.gz
-BuildRequires: %{python_module debtcollector}
-BuildRequires: %{python_module fixtures >= 3.0.0}
+BuildRequires: %{python_module pbr >= 6.1.1}
BuildRequires: %{python_module pip}
+BuildRequires: %{python_module wheel}
+%if %{with test}
+BuildRequires: %{python_module fixtures >= 3.0.0}
+BuildRequires: %{python_module oslo.config >= 5.2.0}
BuildRequires: %{python_module python-subunit >= 1.0.0}
-BuildRequires: %{python_module stestr}
+BuildRequires: %{python_module stestr >= 2.0.0}
BuildRequires: %{python_module testtools >= 2.2.0}
-BuildRequires: %{python_module wheel}
+%endif
BuildRequires: openstack-macros
-Requires: python-fixtures
+Requires: python-fixtures >= 3.0.0
BuildArch: noarch
%if "python%{python_nodots_ver}" == "%{primary_python}"
Obsoletes: python3-oslotest < %{version}
@@ -60,6 +71,7 @@
%pyproject_wheel
%install
+%if !%{with test}
%pyproject_install
%python_clone -a %{buildroot}%{_bindir}/oslo_debug_helper
@@ -73,13 +85,18 @@
%postun
%python_uninstall_alternative oslo_debug_helper
+%else
+
%check
%{openstack_stestr_run}
+%endif
+%if !%{with test}
%files %{python_files}
%license LICENSE
%doc ChangeLog README.rst
%python_alternative %{_bindir}/oslo_debug_helper
%{python_sitelib}/oslotest
%{python_sitelib}/oslotest-%{version}.dist-info
+%endif
++++++ _multibuild ++++++
<multibuild>
<package>test</package>
</multibuild>
++++++ oslotest-6.0.0.tar.gz -> oslotest-6.1.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslotest-6.0.0/.pre-commit-config.yaml
new/oslotest-6.1.0/.pre-commit-config.yaml
--- old/oslotest-6.0.0/.pre-commit-config.yaml 2025-11-11 14:30:30.000000000
+0100
+++ new/oslotest-6.1.0/.pre-commit-config.yaml 2026-03-24 11:31:36.000000000
+0100
@@ -13,13 +13,13 @@
- id: check-yaml
files: .*\.(yaml|yml)$
- repo: https://github.com/astral-sh/ruff-pre-commit
- rev: v0.12.12
+ rev: v0.14.9
hooks:
- id: ruff-check
args: ['--fix', '--unsafe-fixes']
- id: ruff-format
- repo: https://opendev.org/openstack/hacking
- rev: 7.0.0
+ rev: 8.0.0
hooks:
- id: hacking
additional_dependencies: []
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslotest-6.0.0/ChangeLog new/oslotest-6.1.0/ChangeLog
--- old/oslotest-6.0.0/ChangeLog 2025-11-11 14:31:15.000000000 +0100
+++ new/oslotest-6.1.0/ChangeLog 2026-03-24 11:32:27.000000000 +0100
@@ -1,6 +1,20 @@
CHANGES
=======
+6.1.0
+-----
+
+* ruff: Configure hacking as external linter
+* mypy: Disabling warnings for untyped imports
+* Add typing classifier
+* Add mypy
+* typing: Add initial types
+* Remove unused dependency
+* Enable logging related ruff checks
+* Delay string interpolations at logging calls
+* Remove reference to tag framework
+* ruff: Use more specific name to enable pyupgrade rule
+
6.0.0
-----
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslotest-6.0.0/PKG-INFO new/oslotest-6.1.0/PKG-INFO
--- old/oslotest-6.0.0/PKG-INFO 2025-11-11 14:31:15.673163400 +0100
+++ new/oslotest-6.1.0/PKG-INFO 2026-03-24 11:32:28.078053200 +0100
@@ -1,6 +1,6 @@
-Metadata-Version: 2.1
+Metadata-Version: 2.4
Name: oslotest
-Version: 6.0.0
+Version: 6.1.0
Summary: Oslo test framework
Author-email: OpenStack <[email protected]>
Project-URL: Homepage, https://docs.openstack.org/oslotest
@@ -18,26 +18,23 @@
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: Implementation :: CPython
+Classifier: Typing :: Typed
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
Requires-Dist: testtools>=2.2.0
+Dynamic: license-file
+Dynamic: requires-dist
-========================
-Team and repository tags
-========================
+=====================================================
+oslotest -- OpenStack Testing Framework and Utilities
+=====================================================
.. image:: https://governance.openstack.org/tc/badges/oslotest.svg
- :target: https://governance.openstack.org/tc/reference/tags/index.html
.. Change things from this point on
-=====================================================
-oslotest -- OpenStack Testing Framework and Utilities
-=====================================================
-
The Oslo Test framework provides common fixtures, support for debugging, and
better support for mocking results.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslotest-6.0.0/README.rst
new/oslotest-6.1.0/README.rst
--- old/oslotest-6.0.0/README.rst 2025-11-11 14:30:30.000000000 +0100
+++ new/oslotest-6.1.0/README.rst 2026-03-24 11:31:36.000000000 +0100
@@ -1,16 +1,11 @@
-========================
-Team and repository tags
-========================
+=====================================================
+oslotest -- OpenStack Testing Framework and Utilities
+=====================================================
.. image:: https://governance.openstack.org/tc/badges/oslotest.svg
- :target: https://governance.openstack.org/tc/reference/tags/index.html
.. Change things from this point on
-=====================================================
-oslotest -- OpenStack Testing Framework and Utilities
-=====================================================
-
The Oslo Test framework provides common fixtures, support for debugging, and
better support for mocking results.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslotest-6.0.0/oslotest/base.py
new/oslotest-6.1.0/oslotest/base.py
--- old/oslotest-6.0.0/oslotest/base.py 2025-11-11 14:30:30.000000000 +0100
+++ new/oslotest-6.1.0/oslotest/base.py 2026-03-24 11:31:36.000000000 +0100
@@ -15,7 +15,9 @@
"""Common utilities used in testing"""
+from collections.abc import Callable, Sequence
import logging
+from typing import Any
from unittest import mock
import fixtures
@@ -29,7 +31,7 @@
LOG = logging.getLogger(__name__)
_TRUE_VALUES = ('True', 'true', '1', 'yes')
-_LOG_FORMAT = "%(levelname)8s [%(name)s] %(message)s"
+_LOG_FORMAT = '%(levelname)8s [%(name)s] %(message)s'
class BaseTestCase(testtools.TestCase):
@@ -88,8 +90,16 @@
DEFAULT_TIMEOUT = 0
TIMEOUT_SCALING_FACTOR = 1
- def __init__(self, *args, **kwds):
- super().__init__(*args, **kwds)
+ # FIXME(stephenfin): This should only accept two kwargs:
+ # - methodName (from stdlib)
+ # - runTest (from testtools)
+ # But we need to type testtools first
+ def __init__(
+ self,
+ methodName: str = 'runTest',
+ runTest: Any = None,
+ ) -> None:
+ super().__init__(methodName=methodName, runTest=runTest)
# This is the number of characters shown when two objects do not
# match for assertDictEqual, assertMultiLineEqual, and
@@ -97,7 +107,13 @@
# low for comparing most dicts
self.maxDiff = 10000
- def addCleanup(self, function, *args, **kwargs):
+ def addCleanup(
+ self,
+ cleanup: Callable[..., object],
+ /,
+ *args: object,
+ **kwargs: object,
+ ) -> None:
# 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.
@@ -114,9 +130,9 @@
'Unable to patch test case. '
'mock.patch.stopall cleanup was not registered.'
)
- super().addCleanup(function, *args, **kwargs)
+ super().addCleanup(cleanup, *args, **kwargs)
- def setUp(self):
+ def setUp(self) -> None:
super().setUp()
self._set_timeout()
self._fake_output()
@@ -124,7 +140,7 @@
self.useFixture(fixtures.NestedTempfile())
self.useFixture(fixtures.TempHomeDir())
- def _set_timeout(self):
+ def _set_timeout(self) -> None:
self.useFixture(
timeout.Timeout(
default_timeout=self.DEFAULT_TIMEOUT,
@@ -132,24 +148,28 @@
)
)
- def _fake_output(self):
+ def _fake_output(self) -> None:
self.output_fixture = self.useFixture(output.CaptureOutput())
- def _fake_logs(self):
+ def _fake_logs(self) -> None:
self.log_fixture = self.useFixture(log.ConfigureLogging())
- def create_tempfiles(self, files, ext='.conf', default_encoding='utf-8'):
+ def create_tempfiles(
+ self,
+ files: Sequence[
+ tuple[str, str | bytes, str] | tuple[str, str | bytes]
+ ],
+ ext: str = '.conf',
+ default_encoding: str = 'utf-8',
+ ) -> list[str]:
"""Safely create temporary files.
- :param files: Sequence of tuples containing (filename, file_contents).
- :type files: list of tuple
+ :param files: Sequence of tuples containing ``(filename,
+ file_contents)`` or ``(filename, file_contents, encoding)``.
:param ext: File name extension for the temporary file.
- :type ext: str
:param default_encoding: Default file content encoding when it is
- not provided, used to decode the tempfile
- contents from a text string into a binary
- string.
- :type default_encoding: str
+ not provided. Used to decode the tempfile contents from a text
+ string into a binary string.
:return: A list of str with the names of the files created.
"""
tempfiles = []
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslotest-6.0.0/oslotest/createfile.py
new/oslotest-6.1.0/oslotest/createfile.py
--- old/oslotest-6.0.0/oslotest/createfile.py 2025-11-11 14:30:30.000000000
+0100
+++ new/oslotest-6.1.0/oslotest/createfile.py 2026-03-24 11:31:36.000000000
+0100
@@ -32,10 +32,6 @@
:class:`fixtures.NestedTempfile` to set the temporary directory
somewhere safe and to ensure the files are cleaned up.
- .. py:attribute:: path
-
- The canonical name of the file created.
-
:param filename: Base file name or full literal path to the file
to be created.
:param contents: The data to write to the file. Unicode data will
@@ -43,16 +39,24 @@
:param ext: An extension to add to filename.
:param encoding: An encoding to use for unicode data (ignored for
byte strings).
-
"""
- def __init__(self, filename, contents, ext='.conf', encoding='utf-8'):
+ #: The canonical name of the file created.
+ path: str
+
+ def __init__(
+ self,
+ filename: str,
+ contents: str | bytes,
+ ext: str = '.conf',
+ encoding: str = 'utf-8',
+ ) -> None:
self._filename = filename
self._contents = contents
self._ext = ext
self._encoding = encoding
- def setUp(self):
+ def setUp(self) -> None:
super().setUp()
contents = self._contents
if isinstance(contents, str):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslotest-6.0.0/oslotest/log.py
new/oslotest-6.1.0/oslotest/log.py
--- old/oslotest-6.0.0/oslotest/log.py 2025-11-11 14:30:30.000000000 +0100
+++ new/oslotest-6.1.0/oslotest/log.py 2026-03-24 11:31:36.000000000 +0100
@@ -12,6 +12,7 @@
import logging
import os
+from typing import Any
import fixtures
@@ -26,7 +27,7 @@
)
-def _try_int(value):
+def _try_int(value: Any) -> int | None:
"""Try to make some value into an int."""
try:
return int(value)
@@ -62,10 +63,10 @@
DEFAULT_FORMAT = "%(levelname)8s [%(name)s] %(message)s"
"""Default log format"""
- def __init__(self, format=DEFAULT_FORMAT):
+ def __init__(self, format: str = DEFAULT_FORMAT) -> None:
super().__init__()
self._format = format
- self.level = None
+ self.level = 0
_os_debug = os.environ.get('OS_DEBUG')
_os_level = _try_int(_os_debug)
if _os_debug in _TRUE_VALUES:
@@ -77,9 +78,9 @@
elif _os_debug and _os_debug not in _FALSE_VALUES:
raise ValueError(f'OS_DEBUG={_os_debug} is invalid.')
self.capture_logs = os.environ.get('OS_LOG_CAPTURE') in _TRUE_VALUES
- self.logger = None
+ self.logger: fixtures.FakeLogger | None = None
- def setUp(self):
+ def setUp(self) -> None:
super().setUp()
if self.capture_logs:
self.logger = self.useFixture(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslotest-6.0.0/oslotest/mock_fixture.py
new/oslotest-6.1.0/oslotest/mock_fixture.py
--- old/oslotest-6.0.0/oslotest/mock_fixture.py 2025-11-11 14:30:30.000000000
+0100
+++ new/oslotest-6.1.0/oslotest/mock_fixture.py 2026-03-24 11:31:36.000000000
+0100
@@ -13,22 +13,32 @@
# License for the specific language governing permissions and limitations
# under the License.
+from __future__ import annotations
+
+from collections.abc import Callable
import functools
+from typing import Any, ParamSpec, TypeVar, TYPE_CHECKING
from unittest import mock
import fixtures
+_T = TypeVar('_T')
+
-def _lazy_autospec_method(mocked_method, original_method, eat_self):
+def _lazy_autospec_method(
+ mocked_method: Any,
+ original_method: Any,
+ eat_self: bool,
+) -> None:
if mocked_method._mock_check_sig.__dict__.get('autospeced'):
return
- _lazy_autospec = mock.create_autospec(original_method)
+ _lazy_autospec: Any = mock.create_autospec(original_method)
if eat_self:
# consume self argument.
_lazy_autospec = functools.partial(_lazy_autospec, None)
- def _autospeced(*args, **kwargs):
+ def _autospeced(*args: Any, **kwargs: Any) -> None:
_lazy_autospec(*args, **kwargs)
# _mock_check_sig is called by the mock's __call__ method.
@@ -41,7 +51,10 @@
class _AutospecMockMixin:
"""Mock object that lazily autospecs the given spec's methods."""
- def __init__(self, *args, **kwargs):
+ # These are defined by mock.Mock but we need to declare them for typing
+ return_value: Any
+
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs)
autospec = kwargs.get('autospec')
self.__dict__['_autospec'] = autospec
@@ -56,8 +69,8 @@
if autospec:
self.return_value.__dict__['_autospec'] = autospec
- def __getattr__(self, name):
- attr = super().__getattr__(name)
+ def __getattr__(self, name: str) -> Any:
+ attr = super().__getattr__(name) # type: ignore[misc]
original_spec = self.__dict__['_autospec']
if not original_spec:
@@ -71,7 +84,8 @@
original_attr = getattr(original_spec, name)
if callable(original_attr):
# lazily autospec callable attribute.
- eat_self = mock._must_skip(
+ # NOTE: _must_skip is a private function in the mock module
+ eat_self = mock._must_skip( # type: ignore[attr-defined]
original_spec, name, isinstance(original_spec, type)
)
@@ -106,7 +120,7 @@
mocked method's signature is also checked.
"""
- def setUp(self):
+ def setUp(self) -> None:
super().setUp()
# patch both external and internal usage of Mock / MagicMock.
@@ -118,7 +132,16 @@
)
-class _patch(mock._patch):
+if TYPE_CHECKING:
+ Base = mock._patch
+else:
+ # as of Python 3.13 this is not subscriptable at runtime
+ class Base(mock._patch):
+ def __class_getitem__(cls, _):
+ return cls
+
+
+class _patch(Base[_T]):
"""Patch class with working autospec functionality.
Currently, mock.patch functionality doesn't handle the autospec parameter
@@ -128,7 +151,7 @@
https://github.com/testing-cabal/mock/issues/396
"""
- def __enter__(self):
+ def __enter__(self) -> _T:
# NOTE(claudiub): we're doing the autospec checks here so unit tests
# have a chance to set up mocks in advance (e.g.: mocking platform
# specific libraries, which would cause the patch to fail otherwise).
@@ -160,7 +183,8 @@
if autospec:
target = self.getter()
original_attr = getattr(target, self.attribute)
- eat_self = mock._must_skip(
+ # NOTE: _must_skip is a private function in the mock module
+ eat_self = mock._must_skip( # type: ignore[attr-defined]
target, self.attribute, isinstance(target, type)
)
@@ -177,24 +201,32 @@
return super().__enter__()
-def _safe_attribute_error_wrapper(func):
- def wrapper(*args, **kwargs):
+P = ParamSpec('P')
+R = TypeVar('R')
+
+
+def _safe_attribute_error_wrapper(
+ func: Callable[P, R],
+) -> Callable[P, R | None]:
+ def wrapper(*args: P.args, **kwargs: P.kwargs) -> R | None:
try:
return func(*args, **kwargs)
except AttributeError:
- pass
+ return None
return wrapper
-def patch_mock_module():
+def patch_mock_module() -> None:
"""Replaces the mock.patch class."""
- mock._patch = _patch
+ # NOTE: _patch is a private class in the mock module
+ mock._patch = _patch # type: ignore[misc]
# NOTE(claudiub): mock cannot autospec partial functions properly,
# especially those created by LazyLoader objects (scheduler client),
# 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
+ # NOTE: _copy_func_details is a private function in the mock module
+ mock._copy_func_details = _safe_attribute_error_wrapper( # type:
ignore[attr-defined]
+ mock._copy_func_details # type: ignore[attr-defined]
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslotest-6.0.0/oslotest/modules.py
new/oslotest-6.1.0/oslotest/modules.py
--- old/oslotest-6.0.0/oslotest/modules.py 2025-11-11 14:30:30.000000000
+0100
+++ new/oslotest-6.1.0/oslotest/modules.py 2026-03-24 11:31:36.000000000
+0100
@@ -10,7 +10,10 @@
# License for the specific language governing permissions and limitations
# under the License.
+from collections.abc import Sequence
+from importlib.machinery import ModuleSpec
import sys
+from types import ModuleType
import fixtures
@@ -18,11 +21,11 @@
class DisableModuleFixture(fixtures.Fixture):
"""A fixture to provide support for unloading/disabling modules."""
- def __init__(self, module, *args, **kwargs):
- super().__init__(*args, **kwargs)
+ def __init__(self, module: str):
+ super().__init__()
self.module = module
- def setUp(self):
+ def setUp(self) -> None:
"""Ensure ImportError for the specified module."""
super().setUp()
@@ -42,9 +45,16 @@
class _NoModuleFinder:
"""Disallow further imports of 'module'."""
- def __init__(self, module):
+ def __init__(self, module: str) -> None:
self.module = module
- def find_spec(self, fullname, path, target):
+ def find_spec(
+ self,
+ fullname: str,
+ path: Sequence[str] | None,
+ target: ModuleType | None = None,
+ /,
+ ) -> ModuleSpec | None:
if fullname == self.module or fullname.startswith(self.module + '.'):
raise ImportError
+ return None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslotest-6.0.0/oslotest/output.py
new/oslotest-6.1.0/oslotest/output.py
--- old/oslotest-6.0.0/oslotest/output.py 2025-11-11 14:30:30.000000000
+0100
+++ new/oslotest-6.1.0/oslotest/output.py 2026-03-24 11:31:36.000000000
+0100
@@ -11,6 +11,7 @@
# under the License.
import os
+from typing import IO
import fixtures
@@ -44,7 +45,9 @@
"""
- def __init__(self, do_stdout=None, do_stderr=None):
+ def __init__(
+ self, do_stdout: bool | None = None, do_stderr: bool | None = None
+ ):
super().__init__()
if do_stdout is None:
self.do_stdout = (
@@ -58,10 +61,10 @@
)
else:
self.do_stderr = do_stderr
- self.stdout = None
- self.stderr = None
+ self.stdout: IO[str] | None = None
+ self.stderr: IO[str] | None = None
- def setUp(self):
+ def setUp(self) -> None:
super().setUp()
if self.do_stdout:
self._stdout_fixture = fixtures.StringStream('stdout')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslotest-6.0.0/oslotest/tests/unit/test_base.py
new/oslotest-6.1.0/oslotest/tests/unit/test_base.py
--- old/oslotest-6.0.0/oslotest/tests/unit/test_base.py 2025-11-11
14:30:30.000000000 +0100
+++ new/oslotest-6.1.0/oslotest/tests/unit/test_base.py 2026-03-24
11:31:36.000000000 +0100
@@ -14,6 +14,7 @@
import logging
import os
+from typing import Any
import unittest
from unittest import mock
@@ -84,7 +85,8 @@
def test_mock_patch_cleanup_on_teardown(self):
# create an object and save its reference
class Sub:
- pass
+ value: Any
+ backup: Any
obj = Sub()
obj.value = obj.backup = object()
@@ -138,7 +140,7 @@
class TestTempFiles(base.BaseTestCase):
def test_create_unicode_files(self):
- files = [["no_approve", 'ಠ_ಠ']]
+ files = [('no_approve', 'ಠ_ಠ')]
temps = self.create_tempfiles(files)
self.assertEqual(1, len(temps))
with open(temps[0], 'rb') as f:
@@ -146,7 +148,7 @@
self.assertEqual('ಠ_ಠ', str(contents, encoding='utf-8'))
def test_create_unicode_files_encoding(self):
- files = [["embarrassed", '⊙﹏⊙', 'utf-8']]
+ files = [('embarrassed', '⊙﹏⊙', 'utf-8')]
temps = self.create_tempfiles(files)
self.assertEqual(1, len(temps))
with open(temps[0], 'rb') as f:
@@ -155,8 +157,8 @@
def test_create_unicode_files_multi_encoding(self):
files = [
- ["embarrassed", '⊙﹏⊙', 'utf-8'],
- ['abc', 'abc', 'ascii'],
+ ('embarrassed', '⊙﹏⊙', 'utf-8'),
+ ('abc', 'abc', 'ascii'),
]
temps = self.create_tempfiles(files)
self.assertEqual(2, len(temps))
@@ -170,16 +172,16 @@
)
def test_create_bad_encoding(self):
- files = [["hrm", 'ಠ~ಠ', 'ascii']]
+ files = [['hrm', 'ಠ~ಠ', 'ascii']]
self.assertRaises(UnicodeError, self.create_tempfiles, files)
def test_prefix(self):
- files = [["testing", '']]
+ files = [('testing', '')]
temps = self.create_tempfiles(files)
self.assertEqual(1, len(temps))
basename = os.path.basename(temps[0])
self.assertTrue(basename.startswith('testing'))
def test_wrong_length(self):
- files = [["testing"]]
+ files = [('testing',)]
self.assertRaises(ValueError, self.create_tempfiles, files)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/oslotest-6.0.0/oslotest/tests/unit/test_createfile.py
new/oslotest-6.1.0/oslotest/tests/unit/test_createfile.py
--- old/oslotest-6.0.0/oslotest/tests/unit/test_createfile.py 2025-11-11
14:30:30.000000000 +0100
+++ new/oslotest-6.1.0/oslotest/tests/unit/test_createfile.py 2026-03-24
11:31:36.000000000 +0100
@@ -25,8 +25,8 @@
'ಠ_ಠ',
)
f.setUp()
- with open(f.path, 'rb') as f:
- contents = f.read()
+ with open(f.path, 'rb') as fh:
+ contents = fh.read()
self.assertEqual('ಠ_ಠ', str(contents, encoding='utf-8'))
def test_create_unicode_files_encoding(self):
@@ -36,8 +36,8 @@
encoding='utf-8',
)
f.setUp()
- with open(f.path, 'rb') as f:
- contents = f.read()
+ with open(f.path, 'rb') as fh:
+ contents = fh.read()
self.assertEqual('⊙﹏⊙', str(contents, encoding='utf-8'))
def test_create_bad_encoding(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/oslotest-6.0.0/oslotest/tests/unit/test_mock_fixture.py
new/oslotest-6.1.0/oslotest/tests/unit/test_mock_fixture.py
--- old/oslotest-6.0.0/oslotest/tests/unit/test_mock_fixture.py 2025-11-11
14:30:30.000000000 +0100
+++ new/oslotest-6.1.0/oslotest/tests/unit/test_mock_fixture.py 2026-03-24
11:31:36.000000000 +0100
@@ -124,16 +124,16 @@
):
foo = Foo()
# we're checking that method signature is not enforced.
- foo.bar()
+ foo.bar() # type: ignore[call-arg]
mock_meth.assert_called_once_with()
- foo.classic_bar()
+ foo.classic_bar() # type: ignore[call-arg]
mock_cmeth.assert_called_once_with()
- foo.static_bar()
+ foo.static_bar() # type: ignore[call-arg]
mock_smeth.assert_called_once_with()
@mock.patch.object(Foo, 'lish', create=True)
def test_patch_create(self, mock_lish):
foo = Foo()
- foo.lish()
+ foo.lish() # type: ignore[attr-defined]
mock_lish.assert_called_once_with()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslotest-6.0.0/oslotest/tests/unit/test_timeout.py
new/oslotest-6.1.0/oslotest/tests/unit/test_timeout.py
--- old/oslotest-6.0.0/oslotest/tests/unit/test_timeout.py 2025-11-11
14:30:30.000000000 +0100
+++ new/oslotest-6.1.0/oslotest/tests/unit/test_timeout.py 2026-03-24
11:31:36.000000000 +0100
@@ -63,7 +63,7 @@
self, fixture_timeout_mock, fixture_mock, env_get_mock
):
env_get_mock.return_value = 'invalid'
- tc = timeout.Timeout(default_timeout='invalid')
+ tc = timeout.Timeout(default_timeout='invalid') # type: ignore
tc.setUp()
env_get_mock.assert_called_once_with('OS_TEST_TIMEOUT', 0)
self.assertEqual(0, fixture_timeout_mock.call_count)
@@ -89,7 +89,7 @@
self, fixture_timeout_mock, fixture_mock, env_get_mock
):
env_get_mock.return_value = 2
- tc = timeout.Timeout(scaling_factor='invalid')
+ tc = timeout.Timeout(scaling_factor='invalid') # type: ignore
tc.setUp()
env_get_mock.assert_called_once_with('OS_TEST_TIMEOUT', 0)
fixture_timeout_mock.assert_called_once_with(2, gentle=True)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslotest-6.0.0/oslotest/timeout.py
new/oslotest-6.1.0/oslotest/timeout.py
--- old/oslotest-6.0.0/oslotest/timeout.py 2025-11-11 14:30:30.000000000
+0100
+++ new/oslotest-6.1.0/oslotest/timeout.py 2026-03-24 11:31:36.000000000
+0100
@@ -22,7 +22,11 @@
"""
- def __init__(self, default_timeout=0, scaling_factor=1):
+ def __init__(
+ self,
+ default_timeout: int | float = 0,
+ scaling_factor: int | float = 1,
+ ) -> None:
super().__init__()
try:
self._default_timeout = int(default_timeout)
@@ -31,7 +35,7 @@
self._default_timeout = 0
self._scaling_factor = scaling_factor
- def setUp(self):
+ def setUp(self) -> None:
super().setUp()
test_timeout = os.environ.get('OS_TEST_TIMEOUT', self._default_timeout)
try:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslotest-6.0.0/oslotest/tools/config.py
new/oslotest-6.1.0/oslotest/tools/config.py
--- old/oslotest-6.0.0/oslotest/tools/config.py 2025-11-11 14:30:30.000000000
+0100
+++ new/oslotest-6.1.0/oslotest/tools/config.py 2026-03-24 11:31:36.000000000
+0100
@@ -13,6 +13,7 @@
"""Utilities functions for working with oslo.config from the tool scripts."""
import os
+from typing import TypeVar
from oslo_config import cfg
@@ -22,7 +23,7 @@
]
-def get_config_parser():
+def get_config_parser() -> cfg.ConfigOpts:
conf = cfg.ConfigOpts()
conf.register_cli_opt(
cfg.StrOpt(
@@ -34,12 +35,14 @@
return conf
-def parse_arguments(conf):
+_ConfigOptT = TypeVar('_ConfigOptT', bound=cfg.ConfigOpts)
+
+
+def parse_arguments(conf: type[_ConfigOptT]) -> _ConfigOptT:
# 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)
]
- return conf(
- project='oslo',
- default_config_files=default_config_files,
+ return conf( # type: ignore
+ project='oslo', default_config_files=default_config_files
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslotest-6.0.0/oslotest.egg-info/PKG-INFO
new/oslotest-6.1.0/oslotest.egg-info/PKG-INFO
--- old/oslotest-6.0.0/oslotest.egg-info/PKG-INFO 2025-11-11
14:31:15.000000000 +0100
+++ new/oslotest-6.1.0/oslotest.egg-info/PKG-INFO 2026-03-24
11:32:28.000000000 +0100
@@ -1,6 +1,6 @@
-Metadata-Version: 2.1
+Metadata-Version: 2.4
Name: oslotest
-Version: 6.0.0
+Version: 6.1.0
Summary: Oslo test framework
Author-email: OpenStack <[email protected]>
Project-URL: Homepage, https://docs.openstack.org/oslotest
@@ -18,26 +18,23 @@
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: Implementation :: CPython
+Classifier: Typing :: Typed
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
Requires-Dist: testtools>=2.2.0
+Dynamic: license-file
+Dynamic: requires-dist
-========================
-Team and repository tags
-========================
+=====================================================
+oslotest -- OpenStack Testing Framework and Utilities
+=====================================================
.. image:: https://governance.openstack.org/tc/badges/oslotest.svg
- :target: https://governance.openstack.org/tc/reference/tags/index.html
.. Change things from this point on
-=====================================================
-oslotest -- OpenStack Testing Framework and Utilities
-=====================================================
-
The Oslo Test framework provides common fixtures, support for debugging, and
better support for mocking results.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslotest-6.0.0/oslotest.egg-info/SOURCES.txt
new/oslotest-6.1.0/oslotest.egg-info/SOURCES.txt
--- old/oslotest-6.0.0/oslotest.egg-info/SOURCES.txt 2025-11-11
14:31:15.000000000 +0100
+++ new/oslotest-6.1.0/oslotest.egg-info/SOURCES.txt 2026-03-24
11:32:28.000000000 +0100
@@ -35,6 +35,7 @@
oslotest/mock_fixture.py
oslotest/modules.py
oslotest/output.py
+oslotest/py.typed
oslotest/timeout.py
oslotest.egg-info/PKG-INFO
oslotest.egg-info/SOURCES.txt
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslotest-6.0.0/oslotest.egg-info/pbr.json
new/oslotest-6.1.0/oslotest.egg-info/pbr.json
--- old/oslotest-6.0.0/oslotest.egg-info/pbr.json 2025-11-11
14:31:15.000000000 +0100
+++ new/oslotest-6.1.0/oslotest.egg-info/pbr.json 2026-03-24
11:32:28.000000000 +0100
@@ -1 +1 @@
-{"git_version": "b5e4a4c", "is_release": true}
\ No newline at end of file
+{"git_version": "3722be4", "is_release": true}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslotest-6.0.0/oslotest.egg-info/requires.txt
new/oslotest-6.1.0/oslotest.egg-info/requires.txt
--- old/oslotest-6.0.0/oslotest.egg-info/requires.txt 2025-11-11
14:31:15.000000000 +0100
+++ new/oslotest-6.1.0/oslotest.egg-info/requires.txt 2026-03-24
11:32:28.000000000 +0100
@@ -1,3 +1,2 @@
fixtures>=3.0.0
-python-subunit>=1.0.0
testtools>=2.2.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslotest-6.0.0/pyproject.toml
new/oslotest-6.1.0/pyproject.toml
--- old/oslotest-6.0.0/pyproject.toml 2025-11-11 14:30:30.000000000 +0100
+++ new/oslotest-6.1.0/pyproject.toml 2026-03-24 11:31:36.000000000 +0100
@@ -25,6 +25,7 @@
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: Implementation :: CPython",
+ "Typing :: Typed",
]
[project.urls]
@@ -39,6 +40,20 @@
"tools/oslo_debug_helper",
]
+[tool.mypy]
+python_version = "3.10"
+show_column_numbers = true
+show_error_context = true
+strict = true
+disable_error_code = ["import-untyped"]
+exclude = "(?x)(doc | releasenotes)"
+
+[[tool.mypy.overrides]]
+module = ["oslotest.tests.*"]
+disallow_untyped_calls = false
+disallow_untyped_defs = false
+disallow_subclassing_any = false
+
[tool.ruff]
line-length = 79
@@ -47,7 +62,8 @@
docstring-code-format = true
[tool.ruff.lint]
-select = ["E4", "E5", "E7", "E9", "F", "S", "U"]
+select = ["E4", "E5", "E7", "E9", "F", "G", "LOG", "S", "UP"]
+external = ["H"]
ignore = [
# we only use asserts for type narrowing
"S101",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslotest-6.0.0/requirements.txt
new/oslotest-6.1.0/requirements.txt
--- old/oslotest-6.0.0/requirements.txt 2025-11-11 14:30:30.000000000 +0100
+++ new/oslotest-6.1.0/requirements.txt 2026-03-24 11:31:36.000000000 +0100
@@ -1,3 +1,2 @@
fixtures>=3.0.0 # Apache-2.0/BSD
-python-subunit>=1.0.0 # Apache-2.0/BSD
testtools>=2.2.0 # MIT
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslotest-6.0.0/tox.ini new/oslotest-6.1.0/tox.ini
--- old/oslotest-6.0.0/tox.ini 2025-11-11 14:30:30.000000000 +0100
+++ new/oslotest-6.1.0/tox.ini 2026-03-24 11:31:36.000000000 +0100
@@ -10,10 +10,23 @@
commands = stestr run --slowest {posargs}
[testenv:pep8]
+description =
+ Run style checks.
deps =
pre-commit
+ {[testenv:mypy]deps}
commands =
pre-commit run -a
+ {[testenv:mypy]commands}
+
+[testenv:mypy]
+description =
+ Run type checks.
+deps =
+ {[testenv]deps}
+ mypy
+commands =
+ mypy --cache-dir="{envdir}/mypy_cache" {posargs:oslotest}
[testenv:cover]
setenv =
@@ -42,7 +55,7 @@
[flake8]
# We only enable the hacking (H) checks
-select = H,O
+select = H
# H301 Black will put commas after imports that can't fit on one line
ignore = H301
show-source = true