forked from platypush/platypush
More improvements to the inspect
plugin.
- Support for distinct `type` field on constructor and method arguments. - Added `has_varargs` field. - Added `required` field. - Better logic for parsing arguments `default` values.
This commit is contained in:
parent
9beb0a7af3
commit
4062ddbcf0
1 changed files with 38 additions and 9 deletions
|
@ -35,7 +35,7 @@ class Model:
|
||||||
]
|
]
|
||||||
|
|
||||||
_param_docstring_re = re.compile(r'^\s*:param ([^:]+):\s*(.*)')
|
_param_docstring_re = re.compile(r'^\s*:param ([^:]+):\s*(.*)')
|
||||||
_type_docstring_re = re.compile(r'^\s*:type ([^:]+):\s*(.*)')
|
_type_docstring_re = re.compile(r'^\s*:type ([^:]+):\s*([^\s]+).*')
|
||||||
_return_docstring_re = re.compile(r'^\s*:return:\s+(.*)')
|
_return_docstring_re = re.compile(r'^\s*:return:\s+(.*)')
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
@ -67,17 +67,39 @@ class Model:
|
||||||
self.doc, argsdoc = self._parse_docstring(docstring, obj_type=obj_type)
|
self.doc, argsdoc = self._parse_docstring(docstring, obj_type=obj_type)
|
||||||
self.args = {}
|
self.args = {}
|
||||||
self.has_kwargs = False
|
self.has_kwargs = False
|
||||||
|
self.has_varargs = False
|
||||||
|
|
||||||
for arg in list(inspect.signature(obj_type).parameters.values())[1:]:
|
for arg in list(inspect.signature(obj_type).parameters.values())[1:]:
|
||||||
if arg.kind == arg.VAR_KEYWORD:
|
if arg.kind == arg.VAR_KEYWORD:
|
||||||
self.has_kwargs = True
|
self.has_kwargs = True
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if arg.kind == arg.VAR_POSITIONAL:
|
||||||
|
self.has_varargs = True
|
||||||
|
continue
|
||||||
|
|
||||||
self.args[arg.name] = {
|
self.args[arg.name] = {
|
||||||
'default': arg.default
|
'default': (
|
||||||
if not issubclass(arg.default.__class__, type)
|
arg.default if not issubclass(arg.default.__class__, type) else None
|
||||||
else None,
|
),
|
||||||
'doc': argsdoc.get(arg.name),
|
'doc': argsdoc.get(arg.name, {}).get('name'),
|
||||||
|
'required': arg.default is inspect._empty,
|
||||||
|
'type': (
|
||||||
|
argsdoc.get(arg.name, {}).get('type')
|
||||||
|
or (
|
||||||
|
(
|
||||||
|
arg.annotation.__name__
|
||||||
|
if arg.annotation.__module__ == 'builtins'
|
||||||
|
else (
|
||||||
|
None
|
||||||
|
if arg.annotation is inspect._empty
|
||||||
|
else str(arg.annotation).replace('typing.', '')
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if arg.annotation
|
||||||
|
else None
|
||||||
|
)
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
@ -96,7 +118,7 @@ class Model:
|
||||||
"""
|
"""
|
||||||
Iterator for the model public attributes/values pairs.
|
Iterator for the model public attributes/values pairs.
|
||||||
"""
|
"""
|
||||||
for attr in ['name', 'args', 'doc', 'has_kwargs']:
|
for attr in ['name', 'args', 'doc', 'has_varargs', 'has_kwargs']:
|
||||||
yield attr, getattr(self, attr)
|
yield attr, getattr(self, attr)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -105,6 +127,7 @@ class Model:
|
||||||
params = {}
|
params = {}
|
||||||
cur_param = None
|
cur_param = None
|
||||||
cur_param_docstring = ''
|
cur_param_docstring = ''
|
||||||
|
param_types = {}
|
||||||
|
|
||||||
if not docstring:
|
if not docstring:
|
||||||
return None, {}
|
return None, {}
|
||||||
|
@ -122,7 +145,7 @@ class Model:
|
||||||
m = cls._type_docstring_re.match(line)
|
m = cls._type_docstring_re.match(line)
|
||||||
if m:
|
if m:
|
||||||
if cur_param:
|
if cur_param:
|
||||||
cur_param_docstring += '\n**Type:** ' + m.group(2).strip()
|
param_types[cur_param] = m.group(2).strip()
|
||||||
params[cur_param] = cur_param_docstring
|
params[cur_param] = cur_param_docstring
|
||||||
|
|
||||||
cur_param = None
|
cur_param = None
|
||||||
|
@ -151,7 +174,13 @@ class Model:
|
||||||
params[cur_param] = cur_param_docstring
|
params[cur_param] = cur_param_docstring
|
||||||
|
|
||||||
for param, doc in params.items():
|
for param, doc in params.items():
|
||||||
params[param] = cls._post_process_docstring(doc, obj_type=obj_type)
|
params[param] = {
|
||||||
|
'name': cls._post_process_docstring(doc, obj_type=obj_type)
|
||||||
|
}
|
||||||
|
|
||||||
|
param_type = param_types.pop(param, None)
|
||||||
|
if param_type is not None:
|
||||||
|
params[param]['type'] = param_type
|
||||||
|
|
||||||
return cls._post_process_docstring(new_docstring, obj_type=obj_type), params
|
return cls._post_process_docstring(new_docstring, obj_type=obj_type), params
|
||||||
|
|
||||||
|
@ -197,7 +226,7 @@ class PluginModel(Model):
|
||||||
Overrides the default implementation of ``__iter__`` to also include
|
Overrides the default implementation of ``__iter__`` to also include
|
||||||
plugin actions.
|
plugin actions.
|
||||||
"""
|
"""
|
||||||
for attr in ['name', 'args', 'actions', 'doc', 'has_kwargs']:
|
for attr in ['name', 'args', 'actions', 'doc', 'has_varargs', 'has_kwargs']:
|
||||||
if attr == 'actions':
|
if attr == 'actions':
|
||||||
yield attr, {
|
yield attr, {
|
||||||
name: dict(action) for name, action in self.actions.items()
|
name: dict(action) for name, action in self.actions.items()
|
||||||
|
|
Loading…
Reference in a new issue