Skip to content

Commit ef2295f

Browse files
committed
refactor compat.py
1 parent fcc3fef commit ef2295f

11 files changed

Lines changed: 64 additions & 67 deletions

File tree

codeflash/benchmarking/trace_benchmarks.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from pathlib import Path
77

88
from codeflash.cli_cmds.console import logger
9-
from codeflash.code_utils.compat import SAFE_SYS_EXECUTABLE
9+
from codeflash.code_utils.compat import get_safe_sys_executable
1010
from codeflash.code_utils.shell_utils import get_cross_platform_subprocess_run_args
1111

1212

@@ -23,7 +23,7 @@ def trace_benchmarks_pytest(
2323
)
2424
result = subprocess.run( # noqa: PLW1510
2525
[
26-
SAFE_SYS_EXECUTABLE,
26+
get_safe_sys_executable(),
2727
Path(__file__).parent / "pytest_new_process_trace_benchmarks.py",
2828
benchmarks_root,
2929
tests_root,

codeflash/code_utils/checkpoint.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from rich.prompt import Confirm
1111

1212
from codeflash.cli_cmds.console import console
13-
from codeflash.code_utils.compat import codeflash_temp_dir
13+
from codeflash.code_utils.compat import get_codeflash_temp_dir
1414

1515
if TYPE_CHECKING:
1616
import argparse
@@ -19,7 +19,7 @@
1919
class CodeflashRunCheckpoint:
2020
def __init__(self, module_root: Path, checkpoint_dir: Path | None = None) -> None:
2121
if checkpoint_dir is None:
22-
checkpoint_dir = codeflash_temp_dir
22+
checkpoint_dir = get_codeflash_temp_dir()
2323
self.module_root = module_root
2424
self.checkpoint_dir = Path(checkpoint_dir)
2525
# Create a unique checkpoint file name
@@ -141,8 +141,8 @@ def get_all_historical_functions(module_root: Path, checkpoint_dir: Path) -> dic
141141

142142
def ask_should_use_checkpoint_get_functions(args: argparse.Namespace) -> Optional[dict[str, dict[str, str]]]:
143143
previous_checkpoint_functions = None
144-
if args.all and codeflash_temp_dir.is_dir():
145-
previous_checkpoint_functions = get_all_historical_functions(args.module_root, codeflash_temp_dir)
144+
if args.all and get_codeflash_temp_dir().is_dir():
145+
previous_checkpoint_functions = get_all_historical_functions(args.module_root, get_codeflash_temp_dir())
146146
if previous_checkpoint_functions and Confirm.ask(
147147
"Previous Checkpoint detected from an incomplete optimization run, shall I continue the optimization from that point?",
148148
default=True,

codeflash/code_utils/compat.py

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,6 @@
1313
if TYPE_CHECKING:
1414
from jedi.api.environment import InterpreterEnvironment
1515

16-
codeflash_temp_dir: Path
17-
codeflash_cache_dir: Path
18-
codeflash_cache_db: Path
19-
2016

2117
def is_compiled_or_bundled_binary() -> bool:
2218
"""Check if running in a compiled/bundled binary."""
@@ -85,41 +81,34 @@ def _find_python_executable() -> str:
8581
return sys.executable
8682

8783

88-
class Compat:
89-
# os-independent newline
90-
LF: str = os.linesep
91-
92-
IS_POSIX: bool = os.name != "nt"
84+
LF: str = os.linesep
85+
IS_POSIX: bool = os.name != "nt"
9386

94-
@property
95-
def SAFE_SYS_EXECUTABLE(self) -> str:
96-
return Path(_find_python_executable()).as_posix()
9787

98-
@property
99-
def codeflash_cache_dir(self) -> Path:
100-
return Path(user_config_dir(appname="codeflash", appauthor="codeflash-ai", ensure_exists=True))
88+
@lru_cache(maxsize=1)
89+
def get_safe_sys_executable() -> str:
90+
"""Get a safe Python executable path with forward slashes."""
91+
return Path(_find_python_executable()).as_posix()
10192

102-
@property
103-
def codeflash_temp_dir(self) -> Path:
104-
temp_dir = Path(tempfile.gettempdir()) / "codeflash"
105-
if not temp_dir.exists():
106-
temp_dir.mkdir(parents=True, exist_ok=True)
107-
return temp_dir
10893

109-
@property
110-
def codeflash_cache_db(self) -> Path:
111-
return self.codeflash_cache_dir / "codeflash_cache.db"
94+
@lru_cache(maxsize=1)
95+
def get_codeflash_cache_dir() -> Path:
96+
"""Get the codeflash cache directory, creating it if necessary."""
97+
return Path(user_config_dir(appname="codeflash", appauthor="codeflash-ai", ensure_exists=True))
11298

11399

114-
_compat = Compat()
100+
@lru_cache(maxsize=1)
101+
def get_codeflash_temp_dir() -> Path:
102+
"""Get the codeflash temp directory, creating it if necessary."""
103+
temp_dir = Path(tempfile.gettempdir()) / "codeflash"
104+
temp_dir.mkdir(parents=True, exist_ok=True)
105+
return temp_dir
115106

116107

117-
codeflash_temp_dir = _compat.codeflash_temp_dir
118-
codeflash_cache_dir = _compat.codeflash_cache_dir
119-
codeflash_cache_db = _compat.codeflash_cache_db
120-
LF = _compat.LF
121-
SAFE_SYS_EXECUTABLE = _compat.SAFE_SYS_EXECUTABLE
122-
IS_POSIX = _compat.IS_POSIX
108+
@lru_cache(maxsize=1)
109+
def get_codeflash_cache_db() -> Path:
110+
"""Get the path to the codeflash cache database."""
111+
return get_codeflash_cache_dir() / "codeflash_cache.db"
123112

124113

125114
@lru_cache(maxsize=1)

codeflash/code_utils/concolic_utils.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import sentry_sdk
1010

11-
from codeflash.code_utils.compat import SAFE_SYS_EXECUTABLE, codeflash_temp_dir
11+
from codeflash.code_utils.compat import get_codeflash_temp_dir, get_safe_sys_executable
1212

1313

1414
def is_valid_concolic_test(test_code: str, project_root: Optional[str] = None) -> bool:
@@ -18,12 +18,12 @@ def is_valid_concolic_test(test_code: str, project_root: Optional[str] = None) -
1818
sentry_sdk.capture_message(f"CrossHair generated test with syntax error:\n{test_code}")
1919
return False
2020

21-
temp_path = (codeflash_temp_dir / f"concolic_test_{uuid.uuid4().hex}.py").resolve()
21+
temp_path = (get_codeflash_temp_dir() / f"concolic_test_{uuid.uuid4().hex}.py").resolve()
2222
temp_path.write_text(test_code, encoding="utf-8")
2323

2424
try:
2525
result = subprocess.run(
26-
[SAFE_SYS_EXECUTABLE, "-m", "pytest", "--collect-only", "-q", temp_path.as_posix()],
26+
[get_safe_sys_executable(), "-m", "pytest", "--collect-only", "-q", temp_path.as_posix()],
2727
check=False,
2828
capture_output=True,
2929
text=True,

codeflash/code_utils/git_worktree_utils.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@
1212
import git
1313

1414
from codeflash.cli_cmds.console import logger
15-
from codeflash.code_utils.compat import codeflash_cache_dir
15+
from codeflash.code_utils.compat import get_codeflash_cache_dir
1616
from codeflash.code_utils.git_utils import check_running_in_git_repo, git_root_dir
1717

18-
worktree_dirs = codeflash_cache_dir / "worktrees"
19-
patches_dir = codeflash_cache_dir / "patches"
18+
worktree_dirs = get_codeflash_cache_dir() / "worktrees"
19+
patches_dir = get_codeflash_cache_dir() / "patches"
2020

2121

2222
def create_worktree_snapshot_commit(worktree_dir: Path, commit_message: str) -> None:

codeflash/discovery/discover_unit_tests.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
get_run_tmp_file,
2929
module_name_from_file_path,
3030
)
31-
from codeflash.code_utils.compat import SAFE_SYS_EXECUTABLE, codeflash_cache_db, is_compiled_or_bundled_binary
31+
from codeflash.code_utils.compat import get_codeflash_cache_db, get_safe_sys_executable, is_compiled_or_bundled_binary
3232
from codeflash.code_utils.shell_utils import get_cross_platform_subprocess_run_args
3333
from codeflash.models.models import CodePosition, FunctionCalledInTest, TestsInFile, TestType
3434

@@ -137,7 +137,7 @@ class TestsCache:
137137

138138
def __init__(self, project_root_path: str | Path) -> None:
139139
self.project_root_path = Path(project_root_path).resolve().as_posix()
140-
self.connection = sqlite3.connect(codeflash_cache_db)
140+
self.connection = sqlite3.connect(get_codeflash_cache_db())
141141
self.cur = self.connection.cursor()
142142

143143
self.cur.execute(
@@ -675,7 +675,13 @@ def discover_tests_pytest(
675675
cwd=project_root, check=False, text=True, capture_output=True
676676
)
677677
result = subprocess.run( # noqa: PLW1510
678-
[SAFE_SYS_EXECUTABLE, str(discovery_script_path), str(project_root), str(tests_root), str(tmp_pickle_path)],
678+
[
679+
get_safe_sys_executable(),
680+
str(discovery_script_path),
681+
str(project_root),
682+
str(tests_root),
683+
str(tmp_pickle_path),
684+
],
679685
**run_kwargs,
680686
)
681687
try:

codeflash/tracer.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from codeflash.cli_cmds.cli import project_root_from_module_root
2424
from codeflash.cli_cmds.console import console
2525
from codeflash.code_utils.code_utils import get_run_tmp_file
26-
from codeflash.code_utils.compat import SAFE_SYS_EXECUTABLE
26+
from codeflash.code_utils.compat import get_safe_sys_executable
2727
from codeflash.code_utils.config_consts import EffortLevel
2828
from codeflash.code_utils.config_parser import parse_config_file
2929
from codeflash.tracing.pytest_parallelization import pytest_split
@@ -141,7 +141,7 @@ def main(args: Namespace | None = None) -> ArgumentParser:
141141
processes.append(
142142
subprocess.Popen(
143143
[
144-
SAFE_SYS_EXECUTABLE,
144+
get_safe_sys_executable(),
145145
Path(__file__).parent / "tracing" / "tracing_new_process.py",
146146
*updated_sys_argv,
147147
json.dumps(args_dict),
@@ -178,7 +178,7 @@ def main(args: Namespace | None = None) -> ArgumentParser:
178178

179179
subprocess.run(
180180
[
181-
SAFE_SYS_EXECUTABLE,
181+
get_safe_sys_executable(),
182182
Path(__file__).parent / "tracing" / "tracing_new_process.py",
183183
*sys.argv,
184184
json.dumps(args_dict),

codeflash/verification/concolic_testing.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from typing import TYPE_CHECKING
99

1010
from codeflash.cli_cmds.console import console, logger
11-
from codeflash.code_utils.compat import SAFE_SYS_EXECUTABLE
11+
from codeflash.code_utils.compat import get_safe_sys_executable
1212
from codeflash.code_utils.concolic_utils import clean_concolic_tests, is_valid_concolic_test
1313
from codeflash.code_utils.static_analysis import has_typed_parameters
1414
from codeflash.discovery.discover_unit_tests import discover_unit_tests
@@ -44,7 +44,7 @@ def generate_concolic_tests(
4444
try:
4545
cover_result = subprocess.run(
4646
[
47-
SAFE_SYS_EXECUTABLE,
47+
get_safe_sys_executable(),
4848
"-m",
4949
"crosshair",
5050
"cover",

codeflash/verification/test_runner.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
from codeflash.cli_cmds.console import logger
1212
from codeflash.code_utils.code_utils import custom_addopts, get_run_tmp_file
13-
from codeflash.code_utils.compat import IS_POSIX, SAFE_SYS_EXECUTABLE, is_compiled_or_bundled_binary
13+
from codeflash.code_utils.compat import IS_POSIX, get_safe_sys_executable, is_compiled_or_bundled_binary
1414
from codeflash.code_utils.config_consts import TOTAL_LOOPING_TIME_EFFECTIVE
1515
from codeflash.code_utils.coverage_utils import prepare_coverage_files
1616
from codeflash.code_utils.shell_utils import get_cross_platform_subprocess_run_args
@@ -98,9 +98,9 @@ def run_behavioral_tests(
9898
test_files.append(str(file.instrumented_behavior_file_path))
9999

100100
pytest_cmd_list = (
101-
shlex.split(f"{SAFE_SYS_EXECUTABLE} -m pytest", posix=IS_POSIX)
101+
shlex.split(f"{get_safe_sys_executable()} -m pytest", posix=IS_POSIX)
102102
if pytest_cmd == "pytest"
103-
else [SAFE_SYS_EXECUTABLE, "-m", *shlex.split(pytest_cmd, posix=IS_POSIX)]
103+
else [get_safe_sys_executable(), "-m", *shlex.split(pytest_cmd, posix=IS_POSIX)]
104104
)
105105
test_files = list(set(test_files)) # remove multiple calls in the same test function
106106

@@ -147,11 +147,14 @@ def run_behavioral_tests(
147147
coverage_database_file.unlink()
148148
else:
149149
cov_erase = execute_test_subprocess(
150-
shlex.split(f"{SAFE_SYS_EXECUTABLE} -m coverage erase"), cwd=cwd, env=pytest_test_env, timeout=30
150+
shlex.split(f"{get_safe_sys_executable()} -m coverage erase"),
151+
cwd=cwd,
152+
env=pytest_test_env,
153+
timeout=30,
151154
) # this cleanup is necessary to avoid coverage data from previous runs, if there are any, then the current run will be appended to the previous data, which skews the results
152155
logger.debug(cov_erase)
153156
coverage_cmd = [
154-
SAFE_SYS_EXECUTABLE,
157+
get_safe_sys_executable(),
155158
"-m",
156159
"coverage",
157160
"run",
@@ -214,7 +217,7 @@ def run_line_profile_tests(
214217
) -> tuple[Path, subprocess.CompletedProcess]:
215218
if test_framework in {"pytest", "unittest"}: # pytest runs both pytest and unittest tests
216219
pytest_cmd_list = (
217-
shlex.split(f"{SAFE_SYS_EXECUTABLE} -m pytest", posix=IS_POSIX)
220+
shlex.split(f"{get_safe_sys_executable()} -m pytest", posix=IS_POSIX)
218221
if pytest_cmd == "pytest"
219222
else shlex.split(pytest_cmd)
220223
)
@@ -276,7 +279,7 @@ def run_benchmarking_tests(
276279
) -> tuple[Path, subprocess.CompletedProcess]:
277280
if test_framework in {"pytest", "unittest"}: # pytest runs both pytest and unittest tests
278281
pytest_cmd_list = (
279-
shlex.split(f"{SAFE_SYS_EXECUTABLE} -m pytest", posix=IS_POSIX)
282+
shlex.split(f"{get_safe_sys_executable()} -m pytest", posix=IS_POSIX)
280283
if pytest_cmd == "pytest"
281284
else shlex.split(pytest_cmd)
282285
)

tests/test_codeflash_capture.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from pathlib import Path
66

77
from codeflash.code_utils.code_utils import get_run_tmp_file
8-
from codeflash.code_utils.compat import SAFE_SYS_EXECUTABLE
8+
from codeflash.code_utils.compat import get_safe_sys_executable
99
from codeflash.discovery.functions_to_optimize import FunctionToOptimize
1010
from codeflash.models.models import FunctionParent, TestFile, TestFiles, TestingMode, TestType, VerificationType
1111
from codeflash.optimization.function_optimizer import FunctionOptimizer
@@ -54,7 +54,7 @@ def __init__(self):
5454
with sample_code_path.open("w") as f:
5555
f.write(sample_code)
5656
result = execute_test_subprocess(
57-
cwd=test_dir, cmd_list=[f"{SAFE_SYS_EXECUTABLE}", "-m", "pytest", test_file_name, "-s"], env=os.environ.copy()
57+
cwd=test_dir, cmd_list=[f"{get_safe_sys_executable()}", "-m", "pytest", test_file_name, "-s"], env=os.environ.copy()
5858
)
5959
assert not result.stderr
6060
assert result.returncode == 0
@@ -129,7 +129,7 @@ def __init__(self):
129129
with sample_code_path.open("w") as f:
130130
f.write(sample_code)
131131
result = execute_test_subprocess(
132-
cwd=test_dir, cmd_list=[f"{SAFE_SYS_EXECUTABLE}", "-m", "pytest", test_file_name, "-s"], env=os.environ.copy()
132+
cwd=test_dir, cmd_list=[f"{get_safe_sys_executable()}", "-m", "pytest", test_file_name, "-s"], env=os.environ.copy()
133133
)
134134
assert not result.stderr
135135
assert result.returncode == 0
@@ -194,7 +194,7 @@ def __init__(self):
194194
with sample_code_path.open("w") as f:
195195
f.write(sample_code)
196196
result = execute_test_subprocess(
197-
cwd=test_dir, cmd_list=[f"{SAFE_SYS_EXECUTABLE}", "-m", "pytest", test_file_name, "-s"], env=os.environ.copy()
197+
cwd=test_dir, cmd_list=[f"{get_safe_sys_executable()}", "-m", "pytest", test_file_name, "-s"], env=os.environ.copy()
198198
)
199199
assert not result.stderr
200200
assert result.returncode == 0
@@ -279,7 +279,7 @@ def __init__(self):
279279

280280
# Run pytest as a subprocess
281281
result = execute_test_subprocess(
282-
cwd=test_dir, cmd_list=[f"{SAFE_SYS_EXECUTABLE}", "-m", "pytest", test_file_name, "-s"], env=os.environ.copy()
282+
cwd=test_dir, cmd_list=[f"{get_safe_sys_executable()}", "-m", "pytest", test_file_name, "-s"], env=os.environ.copy()
283283
)
284284

285285
# Check for errors
@@ -356,7 +356,7 @@ def __init__(self):
356356
with sample_code_path.open("w") as f:
357357
f.write(sample_code)
358358
result = execute_test_subprocess(
359-
cwd=test_dir, cmd_list=[f"{SAFE_SYS_EXECUTABLE}", "-m", "pytest", test_file_name, "-s"], env=os.environ.copy()
359+
cwd=test_dir, cmd_list=[f"{get_safe_sys_executable()}", "-m", "pytest", test_file_name, "-s"], env=os.environ.copy()
360360
)
361361
assert not result.stderr
362362
assert result.returncode == 0
@@ -1231,7 +1231,7 @@ def __init__(self):
12311231
test_env.pop("CODEFLASH_TEST_CLASS", None)
12321232

12331233
result = execute_test_subprocess(
1234-
cwd=test_dir, cmd_list=[f"{SAFE_SYS_EXECUTABLE}", "-m", "pytest", test_file_name, "-s"], env=test_env
1234+
cwd=test_dir, cmd_list=[f"{get_safe_sys_executable()}", "-m", "pytest", test_file_name, "-s"], env=test_env
12351235
)
12361236
assert result.returncode == 0
12371237
pattern = r"TEST_INFO_START\|\((.*?)\)\|TEST_INFO_END"
@@ -1292,7 +1292,7 @@ def __init__(self):
12921292

12931293
test_env = os.environ.copy()
12941294
result = execute_test_subprocess(
1295-
cwd=test_dir, cmd_list=[f"{SAFE_SYS_EXECUTABLE}", "-m", "pytest", test_file_name, "-s"], env=test_env
1295+
cwd=test_dir, cmd_list=[f"{get_safe_sys_executable()}", "-m", "pytest", test_file_name, "-s"], env=test_env
12961296
)
12971297
assert result.returncode == 0
12981298
pattern = r"TEST_INFO_START\|\((.*?)\)\|TEST_INFO_END"

0 commit comments

Comments
 (0)