__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

aptanhua@216.73.217.25: ~ $
"""Utilities related to attribute docstring extraction."""

from __future__ import annotations

import ast
import inspect
import textwrap
from typing import Any


class DocstringVisitor(ast.NodeVisitor):
    def __init__(self) -> None:
        super().__init__()

        self.target: str | None = None
        self.attrs: dict[str, str] = {}
        self.previous_node_type: type[ast.AST] | None = None

    def visit(self, node: ast.AST) -> Any:
        node_result = super().visit(node)
        self.previous_node_type = type(node)
        return node_result

    def visit_AnnAssign(self, node: ast.AnnAssign) -> Any:
        if isinstance(node.target, ast.Name):
            self.target = node.target.id

    def visit_Expr(self, node: ast.Expr) -> Any:
        if (
            isinstance(node.value, ast.Constant)
            and isinstance(node.value.value, str)
            and self.previous_node_type is ast.AnnAssign
        ):
            docstring = inspect.cleandoc(node.value.value)
            if self.target:
                self.attrs[self.target] = docstring
            self.target = None


def _dedent_source_lines(source: list[str]) -> str:
    # Required for nested class definitions, e.g. in a function block
    dedent_source = textwrap.dedent(''.join(source))
    if dedent_source.startswith((' ', '\t')):
        # We are in the case where there's a dedented (usually multiline) string
        # at a lower indentation level than the class itself. We wrap our class
        # in a function as a workaround.
        dedent_source = f'def dedent_workaround():\n{dedent_source}'
    return dedent_source


def _extract_source_from_frame(cls: type[Any]) -> list[str] | None:
    frame = inspect.currentframe()

    while frame:
        if inspect.getmodule(frame) is inspect.getmodule(cls):
            lnum = frame.f_lineno
            try:
                lines, _ = inspect.findsource(frame)
            except OSError:
                # Source can't be retrieved (maybe because running in an interactive terminal),
                # we don't want to error here.
                pass
            else:
                block_lines = inspect.getblock(lines[lnum - 1 :])
                dedent_source = _dedent_source_lines(block_lines)
                try:
                    block_tree = ast.parse(dedent_source)
                except SyntaxError:
                    pass
                else:
                    stmt = block_tree.body[0]
                    if isinstance(stmt, ast.FunctionDef) and stmt.name == 'dedent_workaround':
                        # `_dedent_source_lines` wrapped the class around the workaround function
                        stmt = stmt.body[0]
                    if isinstance(stmt, ast.ClassDef) and stmt.name == cls.__name__:
                        return block_lines

        frame = frame.f_back


def extract_docstrings_from_cls(cls: type[Any], use_inspect: bool = False) -> dict[str, str]:
    """Map model attributes and their corresponding docstring.

    Args:
        cls: The class of the Pydantic model to inspect.
        use_inspect: Whether to skip usage of frames to find the object and use
            the `inspect` module instead.

    Returns:
        A mapping containing attribute names and their corresponding docstring.
    """
    if use_inspect:
        # Might not work as expected if two classes have the same name in the same source file.
        try:
            source, _ = inspect.getsourcelines(cls)
        except OSError:
            return {}
    else:
        source = _extract_source_from_frame(cls)

    if not source:
        return {}

    dedent_source = _dedent_source_lines(source)

    visitor = DocstringVisitor()
    visitor.visit(ast.parse(dedent_source))
    return visitor.attrs

Filemanager

Name Type Size Permission Actions
__pycache__ Folder 0755
__init__.py File 0 B 0644
_config.py File 12.31 KB 0644
_core_metadata.py File 3.44 KB 0644
_core_utils.py File 23.7 KB 0644
_dataclasses.py File 8.53 KB 0644
_decorators.py File 31.21 KB 0644
_decorators_v1.py File 6.06 KB 0644
_discriminated_union.py File 25.82 KB 0644
_docs_extraction.py File 3.7 KB 0644
_fields.py File 14.58 KB 0644
_forward_ref.py File 611 B 0644
_generate_schema.py File 102.91 KB 0644
_generics.py File 21.69 KB 0644
_git.py File 784 B 0644
_internal_dataclass.py File 144 B 0644
_known_annotated_metadata.py File 13.86 KB 0644
_mock_val_ser.py File 7.14 KB 0644
_model_construction.py File 30.63 KB 0644
_repr.py File 4.46 KB 0644
_schema_generation_shared.py File 4.74 KB 0644
_signature.py File 6.15 KB 0644
_std_types_schema.py File 28.2 KB 0644
_typing_extra.py File 18.97 KB 0644
_utils.py File 12.36 KB 0644
_validate_call.py File 3.7 KB 0644
_validators.py File 10.86 KB 0644