From 6289be831a2d4fbbee69b4726a0ad6fd978a8b76 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Wed, 6 Mar 2024 20:16:58 -0500 Subject: [PATCH] refactor: use dataclasses, no namedtuple --- coverage/parser.py | 10 ++++++---- coverage/sysmon.py | 4 ++-- lab/benchmark/benchmark.py | 6 +++--- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/coverage/parser.py b/coverage/parser.py index 5ad534701..959174c36 100644 --- a/coverage/parser.py +++ b/coverage/parser.py @@ -13,6 +13,7 @@ import token import tokenize +from dataclasses import dataclass from types import CodeType from typing import ( cast, Any, Callable, Dict, Iterable, List, Optional, Protocol, Sequence, @@ -462,7 +463,8 @@ def _find_statements(self) -> Iterable[TLineNo]: # AST analysis # -class ArcStart(collections.namedtuple("Arc", "lineno, cause")): +@dataclass(frozen=True, order=True) +class ArcStart: """The information needed to start an arc. `lineno` is the line number the arc starts from. @@ -474,8 +476,8 @@ class ArcStart(collections.namedtuple("Arc", "lineno, cause")): to have `lineno` interpolated into it. """ - def __new__(cls, lineno: TLineNo, cause: str | None = None) -> ArcStart: - return super().__new__(cls, lineno, cause) + lineno: TLineNo + cause: str = "" class TAddArcFn(Protocol): @@ -1256,7 +1258,7 @@ def _combine_finally_starts(self, starts: set[ArcStart], exits: set[ArcStart]) - """ causes = [] for start in sorted(starts): - if start.cause is not None: + if start.cause: causes.append(start.cause.format(lineno=start.lineno)) cause = " or ".join(causes) exits = {ArcStart(xit.lineno, cause) for xit in exits} diff --git a/coverage/sysmon.py b/coverage/sysmon.py index 5e1371a92..65c5b6e77 100644 --- a/coverage/sysmon.py +++ b/coverage/sysmon.py @@ -5,7 +5,6 @@ from __future__ import annotations -import dataclasses import functools import inspect import os @@ -14,6 +13,7 @@ import threading import traceback +from dataclasses import dataclass from types import CodeType, FrameType from typing import ( Any, @@ -151,7 +151,7 @@ def _decorator(meth: AnyCallable) -> AnyCallable: return _decorator -@dataclasses.dataclass +@dataclass class CodeInfo: """The information we want about each code object.""" diff --git a/lab/benchmark/benchmark.py b/lab/benchmark/benchmark.py index d0d6188fd..1184f0b3e 100644 --- a/lab/benchmark/benchmark.py +++ b/lab/benchmark/benchmark.py @@ -2,7 +2,6 @@ import collections import contextlib -import dataclasses import itertools import os import random @@ -13,6 +12,7 @@ import time from pathlib import Path +from dataclasses import dataclass from typing import Any, Dict, Iterable, Iterator, List, Optional, Tuple import tabulate @@ -480,7 +480,7 @@ def __init__(self, path, slug): self.toxenv = None -@dataclasses.dataclass +@dataclass class Coverage: """A version of coverage.py to use, maybe None.""" @@ -537,7 +537,7 @@ def __init__(self, directory, slug="source", tweaks=None, env_vars=None): ) -@dataclasses.dataclass +@dataclass class Env: """An environment to run a test suite in."""