From: John Mulligan Date: Sat, 9 Apr 2022 19:13:41 +0000 (-0400) Subject: pybind/mgr: add CommonFormatter type and valid_formats method X-Git-Tag: v17.2.1~48^2~11 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=da173dc090ea64121214003b7bd0ca3c51c111e9;p=ceph.git pybind/mgr: add CommonFormatter type and valid_formats method A type that has a valid_formats method, and thus meets the CommonFormatter protocol, supports distinguishing between formats that are known but unsupported for a given API vs. unknown (possibly a typo). To make working with the format names easier this also makes the Format enum inherit from str. Signed-off-by: John Mulligan (cherry picked from commit 77573637cd78e50d1336680a23fd1044d626f855) --- diff --git a/src/pybind/mgr/object_format.py b/src/pybind/mgr/object_format.py index 2dc0ecdabac65..0d2dbb439593e 100644 --- a/src/pybind/mgr/object_format.py +++ b/src/pybind/mgr/object_format.py @@ -8,6 +8,7 @@ import sys from typing import ( Any, Dict, + Iterable, Optional, TYPE_CHECKING, ) @@ -30,7 +31,7 @@ else: DEFAULT_JSON_INDENT: int = 2 -class Format(enum.Enum): +class Format(str, enum.Enum): plain = "plain" json = "json" json_pretty = "json-pretty" @@ -89,6 +90,16 @@ class ReturnValueProvider(Protocol): ... # pragma: no cover +class CommonFormatter(Protocol): + """A protocol that indicates the type is a formatter for multiple + possible formats. + """ + + def valid_formats(self) -> Iterable[str]: + """Return the names of known valid formats.""" + ... # pragma: no cover + + # The _is_name_of_protocol_type functions below are here because the production # builds of the ceph manager are lower than python 3.8 and do not have # typing_extensions available in the resulting images. This means that @@ -182,6 +193,12 @@ class ObjectFormatAdapter: """Return a YAML formatted string representing the input object.""" return yaml.safe_dump(self._fetch_yaml_data()) + format_json_pretty = format_json + + def valid_formats(self) -> Iterable[str]: + """Return valid format names.""" + return set(str(v) for v in Format.__members__) + class ReturnValueAdapter: """A return-value adapter for an object. diff --git a/src/pybind/mgr/tests/test_object_format.py b/src/pybind/mgr/tests/test_object_format.py index 5a1a4b5a227ca..6587955d49cbe 100644 --- a/src/pybind/mgr/tests/test_object_format.py +++ b/src/pybind/mgr/tests/test_object_format.py @@ -128,3 +128,12 @@ def test_return_value(obj: Any, ret: int): # a ReturnValueAdapter instance meets the ReturnValueProvider protocol. assert object_format._is_return_value_provider(rva) assert rva.mgr_return_value() == ret + + +def test_valid_formats(): + ofa = object_format.ObjectFormatAdapter({"fred": "wilma"}) + vf = ofa.valid_formats() + assert "json" in vf + assert "yaml" in vf + assert "xml" in vf + assert "plain" in vf