Skip to content

Commit

Permalink
Add annotation replacements.
Browse files Browse the repository at this point in the history
Based on discussion at mitmproxy#420
  • Loading branch information
staceybellerose committed Apr 7, 2024
1 parent 091cfd6 commit f7b1382
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 7 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@

API Documentation for Python Projects.

# Fork Notes

This fork allows use of modules starting with an underscore. It also allows the
user to perform annotation substitutions. For an example of how to use this, see
[sysmon_pytk/apidocs/make.py](https://github.com/staceybellerose/sysmon-pytk/blob/main/apidocs/make.py).

# Example

Expand Down
2 changes: 1 addition & 1 deletion pdoc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ def bark(self, loud: bool) -> None:
from __future__ import annotations

__docformat__ = "markdown" # explicitly disable rST processing in the examples above.
__version__ = "14.4.0" # this is read from setup.py
__version__ = "14.4.0+sba.0.1" # this is read from setup.py

from pathlib import Path
from typing import overload
Expand Down
14 changes: 8 additions & 6 deletions pdoc/doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
from pdoc.doc_types import empty
from pdoc.doc_types import resolve_annotations
from pdoc.doc_types import safe_eval_type
from pdoc.doc_types import simplify_annotation


def _include_fullname_in_traceback(f):
Expand Down Expand Up @@ -466,11 +467,12 @@ def submodules(self) -> list[Module]:
else:

def include(name: str) -> bool:
return True # because of the downside below
# optimization: we don't even try to load modules starting with an underscore as they would not be
# visible by default. The downside of this is that someone who overrides `is_public` will miss those
# entries, the upsides are 1) better performance and 2) less warnings because of import failures
# (think of OS-specific modules, e.g. _linux.py failing to import on Windows).
return not name.startswith("_")
# return not name.startswith("_")

submodules: list[Module] = []
for mod_name, mod in extract.iter_modules2(self.obj).items():
Expand Down Expand Up @@ -1117,9 +1119,9 @@ def default_value_str(self) -> str:
if self.default_value is empty:
return ""
if isinstance(self.default_value, TypeAliasType):
return formatannotation(self.default_value.__value__)
return simplify_annotation(formatannotation(self.default_value.__value__))
elif self.annotation == TypeAlias:
return formatannotation(self.default_value)
return simplify_annotation(formatannotation(self.default_value))

# This is not perfect, but a solid attempt at preventing accidental leakage of secrets.
# If you have input on how to improve the heuristic, please send a pull request!
Expand Down Expand Up @@ -1151,7 +1153,7 @@ def default_value_str(self) -> str:
def annotation_str(self) -> str:
"""The variable's type annotation as a pretty-printed str."""
if self.annotation is not empty:
return f": {formatannotation(self.annotation)}"
return f": {simplify_annotation(formatannotation(self.annotation))}"
else:
return ""

Expand Down Expand Up @@ -1223,7 +1225,7 @@ def _params(self) -> list[str]:

def _return_annotation_str(self) -> str:
if self.return_annotation is not empty:
return formatannotation(self.return_annotation)
return simplify_annotation(formatannotation(self.return_annotation))
else:
return ""

Expand Down Expand Up @@ -1308,4 +1310,4 @@ def _safe_getdoc(obj: Any) -> str:

def _remove_memory_addresses(x: str) -> str:
"""Remove memory addresses from repr() output"""
return re.sub(r" at 0x[0-9a-fA-F]+(?=>)", "", x)
return simplify_annotation(re.sub(r" at 0x[0-9a-fA-F]+(?=>)", "", x))
31 changes: 31 additions & 0 deletions pdoc/doc_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import functools
import inspect
import operator
import re
import sys
import types
from types import BuiltinFunctionType
Expand All @@ -26,6 +27,7 @@
from . import extract
from ._compat import GenericAlias
from ._compat import UnionType
from ._compat import formatannotation
from .doc_ast import type_checking_sections

if TYPE_CHECKING:
Expand Down Expand Up @@ -231,3 +233,32 @@ def _eval_type(t, globalns, localns, recursive_guard=frozenset()):
return t.copy_with(ev_args)
return t
# ✂ end ✂
# fmt: on


class AnnotationReplacer:
"""A small helper to simplify type annotations."""
replacements: dict[str, str]
rex: re.Pattern | None = None

def __init__(self):
self.replacements = {}

def recompile(self) -> None:
"""
Recompile the regular expression used to replace annotations.
Needs to be called after modifications to `replacements`.
"""
self.rex = re.compile("|".join(re.escape(k) for k in self.replacements))

def __call__(self, text: str) -> str:
"""
Shorten an annotation string.
"""
self.recompile()
if self.rex:
text = self.rex.sub(lambda m: self.replacements[m.group(0)], text)
return text


simplify_annotation = AnnotationReplacer()

0 comments on commit f7b1382

Please sign in to comment.