Skip to content

codetree

Class info

Classes

Name Children Inherits
Node
jinjarope.codetree
Represents a node in the Python code structure tree.
    NodeType
    jinjarope.codetree
    Types of nodes found in Python code structure analysis.
      TreeOptions
      jinjarope.codetree
      Configuration options for tree visualization.

        🛈 DocStrings

        Analyzes and visualizes Python code structure as a tree representation.

        This module provides functionality to parse Python source files and generate a tree-like visualization of their structure, including classes, methods, and functions with their decorators.

        Node dataclass

        Represents a node in the Python code structure tree.

        A node contains information about a specific code element (like a class or function) and maintains relationships with its child nodes.

        Parameters:

        Name Type Description Default
        name str

        The identifier of the code element

        required
        type NodeType

        The classification of the code element

        required
        children list[Node]

        List of child nodes

        required
        line_number int

        Source code line where this element appears

        required
        decorators list[str]

        List of decorator names applied to this element

        required
        Source code in src/jinjarope/codetree.py
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        53
        54
        55
        56
        @dataclass
        class Node:
            """Represents a node in the Python code structure tree.
        
            A node contains information about a specific code element (like a class
            or function) and maintains relationships with its child nodes.
        
            Args:
                name: The identifier of the code element
                type: The classification of the code element
                children: List of child nodes
                line_number: Source code line where this element appears
                decorators: List of decorator names applied to this element
            """
        
            name: str
            type: NodeType
            children: list[Node]
            line_number: int
            decorators: list[str]
        

        NodeType

        Bases: Enum

        Types of nodes found in Python code structure analysis.

        Each enum value represents a different structural element that can be found when parsing Python source code.

        Source code in src/jinjarope/codetree.py
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        class NodeType(Enum):
            """Types of nodes found in Python code structure analysis.
        
            Each enum value represents a different structural element that can be
            found when parsing Python source code.
            """
        
            MODULE = auto()
            CLASS = auto()
            FUNCTION = auto()
            METHOD = auto()
            STATICMETHOD = auto()
            CLASSMETHOD = auto()
            PROPERTY = auto()
            ASYNC_FUNCTION = auto()
            ASYNC_METHOD = auto()
        

        TreeOptions dataclass

        Configuration options for tree visualization.

        Controls the appearance and content of the generated tree structure.

        Parameters:

        Name Type Description Default
        show_types bool

        Include node type annotations

        True
        show_line_numbers bool

        Display source line numbers

        False
        show_decorators bool

        Include decorator information

        True
        sort_alphabetically bool

        Sort nodes by name

        False
        include_private bool

        Include private members (_name)

        True
        include_dunder bool

        Include double underscore methods (name)

        False
        max_depth int | None

        Maximum tree depth to display

        None
        branch_style str

        Style of tree branches ("ascii" or "unicode")

        'ascii'
        Source code in src/jinjarope/codetree.py
        59
        60
        61
        62
        63
        64
        65
        66
        67
        68
        69
        70
        71
        72
        73
        74
        75
        76
        77
        78
        79
        80
        81
        82
        83
        84
        85
        86
        87
        88
        89
        90
        91
        92
        93
        94
        @dataclass
        class TreeOptions:
            """Configuration options for tree visualization.
        
            Controls the appearance and content of the generated tree structure.
        
            Args:
                show_types: Include node type annotations
                show_line_numbers: Display source line numbers
                show_decorators: Include decorator information
                sort_alphabetically: Sort nodes by name
                include_private: Include private members (_name)
                include_dunder: Include double underscore methods (__name__)
                max_depth: Maximum tree depth to display
                branch_style: Style of tree branches ("ascii" or "unicode")
            """
        
            show_types: bool = True
            show_line_numbers: bool = False
            show_decorators: bool = True
            sort_alphabetically: bool = False
            include_private: bool = True
            include_dunder: bool = False
            max_depth: int | None = None
            branch_style: str = "ascii"  # "ascii" or "unicode"
        
            @property
            def symbols(self) -> dict[str, str]:
                """Get tree drawing symbols based on selected style.
        
                Returns a dictionary containing the appropriate symbols for
                drawing tree branches.
                """
                if self.branch_style == "unicode":
                    return {"pipe": "│   ", "last": "└── ", "branch": "├── ", "empty": "    "}
                return {"pipe": "|   ", "last": "`-- ", "branch": "|-- ", "empty": "    "}
        

        symbols property

        symbols: dict[str, str]
        

        Get tree drawing symbols based on selected style.

        Returns a dictionary containing the appropriate symbols for drawing tree branches.

        generate_tree

        generate_tree(
            node: Node,
            options: TreeOptions,
            prefix: str = "",
            is_last: bool = True,
            depth: int = 0,
        ) -> str
        

        Recursively generate a textual tree representation from a Node.

        Traverses the provided Node structure and creates a string representing the tree in ASCII or Unicode format, applying the specified options to control its appearance.

        Parameters:

        Name Type Description Default
        node Node

        The Node to start from

        required
        options TreeOptions

        Configuration options for tree visualization

        required
        prefix str

        Prefix string to use for indentation

        ''
        is_last bool

        Flag indicating if this node is the last child

        True
        depth int

        Current depth in the tree

        0

        Note

        This function is recursive and uses the provided options to determine if a node should be included and how it's formatted.

        Example
        root = parse_object("my_module.py")
        tree_str = generate_tree(root, options)
        print(tree_str)
        
        Source code in src/jinjarope/codetree.py
        197
        198
        199
        200
        201
        202
        203
        204
        205
        206
        207
        208
        209
        210
        211
        212
        213
        214
        215
        216
        217
        218
        219
        220
        221
        222
        223
        224
        225
        226
        227
        228
        229
        230
        231
        232
        233
        234
        235
        236
        237
        238
        239
        240
        241
        242
        243
        244
        245
        246
        247
        248
        249
        250
        251
        252
        253
        254
        255
        256
        257
        258
        259
        260
        261
        262
        263
        def generate_tree(
            node: Node,
            options: TreeOptions,
            prefix: str = "",
            is_last: bool = True,
            depth: int = 0,
        ) -> str:
            """Recursively generate a textual tree representation from a Node.
        
            Traverses the provided Node structure and creates a string
            representing the tree in ASCII or Unicode format, applying
            the specified options to control its appearance.
        
            Args:
                node: The Node to start from
                options: Configuration options for tree visualization
                prefix: Prefix string to use for indentation
                is_last: Flag indicating if this node is the last child
                depth: Current depth in the tree
        
            !!! note
                This function is recursive and uses the provided options to
                determine if a node should be included and how it's formatted.
        
            Example:
                ```python
                root = parse_object("my_module.py")
                tree_str = generate_tree(root, options)
                print(tree_str)
                ```
            """
            if options.max_depth is not None and depth > options.max_depth:
                return ""
        
            if not _should_include_node(node.name, options):
                return ""
        
            symbols = options.symbols
            tree = prefix
            tree += symbols["last"] if is_last else symbols["branch"]
        
            # Build the node label
            label = node.name
            if options.show_types:
                label += f" ({node.type.name})"
            if options.show_line_numbers:
                label += f" [L{node.line_number}]"
            if options.show_decorators and node.decorators:
                label += f" [{', '.join(node.decorators)}]"
        
            tree += f"{label}\n"
        
            children = node.children
            if options.sort_alphabetically:
                children = sorted(children, key=lambda x: x.name)
        
            for i, child in enumerate(children):
                extension = symbols["empty"] if is_last else symbols["pipe"]
                tree += generate_tree(
                    child,
                    options,
                    prefix + extension,
                    i == len(children) - 1,
                    depth + 1,
                )
        
            return tree
        

        get_structure_map

        get_structure_map(
            obj: PathLike[str] | str,
            *,
            show_types: bool = True,
            show_line_numbers: bool = False,
            show_decorators: bool = True,
            sort_alphabetically: bool = False,
            include_private: bool = True,
            include_dunder: bool = False,
            max_depth: int | None = None,
            use_unicode: bool = True
        ) -> str
        

        Generate a textual tree representation of Python code structure.

        Creates a visual tree showing the hierarchical structure of classes, methods, and functions in a Python file, with customizable display options.

        Tip

        Use use_unicode=True for better-looking trees in terminals that support Unicode characters.

        Parameters:

        Name Type Description Default
        obj PathLike[str] | str

        Path to the Python source file or a Python object

        required
        show_types bool

        Include node type annotations

        True
        show_line_numbers bool

        Display source line numbers

        False
        show_decorators bool

        Include decorator information

        True
        sort_alphabetically bool

        Sort nodes by name

        False
        include_private bool

        Include private members

        True
        include_dunder bool

        Include double underscore methods

        False
        max_depth int | None

        Maximum tree depth to display

        None
        use_unicode bool

        Use Unicode characters for tree branches

        True
        Example
        tree = get_structure_map(
            "myfile.py",
            show_types=False,
            show_line_numbers=True,
            sort_alphabetically=True
        )
        print(tree)
        
        Source code in src/jinjarope/codetree.py
        266
        267
        268
        269
        270
        271
        272
        273
        274
        275
        276
        277
        278
        279
        280
        281
        282
        283
        284
        285
        286
        287
        288
        289
        290
        291
        292
        293
        294
        295
        296
        297
        298
        299
        300
        301
        302
        303
        304
        305
        306
        307
        308
        309
        310
        311
        312
        313
        314
        315
        316
        317
        318
        319
        320
        321
        def get_structure_map(
            obj: os.PathLike[str] | str,
            *,
            show_types: bool = True,
            show_line_numbers: bool = False,
            show_decorators: bool = True,
            sort_alphabetically: bool = False,
            include_private: bool = True,
            include_dunder: bool = False,
            max_depth: int | None = None,
            use_unicode: bool = True,
        ) -> str:
            """Generate a textual tree representation of Python code structure.
        
            Creates a visual tree showing the hierarchical structure of classes,
            methods, and functions in a Python file, with customizable display options.
        
            !!! tip
                Use `use_unicode=True` for better-looking trees in terminals
                that support Unicode characters.
        
            Args:
                obj: Path to the Python source file or a Python object
                show_types: Include node type annotations
                show_line_numbers: Display source line numbers
                show_decorators: Include decorator information
                sort_alphabetically: Sort nodes by name
                include_private: Include private members
                include_dunder: Include double underscore methods
                max_depth: Maximum tree depth to display
                use_unicode: Use Unicode characters for tree branches
        
            Example:
                ```python
                tree = get_structure_map(
                    "myfile.py",
                    show_types=False,
                    show_line_numbers=True,
                    sort_alphabetically=True
                )
                print(tree)
                ```
            """
            options = TreeOptions(
                show_types=show_types,
                show_line_numbers=show_line_numbers,
                show_decorators=show_decorators,
                sort_alphabetically=sort_alphabetically,
                include_private=include_private,
                include_dunder=include_dunder,
                max_depth=max_depth,
                branch_style="unicode" if use_unicode else "ascii",
            )
        
            root = parse_object(obj)
            return generate_tree(root, options)
        

        parse_object

        parse_object(obj: PathLike[str] | str | type) -> Node
        

        Parse Python source code into a tree structure.

        Analyzes the AST of a Python file and creates a hierarchical representation of its structure, including classes, methods, and functions.

        Note

        The parser recognizes special method types through decorators and handles both synchronous and asynchronous definitions.

        Parameters:

        Name Type Description Default
        obj PathLike[str] | str | type

        Path to the Python source file

        required
        Example
        root = parse_object("example.py")
        print(f"Found {len(root.children)} top-level definitions")
        
        Source code in src/jinjarope/codetree.py
        118
        119
        120
        121
        122
        123
        124
        125
        126
        127
        128
        129
        130
        131
        132
        133
        134
        135
        136
        137
        138
        139
        140
        141
        142
        143
        144
        145
        146
        147
        148
        149
        150
        151
        152
        153
        154
        155
        156
        157
        158
        159
        160
        161
        162
        163
        164
        165
        166
        167
        168
        169
        170
        171
        172
        173
        174
        175
        176
        177
        178
        179
        180
        181
        182
        183
        184
        185
        186
        187
        188
        189
        190
        191
        192
        193
        194
        def parse_object(obj: os.PathLike[str] | str | type) -> Node:
            """Parse Python source code into a tree structure.
        
            Analyzes the AST of a Python file and creates a hierarchical representation
            of its structure, including classes, methods, and functions.
        
            !!! note
                The parser recognizes special method types through decorators
                and handles both synchronous and asynchronous definitions.
        
            Args:
                obj: Path to the Python source file
        
            Example:
                ```python
                root = parse_object("example.py")
                print(f"Found {len(root.children)} top-level definitions")
                ```
            """
            if isinstance(obj, str | os.PathLike):
                path = upath.UPath(obj)
                content = path.read_text("utf-8")
                name = path.name
            else:
                content = inspect.getsource(obj)
                name = obj.__name__
            tree = ast.parse(content)
            root = Node(name, NodeType.MODULE, [], 0, [])
        
            # Process top-level nodes
            for node in ast.iter_child_nodes(tree):
                if isinstance(node, ast.ClassDef):
                    class_node = Node(
                        node.name,
                        NodeType.CLASS,
                        [],
                        node.lineno,
                        _get_decorator_names(node.decorator_list),
                    )
                    root.children.append(class_node)
        
                    # Process class body
                    for item in node.body:
                        if isinstance(item, ast.FunctionDef | ast.AsyncFunctionDef):
                            decorators = _get_decorator_names(item.decorator_list)
                            node_type = NodeType.METHOD
        
                            # Determine method type based on decorators
                            if "@staticmethod" in decorators:
                                node_type = NodeType.STATICMETHOD
                            elif "@classmethod" in decorators:
                                node_type = NodeType.CLASSMETHOD
                            elif "@property" in decorators:
                                node_type = NodeType.PROPERTY
                            elif isinstance(item, ast.AsyncFunctionDef):
                                node_type = NodeType.ASYNC_METHOD
                            # mypy wants this check
                            assert isinstance(item, ast.FunctionDef | ast.AsyncFunctionDef)
                            method_node = Node(item.name, node_type, [], item.lineno, decorators)
                            class_node.children.append(method_node)
        
                elif isinstance(node, ast.FunctionDef | ast.AsyncFunctionDef):
                    node_type = (
                        NodeType.ASYNC_FUNCTION
                        if isinstance(node, ast.AsyncFunctionDef)
                        else NodeType.FUNCTION
                    )
                    func_node = Node(
                        node.name,
                        node_type,
                        [],
                        node.lineno,
                        _get_decorator_names(node.decorator_list),
                    )
                    root.children.append(func_node)
        
            return root