Skip to content

Commit

Permalink
Try a simpler alternative for python 3.8
Browse files Browse the repository at this point in the history
  • Loading branch information
tristanlatr committed Dec 9, 2024
1 parent 7a23766 commit 283d340
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 280 deletions.
45 changes: 35 additions & 10 deletions pydoctor/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
from pydoctor import factory, qnmatch, utils, linker, astutils, mro
from pydoctor.epydoc.markup import ParsedDocstring
from pydoctor.sphinx import CacheT, SphinxInventory
from pydoctor.topsort import topsort

if TYPE_CHECKING:
from typing import Literal, Protocol, TypeAlias
Expand All @@ -41,6 +40,7 @@
Literal = {True: bool, False: bool}
ASTBuilder = Protocol = object

T = TypeVar('T')

# originally when I started to write pydoctor I had this idea of a big
# tree of Documentables arranged in an almost arbitrary tree.
Expand Down Expand Up @@ -583,7 +583,34 @@ def is_exception(cls: 'Class') -> bool:
return True
return False

_ClassOrStr: TypeAlias = 'Class | str'
Graph: TypeAlias = 'dict[T, list[T]]'

if sys.version_info >= (3, 9):
from graphlib import TopologicalSorter
def topsort(graph: Graph[T]) -> Iterable[T]:
"""
Wrapper for L{graphlib.TopologicalSorter.static_order}.
"""
return TopologicalSorter(graph).static_order()
else:
from collections import deque
def topsort(graph: Graph[T]) -> Iterable[T]:
result = deque()
visited = set()
stack = [[key for key in graph]]

Check warning on line 600 in pydoctor/model.py

View check run for this annotation

Codecov / codecov/patch

pydoctor/model.py#L596-L600

Added lines #L596 - L600 were not covered by tests
while stack:
for i in stack[-1]:
if i in visited and i not in result:
result.appendleft(i)

Check warning on line 604 in pydoctor/model.py

View check run for this annotation

Codecov / codecov/patch

pydoctor/model.py#L604

Added line #L604 was not covered by tests
if i not in visited:
visited.add(i)
stack.append(graph[i])
break

Check warning on line 608 in pydoctor/model.py

View check run for this annotation

Codecov / codecov/patch

pydoctor/model.py#L606-L608

Added lines #L606 - L608 were not covered by tests
else:
stack.pop()
return result

Check warning on line 611 in pydoctor/model.py

View check run for this annotation

Codecov / codecov/patch

pydoctor/model.py#L610-L611

Added lines #L610 - L611 were not covered by tests

ClassOrStr: TypeAlias = 'Class | str'

class ClassHierarchyFinalizer:
"""
Expand Down Expand Up @@ -630,7 +657,7 @@ def _init_finalbaseobjects(o: Class, path:list[Class] | None = None) -> None:
o._finalbases = finalbases

@staticmethod
def _getbases(o: Class) -> Iterator[_ClassOrStr]:
def _getbases(o: Class) -> Iterator[ClassOrStr]:
"""
Like L{Class.baseobjects} but fallback to the expanded
name if the base is not resolved to a L{Class} object.
Expand All @@ -645,8 +672,8 @@ def __init__(self, classes: Iterable[Class]) -> None:
# this calls _init_finalbaseobjects for every class and
# create the graph object for the ones that did not raised
# a cycle-error.
self.graph: dict[_ClassOrStr, list[_ClassOrStr]] = {}
self.computed_mros: dict[_ClassOrStr, list[_ClassOrStr]] = {}
self.graph: dict[ClassOrStr, list[ClassOrStr]] = {}
self.computed_mros: dict[ClassOrStr, list[ClassOrStr]] = {}

for cls in classes:
try:
Expand All @@ -670,7 +697,7 @@ def compute_mros(self) -> None:

# If this raises a CycleError, our code is boggus since we already
# checked for cycles ourself.
static_order: Iterable[_ClassOrStr] = topsort(self.graph)
static_order: Iterable[ClassOrStr] = topsort(self.graph)

for cls in static_order:
if cls in self.computed_mros:
Expand All @@ -680,13 +707,13 @@ def compute_mros(self) -> None:
assert isinstance(cls, Class)
self.computed_mros[cls] = cls._mro = self._compute_mro(cls)

def _compute_mro(self, cls: Class) -> list[_ClassOrStr]:
def _compute_mro(self, cls: Class) -> list[ClassOrStr]:
"""
Compute the method resolution order for this class.
This assumes that the MRO of the bases of the class
have already been computed and stored in C{self.computed_mros}.
"""
result: list[_ClassOrStr] = [cls]
result: list[ClassOrStr] = [cls]

if not (bases:=self.graph[cls]):
return result
Expand Down Expand Up @@ -951,8 +978,6 @@ class Attribute(Inheritable):
_ModuleT = Module
_PackageT = Package

T = TypeVar('T')

def import_mod_from_file_location(module_full_name:str, path: Path) -> types.ModuleType:
spec = importlib.util.spec_from_file_location(module_full_name, path)
if spec is None:
Expand Down
270 changes: 0 additions & 270 deletions pydoctor/topsort.py

This file was deleted.

0 comments on commit 283d340

Please sign in to comment.