Skip to content

Commit d60c145

Browse files
fix: interactive template pick crashes on PromptSession pointer (#205)
* fix: drop unsupported pointer kwarg from template autocomplete questionary.autocomplete forwards unknown kwargs to PromptSession, which rejects pointer and crashes interactive template picking on uvx. Co-authored-by: Cursor <cursoragent@cursor.com> * test: pick autocomplete choice title from kwargs for ANSI-safe lookup Colored category badges make hard-coded titles fail under CI color settings. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 9e0e7e9 commit d60c145

2 files changed

Lines changed: 65 additions & 1 deletion

File tree

packages/create-awesome-python-app/src/create_awesome_python_app/cli.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,6 @@ def scaffold(
247247
choices=list(choice_by_title),
248248
match_middle=True,
249249
qmark="?",
250-
pointer=">",
251250
).ask()
252251
selected_template = choice_by_title.get(str(selected_title), selected_title)
253252
if selected_template == CUSTOM_TEMPLATE_SENTINEL:

packages/create-awesome-python-app/tests/test_interactive.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,71 @@ def test_in_ci_env(monkeypatch) -> None:
2828
os.environ.pop("CI", None)
2929

3030

31+
def test_interactive_template_autocomplete_omits_pointer(
32+
tmp_path: Path, monkeypatch
33+
) -> None:
34+
"""questionary.autocomplete rejects ``pointer`` (PromptSession TypeError)."""
35+
template_dir = tmp_path / "fastapi"
36+
template_dir.mkdir()
37+
(template_dir / "cpa.config.json").write_text(
38+
json.dumps({"name": "fastapi-starter"}),
39+
encoding="utf-8",
40+
)
41+
template_url = f"file://{template_dir}"
42+
catalog = {
43+
"categories": [{"slug": "backend-applications", "name": "Backend"}],
44+
"templates": [
45+
{
46+
"slug": "fastapi-starter",
47+
"name": "FastAPI Starter",
48+
"url": template_url,
49+
"type": "fastapi-backend",
50+
"category": "backend-applications",
51+
}
52+
],
53+
"extensions": [],
54+
}
55+
catalog_file = tmp_path / "templates.json"
56+
catalog_file.write_text(json.dumps(catalog), encoding="utf-8")
57+
monkeypatch.setenv("CPA_CATALOG_URL", f"file://{catalog_file}")
58+
monkeypatch.setenv("CPA_NO_CATALOG_CACHE", "1")
59+
monkeypatch.delenv("CI", raising=False)
60+
61+
captured_kwargs: dict[str, object] = {}
62+
63+
def fake_autocomplete(*_args, **kwargs):
64+
captured_kwargs.update(kwargs)
65+
choices = kwargs.get("choices") or []
66+
# Return a mapped title so choice_by_title resolves to the template URL.
67+
return FakePrompt(choices[0] if choices else template_url)
68+
69+
def fake_checkbox(*_args, **_kwargs):
70+
return FakePrompt([])
71+
72+
captured: dict[str, object] = {}
73+
74+
async def fake_create_python_app(project_directory, options, *_args, **_kwargs):
75+
captured["project_directory"] = project_directory
76+
captured["options"] = options
77+
78+
monkeypatch.setattr("questionary.autocomplete", fake_autocomplete)
79+
monkeypatch.setattr("questionary.checkbox", fake_checkbox)
80+
monkeypatch.setattr(
81+
"create_awesome_python_app.cli.create_python_app",
82+
fake_create_python_app,
83+
)
84+
monkeypatch.setattr(
85+
"create_awesome_python_app.cli.check_for_latest_version",
86+
fake_check_for_latest_version,
87+
)
88+
89+
result = runner.invoke(app, ["--interactive", "--no-install", "api"])
90+
91+
assert result.exit_code == 0, result.stdout + result.stderr
92+
assert "pointer" not in captured_kwargs
93+
assert captured["project_directory"] == "api"
94+
95+
3196
def test_interactive_extension_selection_passes_addon_urls(
3297
tmp_path: Path, monkeypatch
3398
) -> None:

0 commit comments

Comments
 (0)