Skip to content
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
8 changes: 7 additions & 1 deletion lean/components/util/name_extraction.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,10 @@ def convert_to_class_name(file_path: Path):
:return: returns a valid class name
"""
from re import sub
return sub(f"[^a-zA-Z0-9]", "", "".join(map(_capitalize, file_path.name.split(" "))))
class_name = sub(f"[^a-zA-Z0-9]", "", "".join(map(_capitalize, file_path.name.split(" "))))

# An identifier cannot be empty or start with a digit
if class_name == "" or class_name[0].isdigit():
class_name = "_" + class_name

return class_name
16 changes: 16 additions & 0 deletions tests/commands/test_create_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,22 @@ def test_create_project_preserves_capitals_in_class_name() -> None:
assert "class MyFIRSTProject(QCAlgorithm)" in file.read()


@pytest.mark.parametrize("name,class_name", [("2024 momentum", "_2024Momentum"),
("123", "_123")])
def test_create_project_creates_valid_class_name_when_name_starts_with_digit(name: str, class_name: str) -> None:
create_fake_lean_cli_directory()

result = CliRunner().invoke(lean, ["create-project", "--language", "python", name])

assert result.exit_code == 0

with open(Path.cwd() / name / "main.py") as file:
content = file.read()

assert f"class {class_name}(QCAlgorithm)" in content
compile(content, "main.py", "exec")


def test_create_project_aborts_when_path_invalid() -> None:
create_fake_lean_cli_directory()

Expand Down