stubber.rst.reader ================== .. py:module:: stubber.rst.reader .. autoapi-nested-parse:: Read the Micropython library documentation files and use them to build stubs that can be used for static typechecking using a custom-built parser to read and process the micropython RST files - generates: - modules - docstrings - function definitions - function parameters based on documentation - docstrings - classes - docstrings - __init__ method - parameters based on documentation for class - methods - parameters based on documentation for the method - docstrings - exceptions - Tries to determine the return type by parsing the docstring. - Imperative verbs used in docstrings have a strong correlation to return -> None - recognizes documented Generators, Iterators, Callable - Coroutines are identified based tag "This is a Coroutine". Then if the return type was Foo, it will be transformed to : Coroutine[Foo] - a static Lookup list is used for a few methods/functions for which the return type cannot be determined from the docstring. - add NoReturn to a few functions that never return ( stop / deepsleep / reset ) - if no type can be detected the type `Any` or `Incomplete` is used The generated stub files are formatted using `ruff` and checked for validity using `pyright` - ordering of inter-dependent classes in the same module - Literals / constants - documentation contains repeated vars with the same indentation - Module level: .. code-block:: .. data:: IPPROTO_UDP IPPROTO_TCP - class level: .. code-block:: .. data:: Pin.IRQ_FALLING Pin.IRQ_RISING Pin.IRQ_LOW_LEVEL Pin.IRQ_HIGH_LEVEL Selects the IRQ trigger type. - literals documented using a wildcard are added as comments only - Add GLUE imports to allow specific modules to import specific others. - Repeats of definitions in the rst file for similar functions or literals - CONSTANTS ( module and Class level ) - functions - methods - Child/ Parent classes are added based on a (manual) lookup table CHILD_PARENT_CLASS Attributes ---------- .. autoapisummary:: stubber.rst.reader.SEPARATOR stubber.rst.reader.USE_SUBMODULES Classes ------- .. autoapisummary:: stubber.rst.reader.FileReadWriter stubber.rst.reader.RSTReader stubber.rst.reader.RSTParser stubber.rst.reader.RSTWriter Module Contents --------------- .. py:data:: SEPARATOR :value: '::' .. py:data:: USE_SUBMODULES :value: True .. py:class:: FileReadWriter base class for reading rst files .. py:attribute:: filename :type: str :value: '' .. py:attribute:: rst_text :type: List[str] :value: [] .. py:attribute:: max_line :value: 0 .. py:attribute:: line_no :type: int :value: 0 .. py:attribute:: last_line :value: '' .. py:attribute:: output :type: List[str] :value: [] .. py:method:: read_file(filename: pathlib.Path) .. py:method:: write_file(target: pathlib.Path) -> bool .. py:property:: line :type: str get the current line from input, also stores this as last_line to allow for inspection and dumping the json file .. py:method:: is_balanced(s: str) -> bool :staticmethod: Check if a string has balanced parentheses .. py:method:: extend_and_balance_line() -> str Append the current line + next line in order to try to balance the parentheses in order to do this the rst_test array is changed by the function and max_line is adjusted .. py:class:: RSTReader Bases: :py:obj:`FileReadWriter` base class for reading rst files .. py:attribute:: docstring_anchors :value: ['.. note::', '.. data:: Arguments:', '.. data:: Options:', '.. data:: Returns:', '.. data::... .. py:attribute:: current_module :value: '' .. py:attribute:: current_class :value: '' .. py:attribute:: current_function :value: '' .. py:attribute:: clean_rst :value: True .. py:method:: read_file(filename: pathlib.Path) .. py:property:: module_names :type: List[str] list of possible module names [uname , name] (longest first) .. py:property:: at_anchor :type: bool and ..data:: should be added) :type: Stop at anchor '..something' ( however .. note .. py:method:: at_heading(large: bool = False) -> bool stop at heading .. py:method:: read_docstring(large: bool = False) -> List[str] Read a textblock that will be used as a docstring, or used to process a toc tree The textblock is terminated at the following RST line structures/tags .. -- Heading == Heading ~~ Heading The blank lines at the start and end are removed to limit the space the docstring takes up. .. py:method:: clean_docstr(block: List[str]) Clean up a docstring .. py:method:: add_link_to_docstr(block: List[str]) Add clickable hyperlinks to CPython docpages, and clean the docstring from rst constructs .. py:method:: get_rst_hint() parse the '.. :: ' from the current line .. py:method:: strip_prefixes(name: str, strip_mod: bool = True, strip_class: bool = False) Remove the modulename. and or the classname. from the beginning of a name .. py:class:: RSTParser(v_tag: str) Bases: :py:obj:`RSTReader` Parse the RST file and create a ModuleSourceDict most methods have side effects .. py:attribute:: target :value: '.py' .. py:attribute:: output_dict :type: stubber.rst.ModuleSourceDict .. py:attribute:: return_info :type: List[Tuple] :value: [] .. py:attribute:: source_tag .. py:attribute:: source_release .. py:method:: leave_class() .. py:method:: fix_parameters(params: str, name: str = '') -> str Patch / correct the documentation parameter notation to a supported format that works for linting. - params is the string containing the parameters as documented in the rst file - name is the name of the function or method or Class .. py:method:: apply_fix(fix: stubber.rst.lookup.Fix, params: str, name: str = '') :staticmethod: .. py:method:: create_update_class(name: str, params: str, docstr: List[str]) .. py:method:: parse_toc() process table of content with additional rst files, and add / include them in the current module .. py:method:: parse_module() parse a module tag and set the module's docstring .. py:method:: parse_current_module() .. py:method:: parse_function() .. py:method:: parse_class() .. py:method:: parse_method() .. py:method:: lstrip_self(params: str) To avoid duplicate selfs, Remove `self,` from the start of the parameters .. py:method:: parse_exception() .. py:method:: parse_name(line: Optional[str] = None) get the constant/function/class name from a line with an identifier .. py:method:: parse_names(oneliner: bool = True) get a list of constant/function/class names from and following a line with an identifier advances the linecounter oneliner : treat a line with commas as multiple names (used for constants) .. py:method:: parse_data() process ..data:: lines ( one or more) Note: some data islands are included in the docstring of the module/class/function as the ESPNow documentation started to use this pattern. .. py:method:: parse() .. py:class:: RSTWriter(v_tag='v1.xx') Bases: :py:obj:`RSTParser` Reads, parses and writes .. py:method:: write_file(target: pathlib.Path) -> bool .. py:method:: prepare_output() Remove trailing spaces and commas from the output.