From 8af5cdf6a41e7a44f6a0116d59af9621b42c64e1 Mon Sep 17 00:00:00 2001 From: Amadeus Date: Tue, 6 Oct 2026 15:01:23 -0300 Subject: [PATCH] bug: generate a valid class name when the project name starts with a digit convert_to_class_name only removed non-alphanumeric characters, so a project called '2024 Momentum' got 'class 2024Momentum', which does not compile. Prefix the name with an underscore when it is empty or starts with a digit. Co-Authored-By: Claude Opus 5.5 --- lean/components/util/name_extraction.py | 8 +++++++- tests/commands/test_create_project.py | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/lean/components/util/name_extraction.py b/lean/components/util/name_extraction.py index 4c058e86d..2ccfee31c 100644 --- a/lean/components/util/name_extraction.py +++ b/lean/components/util/name_extraction.py @@ -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 diff --git a/tests/commands/test_create_project.py b/tests/commands/test_create_project.py index bc27c93fa..a1c42f8af 100644 --- a/tests/commands/test_create_project.py +++ b/tests/commands/test_create_project.py @@ -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()