Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 0 additions & 2 deletions lafleur/artifacts.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
- TelemetryManager: run statistics persistence and time-series logging
"""

from __future__ import annotations

import difflib
import json
import random
Expand Down
2 changes: 0 additions & 2 deletions lafleur/campaign.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
summaries for campaign analysis.
"""

from __future__ import annotations

import argparse
import html
import json
Expand Down
2 changes: 0 additions & 2 deletions lafleur/corpus_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lafleur/corpus_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
8 changes: 3 additions & 5 deletions lafleur/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
[DRIVER:ERROR] <script_path> - Emitted when a script raises an exception
"""

from __future__ import annotations

import argparse
import collections.abc
import ctypes
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 = {
Expand Down
2 changes: 1 addition & 1 deletion lafleur/execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
6 changes: 2 additions & 4 deletions lafleur/lineage.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 = {
Expand Down Expand Up @@ -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


Expand Down
2 changes: 1 addition & 1 deletion lafleur/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -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}


Expand Down
2 changes: 0 additions & 2 deletions lafleur/mutation_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
- Extracting boilerplate and core code from source files
"""

from __future__ import annotations

import ast
import copy
import math
Expand Down
2 changes: 0 additions & 2 deletions lafleur/mutators/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
functions by operating on small, random slices of their body.
"""

from __future__ import annotations

import ast
import pickle
import random
Expand Down
6 changes: 2 additions & 4 deletions lafleur/mutators/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
flow structures like loops and guards.
"""

from __future__ import annotations

import ast
import builtins
import copy
Expand Down Expand Up @@ -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))

Expand Down Expand Up @@ -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

Expand Down
6 changes: 2 additions & 4 deletions lafleur/mutators/scenarios_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
guard emission and bailout mechanisms.
"""

from __future__ import annotations

import ast
import random
import sys
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
2 changes: 0 additions & 2 deletions lafleur/mutators/scenarios_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
misuse collection primitives like iterators and slices.
"""

from __future__ import annotations

import ast
import random
import sys
Expand Down
2 changes: 0 additions & 2 deletions lafleur/mutators/scenarios_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 0 additions & 2 deletions lafleur/mutators/scenarios_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
modifying class hierarchies (MRO) at runtime.
"""

from __future__ import annotations

import ast
import random
import sys
Expand Down
2 changes: 0 additions & 2 deletions lafleur/mutators/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
with stateful or contract-violating behaviors used by various scenarios.
"""

from __future__ import annotations

import ast
import random
import sys
Expand Down
2 changes: 0 additions & 2 deletions lafleur/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 4 additions & 6 deletions lafleur/triage.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
fuzzing campaigns and linking them to GitHub issues.
"""

from __future__ import annotations

import argparse
import json
import subprocess
Expand All @@ -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


Expand All @@ -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

Expand All @@ -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


Expand Down Expand Up @@ -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
Expand Down
2 changes: 0 additions & 2 deletions lafleur/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
dispatch and preventing accidental mutation.
"""

from __future__ import annotations

from dataclasses import dataclass
from typing import TypedDict

Expand Down
2 changes: 0 additions & 2 deletions tests/test_lineage.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
"""Tests for lafleur.lineage — corpus lineage visualization tool."""

from __future__ import annotations

import json
import sys
import unittest
Expand Down
Loading