diff --git a/CHANGELOG.md b/CHANGELOG.md index c9a7662..b12fb6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -77,6 +77,7 @@ All notable changes to this project should be documented in this file. ### Fixed +- Removed redundant `from __future__ import annotations` from 17 files (16 source + 1 test) since the project targets Python 3.14+ where PEP 649 deferred evaluation is the default, by @devdanzin. - Fixed stat_key inconsistency: orchestrator checked `"timeout_count"` but execution.py returns `"timeouts_found"`, causing `HealthMonitor.record_timeout()` to never trigger, by @devdanzin. ### Enhanced diff --git a/lafleur/artifacts.py b/lafleur/artifacts.py index f1214a8..2c6e7e6 100644 --- a/lafleur/artifacts.py +++ b/lafleur/artifacts.py @@ -6,8 +6,6 @@ - TelemetryManager: run statistics persistence and time-series logging """ -from __future__ import annotations - import difflib import json import random diff --git a/lafleur/campaign.py b/lafleur/campaign.py index 8944934..4d0a82d 100644 --- a/lafleur/campaign.py +++ b/lafleur/campaign.py @@ -6,8 +6,6 @@ summaries for campaign analysis. """ -from __future__ import annotations - import argparse import html import json diff --git a/lafleur/corpus_analysis.py b/lafleur/corpus_analysis.py index beecfc3..172c6f6 100644 --- a/lafleur/corpus_analysis.py +++ b/lafleur/corpus_analysis.py @@ -6,8 +6,6 @@ times, lineage depths, and mutation effectiveness. """ -from __future__ import annotations - import statistics from collections import Counter from collections.abc import Sequence diff --git a/lafleur/corpus_manager.py b/lafleur/corpus_manager.py index 6d3a4e7..bf650b1 100644 --- a/lafleur/corpus_manager.py +++ b/lafleur/corpus_manager.py @@ -201,7 +201,7 @@ def synchronize( file_id = int(Path(filename).stem) if file_id > current_max_id: current_max_id = file_id - except (ValueError, IndexError): + except ValueError, IndexError: continue # Ignore non-integer filenames if current_max_id > self.corpus_file_counter: diff --git a/lafleur/driver.py b/lafleur/driver.py index 46fe33f..6e00449 100644 --- a/lafleur/driver.py +++ b/lafleur/driver.py @@ -15,8 +15,6 @@ [DRIVER:ERROR] - Emitted when a script raises an exception """ -from __future__ import annotations - import argparse import collections.abc import ctypes @@ -197,7 +195,7 @@ def _emit_stats(stats: dict) -> None: try: json.dumps(v) safe[k] = v - except (TypeError, ValueError, OverflowError): + except TypeError, ValueError, OverflowError: safe[k] = repr(v) safe["_serialization_fallback"] = True print(f"[DRIVER:STATS] {json.dumps(safe)}", flush=True) @@ -274,7 +272,7 @@ def snapshot_executor_state(namespace: dict) -> dict[tuple[int, int], int]: id(executor), ctypes.POINTER(PyExecutorObject) ) snapshot[(id(code), offset)] = executor_ptr.contents.exit_count - except (ValueError, TypeError): + except ValueError, TypeError: pass return snapshot @@ -429,7 +427,7 @@ def inspect_executor(executor, code_id: int, offset: int): if executor: executor_count += 1 inspect_executor(executor, id(code), offset) - except (ValueError, TypeError): + except ValueError, TypeError: pass result = { diff --git a/lafleur/execution.py b/lafleur/execution.py index 1e186b5..530f9d6 100644 --- a/lafleur/execution.py +++ b/lafleur/execution.py @@ -504,7 +504,7 @@ def execute_child( selection = self.corpus_manager.select_parent() if selection: polluters.append(selection[0]) - except (AttributeError, IndexError): + except AttributeError, IndexError: # Corpus empty or select_parent not available pass diff --git a/lafleur/lineage.py b/lafleur/lineage.py index 44e2016..de81a83 100644 --- a/lafleur/lineage.py +++ b/lafleur/lineage.py @@ -7,8 +7,6 @@ Output formats: Graphviz DOT (default), JSON, or rendered images (PNG/SVG/PDF). """ -from __future__ import annotations - import argparse import hashlib import json @@ -709,7 +707,7 @@ def scan_crashes(crashes_dir: Path) -> list[dict]: try: with open(metadata_path) as f: meta = json.load(f) - except (json.JSONDecodeError, OSError): + except json.JSONDecodeError, OSError: continue crash_info: dict = { @@ -1661,7 +1659,7 @@ def render_ancestry_svg( timeout=60, ) return result.stdout if result.returncode == 0 else None - except (subprocess.TimeoutExpired, OSError): + except subprocess.TimeoutExpired, OSError: return None diff --git a/lafleur/metadata.py b/lafleur/metadata.py index dde6654..a3604e5 100644 --- a/lafleur/metadata.py +++ b/lafleur/metadata.py @@ -234,7 +234,7 @@ def get_git_info() -> dict[str, str | bool]: is_dirty = bool(result.stdout.strip()) if result.returncode == 0 else False return {"commit": commit_hash, "dirty": is_dirty} - except (subprocess.TimeoutExpired, FileNotFoundError, OSError): + except subprocess.TimeoutExpired, FileNotFoundError, OSError: return {"commit": "unknown", "dirty": False} diff --git a/lafleur/mutation_controller.py b/lafleur/mutation_controller.py index 196d031..e7b7e58 100644 --- a/lafleur/mutation_controller.py +++ b/lafleur/mutation_controller.py @@ -8,8 +8,6 @@ - Extracting boilerplate and core code from source files """ -from __future__ import annotations - import ast import copy import math diff --git a/lafleur/mutators/engine.py b/lafleur/mutators/engine.py index a309b2d..89d3e01 100644 --- a/lafleur/mutators/engine.py +++ b/lafleur/mutators/engine.py @@ -7,8 +7,6 @@ functions by operating on small, random slices of their body. """ -from __future__ import annotations - import ast import pickle import random diff --git a/lafleur/mutators/generic.py b/lafleur/mutators/generic.py index bca6742..8513d81 100644 --- a/lafleur/mutators/generic.py +++ b/lafleur/mutators/generic.py @@ -7,8 +7,6 @@ flow structures like loops and guards. """ -from __future__ import annotations - import ast import builtins import copy @@ -173,7 +171,7 @@ def visit_Constant(self, node: ast.Constant) -> ast.Constant: # Try converting to int (may fail for inf/nan) try: replacements.append(int(val)) - except (ValueError, OverflowError): + except ValueError, OverflowError: pass replacements.append(str(val)) @@ -334,7 +332,7 @@ def visit_Constant(self, node: ast.Constant) -> ast.AST: try: new_node = ast.parse(new_value_str, mode="eval").body return new_node - except (SyntaxError, ValueError): + except SyntaxError, ValueError: return node return node diff --git a/lafleur/mutators/scenarios_control.py b/lafleur/mutators/scenarios_control.py index 0e642fd..3a03921 100644 --- a/lafleur/mutators/scenarios_control.py +++ b/lafleur/mutators/scenarios_control.py @@ -8,8 +8,6 @@ guard emission and bailout mechanisms. """ -from __future__ import annotations - import ast import random import sys @@ -1264,7 +1262,7 @@ def _convert_isinstance_to_match(self, node: ast.If) -> ast.Match | None: ast.fix_missing_locations(match_node) return match_node - except (AttributeError, IndexError): + except AttributeError, IndexError: return None def visit_For(self, node: ast.For) -> ast.stmt: @@ -1327,7 +1325,7 @@ def _convert_for_to_match(self, node: ast.For) -> ast.For | None: ast.fix_missing_locations(new_for) return new_for - except (AttributeError, IndexError): + except AttributeError, IndexError: return None def visit_FunctionDef(self, node: ast.FunctionDef) -> ast.FunctionDef: diff --git a/lafleur/mutators/scenarios_data.py b/lafleur/mutators/scenarios_data.py index 0d16fba..f83b3b7 100644 --- a/lafleur/mutators/scenarios_data.py +++ b/lafleur/mutators/scenarios_data.py @@ -8,8 +8,6 @@ misuse collection primitives like iterators and slices. """ -from __future__ import annotations - import ast import random import sys diff --git a/lafleur/mutators/scenarios_runtime.py b/lafleur/mutators/scenarios_runtime.py index 3e82280..adfc9f0 100644 --- a/lafleur/mutators/scenarios_runtime.py +++ b/lafleur/mutators/scenarios_runtime.py @@ -8,8 +8,6 @@ from outside their scope, and triggering side effects via object finalizers. """ -from __future__ import annotations - import ast import random import sys diff --git a/lafleur/mutators/scenarios_types.py b/lafleur/mutators/scenarios_types.py index 1b19e59..940f828 100644 --- a/lafleur/mutators/scenarios_types.py +++ b/lafleur/mutators/scenarios_types.py @@ -8,8 +8,6 @@ modifying class hierarchies (MRO) at runtime. """ -from __future__ import annotations - import ast import random import sys diff --git a/lafleur/mutators/utils.py b/lafleur/mutators/utils.py index 7d9bc7a..986abc0 100644 --- a/lafleur/mutators/utils.py +++ b/lafleur/mutators/utils.py @@ -8,8 +8,6 @@ with stateful or contract-violating behaviors used by various scenarios. """ -from __future__ import annotations - import ast import random import sys diff --git a/lafleur/registry.py b/lafleur/registry.py index 353b2e5..1d7513f 100644 --- a/lafleur/registry.py +++ b/lafleur/registry.py @@ -5,8 +5,6 @@ sightings across fuzzing runs, and links to reported GitHub issues. """ -from __future__ import annotations - import sqlite3 from contextlib import contextmanager from pathlib import Path diff --git a/lafleur/triage.py b/lafleur/triage.py index bd17e16..754836e 100644 --- a/lafleur/triage.py +++ b/lafleur/triage.py @@ -5,8 +5,6 @@ fuzzing campaigns and linking them to GitHub issues. """ -from __future__ import annotations - import argparse import json import subprocess @@ -23,7 +21,7 @@ def load_json_file(path: Path) -> dict[str, Any] | None: try: with open(path, encoding="utf-8") as f: return json.load(f) - except (FileNotFoundError, json.JSONDecodeError, OSError): + except FileNotFoundError, json.JSONDecodeError, OSError: return None @@ -46,7 +44,7 @@ def get_revision_date(revision: str) -> int | None: ) if result.returncode == 0: return int(result.stdout.strip()) - except (subprocess.TimeoutExpired, ValueError, OSError): + except subprocess.TimeoutExpired, ValueError, OSError: pass return None @@ -60,7 +58,7 @@ def parse_iso_timestamp(timestamp_str: str) -> int | None: timestamp_str = timestamp_str[:-1] + "+00:00" dt = datetime.fromisoformat(timestamp_str) return int(dt.timestamp()) - except (ValueError, TypeError): + except ValueError, TypeError: return None @@ -278,7 +276,7 @@ def import_campaign(args: argparse.Namespace) -> None: if len(rev_part) >= 8: cpython_revision = rev_part revision_date = get_revision_date(cpython_revision) - except (IndexError, ValueError): + except IndexError, ValueError: pass # Fall back to start_time for revision_date proxy diff --git a/lafleur/types.py b/lafleur/types.py index 5f8e22a..d7da6dd 100644 --- a/lafleur/types.py +++ b/lafleur/types.py @@ -12,8 +12,6 @@ dispatch and preventing accidental mutation. """ -from __future__ import annotations - from dataclasses import dataclass from typing import TypedDict diff --git a/tests/test_lineage.py b/tests/test_lineage.py index f644478..7b7a83f 100644 --- a/tests/test_lineage.py +++ b/tests/test_lineage.py @@ -1,7 +1,5 @@ """Tests for lafleur.lineage — corpus lineage visualization tool.""" -from __future__ import annotations - import json import sys import unittest