From f85d8900a3d90ab2790f2c46f83d7acee715a01b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jelmer=20Vernoo=C4=B3?= Date: Tue, 27 Jan 2026 17:12:01 +0000 Subject: [PATCH 1/2] Replace cast and Any with assertions and explicit types --- testtools/testcase.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/testtools/testcase.py b/testtools/testcase.py index 4b07081b..3f14011a 100644 --- a/testtools/testcase.py +++ b/testtools/testcase.py @@ -23,7 +23,7 @@ import types import unittest from collections.abc import Callable, Iterator -from typing import Any, Protocol, TypeVar, cast +from typing import Protocol, TypeVar, cast from unittest.case import SkipTest T = TypeVar("T") @@ -271,9 +271,9 @@ def __init__(self, *args: object, **kwargs: object) -> None: test_method = self._get_test_method() if runTest is None: runTest = getattr(test_method, "_run_test_with", self.run_tests_with) - self.__RunTest: type[RunTest] | Callable[..., RunTest] = cast( - "type[RunTest] | Callable[..., RunTest]", runTest - ) + # runTest should be a RunTest class or factory function + assert callable(runTest), f"runTest must be callable, got {type(runTest)}" + self.__RunTest: type[RunTest] | Callable[..., RunTest] = runTest if getattr(test_method, "__unittest_expecting_failure__", False): setattr(self, self._testMethodName, _expectedFailure(test_method)) # Used internally for onException processing - used to gather extra @@ -1130,16 +1130,23 @@ class WithAttributes: testtools.testcase.MyTest/test_bar[foo] """ - _get_test_method: Any # Provided by the class we're mixed with + # Provided by the class we're mixed with + _get_test_method: Callable[[], Callable[[], object]] def id(self) -> str: - orig = cast(str, super().id()) # type: ignore[misc] + orig = super().id() # type: ignore[misc] + assert isinstance(orig, str), ( + f"Expected str from super().id(), got {type(orig)}" + ) # Depends on testtools.TestCase._get_test_method, be nice to support # plain unittest. fn = self._get_test_method() - attributes = cast(str, getattr(fn, "__testtools_attrs", None)) + attributes = getattr(fn, "__testtools_attrs", None) if not attributes: return orig + assert isinstance(attributes, set), ( + f"Expected set for __testtools_attrs, got {type(attributes)}" + ) return orig + "[" + ",".join(sorted(attributes)) + "]" From 46b317b8dbddd82ebb329682bd330bf8944f94ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jelmer=20Vernoo=C4=B3?= Date: Tue, 27 Jan 2026 17:13:39 +0000 Subject: [PATCH 2/2] Add 'Typing :: Typed' classifier to package metadata --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index cf05833f..c936082a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,6 +25,7 @@ classifiers = [ "Topic :: Software Development :: Libraries", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Software Development :: Testing", + "Typing :: Typed", ] dynamic = ["version"] requires-python = ">=3.10"