"""Base class for pluggable defect mutation rules.""" from abc import ABC, abstractmethod from dataclasses import dataclass from typing import List, Optional @dataclass class Mutation: defect_type: str language: str line_start: int line_end: int mutated_source: str reference_fix: str description: str class MutationRule(ABC): name: str = "" language: str = "" defect_type: str = "" @abstractmethod def detect_and_mutate(self, source: str, filename: str = "") -> Optional[Mutation]: """Return a mutation if the rule can introduce a defect, else None.""" ... def _line_for_position(self, source: str, position: int) -> int: return source[:position].count("\n") + 1