Skip to content

Commit c114dcd

Browse files
jelmerclaude
andcommitted
Fix all remaining ruff E501 and RUF012 issues
- Fixed E501 line length issues by breaking long lines appropriately - Fixed RUF012 mutable class attributes by adding ClassVar annotations - Added 'from typing import ClassVar' imports where needed - Fixed import sorting to maintain project style 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 68e92ff commit c114dcd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+607
-633
lines changed

pyproject.toml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,19 @@ module = [
6060
"testscenarios.*",
6161
]
6262
ignore_missing_imports = true
63+
64+
[tool.ruff.lint]
65+
select = [
66+
"E",
67+
"F",
68+
"I",
69+
"PIE",
70+
"UP",
71+
"RSE",
72+
"RUF",
73+
]
74+
ignore = [
75+
]
76+
77+
[tool.ruff.lint.pydocstyle]
78+
convention = "google"

scripts/_lp_release.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,13 @@
1818
--sign'.
1919
"""
2020

21-
from datetime import datetime, timedelta, tzinfo
2221
import logging
2322
import os
2423
import sys
24+
from datetime import datetime, timedelta, tzinfo
2525

26-
from launchpadlib.launchpad import Launchpad
2726
from launchpadlib import uris
28-
27+
from launchpadlib.launchpad import Launchpad
2928

3029
APP_NAME = "testtools-lp-release"
3130
CACHE_DIR = os.path.expanduser("~/.launchpadlib/cache")

testtools/__init__.py

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,20 @@
33
"""Extensions to the standard Python unittest library."""
44

55
__all__ = [
6-
"clone_test_with_new_id",
7-
"CopyStreamResult",
8-
"ConcurrentTestSuite",
96
"ConcurrentStreamTestSuite",
7+
"ConcurrentTestSuite",
8+
"CopyStreamResult",
109
"DecorateTestCaseResult",
1110
"ErrorHolder",
1211
"ExpectedException",
1312
"ExtendedToOriginalDecorator",
1413
"ExtendedToStreamDecorator",
1514
"FixtureSuite",
16-
"iterate_tests",
17-
"MultipleExceptions",
1815
"MultiTestResult",
16+
"MultipleExceptions",
1917
"PlaceHolder",
20-
"run_test_with",
2118
"ResourcedToStreamDecorator",
22-
"Tagger",
23-
"TestCase",
24-
"TestByTestResult",
25-
"TestResult",
26-
"TestResultDecorator",
27-
"TextTestResult",
2819
"RunTest",
29-
"skip",
30-
"skipIf",
31-
"skipUnless",
3220
"StreamFailFast",
3321
"StreamResult",
3422
"StreamResultRouter",
@@ -37,18 +25,29 @@
3725
"StreamToDict",
3826
"StreamToExtendedDecorator",
3927
"StreamToQueue",
28+
"Tagger",
29+
"TestByTestResult",
30+
"TestCase",
4031
"TestControl",
32+
"TestResult",
33+
"TestResultDecorator",
34+
"TextTestResult",
4135
"ThreadsafeForwardingResult",
4236
"TimestampingStreamResult",
37+
"__version__",
38+
"clone_test_with_new_id",
39+
"iterate_tests",
40+
"run_test_with",
41+
"skip",
42+
"skipIf",
43+
"skipUnless",
4344
"try_import",
4445
"unique_text_generator",
4546
"version",
46-
"__version__",
4747
]
4848

4949
from testtools.helpers import try_import
5050
from testtools.matchers._impl import Matcher # noqa: F401
51-
5251
from testtools.runtest import (
5352
MultipleExceptions,
5453
RunTest,
@@ -90,8 +89,8 @@
9089
TimestampingStreamResult,
9190
)
9291
from testtools.testsuite import (
93-
ConcurrentTestSuite,
9492
ConcurrentStreamTestSuite,
93+
ConcurrentTestSuite,
9594
FixtureSuite,
9695
iterate_tests,
9796
)

testtools/compat.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
"""Compatibility support for python 2 and 3."""
44

55
__all__ = [
6+
"BytesIO",
7+
"StringIO",
68
"_b",
79
"advance_iterator",
810
"reraise",
911
"unicode_output_stream",
10-
"StringIO",
11-
"BytesIO",
1212
]
1313

1414
import codecs
@@ -19,7 +19,7 @@
1919
import unicodedata
2020

2121
# Ensure retro-compatibility with older testtools releases
22-
from io import StringIO, BytesIO
22+
from io import BytesIO, StringIO
2323

2424

2525
def reraise(exc_class, exc_obj, exc_tb, _marker=object()):
@@ -71,7 +71,7 @@ def _slow_escape(text):
7171

7272
def text_repr(text, multiline=None):
7373
"""Rich repr for ``text`` returning unicode, triple quoted if ``multiline``."""
74-
nl = isinstance(text, bytes) and bytes((0xA,)) or "\n"
74+
nl = (isinstance(text, bytes) and bytes((0xA,))) or "\n"
7575
if multiline is None:
7676
multiline = nl in text
7777
if not multiline:

testtools/content.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
"""Content - a MIME-like Content object."""
44

55
__all__ = [
6-
"attach_file",
76
"Content",
7+
"TracebackContent",
8+
"attach_file",
89
"content_from_file",
910
"content_from_stream",
1011
"json_content",
1112
"text_content",
12-
"TracebackContent",
1313
]
1414

1515
import codecs
@@ -19,8 +19,7 @@
1919
import traceback
2020

2121
from testtools.compat import _b
22-
from testtools.content_type import ContentType, JSON, UTF8_TEXT
23-
22+
from testtools.content_type import JSON, UTF8_TEXT, ContentType
2423

2524
_join_b = _b("").join
2625

@@ -62,9 +61,7 @@ class Content:
6261
def __init__(self, content_type, get_bytes):
6362
"""Create a ContentType."""
6463
if None in (content_type, get_bytes):
65-
raise ValueError(
66-
"None not permitted in {!r}, {!r}".format(content_type, get_bytes)
67-
)
64+
raise ValueError(f"None not permitted in {content_type!r}, {get_bytes!r}")
6865
self.content_type = content_type
6966
self._get_bytes = get_bytes
7067

@@ -96,7 +93,7 @@ def iter_text(self):
9693
:raises ValueError: If the content type is not "text/*".
9794
"""
9895
if self.content_type.type != "text":
99-
raise ValueError("Not a text type %r" % self.content_type)
96+
raise ValueError(f"Not a text type {self.content_type!r}")
10097
return self._iter_text()
10198

10299
def _iter_text(self):
@@ -110,8 +107,9 @@ def _iter_text(self):
110107
yield final
111108

112109
def __repr__(self):
113-
return "<Content type={!r}, value={!r}>".format(
114-
self.content_type, _join_b(self.iter_bytes())
110+
return (
111+
f"<Content type={self.content_type!r}, "
112+
f"value={_join_b(self.iter_bytes())!r}>"
115113
)
116114

117115

@@ -250,7 +248,7 @@ def text_content(text):
250248
"""
251249
if not isinstance(text, str):
252250
raise TypeError(
253-
"text_content must be given text, not '%s'." % type(text).__name__
251+
f"text_content must be given text, not '{type(text).__name__}'."
254252
)
255253
return Content(UTF8_TEXT, lambda: [text.encode("utf8")])
256254

testtools/content_type.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@ class ContentType:
1515
def __init__(self, primary_type, sub_type, parameters=None):
1616
"""Create a ContentType."""
1717
if None in (primary_type, sub_type):
18-
raise ValueError(
19-
"None not permitted in {!r}, {!r}".format(primary_type, sub_type)
20-
)
18+
raise ValueError(f"None not permitted in {primary_type!r}, {sub_type!r}")
2119
self.type = primary_type
2220
self.subtype = sub_type
2321
self.parameters = parameters or {}

testtools/matchers/__init__.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
"Always",
1919
"Annotate",
2020
"AnyMatch",
21+
"ContainedByDict",
2122
"Contains",
2223
"ContainsAll",
23-
"ContainedByDict",
2424
"ContainsDict",
2525
"DirContains",
2626
"DirExists",
@@ -48,17 +48,17 @@
4848
"MatchesSetwise",
4949
"MatchesStructure",
5050
"Never",
51-
"NotEquals",
5251
"Not",
52+
"NotEquals",
5353
"PathExists",
5454
"Raises",
55-
"raises",
5655
"SameMembers",
5756
"SamePath",
5857
"StartsWith",
5958
"TarballContains",
60-
"Warnings",
6159
"WarningMessage",
60+
"Warnings",
61+
"raises",
6262
]
6363

6464
from ._basic import (
@@ -120,11 +120,6 @@
120120
MatchesPredicateWithParams,
121121
Not,
122122
)
123-
from ._warnings import (
124-
IsDeprecated,
125-
WarningMessage,
126-
Warnings,
127-
)
128123

129124
# XXX: These are not explicitly included in __all__. It's unclear how much of
130125
# the public interface they really are.
@@ -133,3 +128,8 @@
133128
Mismatch,
134129
MismatchError,
135130
)
131+
from ._warnings import (
132+
IsDeprecated,
133+
WarningMessage,
134+
Warnings,
135+
)

testtools/matchers/_basic.py

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
]
1717

1818
import operator
19-
from pprint import pformat
2019
import re
20+
from pprint import pformat
2121

2222
from ..compat import (
2323
text_repr,
@@ -34,8 +34,7 @@
3434

3535

3636
def _format(thing):
37-
"""
38-
Blocks of text with newlines are formatted as triple-quote
37+
"""Blocks of text with newlines are formatted as triple-quote
3938
strings. Everything else is pretty-printed.
4039
"""
4140
if isinstance(thing, (str, bytes)):
@@ -74,8 +73,10 @@ def describe(self):
7473
actual = repr(self._actual)
7574
reference = repr(self._reference)
7675
if len(actual) + len(reference) > 70:
77-
return "{}:\nreference = {}\nactual = {}\n".format(
78-
self._mismatch_string, _format(self._reference), _format(self._actual)
76+
return (
77+
f"{self._mismatch_string}:\n"
78+
f"reference = {_format(self._reference)}\n"
79+
f"actual = {_format(self._actual)}\n"
7980
)
8081
else:
8182
if self._reference_on_right:
@@ -164,8 +165,9 @@ def match(self, observed):
164165
if expected_only == observed_only == []:
165166
return
166167
return PostfixedMismatch(
167-
"\nmissing: {}\nextra: {}".format(
168-
_format(expected_only), _format(observed_only)
168+
(
169+
f"\nmissing: {_format(expected_only)}\n"
170+
f"extra: {_format(observed_only)}"
169171
),
170172
_BinaryMismatch(observed, "elements differ", self.expected),
171173
)
@@ -182,8 +184,8 @@ def __init__(self, matchee, expected):
182184
self.expected = expected
183185

184186
def describe(self):
185-
return "{} does not start with {}.".format(
186-
text_repr(self.matchee), text_repr(self.expected)
187+
return (
188+
f"{text_repr(self.matchee)} does not start with {text_repr(self.expected)}."
187189
)
188190

189191

@@ -217,8 +219,8 @@ def __init__(self, matchee, expected):
217219
self.expected = expected
218220

219221
def describe(self):
220-
return "{} does not end with {}.".format(
221-
text_repr(self.matchee), text_repr(self.expected)
222+
return (
223+
f"{text_repr(self.matchee)} does not end with {text_repr(self.expected)}."
222224
)
223225

224226

@@ -272,7 +274,9 @@ def describe(self):
272274
if len(self.types) == 1:
273275
typestr = self.types[0].__name__
274276
else:
275-
typestr = "any of (%s)" % ", ".join(type.__name__ for type in self.types)
277+
typestr = "any of ({})".format(
278+
", ".join(type.__name__ for type in self.types)
279+
)
276280
return f"'{self.matchee}' is not an instance of {typestr}"
277281

278282

@@ -321,13 +325,13 @@ def __init__(self, pattern, flags=0):
321325
self.flags = flags
322326

323327
def __str__(self):
324-
args = ["%r" % self.pattern]
328+
args = [f"{self.pattern!r}"]
325329
flag_arg = []
326330
# dir() sorts the attributes for us, so we don't need to do it again.
327331
for flag in dir(re):
328332
if len(flag) == 1:
329333
if self.flags & getattr(re, flag):
330-
flag_arg.append("re.%s" % flag)
334+
flag_arg.append(f"re.{flag}")
331335
if flag_arg:
332336
args.append("|".join(flag_arg))
333337
return "{}({})".format(self.__class__.__name__, ", ".join(args))

0 commit comments

Comments
 (0)