config: annotate ServerArgs fields with their runtime-config namespace (#31809)
This commit is contained in:
@@ -82,6 +82,43 @@ class Arg:
|
||||
resolvable: bool = False
|
||||
|
||||
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class NS:
|
||||
"""Namespace-path marker for a ServerArgs field, attached alongside the
|
||||
field's metadata in ``Annotated``:
|
||||
|
||||
field: A[int, "help", NS("parallel")] = 1
|
||||
field: A[str, Arg(help="…"), NS("exec.moe")] = "auto"
|
||||
|
||||
Kept separate from ``Arg`` (CLI metadata) so the ~400 existing bare-string /
|
||||
multiline field annotations gain a namespace by *appending* one element,
|
||||
without rewriting each ``Arg(...)`` call. ``namespace_of`` reads it to build
|
||||
the RuntimeContext config-bag tree."""
|
||||
|
||||
path: str
|
||||
|
||||
|
||||
@functools.lru_cache(maxsize=None)
|
||||
def namespace_of(cls) -> dict:
|
||||
"""``{field_name: dotted namespace path}`` from the ``NS`` marker in each
|
||||
field's ``Annotated`` metadata.
|
||||
|
||||
Fields without an ``NS`` marker are absent from the map (the coverage lint
|
||||
flags them). Non-dataclass types yield an empty map."""
|
||||
if not dataclasses.is_dataclass(cls):
|
||||
return {}
|
||||
hints = get_type_hints(cls, include_extras=True)
|
||||
out = {}
|
||||
for field in dataclasses.fields(cls):
|
||||
tp = hints.get(field.name, field.type)
|
||||
if get_origin(tp) is Annotated:
|
||||
for a in get_args(tp)[1:]:
|
||||
if isinstance(a, NS):
|
||||
out[field.name] = a.path
|
||||
break
|
||||
return out
|
||||
|
||||
|
||||
@functools.lru_cache(maxsize=None)
|
||||
def resolvable_fields(cls) -> frozenset:
|
||||
"""Names of ``cls`` dataclass fields whose ``Arg`` metadata declares
|
||||
|
||||
+523
-142
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user