Metadata-Version: 2.3
Name: phy-imports-resolver
Version: 0.1.5
Summary: Resolve imports of a python file or module, with site packages & builtin modules excluded.
Author: Alfred DU
Author-email: Alfred DU <ihearmywords@hotmail.com>
License: MIT
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Dist: typer>=0.20.0,<0.21.0 ; extra == 'cli'
Requires-Dist: graphviz>=0.21,<0.22 ; extra == 'cli'
Requires-Dist: gitpython>=3.1.44 ; extra == 'dev'
Requires-Dist: graphviz>=0.21 ; extra == 'dev'
Requires-Dist: mypy>=1.18.2 ; extra == 'dev'
Requires-Dist: pydoc-markdown>=4.8.2 ; extra == 'dev'
Requires-Dist: pylint>=4.0.2 ; extra == 'dev'
Requires-Dist: pytest-dependency>=0.6.0 ; extra == 'dev'
Requires-Dist: pytest>=8.3.5 ; extra == 'dev'
Requires-Dist: requests>=2.32.3 ; extra == 'dev'
Requires-Dist: tox>=4.32.0 ; extra == 'dev'
Requires-Dist: typer>=0.20.0 ; extra == 'dev'
Requires-Python: >=3.10, <4
Project-URL: Homepage, https://github.com/phy-precompiler/imports-resolver
Project-URL: Repository, https://github.com/phy-precompiler/imports-resolver
Project-URL: Issues, https://github.com/phy-precompiler/imports-resolver/issues
Provides-Extra: cli
Provides-Extra: dev
Description-Content-Type: text/markdown

# PHY-imports-resolver

<p align="left">
  <a href="#"><img alt="PyPI" src="https://img.shields.io/pypi/v/phy-imports-resolver.svg"></a>
  <a href="#"><img alt="Python Versions" src="https://img.shields.io/pypi/pyversions/phy-imports-resolver.svg"></a>
  <a href="#"><img alt="License" src="https://img.shields.io/badge/license-MIT-blue.svg"></a>
</p>

Resolve imports of a python file or module recursively, exclude site packages & builtin modules.

This project is part of [`phy`](https://github.com/phy-precompiler).

## Install

If you intend to use this package as a library within your Python project, install it as follows:

```shell
pip install phy-imports-resolver
```

If you plan to use its command-line interface (CLI) to generate graphic diagram, install the `cli` 
optional dependencies:

```shell
pip install phy-imports-resolver[cli]
```

## How to use

Suppose the layout of your python project is:

```shell
src/
├──my_project/
│  ├──file1.py
│  ├──file2.py
│  ├──pkg1.py
│  │  ├── file3.py
│  │  └── __init__.py
│  └──__init__.py
└──script1.py
```

To resolve the imports tree: 

+ Firstly you MUST specify a root directory named `project_dir` to search within; in this case, 
it is `src`. If `project_dir` is not explicitly provided, current directory is used.

+ An entry file path is also required as the start point for the resolver to search from. If you want to resolve from a package instead of a file, use the `__init__.py` file of the package as the entry file.

In this case, if `script1.py` is the entry file to resolve, call the `resolve(entry_file)` method:

```python
import phy_imports_resolver
from pathlib import Path

project_dir = Path('./src')
entry_file = project_dir / 'script1.py'

mod_imports_node = phy_imports_resolver.resolve(entry_file, project_dir)
```

The result `mod_imports_node` is a `ModuleImportsNode` object, which represents a file module or sub package in a hierarchical tree structure of importing relationship. See the definition of `ModuleImportsNode`:

```python
class ModuleImportsNode:
    def __init__(self, mod, project_dir, imports: List['ModuleImportsNode'], **kwargs):
      ...
```

where attribute `mod` stands for the file or package itself, and list attribute `imports` holds other modules imported to itself.

Recursively iterate the `imports` attributes of the entry `ModuleImportsNode` object will given the entire importing relationship tree. 

The complete API docs can be found [here](./docs/module.md).

### use the CLI

```shell
Usage: phy-resolve-imports [OPTIONS] FILE

  Resolve the imports of a python file or module, recursively.

  FILE: path to the entry code file; to resolve package, use path 
        of the `__init__.py` file of the package.

Options:
  -f, --format [xml|png|svg]  Specify the output format  [default: xml]
  -o, --output PATH           Optional output file path.
  --help                      Show this message and exit.
```

For the CLI, current work directory will be used as the root directory to search within.

# API docs

+ [module](docs/module.md)
+ [resolver](docs/resolver.md)
+ [types](docs/types.md)

These markdown docs are generated by [`pydoc-markdown`](https://pypi.org/project/pydoc-markdown/):

```shell
pydoc-markdown -I src -m phy_imports_resolver --render-toc > docs/module.md

pydoc-markdown -I src -m phy_imports_resolver.resolver --render-toc > docs/resolver.md

pydoc-markdown -I src -m phy_imports_resolver.types --render-toc > docs/types.md
```

## Reminder

This package DOES NOT support `importlib` to dynamically import modules, for the module imported by `importlib` can be
variable and thus can only be determined at runtime; otherwise, if the the module imported by `importlib` is
constant string, the developer can absolutely use import statement (non-top-placed) instead.


# Develop

Build the package with `uv`:

```shell
uv build
```
