Upgrade ruff to 0.16.0 and pyright to 1.1.411; convert to f-strings (#847)

* Upgrade ruff to 0.16.0 and pyright to 1.1.411; convert to f-strings

ruff 0.16.0 expanded the default lint rule selection well beyond the
long-standing E4/E7/E9/F, so [tool.ruff.lint] now selects the rule set
explicitly: the pre-0.16 defaults plus the modern-type-hint UP rules and
the two f-string rules (UP030/UP032). All 352 UP030/UP032 findings were
auto-fixed; conversions requiring Python 3.12 f-string quote reuse were
conservatively left as .format() by ruff (verified: the whole package and
test suite byte-compile under CPython 3.10.20, the oldest CI version).
Adopting the other newly-default rule families (BLE, SIM, C4, DTZ, I, ...)
is deferred as a deliberate per-family decision.

ruff format with 0.16.0 also now formats Python code fences in Markdown,
which reformatted one block in parsedmarc/resources/maps/AGENTS.md.

ruff check, ruff format --check, pyright (0 errors/warnings), and the
full test suite (775 passed) are green on the new versions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Address Copilot review findings on the f-string conversion

- Rewrite messages that used backslash line continuations inside string
  literals, which embedded the source indentation as literal whitespace
  in the logged/raised text: the duplicate search-error messages in the
  Elasticsearch and OpenSearch outputs, the 'since'-option warning (which
  also implicitly concatenated "24hrs" and "SMTP" with no separator) and
  the IMAP 'since' debug line, and the missing-org_name KeyError message.
- Build the Splunk HEC newline-delimited payloads by appending to a list
  and joining once instead of quadratic string concatenation in a loop.

Declined: switching the webhook output's logger.error to
logger.exception — the single-line ERROR without a traceback is the
deliberate house pattern for batch-resilient sinks, and changing log
verbosity is out of scope for this refactor PR.

ruff check/format, pyright (0 errors/warnings), 775 tests, and a
CPython 3.10 compileall all pass.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Sean Whalen
2026-07-25 13:46:36 -04:00
committed by GitHub
co-authored by Claude Fable 5
parent df086e7242
commit 0a95a0ceb2
15 changed files with 242 additions and 297 deletions
+13 -13
View File
@@ -73,7 +73,7 @@ class Test(unittest.TestCase):
file = "samples/extract_report/nice-input.xml"
with open(file, "rb") as f:
data = f.read()
print("Testing {0}: ".format(file), end="")
print(f"Testing {file}: ", end="")
xmlout = parsedmarc.extract_report(data)
with open("samples/extract_report/nice-input.xml") as f:
xmlin = f.read()
@@ -84,7 +84,7 @@ class Test(unittest.TestCase):
"""Test extract report function for XML input"""
print()
file = "samples/extract_report/nice-input.xml"
print("Testing {0}: ".format(file), end="")
print(f"Testing {file}: ", end="")
xmlout = parsedmarc.extract_report_from_file_path(file)
with open("samples/extract_report/nice-input.xml") as f:
xmlin = f.read()
@@ -103,7 +103,7 @@ class Test(unittest.TestCase):
"""Test extract report function for gzip input"""
print()
file = "samples/extract_report/nice-input.xml.gz"
print("Testing {0}: ".format(file), end="")
print(f"Testing {file}: ", end="")
xmlout = parsedmarc.extract_report_from_file_path(file)
with open("samples/extract_report/nice-input.xml") as f:
xmlin = f.read()
@@ -114,7 +114,7 @@ class Test(unittest.TestCase):
"""Test extract report function for zip input"""
print()
file = "samples/extract_report/nice-input.xml.zip"
print("Testing {0}: ".format(file), end="")
print(f"Testing {file}: ", end="")
xmlout = parsedmarc.extract_report_from_file_path(file)
with open("samples/extract_report/nice-input.xml") as f:
xmlin = minify_xml(f.read())
@@ -155,7 +155,7 @@ class Test(unittest.TestCase):
for sample_path in sample_paths:
if os.path.isdir(sample_path):
continue
print("Testing {0}: ".format(sample_path), end="")
print(f"Testing {sample_path}: ", end="")
with self.subTest(sample=sample_path):
result = parsedmarc.parse_report_file(
sample_path, always_use_local_files=True, offline=OFFLINE_MODE
@@ -195,7 +195,7 @@ class Test(unittest.TestCase):
print()
sample_paths = glob("samples/failure/*.eml")
for sample_path in sample_paths:
print("Testing {0}: ".format(sample_path), end="")
print(f"Testing {sample_path}: ", end="")
with self.subTest(sample=sample_path):
with open(sample_path) as sample_file:
sample_content = sample_file.read()
@@ -245,7 +245,7 @@ class Test(unittest.TestCase):
"""Test parsing the sample report from RFC 9990 Appendix B"""
print()
sample_path = "samples/aggregate/rfc9990-sample.xml"
print("Testing {0}: ".format(sample_path), end="")
print(f"Testing {sample_path}: ", end="")
result = parsedmarc.parse_report_file(
sample_path, always_use_local_files=True, offline=True
)
@@ -323,7 +323,7 @@ class Test(unittest.TestCase):
sample_path = (
"samples/aggregate/example.net!example.com!1529366400!1529452799.xml"
)
print("Testing {0}: ".format(sample_path), end="")
print(f"Testing {sample_path}: ", end="")
result = parsedmarc.parse_report_file(
sample_path, always_use_local_files=True, offline=True
)
@@ -350,7 +350,7 @@ class Test(unittest.TestCase):
"samples/aggregate/"
"rfc9990-example.net!example.com!1700000000!1700086399.xml"
)
print("Testing {0}: ".format(sample_path), end="")
print(f"Testing {sample_path}: ", end="")
result = parsedmarc.parse_report_file(
sample_path, always_use_local_files=True, offline=True
)
@@ -590,7 +590,7 @@ class Test(unittest.TestCase):
for sample_path in sample_paths:
if os.path.isdir(sample_path):
continue
print("Testing {0}: ".format(sample_path), end="")
print(f"Testing {sample_path}: ", end="")
with self.subTest(sample=sample_path):
result = parsedmarc.parse_report_file(sample_path, offline=OFFLINE_MODE)
assert result["report_type"] == "smtp_tls"
@@ -1658,7 +1658,7 @@ class Test(unittest.TestCase):
"""parse_aggregate_report_file parses bytes input directly"""
print()
sample_path = "samples/aggregate/rfc9990-sample.xml"
print("Testing {0}: ".format(sample_path), end="")
print(f"Testing {sample_path}: ", end="")
with open(sample_path, "rb") as f:
data = f.read()
report = parsedmarc.parse_aggregate_report_file(
@@ -1677,7 +1677,7 @@ class Test(unittest.TestCase):
for sample_path in sample_paths:
if os.path.isdir(sample_path):
continue
print("Testing {0}: ".format(sample_path), end="")
print(f"Testing {sample_path}: ", end="")
with self.subTest(sample=sample_path):
parsed_report = cast(
AggregateReport,
@@ -1702,7 +1702,7 @@ class Test(unittest.TestCase):
print()
sample_paths = glob("samples/failure/*.eml")
for sample_path in sample_paths:
print("Testing CSV for {0}: ".format(sample_path), end="")
print(f"Testing CSV for {sample_path}: ", end="")
with self.subTest(sample=sample_path):
parsed_report = cast(
FailureReport,