From a7aabd7c52256dfe3ef246eb9d1be70029b31711 Mon Sep 17 00:00:00 2001 From: Fabio Manganiello Date: Mon, 22 May 2023 16:32:30 +0200 Subject: [PATCH] Fixed handling of `:meth:` docstring annotations with relative paths. --- platypush/plugins/inspect/_model.py | 19 ++++--- .../plugins/inspect/_parsers/__init__.py | 2 + .../plugins/inspect/_parsers/_backend.py | 2 +- platypush/plugins/inspect/_parsers/_base.py | 2 +- platypush/plugins/inspect/_parsers/_event.py | 2 +- platypush/plugins/inspect/_parsers/_method.py | 55 ++++++++++++++----- platypush/plugins/inspect/_parsers/_plugin.py | 2 +- .../plugins/inspect/_parsers/_response.py | 2 +- platypush/plugins/inspect/_parsers/_schema.py | 2 +- platypush/plugins/sensor/__init__.py | 2 +- 10 files changed, 61 insertions(+), 29 deletions(-) diff --git a/platypush/plugins/inspect/_model.py b/platypush/plugins/inspect/_model.py index 31bd55bd48..d0ea558255 100644 --- a/platypush/plugins/inspect/_model.py +++ b/platypush/plugins/inspect/_model.py @@ -1,7 +1,7 @@ import inspect import json import re -from typing import Callable, Optional, Type +from typing import Callable, List, Optional, Type from platypush.backend import Backend from platypush.message.event import Event @@ -13,6 +13,7 @@ from ._parsers import ( BackendParser, EventParser, MethodParser, + Parser, PluginParser, ResponseParser, SchemaParser, @@ -24,7 +25,7 @@ class Model: Base class for component models. """ - _parsers = [ + _parsers: List[Type[Parser]] = [ BackendParser, EventParser, MethodParser, @@ -51,7 +52,9 @@ class Model: self.package = obj_type.__module__[len(prefix) :] self.name = name or self.package self.last_modified = last_modified - self.doc, argsdoc = self._parse_docstring(doc or obj_type.__doc__ or '') + self.doc, argsdoc = self._parse_docstring( + doc or obj_type.__doc__ or '', obj_type=obj_type + ) self.args = {} self.has_kwargs = False @@ -87,7 +90,7 @@ class Model: yield attr, getattr(self, attr) @classmethod - def _parse_docstring(cls, docstring: str): + def _parse_docstring(cls, docstring: str, obj_type: type): new_docstring = '' params = {} cur_param = None @@ -129,14 +132,14 @@ class Model: params[cur_param] = cur_param_docstring for param, doc in params.items(): - params[param] = cls._post_process_docstring(doc) + params[param] = cls._post_process_docstring(doc, obj_type=obj_type) - return cls._post_process_docstring(new_docstring), params + return cls._post_process_docstring(new_docstring, obj_type=obj_type), params @classmethod - def _post_process_docstring(cls, docstring: str) -> str: + def _post_process_docstring(cls, docstring: str, obj_type: type) -> str: for parsers in cls._parsers: - docstring = parsers.parse(docstring) + docstring = parsers.parse(docstring, obj_type=obj_type) return docstring.strip() diff --git a/platypush/plugins/inspect/_parsers/__init__.py b/platypush/plugins/inspect/_parsers/__init__.py index 9c74b8bcce..82879cddf1 100644 --- a/platypush/plugins/inspect/_parsers/__init__.py +++ b/platypush/plugins/inspect/_parsers/__init__.py @@ -1,4 +1,5 @@ from ._backend import BackendParser +from ._base import Parser from ._event import EventParser from ._method import MethodParser from ._plugin import PluginParser @@ -10,6 +11,7 @@ __all__ = [ 'BackendParser', 'EventParser', 'MethodParser', + 'Parser', 'PluginParser', 'ResponseParser', 'SchemaParser', diff --git a/platypush/plugins/inspect/_parsers/_backend.py b/platypush/plugins/inspect/_parsers/_backend.py index 9d56aabdbd..30f6eaa0f6 100644 --- a/platypush/plugins/inspect/_parsers/_backend.py +++ b/platypush/plugins/inspect/_parsers/_backend.py @@ -16,7 +16,7 @@ class BackendParser(Parser): @override @classmethod - def parse(cls, docstring: str) -> str: + def parse(cls, docstring: str, *_, **__) -> str: while True: m = cls._backend_regex.search(docstring) if not m: diff --git a/platypush/plugins/inspect/_parsers/_base.py b/platypush/plugins/inspect/_parsers/_base.py index f1616ad04e..4ae1be98c1 100644 --- a/platypush/plugins/inspect/_parsers/_base.py +++ b/platypush/plugins/inspect/_parsers/_base.py @@ -8,5 +8,5 @@ class Parser(ABC): @classmethod @abstractmethod - def parse(cls, docstring: str) -> str: + def parse(cls, docstring: str, obj_type: type) -> str: raise NotImplementedError() diff --git a/platypush/plugins/inspect/_parsers/_event.py b/platypush/plugins/inspect/_parsers/_event.py index 5f21ab2261..ffdf4b8c50 100644 --- a/platypush/plugins/inspect/_parsers/_event.py +++ b/platypush/plugins/inspect/_parsers/_event.py @@ -16,7 +16,7 @@ class EventParser(Parser): @override @classmethod - def parse(cls, docstring: str) -> str: + def parse(cls, docstring: str, *_, **__) -> str: while True: m = cls._event_regex.search(docstring) if not m: diff --git a/platypush/plugins/inspect/_parsers/_method.py b/platypush/plugins/inspect/_parsers/_method.py index 686c87b191..619b2fd8cc 100644 --- a/platypush/plugins/inspect/_parsers/_method.py +++ b/platypush/plugins/inspect/_parsers/_method.py @@ -10,26 +10,53 @@ class MethodParser(Parser): respective documentation. """ - _method_regex = re.compile( + _abs_method_regex = re.compile( r'(\s*):meth:`(platypush\.plugins\.(.+?))`', re.MULTILINE ) + _rel_method_regex = re.compile(r'(\s*):meth:`\.(.+?)`', re.MULTILINE) + @override @classmethod - def parse(cls, docstring: str) -> str: + def parse(cls, docstring: str, obj_type: type) -> str: while True: - m = cls._method_regex.search(docstring) - if not m: - break + m = cls._rel_method_regex.search(docstring) + if m: + tokens = m.group(2).split('.') + method = tokens[-1] + package = obj_type.__module__ + rel_package = '.'.join(package.split('.')[2:]) + full_name = '.'.join( + [ + package, + '.'.join(obj_type.__qualname__.split('.')[:-1]), + method, + ] + ) - tokens = m.group(3).split('.') - method = tokens[-1] - package = '.'.join(tokens[:-2]) - docstring = cls._method_regex.sub( - f'{m.group(1)}`{package}.{method} ' - f'`_', - docstring, - count=1, - ) + docstring = cls._rel_method_regex.sub( + f'{m.group(1)}`{package}.{method} ' + f'`_', + docstring, + count=1, + ) + + continue + + m = cls._abs_method_regex.search(docstring) + if m: + tokens = m.group(3).split('.') + method = tokens[-1] + package = '.'.join(tokens[:-2]) + docstring = cls._abs_method_regex.sub( + f'{m.group(1)}`{package}.{method} ' + f'`_', + docstring, + count=1, + ) + + continue + + break return docstring diff --git a/platypush/plugins/inspect/_parsers/_plugin.py b/platypush/plugins/inspect/_parsers/_plugin.py index aa40380922..e78920da59 100644 --- a/platypush/plugins/inspect/_parsers/_plugin.py +++ b/platypush/plugins/inspect/_parsers/_plugin.py @@ -16,7 +16,7 @@ class PluginParser(Parser): @override @classmethod - def parse(cls, docstring: str) -> str: + def parse(cls, docstring: str, *_, **__) -> str: while True: m = cls._plugin_regex.search(docstring) if not m: diff --git a/platypush/plugins/inspect/_parsers/_response.py b/platypush/plugins/inspect/_parsers/_response.py index 222595e1d7..a6cdf68dab 100644 --- a/platypush/plugins/inspect/_parsers/_response.py +++ b/platypush/plugins/inspect/_parsers/_response.py @@ -16,7 +16,7 @@ class ResponseParser(Parser): @override @classmethod - def parse(cls, docstring: str) -> str: + def parse(cls, docstring: str, *_, **__) -> str: while True: m = cls._response_regex.search(docstring) if not m: diff --git a/platypush/plugins/inspect/_parsers/_schema.py b/platypush/plugins/inspect/_parsers/_schema.py index 7e66fcd58e..f7da975276 100644 --- a/platypush/plugins/inspect/_parsers/_schema.py +++ b/platypush/plugins/inspect/_parsers/_schema.py @@ -61,7 +61,7 @@ class SchemaParser(Parser): @override @classmethod - def parse(cls, docstring: str) -> str: + def parse(cls, docstring: str, *_, **__) -> str: while True: m = cls._schema_regex.search(docstring) if not m: diff --git a/platypush/plugins/sensor/__init__.py b/platypush/plugins/sensor/__init__.py index 150172f748..775ac99988 100644 --- a/platypush/plugins/sensor/__init__.py +++ b/platypush/plugins/sensor/__init__.py @@ -378,7 +378,7 @@ class SensorPlugin(RunnablePlugin, SensorEntityManager, ABC): @action def get_data(self, *args, **kwargs): """ - (Deprecated) alias for :meth:`.get_measurement`` + (Deprecated) alias for :meth:`.get_measurement` """ return self.get_measurement(*args, **kwargs)