Skip to content

path normalization and tempdir fixes for windows #363

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion codeflash/benchmarking/replay_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ def create_trace_replay_test_code(
module_name = func.get("module_name")
function_name = func.get("function_name")
class_name = func.get("class_name")
file_path = func.get("file_path")
file_path = Path(func.get("file_path")).as_posix()
benchmark_function_name = func.get("benchmark_function_name")
function_properties = func.get("function_properties")
if not class_name:
Expand Down
3 changes: 2 additions & 1 deletion codeflash/code_utils/code_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,9 @@ def get_run_tmp_file(file_path: Path) -> Path:


def path_belongs_to_site_packages(file_path: Path) -> bool:
file_path_resolved = file_path.resolve()
site_packages = [Path(p) for p in site.getsitepackages()]
return any(file_path.resolve().is_relative_to(site_package_path) for site_package_path in site_packages)
return any(file_path_resolved.is_relative_to(site_package_path) for site_package_path in site_packages)


def is_class_defined_in_file(class_name: str, file_path: Path) -> bool:
Expand Down
2 changes: 1 addition & 1 deletion codeflash/code_utils/coverage_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def generate_candidates(source_code_path: Path) -> list[str]:
current_path = source_code_path.parent

while current_path != current_path.parent:
candidate_path = str(Path(current_path.name) / candidates[-1])
candidate_path = (Path(current_path.name) / candidates[-1]).as_posix()
candidates.append(candidate_path)
current_path = current_path.parent

Expand Down
9 changes: 4 additions & 5 deletions codeflash/code_utils/env_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,17 @@ def check_formatter_installed(formatter_cmds: list[str], exit_on_failure: bool =
if formatter_cmds[0] == "disabled":
return return_code
tmp_code = """print("hello world")"""
with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", suffix=".py") as f:
f.write(tmp_code)
f.flush()
tmp_file = Path(f.name)
with tempfile.TemporaryDirectory() as tmpdir:
tmp_file = Path(tmpdir) / "test_codeflash_formatter.py"
tmp_file.write_text(tmp_code, encoding="utf-8")
try:
format_code(formatter_cmds, tmp_file, print_status=False, exit_on_failure=exit_on_failure)
except Exception:
exit_with_message(
"⚠️ Codeflash requires a code formatter to be installed in your environment, but none was found. Please install a supported formatter, verify the formatter-cmds in your codeflash pyproject.toml config and try again.",
error_on_exit=True,
)
return return_code
return return_code


@lru_cache(maxsize=1)
Expand Down
4 changes: 3 additions & 1 deletion codeflash/code_utils/instrument_existing_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,9 @@ def visit_FunctionDef(self, node: ast.FunctionDef, test_class_name: str | None =
args=[
ast.JoinedStr(
values=[
ast.Constant(value=f"{get_run_tmp_file(Path('test_return_values_'))}"),
ast.Constant(
value=f"{get_run_tmp_file(Path('test_return_values_')).as_posix()}"
),
ast.FormattedValue(
value=ast.Name(id="codeflash_iteration", ctx=ast.Load()),
conversion=-1,
Expand Down
2 changes: 1 addition & 1 deletion codeflash/models/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ def markdown(self) -> str:
"""Returns the markdown representation of the code, including the file path where possible."""
return "\n".join(
[
f"```python{':' + str(code_string.file_path) if code_string.file_path else ''}\n{code_string.code.strip()}\n```"
f"```python{':' + code_string.file_path.as_posix() if code_string.file_path else ''}\n{code_string.code.strip()}\n```"
for code_string in self.code_strings
]
)
Expand Down
6 changes: 3 additions & 3 deletions codeflash/verification/instrument_codeflash_capture.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def instrument_codeflash_capture(
modified_code = add_codeflash_capture_to_init(
target_classes={class_parent.name},
fto_name=function_to_optimize.function_name,
tmp_dir_path=str(get_run_tmp_file(Path("test_return_values"))),
tmp_dir_path=get_run_tmp_file(Path("test_return_values")).as_posix(),
code=original_code,
tests_root=tests_root,
is_fto=True,
Expand All @@ -46,7 +46,7 @@ def instrument_codeflash_capture(
modified_code = add_codeflash_capture_to_init(
target_classes=helper_classes,
fto_name=function_to_optimize.function_name,
tmp_dir_path=str(get_run_tmp_file(Path("test_return_values"))),
tmp_dir_path=get_run_tmp_file(Path("test_return_values")).as_posix(),
code=original_code,
tests_root=tests_root,
is_fto=False,
Expand Down Expand Up @@ -124,7 +124,7 @@ def visit_ClassDef(self, node: ast.ClassDef) -> ast.ClassDef:
keywords=[
ast.keyword(arg="function_name", value=ast.Constant(value=f"{node.name}.__init__")),
ast.keyword(arg="tmp_dir_path", value=ast.Constant(value=self.tmp_dir_path)),
ast.keyword(arg="tests_root", value=ast.Constant(value=str(self.tests_root))),
ast.keyword(arg="tests_root", value=ast.Constant(value=self.tests_root.as_posix())),
ast.keyword(arg="is_fto", value=ast.Constant(value=self.is_fto)),
],
)
Expand Down
4 changes: 2 additions & 2 deletions tests/test_code_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ def test_get_run_tmp_file_reuses_temp_directory() -> None:


def test_path_belongs_to_site_packages_with_site_package_path(monkeypatch: pytest.MonkeyPatch) -> None:
site_packages = [Path("/usr/local/lib/python3.9/site-packages")]
site_packages = [Path("/usr/local/lib/python3.9/site-packages").resolve()]
monkeypatch.setattr(site, "getsitepackages", lambda: site_packages)

file_path = Path("/usr/local/lib/python3.9/site-packages/some_package")
Expand Down Expand Up @@ -465,4 +465,4 @@ def another_function():
pass
"""
result = has_any_async_functions(code)
assert result is False
assert result is False
30 changes: 17 additions & 13 deletions tests/test_codeflash_capture.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def test_example_test_3(self):
class MyClass:
def __init__(self):
self.x = 2
print(f"TEST_INFO_START|{{get_test_info_from_stack('{test_dir!s}')}}|TEST_INFO_END")
print(f"TEST_INFO_START|{{get_test_info_from_stack('{test_dir.as_posix()}')}}|TEST_INFO_END")
"""
test_file_name = "test_stack_info_temp.py"

Expand Down Expand Up @@ -117,7 +117,7 @@ def test_example_test_3(self):
class MyClass:
def __init__(self):
self.x = 2
print(f"TEST_INFO_START|{{get_test_info_from_stack('{test_dir!s}')}}|TEST_INFO_END")
print(f"TEST_INFO_START|{{get_test_info_from_stack('{test_dir.as_posix()}')}}|TEST_INFO_END")
"""
test_file_name = "test_stack_info_temp.py"

Expand Down Expand Up @@ -181,7 +181,7 @@ def test_example_test_3(self):
class MyClass:
def __init__(self):
self.x = 2
print(f"TEST_INFO_START|{{get_test_info_from_stack('{test_dir!s}')}}|TEST_INFO_END")
print(f"TEST_INFO_START|{{get_test_info_from_stack('{test_dir.as_posix()}')}}|TEST_INFO_END")
"""
test_dir = (Path(__file__).parent.parent / "code_to_optimize" / "tests" / "pytest").resolve()
test_file_name = "test_stack_info_temp.py"
Expand Down Expand Up @@ -261,7 +261,7 @@ class MyClass:
def __init__(self):
self.x = 2
# Print out the detected test info each time we instantiate MyClass
print(f"TEST_INFO_START|{{get_test_info_from_stack('{test_dir!s}')}}|TEST_INFO_END")
print(f"TEST_INFO_START|{{get_test_info_from_stack('{test_dir.as_posix()}')}}|TEST_INFO_END")
"""

test_file_name = "test_stack_info_recursive_temp.py"
Expand Down Expand Up @@ -343,7 +343,7 @@ def test_example_test():
class MyClass:
def __init__(self):
self.x = 2
print(f"TEST_INFO_START|{{get_test_info_from_stack('{test_dir!s}')}}|TEST_INFO_END")
print(f"TEST_INFO_START|{{get_test_info_from_stack('{test_dir.as_posix()}')}}|TEST_INFO_END")
"""
test_dir = (Path(__file__).parent.parent / "code_to_optimize" / "tests" / "pytest").resolve()
test_file_name = "test_stack_info_temp.py"
Expand Down Expand Up @@ -410,10 +410,11 @@ def test_example_test_3(self):
self.assertTrue(True)
"""
test_dir = (Path(__file__).parent.parent / "code_to_optimize" / "tests" / "pytest").resolve()
tmp_dir_path = get_run_tmp_file(Path("test_return_values"))
sample_code = f"""
from codeflash.verification.codeflash_capture import codeflash_capture
class MyClass:
@codeflash_capture(function_name="some_function", tmp_dir_path="{get_run_tmp_file(Path("test_return_values"))}", tests_root="{test_dir!s}")
@codeflash_capture(function_name="some_function", tmp_dir_path="{tmp_dir_path.as_posix()}", tests_root="{test_dir.as_posix()}")
def __init__(self, x=2):
self.x = x
"""
Expand Down Expand Up @@ -528,6 +529,7 @@ def test_example_test_3(self):
self.assertTrue(True)
"""
test_dir = (Path(__file__).parent.parent / "code_to_optimize" / "tests" / "pytest").resolve()
tmp_dir_path = get_run_tmp_file(Path("test_return_values"))
# MyClass did not have an init function, we created the init function with the codeflash_capture decorator using instrumentation
sample_code = f"""
from codeflash.verification.codeflash_capture import codeflash_capture
Expand All @@ -536,7 +538,7 @@ def __init__(self):
self.x = 2

class MyClass(ParentClass):
@codeflash_capture(function_name="some_function", tmp_dir_path="{get_run_tmp_file(Path("test_return_values"))}", tests_root="{test_dir!s}")
@codeflash_capture(function_name="some_function", tmp_dir_path="{tmp_dir_path.as_posix()}", tests_root="{test_dir.as_posix()}")
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
"""
Expand Down Expand Up @@ -648,14 +650,15 @@ def test_example_test():

"""
test_dir = (Path(__file__).parent.parent / "code_to_optimize" / "tests" / "pytest").resolve()
tmp_dir_path = get_run_tmp_file(Path("test_return_values"))
sample_code = f"""
from codeflash.verification.codeflash_capture import codeflash_capture

class MyClass:
@codeflash_capture(
function_name="some_function",
tmp_dir_path="{get_run_tmp_file(Path("test_return_values"))}",
tests_root="{test_dir!s}"
tmp_dir_path="{tmp_dir_path.as_posix()}",
tests_root="{test_dir.as_posix()}"
)
def __init__(self, x=2):
self.x = x
Expand Down Expand Up @@ -765,13 +768,14 @@ def test_helper_classes():
assert MyClass().target_function() == 6
"""
test_dir = (Path(__file__).parent.parent / "code_to_optimize" / "tests" / "pytest").resolve()
tmp_dir_path = get_run_tmp_file(Path("test_return_values"))
original_code = f"""
from codeflash.verification.codeflash_capture import codeflash_capture
from code_to_optimize.tests.pytest.helper_file_1 import HelperClass1
from code_to_optimize.tests.pytest.helper_file_2 import HelperClass2, AnotherHelperClass

class MyClass:
@codeflash_capture(function_name='MyClass.__init__', tmp_dir_path='{get_run_tmp_file(Path("test_return_values"))}', tests_root="{test_dir!s}" , is_fto=True)
@codeflash_capture(function_name='MyClass.__init__', tmp_dir_path='{tmp_dir_path.as_posix()}', tests_root="{test_dir.as_posix()}" , is_fto=True)
def __init__(self):
self.x = 1

Expand All @@ -785,7 +789,7 @@ def target_function(self):
from codeflash.verification.codeflash_capture import codeflash_capture

class HelperClass1:
@codeflash_capture(function_name='HelperClass1.__init__', tmp_dir_path='{get_run_tmp_file(Path("test_return_values"))}', tests_root="{test_dir!s}", is_fto=False)
@codeflash_capture(function_name='HelperClass1.__init__', tmp_dir_path='{tmp_dir_path.as_posix()}', tests_root="{test_dir.as_posix()}", is_fto=False)
def __init__(self):
self.y = 1

Expand All @@ -797,15 +801,15 @@ def helper1(self):
from codeflash.verification.codeflash_capture import codeflash_capture

class HelperClass2:
@codeflash_capture(function_name='HelperClass2.__init__', tmp_dir_path='{get_run_tmp_file(Path("test_return_values"))}', tests_root="{test_dir!s}", is_fto=False)
@codeflash_capture(function_name='HelperClass2.__init__', tmp_dir_path='{tmp_dir_path.as_posix()}', tests_root="{test_dir.as_posix()}", is_fto=False)
def __init__(self):
self.z = 2

def helper2(self):
return 2

class AnotherHelperClass:
@codeflash_capture(function_name='AnotherHelperClass.__init__', tmp_dir_path='{get_run_tmp_file(Path("test_return_values"))}', tests_root="{test_dir!s}", is_fto=False)
@codeflash_capture(function_name='AnotherHelperClass.__init__', tmp_dir_path='{tmp_dir_path.as_posix()}', tests_root="{test_dir.as_posix()}", is_fto=False)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

Expand Down
Loading
Loading