Skip to content

Commit

Permalink
refactor: Preserve alias members path by re-aliasing members instead …
Browse files Browse the repository at this point in the history
…of returning target's members
  • Loading branch information
pawamoy committed Aug 23, 2023
1 parent 5bf0746 commit d400cb1
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 86 deletions.
97 changes: 12 additions & 85 deletions src/griffe/dataclasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -420,15 +420,6 @@ def inherited_members(self) -> dict[str, Alias]:
inherited_members[name] = Alias(name, member, parent=self, inherited=True)
return inherited_members

@property
def all_members(self) -> dict[str, Object | Alias]:
"""All members (declared and inherited).
This method is part of the consumer API:
do not use when producing Griffe trees!
"""
return {**self.inherited_members, **self.members}

@property
def is_module(self) -> bool:
"""Tell if this object is a module."""
Expand Down Expand Up @@ -477,54 +468,6 @@ def filter_members(self, *predicates: Callable[[Object | Alias], bool]) -> dict[
members[name] = member
return members

@property
def modules(self) -> dict[str, Module]:
"""Return the module members.
This method is part of the consumer API:
do not use when producing Griffe trees!
Returns:
A dictionary of modules.
"""
return {name: member for name, member in self.all_members.items() if member.kind is Kind.MODULE} # type: ignore[misc]

@property
def classes(self) -> dict[str, Class]:
"""Return the class members.
This method is part of the consumer API:
do not use when producing Griffe trees!
Returns:
A dictionary of classes.
"""
return {name: member for name, member in self.all_members.items() if member.kind is Kind.CLASS} # type: ignore[misc]

@property
def functions(self) -> dict[str, Function]:
"""Return the function members.
This method is part of the consumer API:
do not use when producing Griffe trees!
Returns:
A dictionary of functions.
"""
return {name: member for name, member in self.all_members.items() if member.kind is Kind.FUNCTION} # type: ignore[misc]

@property
def attributes(self) -> dict[str, Attribute]:
"""Return the attribute members.
This method is part of the consumer API:
do not use when producing Griffe trees!
Returns:
A dictionary of attributes.
"""
return {name: member for name, member in self.all_members.items() if member.kind is Kind.ATTRIBUTE} # type: ignore[misc]

@property
def module(self) -> Module:
"""Return the parent module of this object.
Expand Down Expand Up @@ -798,7 +741,7 @@ def __init__(
lineno: int | None = None,
endlineno: int | None = None,
runtime: bool = True,
parent: Module | Class | None = None,
parent: Module | Class | Alias | None = None,
inherited: bool = False,
) -> None:
"""Initialize the alias.
Expand All @@ -818,7 +761,7 @@ def __init__(
self.alias_endlineno: int | None = endlineno
self.runtime: bool = runtime
self.inherited: bool = inherited
self._parent: Module | Class | None = parent
self._parent: Module | Class | Alias | None = parent
self._passed_through: bool = False
if isinstance(target, str):
self._target: Object | Alias | None = None
Expand Down Expand Up @@ -896,7 +839,7 @@ def has_docstrings(self) -> bool:
return False

@property
def parent(self) -> Module | Class | None:
def parent(self) -> Module | Class | Alias | None:
"""Return the parent of this alias.
Returns:
Expand All @@ -905,7 +848,7 @@ def parent(self) -> Module | Class | None:
return self._parent

@parent.setter
def parent(self, value: Module | Class) -> None:
def parent(self, value: Module | Class | Alias) -> None:
self._parent = value
self._update_target_aliases()

Expand Down Expand Up @@ -938,9 +881,10 @@ def docstring(self) -> Docstring | None: # noqa: D102
def docstring(self, docstring: Docstring | None) -> None:
self.final_target.docstring = docstring

@property
@cached_property
def members(self) -> dict[str, Object | Alias]: # noqa: D102
return self.final_target.members
final_target = self.final_target
return {name: Alias(name, target=member, parent=self) for name, member in final_target.members.items()}

@property
def labels(self) -> set[str]: # noqa: D102
Expand All @@ -961,13 +905,12 @@ def aliases(self) -> dict[str, Alias]: # noqa: D102
def member_is_exported(self, member: Object | Alias, *, explicitely: bool = True) -> bool: # noqa: D102
return self.final_target.member_is_exported(member, explicitely=explicitely)

@property
@cached_property
def inherited_members(self) -> dict[str, Alias]: # noqa: D102
return self.final_target.inherited_members

@property
def all_members(self) -> dict[str, Object | Alias]: # noqa: D102
return self.final_target.all_members
final_target = self.final_target
return {
name: Alias(name, target=member, parent=self) for name, member in final_target.inherited_members.items()
}

def is_kind(self, kind: str | Kind | set[str | Kind]) -> bool: # noqa: D102
return self.final_target.is_kind(kind)
Expand All @@ -994,22 +937,6 @@ def has_labels(self, labels: set[str]) -> bool: # noqa: D102
def filter_members(self, *predicates: Callable[[Object | Alias], bool]) -> dict[str, Object | Alias]: # noqa: D102
return self.final_target.filter_members(*predicates)

@property
def modules(self) -> dict[str, Module]: # noqa: D102
return self.final_target.modules

@property
def classes(self) -> dict[str, Class]: # noqa: D102
return self.final_target.classes

@property
def functions(self) -> dict[str, Function]: # noqa: D102
return self.final_target.functions

@property
def attributes(self) -> dict[str, Attribute]: # noqa: D102
return self.final_target.attributes

@property
def module(self) -> Module: # noqa: D102
return self.final_target.module
Expand Down
60 changes: 59 additions & 1 deletion src/griffe/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@
from contextlib import suppress
from typing import TYPE_CHECKING, Any, Sequence, TypeVar

from griffe.enumerations import Kind
from griffe.exceptions import AliasResolutionError, CyclicAliasError
from griffe.logger import get_logger
from griffe.merger import merge_stubs

if TYPE_CHECKING:
from griffe.dataclasses import Alias, Object
from griffe.dataclasses import Alias, Attribute, Class, Function, Module, Object

logger = get_logger(__name__)
_ObjType = TypeVar("_ObjType")
Expand Down Expand Up @@ -206,6 +207,63 @@ def set_member(self, key: str | Sequence[str], value: Object | Alias) -> None:
class ObjectAliasMixin:
"""A mixin for methods that appear both in objects and aliases, unchanged."""

@property
def all_members(self) -> dict[str, Object | Alias]:
"""All members (declared and inherited).
This method is part of the consumer API:
do not use when producing Griffe trees!
"""
return {**self.inherited_members, **self.members} # type: ignore[attr-defined]

@property
def modules(self) -> dict[str, Module]:
"""Return the module members.
This method is part of the consumer API:
do not use when producing Griffe trees!
Returns:
A dictionary of modules.
"""
return {name: member for name, member in self.all_members.items() if member.kind is Kind.MODULE} # type: ignore[misc]

@property
def classes(self) -> dict[str, Class]:
"""Return the class members.
This method is part of the consumer API:
do not use when producing Griffe trees!
Returns:
A dictionary of classes.
"""
return {name: member for name, member in self.all_members.items() if member.kind is Kind.CLASS} # type: ignore[misc]

@property
def functions(self) -> dict[str, Function]:
"""Return the function members.
This method is part of the consumer API:
do not use when producing Griffe trees!
Returns:
A dictionary of functions.
"""
return {name: member for name, member in self.all_members.items() if member.kind is Kind.FUNCTION} # type: ignore[misc]

@property
def attributes(self) -> dict[str, Attribute]:
"""Return the attribute members.
This method is part of the consumer API:
do not use when producing Griffe trees!
Returns:
A dictionary of attributes.
"""
return {name: member for name, member in self.all_members.items() if member.kind is Kind.ATTRIBUTE} # type: ignore[misc]

def is_exported(self, *, explicitely: bool = True) -> bool:
"""Tell if this object/alias is implicitely exported by its parent.
Expand Down

0 comments on commit d400cb1

Please sign in to comment.