Skip to content

Commit

Permalink
feat: Replace the docstring_parser library with Griffe (#79)
Browse files Browse the repository at this point in the history
### Summary of Changes
Slowly removing the
[docstring_parser](https://github.com/rr-/docstring_parser) library and
replacing it with [Griffe](https://github.com/mkdocstrings/griffe).

---------

Co-authored-by: megalinter-bot <129584137+megalinter-bot@users.noreply.github.com>
Co-authored-by: Lars Reimann <mail@larsreimann.com>
  • Loading branch information
3 people committed Apr 7, 2024
1 parent 8ea5a43 commit 9b2f802
Show file tree
Hide file tree
Showing 40 changed files with 3,013 additions and 1,214 deletions.
30 changes: 16 additions & 14 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ safe-ds-stubgen = "safeds_stubgen.main:main"
[tool.poetry.dependencies]
python = "^3.11"
mypy = "^1.6.1"
docstring-parser = "^0.15"
griffe = "^0.42.0"

[tool.poetry.group.dev.dependencies]
pytest = ">=7.4.3,<9.0.0"
Expand Down
11 changes: 5 additions & 6 deletions src/safeds_stubgen/api_analyzer/_ast_visitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ def _parse_results(self, node: mp_nodes.FuncDef, function_id: str) -> list[Resul
if ret_type is None:
return []

result_docstring = self.docstring_parser.get_result_documentation(node)
result_docstring = self.docstring_parser.get_result_documentation(node.fullname)

if type_is_inferred and isinstance(ret_type, sds_types.TupleType):
return self._create_inferred_results(ret_type, result_docstring, function_id)
Expand Down Expand Up @@ -670,7 +670,7 @@ def _create_attribute(
if isinstance(parent, Function) and parent.name == "__init__":
parent = self.__declaration_stack[-2]
assert isinstance(parent, Class)
docstring = self.docstring_parser.get_attribute_documentation(parent, name)
docstring = self.docstring_parser.get_attribute_documentation(parent.id, name)

# Remove __init__ for attribute ids
id_ = self._create_id_from_stack(name).replace("__init__/", "")
Expand Down Expand Up @@ -727,10 +727,9 @@ def _parse_parameter_data(self, node: mp_nodes.FuncDef, function_id: str) -> lis
# Create parameter docstring
parent = self.__declaration_stack[-1]
docstring = self.docstring_parser.get_parameter_documentation(
function_node=node,
function_qname=node.fullname,
parameter_name=arg_name,
parameter_assigned_by=arg_kind,
parent_class=parent if isinstance(parent, Class) else None,
parent_class_qname=parent.id if isinstance(parent, Class) else "",
)

if isinstance(default_value, type): # pragma: no cover
Expand Down Expand Up @@ -874,7 +873,7 @@ def mypy_type_to_abstract_type(
name, qname = self._find_alias(missing_import_name)
return sds_types.NamedType(name=name, qname=qname)
else:
return sds_types.NamedType(name="Any", qname="builtins.Any")
return sds_types.NamedType(name="Any", qname="typing.Any")
elif isinstance(mypy_type, mp_types.NoneType):
return sds_types.NamedType(name="None", qname="builtins.None")
elif isinstance(mypy_type, mp_types.LiteralType):
Expand Down
20 changes: 10 additions & 10 deletions src/safeds_stubgen/api_analyzer/_get_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,22 +57,22 @@ def get_api(
raise ValueError("No files found to analyse.")

# Get distribution data
dist = distribution(package_name) or ""
dist_version = distribution_version(dist) or ""
dist = distribution(package_name=package_name) or ""
dist_version = distribution_version(dist=dist) or ""

# Get mypy ast and aliases
build_result = _get_mypy_build(walkable_files)
mypy_asts = _get_mypy_asts(build_result, walkable_files, package_paths)
aliases = _get_aliases(build_result.types, package_name)
build_result = _get_mypy_build(files=walkable_files)
mypy_asts = _get_mypy_asts(build_result=build_result, files=walkable_files, package_paths=package_paths)
aliases = _get_aliases(result_types=build_result.types, package_name=package_name)

# Setup api walker
api = API(dist, package_name, dist_version)
docstring_parser = create_docstring_parser(docstring_style)
callable_visitor = MyPyAstVisitor(docstring_parser, api, aliases)
walker = ASTWalker(callable_visitor)
api = API(distribution=dist, package=package_name, version=dist_version)
docstring_parser = create_docstring_parser(style=docstring_style, package_path=root)
callable_visitor = MyPyAstVisitor(docstring_parser=docstring_parser, api=api, aliases=aliases)
walker = ASTWalker(handler=callable_visitor)

for tree in mypy_asts:
walker.walk(tree)
walker.walk(tree=tree)

return callable_visitor.api

Expand Down
8 changes: 2 additions & 6 deletions src/safeds_stubgen/docstring_parsing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,19 @@
from ._abstract_docstring_parser import AbstractDocstringParser
from ._create_docstring_parser import create_docstring_parser
from ._docstring import AttributeDocstring, ClassDocstring, FunctionDocstring, ParameterDocstring, ResultDocstring
from ._docstring_parser import DocstringParser
from ._docstring_style import DocstringStyle
from ._googledoc_parser import GoogleDocParser
from ._numpydoc_parser import NumpyDocParser
from ._plaintext_docstring_parser import PlaintextDocstringParser
from ._restdoc_parser import RestDocParser

__all__ = [
"AbstractDocstringParser",
"AttributeDocstring",
"ClassDocstring",
"create_docstring_parser",
"DocstringParser",
"DocstringStyle",
"FunctionDocstring",
"GoogleDocParser",
"NumpyDocParser",
"ParameterDocstring",
"PlaintextDocstringParser",
"RestDocParser",
"ResultDocstring",
]
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
if TYPE_CHECKING:
from mypy import nodes

from safeds_stubgen.api_analyzer import Class, ParameterAssignment

from ._docstring import (
AttributeDocstring,
ClassDocstring,
Expand All @@ -29,21 +27,20 @@ def get_function_documentation(self, function_node: nodes.FuncDef) -> FunctionDo
@abstractmethod
def get_parameter_documentation(
self,
function_node: nodes.FuncDef,
function_qname: str,
parameter_name: str,
parameter_assigned_by: ParameterAssignment,
parent_class: Class | None,
parent_class_qname: str,
) -> ParameterDocstring:
pass # pragma: no cover

@abstractmethod
def get_attribute_documentation(
self,
parent_class: Class,
parent_class_qname: str,
attribute_name: str,
) -> AttributeDocstring:
pass # pragma: no cover

@abstractmethod
def get_result_documentation(self, function_node: nodes.FuncDef) -> ResultDocstring:
def get_result_documentation(self, function_qname: str) -> ResultDocstring:
pass # pragma: no cover
16 changes: 9 additions & 7 deletions src/safeds_stubgen/docstring_parsing/_create_docstring_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,24 @@

from typing import TYPE_CHECKING

from griffe.enumerations import Parser

from ._docstring_parser import DocstringParser
from ._docstring_style import DocstringStyle
from ._googledoc_parser import GoogleDocParser
from ._numpydoc_parser import NumpyDocParser
from ._plaintext_docstring_parser import PlaintextDocstringParser
from ._restdoc_parser import RestDocParser

if TYPE_CHECKING:
from pathlib import Path

from ._abstract_docstring_parser import AbstractDocstringParser


def create_docstring_parser(style: DocstringStyle) -> AbstractDocstringParser:
def create_docstring_parser(style: DocstringStyle, package_path: Path) -> AbstractDocstringParser:
if style == DocstringStyle.GOOGLE:
return GoogleDocParser()
return DocstringParser(parser=Parser.google, package_path=package_path)
elif style == DocstringStyle.NUMPYDOC:
return NumpyDocParser()
return DocstringParser(parser=Parser.numpy, package_path=package_path)
elif style == DocstringStyle.REST:
return RestDocParser()
return DocstringParser(parser=Parser.sphinx, package_path=package_path)
else:
return PlaintextDocstringParser()
9 changes: 5 additions & 4 deletions src/safeds_stubgen/docstring_parsing/_docstring.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
if TYPE_CHECKING:
from typing import Any

from safeds_stubgen.api_analyzer import AbstractType


@dataclass(frozen=True)
class ClassDocstring:
Expand All @@ -28,7 +30,7 @@ def to_dict(self) -> dict[str, Any]:

@dataclass(frozen=True)
class ParameterDocstring:
type: str = ""
type: AbstractType | None = None
default_value: str = ""
description: str = ""

Expand All @@ -38,8 +40,7 @@ def to_dict(self) -> dict[str, Any]:

@dataclass(frozen=True)
class AttributeDocstring:
type: str = ""
default_value: str = ""
type: AbstractType | None = None
description: str = ""

def to_dict(self) -> dict[str, Any]:
Expand All @@ -48,7 +49,7 @@ def to_dict(self) -> dict[str, Any]:

@dataclass(frozen=True)
class ResultDocstring:
type: str = ""
type: AbstractType | None = None
description: str = ""

def to_dict(self) -> dict[str, Any]:
Expand Down

0 comments on commit 9b2f802

Please sign in to comment.