mirror of
https://github.com/Comfy-Org/ComfyUI.git
synced 2026-08-26 02:42:36 +08:00
--feature-flag: strict bool coercion + drop invalid values
Per @rattus128 review on PR #13685: silently coercing typo'd bool values (e.g. `--feature-flag show_signin_button=ture`) to `False` was a confusing UX. Make bool coercion strict and drop unparseable flags entirely. - `_coerce_bool`: accept only `true`/`false` (case-insensitive); raise `ValueError` for anything else (`ture`, `yes`, `1`, ``). - `_coerce_flag_value`: no longer swallows exceptions; raises on bad coercion so the caller decides what to do. - `_parse_cli_feature_flags`: catches `ValueError`/`TypeError`, logs a warning ("dropping flag"), and omits the flag from the result. ComfyUI still starts; `SERVER_FEATURE_FLAGS` retains the registered default; other valid `--feature-flag` entries on the same command line are unaffected. Tests: - `test_bool_typo_raises`: `ture`/`yes`/`1`/`""` all raise ValueError. - `test_failed_int_coercion_raises`: replaces the old "falls back to string" test now that coercion failures propagate. - `test_invalid_bool_value_dropped`: parser drops the bad flag and logs a warning, while a valid sibling flag still parses. 19/19 unit tests pass. Co-authored-by: Amp <amp@ampcode.com> Amp-Thread-ID: https://ampcode.com/threads/T-019df5a8-36be-7107-a4af-c7e4f51687df
This commit is contained in:
@@ -28,8 +28,22 @@ CLI_FEATURE_FLAG_REGISTRY: dict[str, FeatureFlagInfo] = {
|
||||
}
|
||||
|
||||
|
||||
def _coerce_bool(v: str) -> bool:
|
||||
"""Strict bool coercion: only 'true'/'false' (case-insensitive).
|
||||
|
||||
Anything else raises ValueError so the caller can warn and drop the flag,
|
||||
rather than silently treating typos like 'ture' or 'yes' as False.
|
||||
"""
|
||||
lower = v.lower()
|
||||
if lower == "true":
|
||||
return True
|
||||
if lower == "false":
|
||||
return False
|
||||
raise ValueError(f"expected 'true' or 'false', got {v!r}")
|
||||
|
||||
|
||||
_COERCE_FNS: dict[str, Any] = {
|
||||
"bool": lambda v: v.lower() == "true",
|
||||
"bool": _coerce_bool,
|
||||
"int": lambda v: int(v),
|
||||
"float": lambda v: float(v),
|
||||
}
|
||||
@@ -38,8 +52,9 @@ _COERCE_FNS: dict[str, Any] = {
|
||||
def _coerce_flag_value(key: str, raw_value: str) -> Any:
|
||||
"""Coerce a raw string value using the registry type, or keep as string.
|
||||
|
||||
Returns the raw string if the key is unregistered, the type is unknown,
|
||||
or coercion fails (with a warning logged in the failure case).
|
||||
Returns the raw string if the key is unregistered or the type is unknown.
|
||||
Raises ValueError/TypeError if the key is registered with a known type but
|
||||
the value cannot be coerced; callers are expected to warn and drop the flag.
|
||||
"""
|
||||
info = CLI_FEATURE_FLAG_REGISTRY.get(key)
|
||||
if info is None:
|
||||
@@ -47,20 +62,16 @@ def _coerce_flag_value(key: str, raw_value: str) -> Any:
|
||||
coerce = _COERCE_FNS.get(info["type"])
|
||||
if coerce is None:
|
||||
return raw_value
|
||||
try:
|
||||
return coerce(raw_value)
|
||||
except (ValueError, TypeError):
|
||||
logging.warning(
|
||||
"Could not coerce --feature-flag %s=%r to %s; using raw string.",
|
||||
key, raw_value, info["type"],
|
||||
)
|
||||
return raw_value
|
||||
return coerce(raw_value)
|
||||
|
||||
|
||||
def _parse_cli_feature_flags() -> dict[str, Any]:
|
||||
"""Parse --feature-flag key=value pairs from CLI args into a dict.
|
||||
|
||||
Items without '=' default to the value 'true' (bare flag form).
|
||||
Flags whose value cannot be coerced to the registered type are dropped
|
||||
with a warning, so a typo like '--feature-flag some_bool=ture' does not
|
||||
silently take effect as the wrong value.
|
||||
"""
|
||||
result: dict[str, Any] = {}
|
||||
for item in getattr(args, "feature_flag", []):
|
||||
@@ -70,7 +81,14 @@ def _parse_cli_feature_flags() -> dict[str, Any]:
|
||||
continue
|
||||
if not sep:
|
||||
raw_value = "true"
|
||||
result[key] = _coerce_flag_value(key, raw_value.strip())
|
||||
try:
|
||||
result[key] = _coerce_flag_value(key, raw_value.strip())
|
||||
except (ValueError, TypeError) as e:
|
||||
info = CLI_FEATURE_FLAG_REGISTRY.get(key, {})
|
||||
logging.warning(
|
||||
"Could not coerce --feature-flag %s=%r to %s (%s); dropping flag.",
|
||||
key, raw_value.strip(), info.get("type", "?"), e,
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user