Skip to content

Commit

Permalink
refactor: Load properties as attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
pawamoy committed Nov 30, 2022
1 parent 727456d commit 9c1a5a9
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 2 deletions.
15 changes: 15 additions & 0 deletions src/griffe/agents/visitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,21 @@ def handle_function(self, node: ast.AsyncFunctionDef | ast.FunctionDef, labels:
lineno = node.lineno

labels |= self.decorators_to_labels(decorators)

if "property" in labels:
attribute = Attribute(
name=node.name,
value=None,
annotation=safe_get_annotation(node.returns, parent=self.current),
lineno=node.lineno,
endlineno=node.end_lineno, # type: ignore[union-attr]
docstring=self._get_docstring(node),
runtime=not self.type_guarded,
)
attribute.labels |= labels
self.current[node.name] = attribute
return

base_property, property_function = self.get_base_property(decorators)

# handle parameters
Expand Down
7 changes: 6 additions & 1 deletion src/griffe/docstrings/google.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,12 @@ def _read_returns_section( # noqa: WPS231
else:
# try to retrieve the annotation from the docstring parent
with suppress(AttributeError, KeyError, ValueError):
annotation = docstring.parent.returns # type: ignore[union-attr]
if docstring.parent.is_function: # type: ignore[union-attr]
annotation = docstring.parent.returns # type: ignore[union-attr]
elif docstring.parent.is_attribute: # type: ignore[union-attr]
annotation = docstring.parent.annotation # type: ignore[union-attr]
else:
raise ValueError
if len(block) > 1:
if annotation.is_tuple:
annotation = annotation.tuple_item(index)
Expand Down
7 changes: 6 additions & 1 deletion src/griffe/docstrings/numpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,12 @@ def _read_returns_section( # noqa: WPS231
if annotation is None:
# try to retrieve the annotation from the docstring parent
with suppress(AttributeError, KeyError, ValueError):
annotation = docstring.parent.returns # type: ignore[union-attr]
if docstring.parent.is_function: # type: ignore[union-attr]
annotation = docstring.parent.returns # type: ignore[union-attr]
elif docstring.parent.is_attribute: # type: ignore[union-attr]
annotation = docstring.parent.annotation # type: ignore[union-attr]
else:
raise ValueError
if len(items) > 1:
if annotation.is_tuple:
annotation = annotation.tuple_item(index)
Expand Down
19 changes: 19 additions & 0 deletions tests/test_visitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,3 +260,22 @@ def method(self):
assert module.docstring.lineno == 2
assert module["C"].docstring.lineno == 6
assert module["C.method"].docstring.lineno == 10


def test_create_properties_as_attributes():
"""Assert properties are created as attributes and not functions."""
with temporary_visited_module(
"""
from functools import cached_property
class C:
@property
def prop(self) -> bool:
return True
@cached_property
def cached_prop(self) -> int:
return 0
"""
) as module:
assert module["C.prop"].is_attribute
assert module["C.cached_prop"].is_attribute

0 comments on commit 9c1a5a9

Please sign in to comment.