Skip to main content

Pretty-print a project's module tree

Project description

pypatree

CI PyPI Python License

Pretty-print a project's module tree with syntax-highlighted signatures.

uv add --dev pypatree
uv run pypatree
pypatree  pypatree - Pretty-print a project's module tree.
├── __main__
│   ├── main() -> None
│   └── run(cfg: pypatree.config.Config) -> None
├── config  Configuration types for pypatree.
│   ├── Config(
│   │       scope: Optional[str],
│   │       exclude: Optional[str],
│   │       docstrings: pypatree.config.DocstringMode,
│   │       show_defaults: bool,
│   │       verbose: bool,
│   │   ) -> None
│   └── DocstringMode(*args, **kwargs)
├── discovery
│   └── get_packages(exclude: Optional[str]) -> dict[str, list[str]]
├── display
│   ├── print_tree(
│   │       pkg_name: str,
│   │       tree: dict[str, typing.Any],
│   │       cfg: pypatree.config.Config,
│   │   ) -> None
│   └── render_tree(tree: dict[str, typing.Any], prefix: str) -> list[str]
├── introspection
│   ├── format_signature(obj: Union[Callable, type], show_defaults: bool) -> str
│   ├── get_module_docstring(modname: str, short: bool) -> Optional[str]
│   ├── get_module_items(
│   │       modname: str,
│   │       exclude: Optional[str],
│   │       show_defaults: bool,
│   │   ) -> list[str]
│   └── safe_import(modname: str) -> Optional[module]
└── tree
    ├── build_tree(
    │       submods: list[str],
    │       pkg_name: str,
    │       exclude: Optional[str],
    │       show_defaults: bool,
    │   ) -> dict[str, typing.Any]
    └── get_subtree(
            tree: dict[str, typing.Any],
            path: list[str],
        ) -> Optional[dict[str, Any]]

Run pypatree --help for options:

usage: pypatree [-h] [OPTIONS] [MODULE]

Display module tree with public functions/classes.

╭─ positional arguments ─────────────────────────────────────────────────────╮
│ [MODULE]                                                                   │
│     Module path to scope to (e.g., 'mypkg.submodule'). (default: None)     │
╰────────────────────────────────────────────────────────────────────────────╯
╭─ options ──────────────────────────────────────────────────────────────────╮
│ -h, --help                                                                 │
│     show this help message and exit                                        │
│ --exclude {None}|STR                                                       │
│     Regex to exclude module segments (default: test modules). Use '' for   │
│     none. (default: '^test$|^test_')                                       │
│ --docstrings {none,short,full}                                             │
│     Show module docstrings: none, short (first line), or full. (default:   │
│     short)                                                                 │
│ --show-defaults, --no-show-defaults                                        │
│     Show default argument values in signatures. (default: False)           │
│ --verbose, --no-verbose                                                    │
│     Enable debug logging to stderr. (default: False)                       │
╰────────────────────────────────────────────────────────────────────────────╯

Example on httpx:

httpx
├── ASGITransport(
│       app: _ASGIApp,
│       raise_app_exceptions: bool,
│       root_path: str,
│       client: tuple[str, int],
│   ) -> None
├── AsyncBaseTransport(*args, **kwargs)
├── AsyncByteStream(*args, **kwargs)
├── AsyncClient(
│       *,
│       auth: AuthTypes | None,
│       params: QueryParamTypes | None,
│       headers: HeaderTypes | None,
│       cookies: CookieTypes | None,
│       verify: ssl.SSLContext | str | bool,
│       cert: CertTypes | None,
│       http1: bool,
│       http2: bool,
│       proxy: ProxyTypes | None,
│       mounts: None | typing.Mapping[str, AsyncBaseTransport | None],
│       timeout: TimeoutTypes,
│       follow_redirects: bool,
│       limits: Limits,
│       max_redirects: int,
│       event_hooks: None | typing.Mapping[str, list[EventHook]],
│       base_url: URL | str,
│       transport: AsyncBaseTransport | None,
│       trust_env: bool,
│       default_encoding: str | typing.Callable[[bytes], str],
│   ) -> None
├── AsyncHTTPTransport(
│       verify: ssl.SSLContext | str | bool,
│       cert: CertTypes | None,
│       trust_env: bool,
│       http1: bool,
│       http2: bool,
│       limits: Limits,
│       proxy: ProxyTypes | None,
│       uds: str | None,
│       local_address: str | None,
│       retries: int,
│       socket_options: typing.Iterable[SOCKET_OPTION] | None,
│   ) -> None
├── Auth(*args, **kwargs)
├── BaseTransport(*args, **kwargs)
├── BasicAuth(username: str | bytes, password: str | bytes) -> None
├── ByteStream(stream: bytes) -> None
├── Client(
│       *,
│       auth: AuthTypes | None,
│       params: QueryParamTypes | None,
│       headers: HeaderTypes | None,
│       cookies: CookieTypes | None,
│       verify: ssl.SSLContext | str | bool,
│       cert: CertTypes | None,
│       trust_env: bool,
│       http1: bool,
│       http2: bool,
│       proxy: ProxyTypes | None,
│       mounts: None | typing.Mapping[str, BaseTransport | None],
│       timeout: TimeoutTypes,
│       follow_redirects: bool,
│       limits: Limits,
│       max_redirects: int,
│       event_hooks: None | typing.Mapping[str, list[EventHook]],
│       base_url: URL | str,
│       transport: BaseTransport | None,
│       default_encoding: str | typing.Callable[[bytes], str],
│   ) -> None
├── CloseError(message: str, *, request: Request | None) -> None
├── ConnectError(message: str, *, request: Request | None) -> None
├── ConnectTimeout(message: str, *, request: Request | None) -> None
├── CookieConflict(message: str) -> None
├── Cookies(cookies: CookieTypes | None) -> None
├── DecodingError(message: str, *, request: Request | None) -> None
├── DigestAuth(username: str | bytes, password: str | bytes) -> None
├── FunctionAuth(func: typing.Callable[[Request], Request]) -> None
├── HTTPError(message: str) -> None
├── HTTPStatusError(
│       message: str,
│       *,
│       request: Request,
│       response: Response,
│   ) -> None
├── HTTPTransport(
│       verify: ssl.SSLContext | str | bool,
│       cert: CertTypes | None,
│       trust_env: bool,
│       http1: bool,
│       http2: bool,
│       limits: Limits,
│       proxy: ProxyTypes | None,
│       uds: str | None,
│       local_address: str | None,
│       retries: int,
│       socket_options: typing.Iterable[SOCKET_OPTION] | None,
│   ) -> None
├── Headers(headers: HeaderTypes | None, encoding: str | None) -> None
├── InvalidURL(message: str) -> None
├── Limits(
│       *,
│       max_connections: int | None,
│       max_keepalive_connections: int | None,
│       keepalive_expiry: float | None,
│   ) -> None
├── LocalProtocolError(message: str, *, request: Request | None) -> None
├── MockTransport(handler: SyncHandler | AsyncHandler) -> None
├── NetRCAuth(file: str | None) -> None
├── NetworkError(message: str, *, request: Request | None) -> None
├── PoolTimeout(message: str, *, request: Request | None) -> None
├── ProtocolError(message: str, *, request: Request | None) -> None
├── Proxy(
│       url: URL | str,
│       *,
│       ssl_context: ssl.SSLContext | None,
│       auth: tuple[str, str] | None,
│       headers: HeaderTypes | None,
│   ) -> None
├── ProxyError(message: str, *, request: Request | None) -> None
├── QueryParams(*args: QueryParamTypes | None, **kwargs: typing.Any) -> None
├── ReadError(message: str, *, request: Request | None) -> None
├── ReadTimeout(message: str, *, request: Request | None) -> None
├── RemoteProtocolError(message: str, *, request: Request | None) -> None
├── Request(
│       method: str,
│       url: URL | str,
│       *,
│       params: QueryParamTypes | None,
│       headers: HeaderTypes | None,
│       cookies: CookieTypes | None,
│       content: RequestContent | None,
│       data: RequestData | None,
│       files: RequestFiles | None,
│       json: typing.Any | None,
│       stream: SyncByteStream | AsyncByteStream | None,
│       extensions: RequestExtensions | None,
│   ) -> None
├── RequestError(message: str, *, request: Request | None) -> None
├── RequestNotRead() -> None
├── Response(
│       status_code: int,
│       *,
│       headers: HeaderTypes | None,
│       content: ResponseContent | None,
│       text: str | None,
│       html: str | None,
│       json: typing.Any,
│       stream: SyncByteStream | AsyncByteStream | None,
│       request: Request | None,
│       extensions: ResponseExtensions | None,
│       history: list[Response] | None,
│       default_encoding: str | typing.Callable[[bytes], str],
│   ) -> None
├── ResponseNotRead() -> None
├── StreamClosed() -> None
├── StreamConsumed() -> None
├── StreamError(message: str) -> None
├── SyncByteStream(*args, **kwargs)
├── Timeout(
│       timeout: TimeoutTypes | UnsetType,
│       *,
│       connect: None | float | UnsetType,
│       read: None | float | UnsetType,
│       write: None | float | UnsetType,
│       pool: None | float | UnsetType,
│   ) -> None
├── TimeoutException(message: str, *, request: Request | None) -> None
├── TooManyRedirects(message: str, *, request: Request | None) -> None
├── TransportError(message: str, *, request: Request | None) -> None
├── URL(url: URL | str, **kwargs: typing.Any) -> None
├── UnsupportedProtocol(message: str, *, request: Request | None) -> None
├── WSGITransport(
│       app: WSGIApplication,
│       raise_app_exceptions: bool,
│       script_name: str,
│       remote_addr: str,
│       wsgi_errors: typing.TextIO | None,
│   ) -> None
├── WriteError(message: str, *, request: Request | None) -> None
├── WriteTimeout(message: str, *, request: Request | None) -> None
├── codes(*args, **kwargs)
├── create_ssl_context(
│       verify: ssl.SSLContext | str | bool,
│       cert: CertTypes | None,
│       trust_env: bool,
│   ) -> ssl.SSLContext
├── delete(
│       url: URL | str,
│       *,
│       params: QueryParamTypes | None,
│       headers: HeaderTypes | None,
│       cookies: CookieTypes | None,
│       auth: AuthTypes | None,
│       proxy: ProxyTypes | None,
│       follow_redirects: bool,
│       timeout: TimeoutTypes,
│       verify: ssl.SSLContext | str | bool,
│       trust_env: bool,
│   ) -> Response
├── get(
│       url: URL | str,
│       *,
│       params: QueryParamTypes | None,
│       headers: HeaderTypes | None,
│       cookies: CookieTypes | None,
│       auth: AuthTypes | None,
│       proxy: ProxyTypes | None,
│       follow_redirects: bool,
│       verify: ssl.SSLContext | str | bool,
│       timeout: TimeoutTypes,
│       trust_env: bool,
│   ) -> Response
├── head(
│       url: URL | str,
│       *,
│       params: QueryParamTypes | None,
│       headers: HeaderTypes | None,
│       cookies: CookieTypes | None,
│       auth: AuthTypes | None,
│       proxy: ProxyTypes | None,
│       follow_redirects: bool,
│       verify: ssl.SSLContext | str | bool,
│       timeout: TimeoutTypes,
│       trust_env: bool,
│   ) -> Response
├── main() -> None
├── options(
│       url: URL | str,
│       *,
│       params: QueryParamTypes | None,
│       headers: HeaderTypes | None,
│       cookies: CookieTypes | None,
│       auth: AuthTypes | None,
│       proxy: ProxyTypes | None,
│       follow_redirects: bool,
│       verify: ssl.SSLContext | str | bool,
│       timeout: TimeoutTypes,
│       trust_env: bool,
│   ) -> Response
├── patch(
│       url: URL | str,
│       *,
│       content: RequestContent | None,
│       data: RequestData | None,
│       files: RequestFiles | None,
│       json: typing.Any | None,
│       params: QueryParamTypes | None,
│       headers: HeaderTypes | None,
│       cookies: CookieTypes | None,
│       auth: AuthTypes | None,
│       proxy: ProxyTypes | None,
│       follow_redirects: bool,
│       verify: ssl.SSLContext | str | bool,
│       timeout: TimeoutTypes,
│       trust_env: bool,
│   ) -> Response
├── post(
│       url: URL | str,
│       *,
│       content: RequestContent | None,
│       data: RequestData | None,
│       files: RequestFiles | None,
│       json: typing.Any | None,
│       params: QueryParamTypes | None,
│       headers: HeaderTypes | None,
│       cookies: CookieTypes | None,
│       auth: AuthTypes | None,
│       proxy: ProxyTypes | None,
│       follow_redirects: bool,
│       verify: ssl.SSLContext | str | bool,
│       timeout: TimeoutTypes,
│       trust_env: bool,
│   ) -> Response
├── put(
│       url: URL | str,
│       *,
│       content: RequestContent | None,
│       data: RequestData | None,
│       files: RequestFiles | None,
│       json: typing.Any | None,
│       params: QueryParamTypes | None,
│       headers: HeaderTypes | None,
│       cookies: CookieTypes | None,
│       auth: AuthTypes | None,
│       proxy: ProxyTypes | None,
│       follow_redirects: bool,
│       verify: ssl.SSLContext | str | bool,
│       timeout: TimeoutTypes,
│       trust_env: bool,
│   ) -> Response
├── request(
│       method: str,
│       url: URL | str,
│       *,
│       params: QueryParamTypes | None,
│       content: RequestContent | None,
│       data: RequestData | None,
│       files: RequestFiles | None,
│       json: typing.Any | None,
│       headers: HeaderTypes | None,
│       cookies: CookieTypes | None,
│       auth: AuthTypes | None,
│       proxy: ProxyTypes | None,
│       timeout: TimeoutTypes,
│       follow_redirects: bool,
│       verify: ssl.SSLContext | str | bool,
│       trust_env: bool,
│   ) -> Response
├── stream(
│       method: str,
│       url: URL | str,
│       *,
│       params: QueryParamTypes | None,
│       content: RequestContent | None,
│       data: RequestData | None,
│       files: RequestFiles | None,
│       json: typing.Any | None,
│       headers: HeaderTypes | None,
│       cookies: CookieTypes | None,
│       auth: AuthTypes | None,
│       proxy: ProxyTypes | None,
│       timeout: TimeoutTypes,
│       follow_redirects: bool,
│       verify: ssl.SSLContext | str | bool,
│       trust_env: bool,
│   ) -> typing.Iterator[Response]
├── __version__
├── _api
├── _auth
├── _client
│   ├── BaseClient(
│   │       *,
│   │       auth: AuthTypes | None,
│   │       params: QueryParamTypes | None,
│   │       headers: HeaderTypes | None,
│   │       cookies: CookieTypes | None,
│   │       timeout: TimeoutTypes,
│   │       follow_redirects: bool,
│   │       max_redirects: int,
│   │       event_hooks: None | typing.Mapping[str, list[EventHook]],
│   │       base_url: URL | str,
│   │       trust_env: bool,
│   │       default_encoding: str | typing.Callable[[bytes], str],
│   │   ) -> None
│   ├── BoundAsyncStream(
│   │       stream: AsyncByteStream,
│   │       response: Response,
│   │       start: float,
│   │   ) -> None
│   ├── BoundSyncStream(
│   │       stream: SyncByteStream,
│   │       response: Response,
│   │       start: float,
│   │   ) -> None
│   ├── ClientState(*args, **kwargs)
│   └── UseClientDefault(*args, **kwargs)
├── _config
│   └── UnsetType(*args, **kwargs)
├── _content
│   ├── AsyncIteratorByteStream(stream: AsyncIterable[bytes]) -> None
│   ├── IteratorByteStream(stream: Iterable[bytes]) -> None
│   ├── UnattachedStream(*args, **kwargs)
│   ├── encode_content(
│   │       content: str | bytes | Iterable[bytes] | AsyncIterable[bytes],
│   │   ) -> tuple[dict[str, str], SyncByteStream | AsyncByteStream]
│   ├── encode_html(html: str) -> tuple[dict[str, str], ByteStream]
│   ├── encode_json(json: Any) -> tuple[dict[str, str], ByteStream]
│   ├── encode_multipart_data(
│   │       data: RequestData,
│   │       files: RequestFiles,
│   │       boundary: bytes | None,
│   │   ) -> tuple[dict[str, str], MultipartStream]
│   ├── encode_request(
│   │       content: RequestContent | None,
│   │       data: RequestData | None,
│   │       files: RequestFiles | None,
│   │       json: Any | None,
│   │       boundary: bytes | None,
│   │   ) -> tuple[dict[str, str], SyncByteStream | AsyncByteStream]
│   ├── encode_response(
│   │       content: ResponseContent | None,
│   │       text: str | None,
│   │       html: str | None,
│   │       json: Any | None,
│   │   ) -> tuple[dict[str, str], SyncByteStream | AsyncByteStream]
│   ├── encode_text(text: str) -> tuple[dict[str, str], ByteStream]
│   └── encode_urlencoded_data(
│           data: RequestData,
│       ) -> tuple[dict[str, str], ByteStream]
├── _decoders  Handlers for Content-Encoding.
│   ├── BrotliDecoder() -> None
│   ├── ByteChunker(chunk_size: int | None) -> None
│   ├── ContentDecoder(*args, **kwargs)
│   ├── DeflateDecoder() -> None
│   ├── GZipDecoder() -> None
│   ├── IdentityDecoder(*args, **kwargs)
│   ├── LineDecoder() -> None
│   ├── MultiDecoder(children: typing.Sequence[ContentDecoder]) -> None
│   ├── TextChunker(chunk_size: int | None) -> None
│   ├── TextDecoder(encoding: str) -> None
│   └── ZStandardDecoder() -> None
├── _exceptions  Our exception hierarchy:
│   └── request_context(request: Request | None) -> typing.Iterator[None]
├── _main
├── _models
├── _multipart
│   ├── DataField(name: str, value: str | bytes | int | float | None) -> None
│   ├── FileField(name: str, value: FileTypes) -> None
│   ├── MultipartStream(
│   │       data: RequestData,
│   │       files: RequestFiles,
│   │       boundary: bytes | None,
│   │   ) -> None
│   └── get_multipart_boundary_from_content_type(
│           content_type: bytes | None,
│       ) -> bytes | None
├── _status_codes
├── _transports
│   ├── asgi
│   │   ├── ASGIResponseStream(body: list[bytes]) -> None
│   │   ├── create_event() -> Event
│   │   └── is_running_trio() -> bool
│   ├── base
│   ├── default  Custom transports, with nicely configured defaults.
│   │   ├── AsyncResponseStream(httpcore_stream: typing.AsyncIterable[bytes]) ->
│   │   │   None
│   │   ├── ResponseStream(httpcore_stream: typing.Iterable[bytes]) -> None
│   │   └── map_httpcore_exceptions() -> typing.Iterator[None]
│   ├── mock
│   └── wsgi
│       └── WSGIByteStream(result: typing.Iterable[bytes]) -> None
├── _types  Type definitions for type checking purposes.
├── _urlparse  An implementation of `urlparse` that provides URL validation and 
│   normalization
│   ├── PERCENT(string: str) -> str
│   ├── ParseResult(*args, **kwargs)
│   ├── encode_host(host: str) -> str
│   ├── normalize_path(path: str) -> str
│   ├── normalize_port(port: str | int | None, scheme: str) -> int | None
│   ├── percent_encoded(string: str, safe: str) -> str
│   ├── quote(string: str, safe: str) -> str
│   ├── urlparse(url: str, **kwargs: str | None) -> ParseResult
│   └── validate_path(path: str, has_scheme: bool, has_authority: bool) -> None
├── _urls
└── _utils
    ├── URLPattern(pattern: str) -> None
    ├── get_environment_proxies() -> dict[str, str | None]
    ├── is_ipv4_hostname(hostname: str) -> bool
    ├── is_ipv6_hostname(hostname: str) -> bool
    ├── peek_filelike_length(stream: typing.Any) -> int | None
    ├── primitive_value_to_str(value: PrimitiveData) -> str
    ├── to_bytes(value: str | bytes, encoding: str) -> bytes
    ├── to_bytes_or_str(value: str, match_type_of: typing.AnyStr) -> 
    │   typing.AnyStr
    ├── to_str(value: str | bytes, encoding: str) -> str
    └── unquote(value: str) -> str
tests
├── client
├── common
├── concurrency
├── conftest
└── models

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pypatree-0.4.0.tar.gz (73.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pypatree-0.4.0-py3-none-any.whl (17.7 kB view details)

Uploaded Python 3

File details

Details for the file pypatree-0.4.0.tar.gz.

File metadata

  • Download URL: pypatree-0.4.0.tar.gz
  • Upload date:
  • Size: 73.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pypatree-0.4.0.tar.gz
Algorithm Hash digest
SHA256 19586563475c1ab00a6343759409a443365964c0b947436797d4eee652a11c96
MD5 3b541df3026c06421f6e832b2ce603df
BLAKE2b-256 d4acfb35ab6bba17b00610e278db92a3d6cec9f78b23bffb0c73380b7a1bedd9

See more details on using hashes here.

File details

Details for the file pypatree-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: pypatree-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 17.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pypatree-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 eb558c5fd2a50dee6827d32233842bdde1362b64644de4d6b755a1b91a166360
MD5 ef67e3632121568e7e73387a39f85b61
BLAKE2b-256 d14b4057b7b43b46061f2ba96301f14ee30eaabb5aa9e5e175b0cdf3e09a0b0c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page