SXXXXXXX_ProfileAnalyzer/profileanalyzer/core/core.py
VALLONGOL e766172c47 Chore: Stop tracking files based on .gitignore update.
Untracked files matching the following rules:
- Rule "!.vscode/launch.json": 1 file
- Rule "*.prof": 6 files
2025-06-23 14:07:01 +02:00

132 lines
4.9 KiB
Python

# profileAnalyzer/core/core.py
# ... (tutti gli import e le altre classi/funzioni restano invariate) ...
import pstats
from io import StringIO
import subprocess
import sys
import os
from dataclasses import dataclass, field
from typing import List, Optional
from datetime import datetime
@dataclass
class LaunchProfile:
name: str
run_as_module: bool = False
target_path: str = ""
module_name: str = ""
script_args: str = ""
python_interpreter: str = sys.executable
class ProfileAnalyzer:
# ... (nessuna modifica qui)
def __init__(self):
self.stats: Optional[pstats.Stats] = None
self.profile_path: Optional[str] = None
def load_profile(self, filepath: str) -> bool:
try:
self.stats = pstats.Stats(filepath)
self.stats.strip_dirs()
self.profile_path = filepath
return True
except (FileNotFoundError, TypeError, OSError) as e:
print(f"Error loading profile file '{filepath}': {e}")
self.stats = None
self.profile_path = None
return False
def get_stats(self, sort_by: str, limit: int = 200) -> list:
if not self.stats:
return []
s = StringIO()
stats_to_print = pstats.Stats(self.profile_path, stream=s)
stats_to_print.strip_dirs()
stats_to_print.sort_stats(sort_by)
stats_to_print.print_stats(limit)
s.seek(0)
lines = s.getvalue().splitlines()
results = []
data_started = False
for line in lines:
if not line.strip(): continue
if 'ncalls' in line and 'tottime' in line:
data_started = True
continue
if data_started:
parts = line.strip().split(maxsplit=5)
if len(parts) == 6:
try:
results.append((parts[0], float(parts[1]), float(parts[2]), float(parts[3]), float(parts[4]), parts[5]))
except (ValueError, IndexError):
continue
return results
def run_and_profile_script(profile: LaunchProfile) -> Optional[str]:
"""Runs a target Python script/module under cProfile."""
# --- Output File Path Definition (prima di tutto) ---
output_dir = os.path.join(os.getcwd(), "execution_profiles")
os.makedirs(output_dir, exist_ok=True)
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
profile_name_sanitized = profile.name.replace(' ', '_').replace('.', '_')
# **CORREZIONE**: Creare un percorso assoluto fin da subito
profile_output_path = os.path.abspath(os.path.join(output_dir, f"{timestamp}_{profile_name_sanitized}.prof"))
# --- Command and Working Directory Definition ---
command = [profile.python_interpreter, "-m", "cProfile", "-o", profile_output_path]
working_directory = None
if profile.run_as_module:
if not profile.module_name:
print("Error: Module name is required.")
return None
# target_path in module mode is the project root
if not profile.target_path or not os.path.isdir(profile.target_path):
print(f"Error: Project Root Folder is not a valid directory: {profile.target_path}")
return None
# **CORREZIONE**: la sintassi corretta è '-m' seguito dal nome del modulo
command.extend(["-m", profile.module_name])
working_directory = profile.target_path
else:
# **CORREZIONE**: target_path è il percorso dello script
if not profile.target_path or not os.path.exists(profile.target_path):
print(f"Error: Script path does not exist: {profile.target_path}")
return None
command.append(profile.target_path)
working_directory = os.path.dirname(profile.target_path)
if profile.script_args:
command.extend(profile.script_args.split())
try:
print(f"Executing profiling command: {' '.join(command)}")
print(f"Working Directory for subprocess: {working_directory}")
process = subprocess.Popen(
command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
cwd=working_directory
)
stdout, stderr = process.communicate()
if stdout: print(f"--- STDOUT ---\n{stdout}")
if stderr: print(f"--- STDERR ---\n{stderr}")
if process.returncode != 0:
print(f"Warning: Profiled script exited with non-zero status: {process.returncode}")
if not os.path.exists(profile_output_path) or os.path.getsize(profile_output_path) == 0:
print("Error: Profiling failed and no output file was generated.")
return None
print(f"Profiling data saved to: {profile_output_path}")
return profile_output_path
except Exception as e:
print(f"Failed to run and profile script: {e}")
return None