Skip to content

Commit 48b4596

Browse files
refactor: improve type safety in CLI output handling
Add OutputData TypedDict for CLI output data structure. Replace generic dict[str, Any] with typed OutputData. Changes: - vcs-versioning/src/vcs_versioning/_cli/__init__.py: - Add OutputData TypedDict extending ConfigOverridesDict - Replace MutableMapping[str, Any] with OutputData in print functions - Add type: ignore for dynamic attribute access - Add assertions and map(str, ...) for proper type handling - Better type hints throughout
1 parent 1ad7935 commit 48b4596

File tree

1 file changed

+18
-9
lines changed

1 file changed

+18
-9
lines changed

vcs-versioning/src/vcs_versioning/_cli/__init__.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
import json
44
import os
55
import sys
6-
from collections.abc import MutableMapping
6+
from collections.abc import Iterable
77
from importlib.resources import files
88
from pathlib import Path
9-
from typing import Any
9+
from typing import TypedDict
10+
11+
from vcs_versioning._overrides import ConfigOverridesDict
1012

1113
from .. import _discover as discover
1214
from .._config import Configuration
@@ -15,6 +17,12 @@
1517
from ._args import CliNamespace, get_cli_parser
1618

1719

20+
class OutputData(TypedDict, ConfigOverridesDict, total=False):
21+
version: str
22+
files: list[str]
23+
queries: list[str]
24+
25+
1826
def _get_version_for_cli(config: Configuration, opts: CliNamespace) -> str:
1927
"""Get version string for CLI output, handling special cases and exceptions."""
2028
if opts.no_version:
@@ -68,7 +76,7 @@ def main(
6876

6977
# flake8: noqa: C901
7078
def command(opts: CliNamespace, version: str, config: Configuration) -> int:
71-
data: dict[str, Any] = {}
79+
data: OutputData = {}
7280

7381
if opts.command == "ls":
7482
opts.query = ["files"]
@@ -100,7 +108,7 @@ def command(opts: CliNamespace, version: str, config: Configuration) -> int:
100108
try:
101109
if q.startswith("_"):
102110
raise AttributeError()
103-
data[q] = getattr(config, q)
111+
data[q] = getattr(config, q) # type: ignore[literal-required]
104112
except AttributeError:
105113
sys.stderr.write(f"Error: unknown query: '{q}'\n")
106114
return 1
@@ -110,11 +118,11 @@ def command(opts: CliNamespace, version: str, config: Configuration) -> int:
110118
return 0
111119

112120

113-
def print_json(data: MutableMapping[str, Any]) -> None:
121+
def print_json(data: OutputData) -> None:
114122
print(json.dumps(data, indent=2))
115123

116124

117-
def print_plain(data: MutableMapping[str, Any]) -> None:
125+
def print_plain(data: OutputData) -> None:
118126
version = data.pop("version", None)
119127
if version:
120128
print(version)
@@ -125,15 +133,16 @@ def print_plain(data: MutableMapping[str, Any]) -> None:
125133
for query in queries:
126134
print(query)
127135
if data:
128-
print("\n".join(data.values()))
136+
print("\n".join(map(str, data.values())))
129137

130138

131-
def print_key_value(data: MutableMapping[str, Any]) -> None:
139+
def print_key_value(data: OutputData) -> None:
132140
for key, value in data.items():
133141
if isinstance(value, str):
134142
print(f"{key} = {value}")
135143
else:
136-
str_value = "\n ".join(value)
144+
assert isinstance(value, Iterable)
145+
str_value = "\n ".join(map(str, value))
137146
print(f"{key} = {str_value}")
138147

139148

0 commit comments

Comments
 (0)