Skip to content

Commit

Permalink
refactor: Avoid circular import
Browse files Browse the repository at this point in the history
  • Loading branch information
pawamoy committed Nov 13, 2021
1 parent 1e9c9ae commit ef27dcd
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 39 deletions.
27 changes: 10 additions & 17 deletions src/griffe/node_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,14 @@
from ast import keyword as NodeKeyword
from functools import partial
from pathlib import Path
from typing import Any
from typing import TYPE_CHECKING

from griffe.collections import lines_collection
from griffe.dataclasses import Class, Docstring, Module
from griffe.docstrings.parsers import Parser
from griffe.expressions import Expression, Name

if TYPE_CHECKING:
from griffe.dataclasses import Class, Module


def _join(sequence, item):
if not sequence:
Expand Down Expand Up @@ -186,37 +187,29 @@ def get_annotation(node: Node, parent: Class | Module) -> str | Name | Expressio
# docstrings
def get_docstring(
node: Node,
parser: Parser | None = None,
parser_options: dict[str, Any] | None = None,
strict: bool = False,
) -> Docstring | None:
) -> tuple[str | None, int | None, int | None]:
"""Extract a docstring.
Parameters:
node: The node to extract the docstring from.
parser: The docstring parser to set on the docstring.
parser_options: The docstring parsing options to set on the docstring.
strict: Whether to skip searching the body (functions).
Returns:
A docstring.
A tuple with the value and line numbers of the docstring.
"""
# TODO: possible optimization using a type map
if isinstance(node, NodeExpr):
doc = node.value
elif node.body and isinstance(node.body[0], NodeExpr) and not strict: # type: ignore
doc = node.body[0].value # type: ignore
else:
return None
return None, None, None
if isinstance(doc, NodeConstant) and isinstance(doc.value, str):
return Docstring(
doc.value, lineno=doc.lineno, endlineno=doc.end_lineno, parser=parser, parser_options=parser_options
)
return doc.value, doc.lineno, doc.end_lineno
if isinstance(doc, NodeStr):
return Docstring(
doc.s, lineno=doc.lineno, endlineno=doc.end_lineno, parser=parser, parser_options=parser_options
)
return None
return doc.s, doc.lineno, doc.end_lineno
return None, None, None


# ==========================================================
Expand Down
50 changes: 28 additions & 22 deletions src/griffe/visitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,18 @@
from pathlib import Path
from typing import Any

from griffe.dataclasses import Attribute, Class, Decorator, Function, Kind, Module, Parameter, ParameterKind, Parameters
from griffe.dataclasses import (
Attribute,
Class,
Decorator,
Docstring,
Function,
Kind,
Module,
Parameter,
ParameterKind,
Parameters,
)
from griffe.docstrings.parsers import Parser
from griffe.expressions import Expression, Name
from griffe.extended_ast import LastNodeError
Expand Down Expand Up @@ -92,6 +103,18 @@ def _visit(self, node: Node, parent: Node | None = None) -> None:
node.parent = parent # type: ignore
self._run_specific_or_generic(node)

def _get_docstring(self, node: Node, strict: bool = False) -> Docstring | None:
value, lineno, endlineno = get_docstring(node, strict=strict)
if value is None:
return None
return Docstring(
value,
lineno=lineno,
endlineno=endlineno,
parser=self.docstring_parser,
parser_options=self.docstring_options,
)

def get_module(self) -> Module:
# optimization: equivalent to ast.parse, but with optimize=1 to remove assert statements
# TODO: with options, could use optimize=2 to remove docstrings
Expand All @@ -118,11 +141,7 @@ def visit_Module(self, node) -> None:
name=self.module_name,
filepath=self.filepath,
parent=self.parent,
docstring=get_docstring(
node,
parser=self.docstring_parser,
parser_options=self.docstring_options,
),
docstring=self._get_docstring(node),
)
self.generic_visit(node)

Expand All @@ -149,11 +168,7 @@ def visit_ClassDef(self, node) -> None:
name=node.name,
lineno=lineno,
endlineno=node.end_lineno,
docstring=get_docstring(
node,
parser=self.docstring_parser,
parser_options=self.docstring_options,
),
docstring=self._get_docstring(node),
decorators=decorators,
bases=bases,
)
Expand Down Expand Up @@ -247,11 +262,7 @@ def handle_function(self, node, labels: set | None = None): # noqa: WPS231
parameters=parameters,
returns=get_annotation(node.returns, parent=self.current),
decorators=decorators,
docstring=get_docstring(
node,
parser=self.docstring_parser,
parser_options=self.docstring_options,
),
docstring=self._get_docstring(node),
)
self.current[node.name] = function

Expand Down Expand Up @@ -301,12 +312,7 @@ def handle_attribute(self, node, annotation: str | Name | Expression | None = No
value = get_value(node.value)

try:
docstring = get_docstring(
node.next,
parser=self.docstring_parser,
parser_options=self.docstring_options,
strict=True,
)
docstring = self._get_docstring(node.next, strict=True)
except (LastNodeError, AttributeError):
docstring = None

Expand Down

0 comments on commit ef27dcd

Please sign in to comment.