mirror of
https://github.com/codeflash-ai/codeflash.git
synced 2026-05-04 18:25:17 +00:00
reinsert
This commit is contained in:
parent
7278ab39c1
commit
16d21e7464
18 changed files with 271 additions and 218 deletions
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -18,10 +18,9 @@ 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:
|
||||
|
|
@ -29,7 +28,7 @@ def check_formatter_installed(formatter_cmds: list[str], exit_on_failure: bool =
|
|||
"⚠️ 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)
|
||||
|
|
|
|||
|
|
@ -212,7 +212,9 @@ class InjectPerfOnly(ast.NodeTransformer):
|
|||
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,
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ class CodeStringsMarkdown(BaseModel):
|
|||
"""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
|
||||
]
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
@ -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,
|
||||
|
|
@ -124,7 +124,7 @@ class InitDecorator(ast.NodeTransformer):
|
|||
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)),
|
||||
],
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
@ -465,4 +465,4 @@ def another_function():
|
|||
pass
|
||||
"""
|
||||
result = has_any_async_functions(code)
|
||||
assert result is False
|
||||
assert result is False
|
||||
|
|
@ -42,7 +42,7 @@ from codeflash.verification.codeflash_capture import get_test_info_from_stack
|
|||
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"
|
||||
|
||||
|
|
@ -117,7 +117,7 @@ from codeflash.verification.codeflash_capture import get_test_info_from_stack
|
|||
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"
|
||||
|
||||
|
|
@ -181,7 +181,7 @@ from codeflash.verification.codeflash_capture import get_test_info_from_stack
|
|||
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"
|
||||
|
|
@ -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"
|
||||
|
|
@ -343,7 +343,7 @@ from codeflash.verification.codeflash_capture import get_test_info_from_stack
|
|||
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"
|
||||
|
|
@ -410,10 +410,11 @@ class TestUnittestExample(unittest.TestCase):
|
|||
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
|
||||
"""
|
||||
|
|
@ -528,6 +529,7 @@ class TestUnittestExample(unittest.TestCase):
|
|||
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
|
||||
|
|
@ -536,7 +538,7 @@ class ParentClass:
|
|||
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)
|
||||
"""
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -785,7 +789,7 @@ class MyClass:
|
|||
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
|
||||
|
||||
|
|
@ -797,7 +801,7 @@ class HelperClass1:
|
|||
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
|
||||
|
||||
|
|
@ -805,7 +809,7 @@ class HelperClass2:
|
|||
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)
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,11 @@ from codeflash.discovery.functions_to_optimize import FunctionToOptimize
|
|||
from codeflash.optimization.function_optimizer import FunctionOptimizer
|
||||
from codeflash.verification.verification_utils import TestConfig
|
||||
|
||||
@pytest.fixture
|
||||
def temp_dir():
|
||||
with tempfile.TemporaryDirectory() as tmpdirname:
|
||||
yield Path(tmpdirname)
|
||||
|
||||
def test_remove_duplicate_imports():
|
||||
"""Test that duplicate imports are removed when should_sort_imports is True."""
|
||||
original_code = "import os\nimport os\n"
|
||||
|
|
@ -36,17 +41,15 @@ def test_sorting_imports():
|
|||
assert new_code == "import os\nimport sys\nimport unittest\n"
|
||||
|
||||
|
||||
def test_sort_imports_without_formatting():
|
||||
def test_sort_imports_without_formatting(temp_dir):
|
||||
"""Test that imports are sorted when formatting is disabled and should_sort_imports is True."""
|
||||
with tempfile.NamedTemporaryFile() as tmp:
|
||||
tmp.write(b"import sys\nimport unittest\nimport os\n")
|
||||
tmp.flush()
|
||||
tmp_path = Path(tmp.name)
|
||||
temp_file = temp_dir / "test_file.py"
|
||||
temp_file.write_text("import sys\nimport unittest\nimport os\n")
|
||||
|
||||
new_code = format_code(formatter_cmds=["disabled"], path=tmp_path)
|
||||
assert new_code is not None
|
||||
new_code = sort_imports(new_code)
|
||||
assert new_code == "import os\nimport sys\nimport unittest\n"
|
||||
new_code = format_code(formatter_cmds=["disabled"], path=temp_file)
|
||||
assert new_code is not None
|
||||
new_code = sort_imports(new_code)
|
||||
assert new_code == "import os\nimport sys\nimport unittest\n"
|
||||
|
||||
|
||||
def test_dedup_and_sort_imports_deduplicates():
|
||||
|
|
@ -100,7 +103,7 @@ def foo():
|
|||
assert actual == expected
|
||||
|
||||
|
||||
def test_formatter_cmds_non_existent():
|
||||
def test_formatter_cmds_non_existent(temp_dir):
|
||||
"""Test that default formatter-cmds is used when it doesn't exist in the toml."""
|
||||
config_data = """
|
||||
[tool.codeflash]
|
||||
|
|
@ -109,24 +112,18 @@ tests-root = "tests"
|
|||
test-framework = "pytest"
|
||||
ignore-paths = []
|
||||
"""
|
||||
config_file = temp_dir / "config.toml"
|
||||
config_file.write_text(config_data)
|
||||
|
||||
with tempfile.NamedTemporaryFile(suffix=".toml", delete=False) as tmp:
|
||||
tmp.write(config_data.encode())
|
||||
tmp.flush()
|
||||
tmp_path = Path(tmp.name)
|
||||
|
||||
try:
|
||||
config, _ = parse_config_file(tmp_path)
|
||||
assert config["formatter_cmds"] == ["black $file"]
|
||||
finally:
|
||||
os.remove(tmp_path)
|
||||
config, _ = parse_config_file(config_file)
|
||||
assert config["formatter_cmds"] == ["black $file"]
|
||||
|
||||
try:
|
||||
import black
|
||||
except ImportError:
|
||||
pytest.skip("black is not installed")
|
||||
|
||||
original_code = b"""
|
||||
original_code = """
|
||||
import os
|
||||
import sys
|
||||
def foo():
|
||||
|
|
@ -136,23 +133,21 @@ import sys
|
|||
|
||||
|
||||
def foo():
|
||||
return os.path.join(sys.path[0], "bar")
|
||||
return os.path.join(sys.path[0], \"bar\")
|
||||
"""
|
||||
with tempfile.NamedTemporaryFile() as tmp:
|
||||
tmp.write(original_code)
|
||||
tmp.flush()
|
||||
tmp_path = tmp.name
|
||||
temp_file = temp_dir / "test_file.py"
|
||||
temp_file.write_text(original_code)
|
||||
|
||||
actual = format_code(formatter_cmds=["black $file"], path=Path(tmp_path))
|
||||
assert actual == expected
|
||||
actual = format_code(formatter_cmds=["black $file"], path=temp_file)
|
||||
assert actual == expected
|
||||
|
||||
|
||||
def test_formatter_black():
|
||||
def test_formatter_black(temp_dir):
|
||||
try:
|
||||
import black
|
||||
except ImportError:
|
||||
pytest.skip("black is not installed")
|
||||
original_code = b"""
|
||||
original_code = """
|
||||
import os
|
||||
import sys
|
||||
def foo():
|
||||
|
|
@ -162,23 +157,21 @@ import sys
|
|||
|
||||
|
||||
def foo():
|
||||
return os.path.join(sys.path[0], "bar")
|
||||
return os.path.join(sys.path[0], \"bar\")
|
||||
"""
|
||||
with tempfile.NamedTemporaryFile() as tmp:
|
||||
tmp.write(original_code)
|
||||
tmp.flush()
|
||||
tmp_path = tmp.name
|
||||
temp_file = temp_dir / "test_file.py"
|
||||
temp_file.write_text(original_code)
|
||||
|
||||
actual = format_code(formatter_cmds=["black $file"], path=Path(tmp_path))
|
||||
assert actual == expected
|
||||
actual = format_code(formatter_cmds=["black $file"], path=temp_file)
|
||||
assert actual == expected
|
||||
|
||||
|
||||
def test_formatter_ruff():
|
||||
def test_formatter_ruff(temp_dir):
|
||||
try:
|
||||
import ruff # type: ignore
|
||||
except ImportError:
|
||||
pytest.skip("ruff is not installed")
|
||||
original_code = b"""
|
||||
original_code = """
|
||||
import os
|
||||
import sys
|
||||
def foo():
|
||||
|
|
@ -188,32 +181,29 @@ import sys
|
|||
|
||||
|
||||
def foo():
|
||||
return os.path.join(sys.path[0], "bar")
|
||||
return os.path.join(sys.path[0], \"bar\")
|
||||
"""
|
||||
with tempfile.NamedTemporaryFile(suffix=".py") as tmp:
|
||||
tmp.write(original_code)
|
||||
tmp.flush()
|
||||
tmp_path = tmp.name
|
||||
temp_file = temp_dir / "test_file.py"
|
||||
temp_file.write_text(original_code)
|
||||
|
||||
actual = format_code(
|
||||
formatter_cmds=["ruff check --exit-zero --fix $file", "ruff format $file"], path=Path(tmp_path)
|
||||
)
|
||||
assert actual == expected
|
||||
actual = format_code(
|
||||
formatter_cmds=["ruff check --exit-zero --fix $file", "ruff format $file"], path=temp_file
|
||||
)
|
||||
assert actual == expected
|
||||
|
||||
|
||||
def test_formatter_error():
|
||||
def test_formatter_error(temp_dir):
|
||||
original_code = """
|
||||
import os
|
||||
import sys
|
||||
def foo():
|
||||
return os.path.join(sys.path[0], 'bar')"""
|
||||
expected = original_code
|
||||
with tempfile.NamedTemporaryFile("w") as tmp:
|
||||
tmp.write(original_code)
|
||||
tmp.flush()
|
||||
tmp_path = tmp.name
|
||||
with pytest.raises(FileNotFoundError):
|
||||
format_code(formatter_cmds=["exit 1"], path=Path(tmp_path))
|
||||
temp_file = temp_dir / "test_file.py"
|
||||
temp_file.write_text(original_code)
|
||||
|
||||
with pytest.raises(FileNotFoundError):
|
||||
format_code(formatter_cmds=["exit 1"], path=temp_file)
|
||||
|
||||
|
||||
def _run_formatting_test(source_code: str, should_content_change: bool, expected = None, optimized_function: str = ""):
|
||||
|
|
|
|||
|
|
@ -21,11 +21,15 @@ def test_function_eligible_for_optimization() -> None:
|
|||
return a**2
|
||||
"""
|
||||
functions_found = {}
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".py") as f:
|
||||
f.write(function)
|
||||
f.flush()
|
||||
functions_found = find_all_functions_in_file(Path(f.name))
|
||||
assert functions_found[Path(f.name)][0].function_name == "test_function_eligible_for_optimization"
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp_dir_path = Path(temp_dir)
|
||||
file_path = temp_dir_path / "test_function.py"
|
||||
|
||||
with file_path.open("w") as f:
|
||||
f.write(function)
|
||||
|
||||
functions_found = find_all_functions_in_file(file_path)
|
||||
assert functions_found[file_path][0].function_name == "test_function_eligible_for_optimization"
|
||||
|
||||
# Has no return statement
|
||||
function = """def test_function_not_eligible_for_optimization():
|
||||
|
|
@ -33,28 +37,40 @@ def test_function_eligible_for_optimization() -> None:
|
|||
print(a)
|
||||
"""
|
||||
functions_found = {}
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".py") as f:
|
||||
f.write(function)
|
||||
f.flush()
|
||||
functions_found = find_all_functions_in_file(Path(f.name))
|
||||
assert len(functions_found[Path(f.name)]) == 0
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp_dir_path = Path(temp_dir)
|
||||
file_path = temp_dir_path / "test_function.py"
|
||||
|
||||
with file_path.open("w") as f:
|
||||
f.write(function)
|
||||
|
||||
functions_found = find_all_functions_in_file(file_path)
|
||||
assert len(functions_found[file_path]) == 0
|
||||
|
||||
|
||||
# we want to trigger an error in the function discovery
|
||||
function = """def test_invalid_code():"""
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".py") as f:
|
||||
f.write(function)
|
||||
f.flush()
|
||||
functions_found = find_all_functions_in_file(Path(f.name))
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp_dir_path = Path(temp_dir)
|
||||
file_path = temp_dir_path / "test_function.py"
|
||||
|
||||
with file_path.open("w") as f:
|
||||
f.write(function)
|
||||
|
||||
functions_found = find_all_functions_in_file(file_path)
|
||||
assert functions_found == {}
|
||||
|
||||
|
||||
|
||||
|
||||
def test_find_top_level_function_or_method():
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".py") as f:
|
||||
f.write(
|
||||
"""def functionA():
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp_dir_path = Path(temp_dir)
|
||||
file_path = temp_dir_path / "test_function.py"
|
||||
|
||||
with file_path.open("w") as f:
|
||||
f.write(
|
||||
"""def functionA():
|
||||
def functionB():
|
||||
return 5
|
||||
class E:
|
||||
|
|
@ -76,42 +92,48 @@ class AirbyteEntrypoint(object):
|
|||
def non_classmethod_function(cls, name):
|
||||
return cls.name
|
||||
"""
|
||||
)
|
||||
f.flush()
|
||||
path_obj_name = Path(f.name)
|
||||
assert inspect_top_level_functions_or_methods(path_obj_name, "functionA").is_top_level
|
||||
assert not inspect_top_level_functions_or_methods(path_obj_name, "functionB").is_top_level
|
||||
assert inspect_top_level_functions_or_methods(path_obj_name, "functionC", class_name="A").is_top_level
|
||||
assert not inspect_top_level_functions_or_methods(path_obj_name, "functionD", class_name="A").is_top_level
|
||||
assert not inspect_top_level_functions_or_methods(path_obj_name, "functionF", class_name="E").is_top_level
|
||||
assert not inspect_top_level_functions_or_methods(path_obj_name, "functionA").has_args
|
||||
)
|
||||
|
||||
assert inspect_top_level_functions_or_methods(file_path, "functionA").is_top_level
|
||||
assert not inspect_top_level_functions_or_methods(file_path, "functionB").is_top_level
|
||||
assert inspect_top_level_functions_or_methods(file_path, "functionC", class_name="A").is_top_level
|
||||
assert not inspect_top_level_functions_or_methods(file_path, "functionD", class_name="A").is_top_level
|
||||
assert not inspect_top_level_functions_or_methods(file_path, "functionF", class_name="E").is_top_level
|
||||
assert not inspect_top_level_functions_or_methods(file_path, "functionA").has_args
|
||||
staticmethod_func = inspect_top_level_functions_or_methods(
|
||||
path_obj_name, "handle_record_counts", class_name=None, line_no=15
|
||||
file_path, "handle_record_counts", class_name=None, line_no=15
|
||||
)
|
||||
assert staticmethod_func.is_staticmethod
|
||||
assert staticmethod_func.staticmethod_class_name == "AirbyteEntrypoint"
|
||||
assert inspect_top_level_functions_or_methods(
|
||||
path_obj_name, "functionE", class_name="AirbyteEntrypoint"
|
||||
file_path, "functionE", class_name="AirbyteEntrypoint"
|
||||
).is_classmethod
|
||||
assert not inspect_top_level_functions_or_methods(
|
||||
path_obj_name, "non_classmethod_function", class_name="AirbyteEntrypoint"
|
||||
file_path, "non_classmethod_function", class_name="AirbyteEntrypoint"
|
||||
).is_top_level
|
||||
# needed because this will be traced with a class_name being passed
|
||||
|
||||
# we want to write invalid code to ensure that the function discovery does not crash
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".py") as f:
|
||||
f.write(
|
||||
"""def functionA():
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp_dir_path = Path(temp_dir)
|
||||
file_path = temp_dir_path / "test_function.py"
|
||||
|
||||
with file_path.open("w") as f:
|
||||
f.write(
|
||||
"""def functionA():
|
||||
"""
|
||||
)
|
||||
f.flush()
|
||||
path_obj_name = Path(f.name)
|
||||
assert not inspect_top_level_functions_or_methods(path_obj_name, "functionA")
|
||||
)
|
||||
|
||||
assert not inspect_top_level_functions_or_methods(file_path, "functionA")
|
||||
|
||||
def test_class_method_discovery():
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".py") as f:
|
||||
f.write(
|
||||
"""class A:
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp_dir_path = Path(temp_dir)
|
||||
file_path = temp_dir_path / "test_function.py"
|
||||
|
||||
with file_path.open("w") as f:
|
||||
f.write(
|
||||
"""class A:
|
||||
def functionA():
|
||||
return True
|
||||
def functionB():
|
||||
|
|
@ -123,21 +145,20 @@ class X:
|
|||
return False
|
||||
def functionA():
|
||||
return True"""
|
||||
)
|
||||
f.flush()
|
||||
)
|
||||
|
||||
test_config = TestConfig(
|
||||
tests_root="tests", project_root_path=".", test_framework="pytest", tests_project_rootdir=Path()
|
||||
)
|
||||
path_obj_name = Path(f.name)
|
||||
functions, functions_count, _ = get_functions_to_optimize(
|
||||
optimize_all=None,
|
||||
replay_test=None,
|
||||
file=path_obj_name,
|
||||
file=file_path,
|
||||
only_get_this_function="A.functionA",
|
||||
test_cfg=test_config,
|
||||
ignore_paths=[Path("/bruh/")],
|
||||
project_root=path_obj_name.parent,
|
||||
module_root=path_obj_name.parent,
|
||||
project_root=file_path.parent,
|
||||
module_root=file_path.parent,
|
||||
)
|
||||
assert len(functions) == 1
|
||||
for file in functions:
|
||||
|
|
@ -148,12 +169,12 @@ def functionA():
|
|||
functions, functions_count, _ = get_functions_to_optimize(
|
||||
optimize_all=None,
|
||||
replay_test=None,
|
||||
file=path_obj_name,
|
||||
file=file_path,
|
||||
only_get_this_function="X.functionA",
|
||||
test_cfg=test_config,
|
||||
ignore_paths=[Path("/bruh/")],
|
||||
project_root=path_obj_name.parent,
|
||||
module_root=path_obj_name.parent,
|
||||
project_root=file_path.parent,
|
||||
module_root=file_path.parent,
|
||||
)
|
||||
assert len(functions) == 1
|
||||
for file in functions:
|
||||
|
|
@ -164,12 +185,12 @@ def functionA():
|
|||
functions, functions_count, _ = get_functions_to_optimize(
|
||||
optimize_all=None,
|
||||
replay_test=None,
|
||||
file=path_obj_name,
|
||||
file=file_path,
|
||||
only_get_this_function="functionA",
|
||||
test_cfg=test_config,
|
||||
ignore_paths=[Path("/bruh/")],
|
||||
project_root=path_obj_name.parent,
|
||||
module_root=path_obj_name.parent,
|
||||
project_root=file_path.parent,
|
||||
module_root=file_path.parent,
|
||||
)
|
||||
assert len(functions) == 1
|
||||
for file in functions:
|
||||
|
|
@ -178,8 +199,12 @@ def functionA():
|
|||
|
||||
|
||||
def test_nested_function():
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".py") as f:
|
||||
f.write(
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp_dir_path = Path(temp_dir)
|
||||
file_path = temp_dir_path / "test_function.py"
|
||||
|
||||
with file_path.open("w") as f:
|
||||
f.write(
|
||||
"""
|
||||
import copy
|
||||
|
||||
|
|
@ -223,28 +248,31 @@ def propagate_attributes(
|
|||
traverse(source_node_id)
|
||||
return modified_nodes
|
||||
"""
|
||||
)
|
||||
f.flush()
|
||||
)
|
||||
|
||||
test_config = TestConfig(
|
||||
tests_root="tests", project_root_path=".", test_framework="pytest", tests_project_rootdir=Path()
|
||||
)
|
||||
path_obj_name = Path(f.name)
|
||||
functions, functions_count, _ = get_functions_to_optimize(
|
||||
optimize_all=None,
|
||||
replay_test=None,
|
||||
file=path_obj_name,
|
||||
file=file_path,
|
||||
test_cfg=test_config,
|
||||
only_get_this_function=None,
|
||||
ignore_paths=[Path("/bruh/")],
|
||||
project_root=path_obj_name.parent,
|
||||
module_root=path_obj_name.parent,
|
||||
project_root=file_path.parent,
|
||||
module_root=file_path.parent,
|
||||
)
|
||||
|
||||
assert len(functions) == 1
|
||||
assert functions_count == 1
|
||||
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".py") as f:
|
||||
f.write(
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp_dir_path = Path(temp_dir)
|
||||
file_path = temp_dir_path / "test_function.py"
|
||||
|
||||
with file_path.open("w") as f:
|
||||
f.write(
|
||||
"""
|
||||
def outer_function():
|
||||
def inner_function():
|
||||
|
|
@ -252,28 +280,31 @@ def outer_function():
|
|||
|
||||
return inner_function
|
||||
"""
|
||||
)
|
||||
f.flush()
|
||||
)
|
||||
|
||||
test_config = TestConfig(
|
||||
tests_root="tests", project_root_path=".", test_framework="pytest", tests_project_rootdir=Path()
|
||||
)
|
||||
path_obj_name = Path(f.name)
|
||||
functions, functions_count, _ = get_functions_to_optimize(
|
||||
optimize_all=None,
|
||||
replay_test=None,
|
||||
file=path_obj_name,
|
||||
file=file_path,
|
||||
test_cfg=test_config,
|
||||
only_get_this_function=None,
|
||||
ignore_paths=[Path("/bruh/")],
|
||||
project_root=path_obj_name.parent,
|
||||
module_root=path_obj_name.parent,
|
||||
project_root=file_path.parent,
|
||||
module_root=file_path.parent,
|
||||
)
|
||||
|
||||
assert len(functions) == 1
|
||||
assert functions_count == 1
|
||||
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".py") as f:
|
||||
f.write(
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp_dir_path = Path(temp_dir)
|
||||
file_path = temp_dir_path / "test_function.py"
|
||||
|
||||
with file_path.open("w") as f:
|
||||
f.write(
|
||||
"""
|
||||
def outer_function():
|
||||
def inner_function():
|
||||
|
|
@ -283,21 +314,20 @@ def outer_function():
|
|||
pass
|
||||
return inner_function, another_inner_function
|
||||
"""
|
||||
)
|
||||
f.flush()
|
||||
)
|
||||
|
||||
test_config = TestConfig(
|
||||
tests_root="tests", project_root_path=".", test_framework="pytest", tests_project_rootdir=Path()
|
||||
)
|
||||
path_obj_name = Path(f.name)
|
||||
functions, functions_count, _ = get_functions_to_optimize(
|
||||
optimize_all=None,
|
||||
replay_test=None,
|
||||
file=path_obj_name,
|
||||
file=file_path,
|
||||
test_cfg=test_config,
|
||||
only_get_this_function=None,
|
||||
ignore_paths=[Path("/bruh/")],
|
||||
project_root=path_obj_name.parent,
|
||||
module_root=path_obj_name.parent,
|
||||
project_root=file_path.parent,
|
||||
module_root=file_path.parent,
|
||||
)
|
||||
|
||||
assert len(functions) == 1
|
||||
|
|
|
|||
|
|
@ -3,13 +3,20 @@ import tempfile
|
|||
from codeflash.code_utils.code_extractor import get_code
|
||||
from codeflash.discovery.functions_to_optimize import FunctionToOptimize
|
||||
from codeflash.models.models import FunctionParent
|
||||
import pytest
|
||||
from pathlib import Path
|
||||
|
||||
@pytest.fixture
|
||||
def temp_dir():
|
||||
with tempfile.TemporaryDirectory() as tmpdirname:
|
||||
yield Path(tmpdirname)
|
||||
|
||||
|
||||
def test_get_code_function() -> None:
|
||||
def test_get_code_function(temp_dir: Path) -> None:
|
||||
code = """def test(self):
|
||||
return self._test"""
|
||||
|
||||
with tempfile.NamedTemporaryFile("w") as f:
|
||||
with (temp_dir / "temp_file.py").open(mode="w") as f:
|
||||
f.write(code)
|
||||
f.flush()
|
||||
|
||||
|
|
@ -18,14 +25,14 @@ def test_get_code_function() -> None:
|
|||
assert contextual_dunder_methods == set()
|
||||
|
||||
|
||||
def test_get_code_property() -> None:
|
||||
def test_get_code_property(temp_dir: Path) -> None:
|
||||
code = """class TestClass:
|
||||
def __init__(self):
|
||||
self._test = 5
|
||||
@property
|
||||
def test(self):
|
||||
return self._test"""
|
||||
with tempfile.NamedTemporaryFile("w") as f:
|
||||
with (temp_dir / "temp_file.py").open(mode="w") as f:
|
||||
f.write(code)
|
||||
f.flush()
|
||||
|
||||
|
|
@ -36,7 +43,7 @@ def test_get_code_property() -> None:
|
|||
assert contextual_dunder_methods == {("TestClass", "__init__")}
|
||||
|
||||
|
||||
def test_get_code_class() -> None:
|
||||
def test_get_code_class(temp_dir: Path) -> None:
|
||||
code = """
|
||||
class TestClass:
|
||||
def __init__(self):
|
||||
|
|
@ -54,7 +61,7 @@ class TestClass:
|
|||
@property
|
||||
def test(self):
|
||||
return self._test"""
|
||||
with tempfile.NamedTemporaryFile("w") as f:
|
||||
with (temp_dir / "temp_file.py").open(mode="w") as f:
|
||||
f.write(code)
|
||||
f.flush()
|
||||
|
||||
|
|
@ -65,7 +72,7 @@ class TestClass:
|
|||
assert contextual_dunder_methods == {("TestClass", "__init__")}
|
||||
|
||||
|
||||
def test_get_code_bubble_sort_class() -> None:
|
||||
def test_get_code_bubble_sort_class(temp_dir: Path) -> None:
|
||||
code = """
|
||||
def hi():
|
||||
pass
|
||||
|
|
@ -105,7 +112,7 @@ class BubbleSortClass:
|
|||
arr[j + 1] = temp
|
||||
return arr
|
||||
"""
|
||||
with tempfile.NamedTemporaryFile("w") as f:
|
||||
with (temp_dir / "temp_file.py").open(mode="w") as f:
|
||||
f.write(code)
|
||||
f.flush()
|
||||
|
||||
|
|
@ -116,7 +123,7 @@ class BubbleSortClass:
|
|||
assert contextual_dunder_methods == {("BubbleSortClass", "__init__"), ("BubbleSortClass", "__call__")}
|
||||
|
||||
|
||||
def test_get_code_indent() -> None:
|
||||
def test_get_code_indent(temp_dir: Path) -> None:
|
||||
code = """def hi():
|
||||
pass
|
||||
|
||||
|
|
@ -168,7 +175,7 @@ def non():
|
|||
def helper(self, arr, j):
|
||||
return arr[j] > arr[j + 1]
|
||||
"""
|
||||
with tempfile.NamedTemporaryFile("w") as f:
|
||||
with (temp_dir / "temp_file.py").open(mode="w") as f:
|
||||
f.write(code)
|
||||
f.flush()
|
||||
new_code, contextual_dunder_methods = get_code(
|
||||
|
|
@ -198,7 +205,7 @@ def non():
|
|||
def unsorter(self, arr):
|
||||
return shuffle(arr)
|
||||
"""
|
||||
with tempfile.NamedTemporaryFile("w") as f:
|
||||
with (temp_dir / "temp_file.py").open(mode="w") as f:
|
||||
f.write(code)
|
||||
f.flush()
|
||||
new_code, contextual_dunder_methods = get_code(
|
||||
|
|
@ -212,7 +219,7 @@ def non():
|
|||
assert contextual_dunder_methods == {("BubbleSortClass", "__init__"), ("BubbleSortClass", "__call__")}
|
||||
|
||||
|
||||
def test_get_code_multiline_class_def() -> None:
|
||||
def test_get_code_multiline_class_def(temp_dir: Path) -> None:
|
||||
code = """class StatementAssignmentVariableConstantMutable(
|
||||
StatementAssignmentVariableMixin, StatementAssignmentVariableConstantMutableBase
|
||||
):
|
||||
|
|
@ -235,7 +242,7 @@ def test_get_code_multiline_class_def() -> None:
|
|||
def computeStatement(self, trace_collection):
|
||||
return self, None, None
|
||||
"""
|
||||
with tempfile.NamedTemporaryFile("w") as f:
|
||||
with (temp_dir / "temp_file.py").open(mode="w") as f:
|
||||
f.write(code)
|
||||
f.flush()
|
||||
|
||||
|
|
@ -252,13 +259,13 @@ def test_get_code_multiline_class_def() -> None:
|
|||
assert contextual_dunder_methods == set()
|
||||
|
||||
|
||||
def test_get_code_dataclass_attribute():
|
||||
def test_get_code_dataclass_attribute(temp_dir: Path) -> None:
|
||||
code = """@dataclass
|
||||
class CustomDataClass:
|
||||
name: str = ""
|
||||
data: List[int] = field(default_factory=list)"""
|
||||
|
||||
with tempfile.NamedTemporaryFile("w") as f:
|
||||
with (temp_dir / "temp_file.py").open(mode="w") as f:
|
||||
f.write(code)
|
||||
f.flush()
|
||||
|
||||
|
|
@ -269,4 +276,4 @@ class CustomDataClass:
|
|||
[FunctionToOptimize("name", f.name, [FunctionParent("CustomDataClass", "ClassDef")])]
|
||||
)
|
||||
assert new_code is None
|
||||
assert contextual_dunder_methods == set()
|
||||
assert contextual_dunder_methods == set()
|
||||
|
|
@ -213,11 +213,12 @@ class _PersistentCache(Generic[_P, _R, _CacheBackendT]):
|
|||
lifespan=self.__duration__,
|
||||
)
|
||||
'''
|
||||
with tempfile.NamedTemporaryFile(mode="w") as f:
|
||||
f.write(code)
|
||||
f.flush()
|
||||
file_path = Path(f.name).resolve()
|
||||
project_root_path = file_path.parent.resolve()
|
||||
with tempfile.TemporaryDirectory() as tempdir:
|
||||
tempdir_path = Path(tempdir)
|
||||
file_path = (tempdir_path / "typed_code_helper.py").resolve()
|
||||
file_path.write_text(code, encoding="utf-8")
|
||||
project_root_path = tempdir_path.resolve()
|
||||
project_root_path = tempdir_path.resolve()
|
||||
function_to_optimize = FunctionToOptimize(
|
||||
function_name="__call__",
|
||||
file_path=file_path,
|
||||
|
|
@ -437,4 +438,4 @@ def sorter_deps(arr):
|
|||
code_context.helper_functions[0].fully_qualified_name
|
||||
== "code_to_optimize.bubble_sort_dep1_helper.dep1_comparer"
|
||||
)
|
||||
assert code_context.helper_functions[1].fully_qualified_name == "code_to_optimize.bubble_sort_dep2_swap.dep2_swap"
|
||||
assert code_context.helper_functions[1].fully_qualified_name == "code_to_optimize.bubble_sort_dep2_swap.dep2_swap"
|
||||
|
|
@ -123,7 +123,7 @@ def test_sort():
|
|||
assert new_test is not None
|
||||
assert new_test.replace('"', "'") == expected.format(
|
||||
module_path="code_to_optimize.tests.pytest.test_perfinjector_bubble_sort_results_temp",
|
||||
tmp_dir_path=get_run_tmp_file(Path("test_return_values")),
|
||||
tmp_dir_path=get_run_tmp_file(Path("test_return_values")).as_posix(),
|
||||
).replace('"', "'")
|
||||
|
||||
with test_path.open("w") as f:
|
||||
|
|
@ -276,16 +276,16 @@ def test_sort():
|
|||
fto = FunctionToOptimize(
|
||||
function_name="sorter", parents=[FunctionParent(name="BubbleSorter", type="ClassDef")], file_path=Path(fto_path)
|
||||
)
|
||||
with tempfile.NamedTemporaryFile(mode="w") as f:
|
||||
f.write(code)
|
||||
f.flush()
|
||||
with tempfile.TemporaryDirectory() as tmpdirname:
|
||||
tmp_test_path = Path(tmpdirname) / "test_class_method_behavior_results_temp.py"
|
||||
tmp_test_path.write_text(code, encoding="utf-8")
|
||||
|
||||
success, new_test = inject_profiling_into_existing_test(
|
||||
Path(f.name), [CodePosition(7, 13), CodePosition(12, 13)], fto, Path(f.name).parent, "pytest"
|
||||
tmp_test_path, [CodePosition(7, 13), CodePosition(12, 13)], fto, tmp_test_path.parent, "pytest"
|
||||
)
|
||||
assert success
|
||||
assert new_test.replace('"', "'") == expected.format(
|
||||
module_path=Path(f.name).name, tmp_dir_path=get_run_tmp_file(Path("test_return_values"))
|
||||
module_path=tmp_test_path.stem, tmp_dir_path=get_run_tmp_file(Path("test_return_values")).as_posix()
|
||||
).replace('"', "'")
|
||||
tests_root = (Path(__file__).parent.resolve() / "../code_to_optimize/tests/pytest/").resolve()
|
||||
test_path = tests_root / "test_class_method_behavior_results_temp.py"
|
||||
|
|
@ -295,7 +295,7 @@ def test_sort():
|
|||
try:
|
||||
new_test = expected.format(
|
||||
module_path="code_to_optimize.tests.pytest.test_class_method_behavior_results_temp",
|
||||
tmp_dir_path=get_run_tmp_file(Path("test_return_values")),
|
||||
tmp_dir_path=get_run_tmp_file(Path("test_return_values")).as_posix(),
|
||||
)
|
||||
|
||||
with test_path.open("w") as f:
|
||||
|
|
@ -486,4 +486,4 @@ class BubbleSorter:
|
|||
finally:
|
||||
fto_path.write_text(original_code, "utf-8")
|
||||
test_path.unlink(missing_ok=True)
|
||||
test_path_perf.unlink(missing_ok=True)
|
||||
test_path_perf.unlink(missing_ok=True)
|
||||
|
|
@ -22,7 +22,7 @@ from codeflash.verification.codeflash_capture import codeflash_capture
|
|||
|
||||
class MyClass:
|
||||
|
||||
@codeflash_capture(function_name='MyClass.__init__', tmp_dir_path='{get_run_tmp_file(Path("test_return_values"))!s}', tests_root='{test_path.parent!s}', is_fto=True)
|
||||
@codeflash_capture(function_name='MyClass.__init__', tmp_dir_path='{get_run_tmp_file(Path("test_return_values")).as_posix()}', tests_root='{test_path.parent.as_posix()}', is_fto=True)
|
||||
def __init__(self):
|
||||
self.x = 1
|
||||
|
||||
|
|
@ -86,7 +86,7 @@ from codeflash.verification.codeflash_capture import codeflash_capture
|
|||
|
||||
class MyClass(ParentClass):
|
||||
|
||||
@codeflash_capture(function_name='MyClass.__init__', tmp_dir_path='{get_run_tmp_file(Path("test_return_values"))!s}', tests_root='{test_path.parent!s}', is_fto=True)
|
||||
@codeflash_capture(function_name='MyClass.__init__', tmp_dir_path='{get_run_tmp_file(Path("test_return_values")).as_posix()}', tests_root='{test_path.parent.as_posix()}', is_fto=True)
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
|
|
@ -128,7 +128,7 @@ from codeflash.verification.codeflash_capture import codeflash_capture
|
|||
|
||||
class MyClass:
|
||||
|
||||
@codeflash_capture(function_name='MyClass.__init__', tmp_dir_path='{get_run_tmp_file(Path("test_return_values"))!s}', tests_root='{test_path.parent!s}', is_fto=True)
|
||||
@codeflash_capture(function_name='MyClass.__init__', tmp_dir_path='{get_run_tmp_file(Path("test_return_values")).as_posix()}', tests_root='{test_path.parent.as_posix()}', is_fto=True)
|
||||
def __init__(self):
|
||||
self.x = 1
|
||||
|
||||
|
|
@ -184,7 +184,7 @@ from codeflash.verification.codeflash_capture import codeflash_capture
|
|||
|
||||
class MyClass:
|
||||
|
||||
@codeflash_capture(function_name='MyClass.__init__', tmp_dir_path='{get_run_tmp_file(Path("test_return_values"))!s}', tests_root='{test_path.parent!s}', is_fto=True)
|
||||
@codeflash_capture(function_name='MyClass.__init__', tmp_dir_path='{get_run_tmp_file(Path("test_return_values")).as_posix()}', tests_root='{test_path.parent.as_posix()}', is_fto=True)
|
||||
def __init__(self):
|
||||
self.x = 1
|
||||
|
||||
|
|
@ -197,7 +197,7 @@ from codeflash.verification.codeflash_capture import codeflash_capture
|
|||
|
||||
class HelperClass:
|
||||
|
||||
@codeflash_capture(function_name='HelperClass.__init__', tmp_dir_path='{get_run_tmp_file(Path("test_return_values"))!s}', tests_root='{test_path.parent!s}', is_fto=False)
|
||||
@codeflash_capture(function_name='HelperClass.__init__', tmp_dir_path='{get_run_tmp_file(Path("test_return_values")).as_posix()}', tests_root='{test_path.parent.as_posix()}', is_fto=False)
|
||||
def __init__(self):
|
||||
self.y = 1
|
||||
|
||||
|
|
@ -271,7 +271,7 @@ from codeflash.verification.codeflash_capture import codeflash_capture
|
|||
|
||||
class MyClass:
|
||||
|
||||
@codeflash_capture(function_name='MyClass.__init__', tmp_dir_path='{get_run_tmp_file(Path("test_return_values"))!s}', tests_root='{test_path.parent!s}', is_fto=True)
|
||||
@codeflash_capture(function_name='MyClass.__init__', tmp_dir_path='{get_run_tmp_file(Path("test_return_values")).as_posix()}', tests_root='{test_path.parent.as_posix()}', is_fto=True)
|
||||
def __init__(self):
|
||||
self.x = 1
|
||||
|
||||
|
|
@ -289,7 +289,7 @@ 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"))!s}', tests_root='{test_path.parent!s}', is_fto=False)
|
||||
@codeflash_capture(function_name='HelperClass1.__init__', tmp_dir_path='{get_run_tmp_file(Path("test_return_values")).as_posix()}', tests_root='{test_path.parent.as_posix()}', is_fto=False)
|
||||
def __init__(self):
|
||||
self.y = 1
|
||||
|
||||
|
|
@ -304,7 +304,7 @@ 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"))!s}', tests_root='{test_path.parent!s}', is_fto=False)
|
||||
@codeflash_capture(function_name='HelperClass2.__init__', tmp_dir_path='{get_run_tmp_file(Path("test_return_values")).as_posix()}', tests_root='{test_path.parent.as_posix()}', is_fto=False)
|
||||
def __init__(self):
|
||||
self.z = 2
|
||||
|
||||
|
|
@ -313,7 +313,7 @@ class HelperClass2:
|
|||
|
||||
class AnotherHelperClass:
|
||||
|
||||
@codeflash_capture(function_name='AnotherHelperClass.__init__', tmp_dir_path='{get_run_tmp_file(Path("test_return_values"))!s}', tests_root='{test_path.parent!s}', is_fto=False)
|
||||
@codeflash_capture(function_name='AnotherHelperClass.__init__', tmp_dir_path='{get_run_tmp_file(Path("test_return_values")).as_posix()}', tests_root='{test_path.parent.as_posix()}', is_fto=False)
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
|
|
|
|||
|
|
@ -287,17 +287,25 @@ def test_run_and_parse_picklepatch() -> None:
|
|||
total_benchmark_timings = codeflash_benchmark_plugin.get_benchmark_timings(output_file)
|
||||
function_to_results = validate_and_format_benchmark_table(function_benchmark_timings, total_benchmark_timings)
|
||||
assert "code_to_optimize.bubble_sort_picklepatch_test_unused_socket.bubble_sort_with_unused_socket" in function_to_results
|
||||
|
||||
# Close the connection to allow file cleanup on Windows
|
||||
conn.close()
|
||||
|
||||
test_name, total_time, function_time, percent = function_to_results["code_to_optimize.bubble_sort_picklepatch_test_unused_socket.bubble_sort_with_unused_socket"][0]
|
||||
assert total_time > 0.0
|
||||
assert function_time > 0.0
|
||||
assert percent > 0.0
|
||||
|
||||
test_name, total_time, function_time, percent = \
|
||||
function_to_results["code_to_optimize.bubble_sort_picklepatch_test_unused_socket.bubble_sort_with_unused_socket"][0]
|
||||
assert total_time > 0.0
|
||||
assert function_time > 0.0
|
||||
assert percent > 0.0
|
||||
# Handle the case where function runs too fast to be measured
|
||||
unused_socket_results = function_to_results["code_to_optimize.bubble_sort_picklepatch_test_unused_socket.bubble_sort_with_unused_socket"]
|
||||
if unused_socket_results:
|
||||
test_name, total_time, function_time, percent = unused_socket_results[0]
|
||||
assert total_time >= 0.0
|
||||
# Function might be too fast, so we allow 0.0 function_time
|
||||
assert function_time >= 0.0
|
||||
assert percent >= 0.0
|
||||
used_socket_results = function_to_results["code_to_optimize.bubble_sort_picklepatch_test_used_socket.bubble_sort_with_used_socket"]
|
||||
# on windows , if the socket is not used we might not have resultssss
|
||||
if used_socket_results:
|
||||
test_name, total_time, function_time, percent = used_socket_results[0]
|
||||
assert total_time >= 0.0
|
||||
assert function_time >= 0.0
|
||||
assert percent >= 0.0
|
||||
|
||||
bubble_sort_unused_socket_path = (project_root / "code_to_optimize"/ "bubble_sort_picklepatch_test_unused_socket.py").as_posix()
|
||||
bubble_sort_used_socket_path = (project_root / "code_to_optimize" / "bubble_sort_picklepatch_test_used_socket.py").as_posix()
|
||||
|
|
@ -510,4 +518,3 @@ def bubble_sort_with_used_socket(data_container):
|
|||
shutil.rmtree(replay_tests_dir, ignore_errors=True)
|
||||
fto_unused_socket_path.write_text(original_fto_unused_socket_code)
|
||||
fto_used_socket_path.write_text(original_fto_used_socket_code)
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,12 @@ class TestReadApiKeyFromShellConfig(unittest.TestCase):
|
|||
self.test_rc_path = "test_shell_rc"
|
||||
self.api_key = "cf-1234567890abcdef"
|
||||
os.environ["SHELL"] = "/bin/bash" # Set a default shell for testing
|
||||
|
||||
# Set up platform-specific export syntax
|
||||
if os.name == "nt": # Windows
|
||||
self.api_key_export = f'set CODEFLASH_API_KEY={self.api_key}'
|
||||
else: # Unix-like systems
|
||||
self.api_key_export = f'export CODEFLASH_API_KEY="{self.api_key}"'
|
||||
|
||||
def tearDown(self):
|
||||
"""Cleanup the temporary shell configuration file after testing."""
|
||||
|
|
@ -50,7 +56,7 @@ class TestReadApiKeyFromShellConfig(unittest.TestCase):
|
|||
with patch("codeflash.code_utils.shell_utils.get_shell_rc_path") as mock_get_shell_rc_path:
|
||||
mock_get_shell_rc_path.return_value = self.test_rc_path
|
||||
with patch(
|
||||
"builtins.open", mock_open(read_data=f'export CODEFLASH_API_KEY="{self.api_key}"\n')
|
||||
"builtins.open", mock_open(read_data=f'{self.api_key_export}\n')
|
||||
) as mock_file:
|
||||
self.assertEqual(read_api_key_from_shell_config(), self.api_key)
|
||||
mock_file.assert_called_once_with(self.test_rc_path, encoding="utf8")
|
||||
|
|
@ -91,9 +97,15 @@ class TestReadApiKeyFromShellConfig(unittest.TestCase):
|
|||
def test_multiple_api_key_exports(self, mock_get_shell_rc_path):
|
||||
"""Test with multiple API key exports."""
|
||||
mock_get_shell_rc_path.return_value = self.test_rc_path
|
||||
if os.name == "nt": # Windows
|
||||
first_export = 'set CODEFLASH_API_KEY=cf-firstkey'
|
||||
second_export = f'set CODEFLASH_API_KEY={self.api_key}'
|
||||
else: # Unix-like systems
|
||||
first_export = 'export CODEFLASH_API_KEY="cf-firstkey"'
|
||||
second_export = f'export CODEFLASH_API_KEY="{self.api_key}"'
|
||||
with patch(
|
||||
"builtins.open",
|
||||
mock_open(read_data=f'export CODEFLASH_API_KEY="cf-firstkey"\nexport CODEFLASH_API_KEY="{self.api_key}"\n'),
|
||||
mock_open(read_data=f'{first_export}\n{second_export}\n'),
|
||||
):
|
||||
self.assertEqual(read_api_key_from_shell_config(), self.api_key)
|
||||
|
||||
|
|
@ -103,7 +115,7 @@ class TestReadApiKeyFromShellConfig(unittest.TestCase):
|
|||
mock_get_shell_rc_path.return_value = self.test_rc_path
|
||||
with patch(
|
||||
"builtins.open",
|
||||
mock_open(read_data=f'# Setting API Key\nexport CODEFLASH_API_KEY="{self.api_key}"\n# Done\n'),
|
||||
mock_open(read_data=f'# Setting API Key\n{self.api_key_export}\n# Done\n'),
|
||||
):
|
||||
self.assertEqual(read_api_key_from_shell_config(), self.api_key)
|
||||
|
||||
|
|
@ -111,7 +123,7 @@ class TestReadApiKeyFromShellConfig(unittest.TestCase):
|
|||
def test_api_key_in_comment(self, mock_get_shell_rc_path):
|
||||
"""Test with API key export in a comment."""
|
||||
mock_get_shell_rc_path.return_value = self.test_rc_path
|
||||
with patch("builtins.open", mock_open(read_data=f'# export CODEFLASH_API_KEY="{self.api_key}"\n')):
|
||||
with patch("builtins.open", mock_open(read_data=f'# {self.api_key_export}\n')):
|
||||
self.assertIsNone(read_api_key_from_shell_config())
|
||||
|
||||
@patch("codeflash.code_utils.shell_utils.get_shell_rc_path")
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ from codeflash.benchmarking.replay_test import get_next_arg_and_return
|
|||
from codeflash.picklepatch.pickle_patcher import PicklePatcher as pickle
|
||||
|
||||
functions = ['compute_and_sort', 'sorter']
|
||||
trace_file_path = r"{output_file}"
|
||||
trace_file_path = r"{output_file.as_posix()}"
|
||||
|
||||
def test_code_to_optimize_process_and_bubble_sort_codeflash_trace_compute_and_sort_test_compute_and_sort():
|
||||
for args_pkl, kwargs_pkl in get_next_arg_and_return(trace_file=trace_file_path, benchmark_function_name="test_compute_and_sort", function_name="compute_and_sort", file_path=r"{process_and_bubble_sort_path}", num_to_get=100):
|
||||
|
|
@ -196,6 +196,8 @@ def test_trace_multithreaded_benchmark() -> None:
|
|||
"SELECT function_name, class_name, module_name, file_path, benchmark_function_name, benchmark_module_path, benchmark_line_number FROM benchmark_function_timings ORDER BY benchmark_module_path, benchmark_function_name, function_name")
|
||||
function_calls = cursor.fetchall()
|
||||
|
||||
conn.close()
|
||||
|
||||
# Assert the length of function calls
|
||||
assert len(function_calls) == 10, f"Expected 10 function calls, but got {len(function_calls)}"
|
||||
function_benchmark_timings = codeflash_benchmark_plugin.get_function_benchmark_timings(output_file)
|
||||
|
|
@ -204,9 +206,9 @@ def test_trace_multithreaded_benchmark() -> None:
|
|||
assert "code_to_optimize.bubble_sort_codeflash_trace.sorter" in function_to_results
|
||||
|
||||
test_name, total_time, function_time, percent = function_to_results["code_to_optimize.bubble_sort_codeflash_trace.sorter"][0]
|
||||
assert total_time > 0.0
|
||||
assert function_time > 0.0
|
||||
assert percent > 0.0
|
||||
assert total_time >= 0.0
|
||||
assert function_time >= 0.0
|
||||
assert percent >= 0.0
|
||||
|
||||
bubble_sort_path = (project_root / "bubble_sort_codeflash_trace.py").as_posix()
|
||||
# Expected function calls
|
||||
|
|
|
|||
|
|
@ -72,8 +72,8 @@ class TestTracer:
|
|||
with tempfile.NamedTemporaryFile(mode="w", suffix=".toml", delete=False, dir=temp_dir) as f:
|
||||
f.write(f"""
|
||||
[tool.codeflash]
|
||||
module-root = "{current_dir}"
|
||||
tests-root = "{tests_dir}"
|
||||
module-root = "{current_dir.as_posix()}"
|
||||
tests-root = "{tests_dir.as_posix()}"
|
||||
test-framework = "pytest"
|
||||
ignore-paths = []
|
||||
""")
|
||||
|
|
|
|||
2
uv.lock
2
uv.lock
|
|
@ -246,7 +246,6 @@ dependencies = [
|
|||
|
||||
[package.dev-dependencies]
|
||||
dev = [
|
||||
{ name = "codeflash-benchmark" },
|
||||
{ name = "ipython", version = "8.18.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
|
||||
{ name = "ipython", version = "8.37.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" },
|
||||
{ name = "ipython", version = "9.4.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" },
|
||||
|
|
@ -306,7 +305,6 @@ requires-dist = [
|
|||
|
||||
[package.metadata.requires-dev]
|
||||
dev = [
|
||||
{ name = "codeflash-benchmark", editable = "codeflash-benchmark" },
|
||||
{ name = "ipython", specifier = ">=8.12.0" },
|
||||
{ name = "lxml-stubs", specifier = ">=0.5.1" },
|
||||
{ name = "mypy", specifier = ">=1.13" },
|
||||
|
|
|
|||
Loading…
Reference in a new issue