From e2c850eb173423382d34d16bb5e1863e7a45e8a1 Mon Sep 17 00:00:00 2001 From: Yijia-Xiao Date: Sun, 10 May 2026 19:29:41 +0000 Subject: [PATCH] fix(cli): preserve exchange suffixes in ticker prompt The typer.prompt-based input could lose .SH/.SZ/.SS/.HK suffixes on some shells, so exchange-qualified tickers like 000404.SH arrived truncated to 000404 and failed downstream lookups. Switch to questionary.text which reads the raw line; keep SPY-on-empty behavior and validate the allowed character set (alnum, ._-^) up to 32 chars. #770 --- cli/main.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/cli/main.py b/cli/main.py index 42794821d..ecfc63d59 100644 --- a/cli/main.py +++ b/cli/main.py @@ -1,6 +1,7 @@ from typing import Optional import datetime import typer +import questionary from pathlib import Path from functools import wraps from rich.console import Console @@ -615,8 +616,26 @@ def get_user_selections(): def get_ticker(): - """Get ticker symbol from user input.""" - return typer.prompt("", default="SPY") + """Get ticker symbol from user input, preserving exchange suffixes.""" + # typer.prompt strips trailing dot-suffixes on some shells (e.g. 000404.SH + # collapses to 000404). questionary.text reads the raw line. + ticker = questionary.text( + "", + validate=lambda value: ( + not value.strip() + or ( + all(ch.isalnum() or ch in "._-^" for ch in value.strip()) + and len(value.strip()) <= 32 + ) + ) + or "Please enter a valid ticker symbol, e.g. AAPL, 000404.SZ, 0700.HK.", + ).ask() + + if ticker is None: + console.print("\n[red]No ticker symbol provided. Exiting...[/red]") + raise typer.Exit(1) + + return (ticker.strip() or "SPY").upper() def get_analysis_date():