from typing import Any, Protocol

class _SupportsGraphident(Protocol):
    graphident: str

# TODO: For typing purposes, once #5768 is complete, it'll be easier to use the modulegraph package directly.

# code, filename and packagepath are always initialized to None. But they can be given a value later.
class Node:
    # Compiled code. See stdlib.builtins.compile
    code: Any | None
    filename: str | None
    graphident: str
    identifier: str
    packagepath: str | None
    def __init__(self, identifier: str) -> None: ...
    def is_global_attr(self, attr_name: str) -> bool: ...
    def is_submodule(self, submodule_basename: str) -> bool: ...
    def add_global_attr(self, attr_name: str) -> None: ...
    def add_global_attrs_from_module(self, target_module: Node) -> None: ...
    def add_submodule(self, submodule_basename: str, submodule_node: Node) -> None: ...
    def get_submodule(self, submodule_basename: str) -> Node: ...
    def get_submodule_or_none(self, submodule_basename: str) -> Node | None: ...
    def remove_global_attr_if_found(self, attr_name: str) -> None: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __lt__(self, other: _SupportsGraphident) -> bool: ...
    def __le__(self, other: _SupportsGraphident) -> bool: ...
    def __gt__(self, other: _SupportsGraphident) -> bool: ...
    def __ge__(self, other: _SupportsGraphident) -> bool: ...
    def infoTuple(self) -> tuple[str]: ...

class Alias(str): ...

class BaseModule(Node):
    filename: str
    packagepath: str
    def __init__(self, name: str, filename: str | None = ..., path: str | None = ...) -> None: ...
    # Returns a tuple of length 0, 1, 2, or 3
    def infoTuple(self) -> tuple[str, ...]: ...  # type: ignore[override]

class Package(BaseModule): ...
