Nymbo commited on
Commit
07e140c
·
verified ·
1 Parent(s): 858a56f

Update Modules/_docstrings.py

Browse files
Files changed (1) hide show
  1. Modules/_docstrings.py +1 -74
Modules/_docstrings.py CHANGED
@@ -1,22 +1,12 @@
1
  from __future__ import annotations
2
 
3
- import ast
4
  import inspect
5
- import sys
6
- import types
7
- from typing import Any, Annotated, get_args, get_origin, get_type_hints, Union
8
 
9
 
10
  def _typename(tp: Any) -> str:
11
  """Return a readable type name from a type or annotation."""
12
  try:
13
- # Unwrap Optional[T] -> T
14
- origin = get_origin(tp)
15
- if origin is Union or (sys.version_info >= (3, 10) and origin is types.UnionType):
16
- args = [a for a in get_args(tp) if a is not type(None)]
17
- if len(args) == 1:
18
- return _typename(args[0])
19
-
20
  if hasattr(tp, "__name__"):
21
  return tp.__name__ # e.g. int, str
22
  if getattr(tp, "__module__", None) and getattr(tp, "__qualname__", None):
@@ -42,43 +32,6 @@ def _extract_base_and_meta(annotation: Any) -> tuple[Any, str | None]:
42
  return annotation, None
43
 
44
 
45
- def _parse_annotated_string(annot_str: str) -> tuple[str, str | None]:
46
- """Fallback: parse 'Annotated[Type, "desc"]' string using AST."""
47
- try:
48
- expr = ast.parse(annot_str, mode='eval').body
49
- if isinstance(expr, ast.Subscript):
50
- val = expr.value
51
- is_annotated = False
52
- if isinstance(val, ast.Name) and val.id == 'Annotated':
53
- is_annotated = True
54
- elif isinstance(val, ast.Attribute) and val.attr == 'Annotated':
55
- is_annotated = True
56
-
57
- if is_annotated:
58
- sl = expr.slice
59
- # In 3.9+, slice is the node. In <3.9, it might be Index/ExtSlice.
60
- if isinstance(sl, ast.Tuple):
61
- elts = sl.elts
62
- if len(elts) >= 2:
63
- # elts[0] is type, elts[1] is metadata
64
- meta_node = elts[1]
65
- desc = None
66
- if isinstance(meta_node, ast.Constant) and isinstance(meta_node.value, str):
67
- desc = meta_node.value
68
- elif isinstance(meta_node, ast.Str):
69
- desc = meta_node.s
70
-
71
- if desc:
72
- if hasattr(ast, 'unparse'):
73
- type_str = ast.unparse(elts[0])
74
- else:
75
- type_str = "Any"
76
- return type_str, desc
77
- except Exception:
78
- pass
79
- return annot_str, None
80
-
81
-
82
  def autodoc(summary: str | None = None, returns: str | None = None, *, force: bool = False):
83
  """
84
  Decorator that auto-generates a concise Google-style docstring from a function's
@@ -105,24 +58,7 @@ def autodoc(summary: str | None = None, returns: str | None = None, *, force: bo
105
  # include_extras=True to retain Annotated metadata
106
  hints = get_type_hints(func, include_extras=True, globalns=getattr(func, "__globals__", None))
107
  except Exception:
108
- # Fallback: try to evaluate annotations manually if they are strings
109
  hints = {}
110
- sig = inspect.signature(func)
111
- for name, param in sig.parameters.items():
112
- if isinstance(param.annotation, str):
113
- try:
114
- # Ensure typing is available in eval context
115
- globs = getattr(func, "__globals__", {}).copy()
116
- import typing
117
- globs['typing'] = typing
118
- for t in ['Annotated', 'Literal', 'Optional', 'Union', 'List', 'Dict', 'Any']:
119
- if t not in globs:
120
- globs[t] = getattr(typing, t)
121
-
122
- val = eval(param.annotation, globs)
123
- hints[name] = val
124
- except Exception:
125
- pass
126
 
127
  sig = inspect.signature(func)
128
 
@@ -144,16 +80,7 @@ def autodoc(summary: str | None = None, returns: str | None = None, *, force: bo
144
  if name == "self":
145
  continue
146
  annot = hints.get(name, param.annotation)
147
-
148
  base, meta = _extract_base_and_meta(annot)
149
-
150
- # If meta is missing and annot is a string, try AST fallback
151
- if meta is None and isinstance(annot, str):
152
- base_str, meta_str = _parse_annotated_string(annot)
153
- if meta_str:
154
- base = base_str
155
- meta = meta_str
156
-
157
  tname = _typename(base) if base is not inspect._empty else None
158
  desc = meta or ""
159
  if tname and tname != str(inspect._empty):
 
1
  from __future__ import annotations
2
 
 
3
  import inspect
4
+ from typing import Any, Annotated, get_args, get_origin, get_type_hints
 
 
5
 
6
 
7
  def _typename(tp: Any) -> str:
8
  """Return a readable type name from a type or annotation."""
9
  try:
 
 
 
 
 
 
 
10
  if hasattr(tp, "__name__"):
11
  return tp.__name__ # e.g. int, str
12
  if getattr(tp, "__module__", None) and getattr(tp, "__qualname__", None):
 
32
  return annotation, None
33
 
34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  def autodoc(summary: str | None = None, returns: str | None = None, *, force: bool = False):
36
  """
37
  Decorator that auto-generates a concise Google-style docstring from a function's
 
58
  # include_extras=True to retain Annotated metadata
59
  hints = get_type_hints(func, include_extras=True, globalns=getattr(func, "__globals__", None))
60
  except Exception:
 
61
  hints = {}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
 
63
  sig = inspect.signature(func)
64
 
 
80
  if name == "self":
81
  continue
82
  annot = hints.get(name, param.annotation)
 
83
  base, meta = _extract_base_and_meta(annot)
 
 
 
 
 
 
 
 
84
  tname = _typename(base) if base is not inspect._empty else None
85
  desc = meta or ""
86
  if tname and tname != str(inspect._empty):