Skip to content

Commit 9476907

Browse files
authored
Merge pull request ceph#45467 from phlogistonjohn/jjm-format-exp2
A module and decorator for generically handling format= in python mgr modules Reviewed-by: Adam King <[email protected]> Reviewed-by: Ernesto Puerta <[email protected]> Reviewed-by: Redouane Kachach <[email protected]>
2 parents 54cdc1d + 4904b02 commit 9476907

File tree

7 files changed

+990
-14
lines changed

7 files changed

+990
-14
lines changed

.github/labeler.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ mgr:
5454
- src/pybind/mgr/ceph_module.pyi
5555
- src/pybind/mgr/mgr_module.py
5656
- src/pybind/mgr/mgr_util.py
57+
- src/pybind/mgr/object_format.py
5758
- src/pybind/mgr/requirements.txt
5859
- src/pybind/mgr/tox.ini
5960
- src/test/mgr/**

ceph.spec.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1738,6 +1738,7 @@ fi
17381738
%dir %{_datadir}/ceph/mgr
17391739
%{_datadir}/ceph/mgr/mgr_module.*
17401740
%{_datadir}/ceph/mgr/mgr_util.*
1741+
%{_datadir}/ceph/mgr/object_format.*
17411742
%{_unitdir}/[email protected]
17421743
%{_unitdir}/ceph-mgr.target
17431744
%attr(750,ceph,ceph) %dir %{_localstatedir}/lib/ceph/mgr

src/pybind/mgr/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,5 @@ set(mgr_modules
5858
install(DIRECTORY ${mgr_modules}
5959
DESTINATION ${CEPH_INSTALL_DATADIR}/mgr
6060
${mgr_module_install_excludes})
61-
install(FILES mgr_module.py mgr_util.py
61+
install(FILES mgr_module.py mgr_util.py object_format.py
6262
DESTINATION ${CEPH_INSTALL_DATADIR}/mgr)

src/pybind/mgr/mgr_module.py

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,26 @@ def device_class_counts(self) -> Dict[str, int]:
329329

330330
HandlerFuncType = Callable[..., Tuple[int, str, str]]
331331

332+
def _extract_target_func(
333+
f: HandlerFuncType
334+
) -> Tuple[HandlerFuncType, Dict[str, Any]]:
335+
"""In order to interoperate with other decorated functions,
336+
we need to find the original function which will provide
337+
the main set of arguments. While we descend through the
338+
stack of wrapped functions, gather additional arguments
339+
the decorators may want to provide.
340+
"""
341+
# use getattr to keep mypy happy
342+
wrapped = getattr(f, "__wrapped__", None)
343+
if not wrapped:
344+
return f, {}
345+
extra_args = {}
346+
while wrapped is not None:
347+
extra_args.update(getattr(f, "extra_args", {}))
348+
f = wrapped
349+
wrapped = getattr(f, "__wrapped__", None)
350+
return f, extra_args
351+
332352

333353
class CLICommand(object):
334354
COMMANDS = {} # type: Dict[str, CLICommand]
@@ -346,8 +366,9 @@ def __init__(self,
346366

347367
KNOWN_ARGS = '_', 'self', 'mgr', 'inbuf', 'return'
348368

349-
@staticmethod
350-
def load_func_metadata(f: HandlerFuncType) -> Tuple[str, Dict[str, Any], int, str]:
369+
@classmethod
370+
def _load_func_metadata(cls: Any, f: HandlerFuncType) -> Tuple[str, Dict[str, Any], int, str]:
371+
f, extra_args = _extract_target_func(f)
351372
desc = (inspect.getdoc(f) or '').replace('\n', ' ')
352373
full_argspec = inspect.getfullargspec(f)
353374
arg_spec = full_argspec.annotations
@@ -357,7 +378,7 @@ def load_func_metadata(f: HandlerFuncType) -> Tuple[str, Dict[str, Any], int, st
357378
args = []
358379
positional = True
359380
for index, arg in enumerate(full_argspec.args):
360-
if arg in CLICommand.KNOWN_ARGS:
381+
if arg in cls.KNOWN_ARGS:
361382
continue
362383
if arg == '_end_positional_':
363384
positional = False
@@ -377,11 +398,19 @@ def load_func_metadata(f: HandlerFuncType) -> Tuple[str, Dict[str, Any], int, st
377398
dict(name=arg),
378399
has_default,
379400
positional))
401+
for argname, argtype in extra_args.items():
402+
# avoid shadowing args from the function
403+
if argname in arg_spec:
404+
continue
405+
arg_spec[argname] = argtype
406+
args.append(CephArgtype.to_argdesc(
407+
argtype, dict(name=arg), has_default=True, positional=False
408+
))
380409
return desc, arg_spec, first_default, ' '.join(args)
381410

382411
def store_func_metadata(self, f: HandlerFuncType) -> None:
383412
self.desc, self.arg_spec, self.first_default, self.args = \
384-
self.load_func_metadata(f)
413+
self._load_func_metadata(f)
385414

386415
def __call__(self, func: HandlerFuncType) -> HandlerFuncType:
387416
self.store_func_metadata(func)

0 commit comments

Comments
 (0)