diff options
| author | 2022-10-25 21:29:47 +0100 | |
|---|---|---|
| committer | 2022-10-25 21:29:47 +0100 | |
| commit | c7a6ddd00eb371759d837aa75fa397c6d5771401 (patch) | |
| tree | 54902b389c4c79b9426b7ed20b2f7c3c522b5eeb /docs | |
| parent | Merge pull request #138 from python-discord/bump-d.py (diff) | |
| parent | bump sphinx and sphinx-autodoc-typehints (diff) | |
Merge pull request #88 from Numerlor/no-duplicate-deco
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/utils.py | 49 | 
1 files changed, 35 insertions, 14 deletions
diff --git a/docs/utils.py b/docs/utils.py index cb4ffd50..c8bbc895 100644 --- a/docs/utils.py +++ b/docs/utils.py @@ -72,21 +72,11 @@ def linkcode_resolve(repo_link: str, domain: str, info: dict[str, str]) -> typin          while isinstance(source.body[0], ast.ClassDef):              source = source.body[0] -        for ast_obj in source.body: -            if isinstance(ast_obj, ast.Assign): -                names = [] -                for target in ast_obj.targets: -                    if isinstance(target, ast.Tuple): -                        names.extend([name.id for name in target.elts]) -                    else: -                        names.append(target.id) - -                if symbol_name in names: -                    start, end = ast_obj.lineno, ast_obj.end_lineno -                    break -        else: +        pos = _global_assign_pos(source, symbol_name) +        if pos is None:              raise Exception(f"Could not find symbol `{symbol_name}` in {module.__name__}.") - +        else: +            start, end = pos          _, offset = inspect.getsourcelines(symbol[-2])          if offset != 0:              offset -= 1 @@ -108,6 +98,37 @@ def linkcode_resolve(repo_link: str, domain: str, info: dict[str, str]) -> typin      return url +class NodeWithBody(typing.Protocol): +    """An AST node with the body attribute.""" + +    body: list[ast.AST] + + +def _global_assign_pos(ast_: NodeWithBody, name: str) -> typing.Union[tuple[int, int], None]: +    """ +    Find the first instance where the `name` global is defined in `ast_`. + +    Check top-level assignments and assignments nested in top-level if blocks. +    """ +    for ast_obj in ast_.body: +        if isinstance(ast_obj, ast.Assign): +            names = [] +            for target in ast_obj.targets: +                if isinstance(target, ast.Tuple): +                    names.extend([name.id for name in target.elts if isinstance(name, ast.Name)]) +                else: +                    if isinstance(target, ast.Name): +                        names.append(target.id) + +            if name in names: +                return ast_obj.lineno, ast_obj.end_lineno + +        elif isinstance(ast_obj, ast.If): +            pos_in_if = _global_assign_pos(ast_obj, name) +            if pos_in_if is not None: +                return pos_in_if + +  def cleanup() -> None:      """Remove unneeded autogenerated doc files, and clean up others."""      included = __get_included()  |