pretty-mod 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pretty_mod-0.0.1/.github/workflows/publish.yml +20 -0
- pretty_mod-0.0.1/.github/workflows/static-analysis.yml +26 -0
- pretty_mod-0.0.1/.github/workflows/tests.yml +41 -0
- pretty_mod-0.0.1/.gitignore +13 -0
- pretty_mod-0.0.1/.pre-commit-config.yaml +21 -0
- pretty_mod-0.0.1/PKG-INFO +87 -0
- pretty_mod-0.0.1/README.md +79 -0
- pretty_mod-0.0.1/examples/README.md +44 -0
- pretty_mod-0.0.1/examples/advanced_exploration.py +200 -0
- pretty_mod-0.0.1/examples/basic_usage.py +93 -0
- pretty_mod-0.0.1/justfile +36 -0
- pretty_mod-0.0.1/pyproject.toml +34 -0
- pretty_mod-0.0.1/src/pretty_mod/__init__.py +3 -0
- pretty_mod-0.0.1/src/pretty_mod/explorer.py +304 -0
- pretty_mod-0.0.1/src/pretty_mod/py.typed +0 -0
- pretty_mod-0.0.1/tests/__init__.py +0 -0
- pretty_mod-0.0.1/tests/test_explorer.py +213 -0
- pretty_mod-0.0.1/uv.lock +552 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
on:
|
|
3
|
+
release:
|
|
4
|
+
types: [published]
|
|
5
|
+
workflow_dispatch:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
publish-pypi-release:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- name: Checkout
|
|
12
|
+
uses: actions/checkout@v4
|
|
13
|
+
with:
|
|
14
|
+
fetch-depth: 0
|
|
15
|
+
- run: python3 -m pip install --upgrade build && python3 -m build
|
|
16
|
+
- name: Publish package
|
|
17
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
18
|
+
with:
|
|
19
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
20
|
+
verbose: true
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
name: Run static analysis
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ["main"]
|
|
6
|
+
pull_request:
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
static_analysis:
|
|
14
|
+
timeout-minutes: 1
|
|
15
|
+
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
- name: Install uv and set the python version
|
|
21
|
+
uses: astral-sh/setup-uv@v5
|
|
22
|
+
with:
|
|
23
|
+
python-version: "3.10"
|
|
24
|
+
- uses: extractions/setup-just@v3
|
|
25
|
+
- name: Run pre-commit
|
|
26
|
+
run: uv run pre-commit run --all-files
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: Run tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ["main"]
|
|
6
|
+
paths:
|
|
7
|
+
- "src/**/*.py"
|
|
8
|
+
- "tests/**/*.py"
|
|
9
|
+
|
|
10
|
+
pull_request:
|
|
11
|
+
paths:
|
|
12
|
+
- "src/**/*.py"
|
|
13
|
+
- "tests/**/*.py"
|
|
14
|
+
workflow_dispatch:
|
|
15
|
+
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
run_tests:
|
|
21
|
+
# Skip the entire job for fork PRs
|
|
22
|
+
if: ${{ !(github.event.pull_request.head.repo.fork) }}
|
|
23
|
+
name: Python ${{ matrix.python-version }} on ${{ matrix.os }}
|
|
24
|
+
timeout-minutes: 10
|
|
25
|
+
strategy:
|
|
26
|
+
matrix:
|
|
27
|
+
os: [ubuntu-latest]
|
|
28
|
+
python-version: ["3.10"]
|
|
29
|
+
|
|
30
|
+
runs-on: ${{ matrix.os }}
|
|
31
|
+
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@v4
|
|
34
|
+
|
|
35
|
+
- name: Install uv and set the python version
|
|
36
|
+
uses: astral-sh/setup-uv@v5
|
|
37
|
+
with:
|
|
38
|
+
python-version: ${{ matrix.python-version }}
|
|
39
|
+
|
|
40
|
+
- name: Run tests
|
|
41
|
+
run: uv run --frozen pytest
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
3
|
+
# Ruff version.
|
|
4
|
+
rev: v0.9.1
|
|
5
|
+
hooks:
|
|
6
|
+
# Run the linter.
|
|
7
|
+
- id: ruff
|
|
8
|
+
args: [--fix]
|
|
9
|
+
# Run the formatter.
|
|
10
|
+
- id: ruff-format
|
|
11
|
+
- repo: https://github.com/astral-sh/uv-pre-commit
|
|
12
|
+
rev: 0.7.3
|
|
13
|
+
hooks:
|
|
14
|
+
- id: uv-lock
|
|
15
|
+
- repo: local
|
|
16
|
+
hooks:
|
|
17
|
+
- id: ty-check
|
|
18
|
+
name: Typecheck
|
|
19
|
+
entry: just typecheck
|
|
20
|
+
language: system
|
|
21
|
+
pass_filenames: false
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pretty-mod
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: A module tree explorer for humans and LLMs
|
|
5
|
+
Author-email: zzstoatzz <thrast36@gmail.com>
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
|
|
9
|
+
# pretty-mod
|
|
10
|
+
|
|
11
|
+
A module tree explorer for humans and LLMs.
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
uv add pretty-mod
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from pretty_mod.explorer import ModuleTreeExplorer
|
|
23
|
+
|
|
24
|
+
# Explore a module structure
|
|
25
|
+
explorer = ModuleTreeExplorer("json", max_depth=2)
|
|
26
|
+
explorer.explore()
|
|
27
|
+
print(explorer.get_tree_string())
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
<details>
|
|
31
|
+
<summary>Example output</summary>
|
|
32
|
+
|
|
33
|
+
```text
|
|
34
|
+
📦 json
|
|
35
|
+
└── 📜 __all__: dump, dumps, load, loads, JSONDecoder, JSONDecodeError, JSONEncoder
|
|
36
|
+
├── ⚡ functions: dump, dumps, load, loads
|
|
37
|
+
├── 📦 decoder
|
|
38
|
+
├── 📜 __all__: JSONDecoder, JSONDecodeError
|
|
39
|
+
├── 🔷 classes: JSONDecodeError, JSONDecoder
|
|
40
|
+
├── 📦 encoder
|
|
41
|
+
├── 🔷 classes: JSONEncoder
|
|
42
|
+
├── ⚡ functions: py_encode_basestring, py_encode_basestring_ascii
|
|
43
|
+
├── 📦 scanner
|
|
44
|
+
├── 📜 __all__: make_scanner
|
|
45
|
+
└── 📦 tool
|
|
46
|
+
└── ⚡ functions: main
|
|
47
|
+
```
|
|
48
|
+
</details>
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
from pretty_mod.explorer import display_signature
|
|
54
|
+
|
|
55
|
+
# Display function signatures
|
|
56
|
+
print(display_signature("json:loads"))
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
<details>
|
|
60
|
+
<summary>Example output</summary>
|
|
61
|
+
|
|
62
|
+
```text
|
|
63
|
+
📎 loads
|
|
64
|
+
├── Parameters:
|
|
65
|
+
├── s
|
|
66
|
+
├── cls = None (keyword-only)
|
|
67
|
+
├── object_hook = None (keyword-only)
|
|
68
|
+
├── parse_float = None (keyword-only)
|
|
69
|
+
├── parse_int = None (keyword-only)
|
|
70
|
+
├── parse_constant = None (keyword-only)
|
|
71
|
+
├── object_pairs_hook = None (keyword-only)
|
|
72
|
+
└── kw (**kwargs)
|
|
73
|
+
```
|
|
74
|
+
</details>
|
|
75
|
+
|
|
76
|
+
## Examples
|
|
77
|
+
|
|
78
|
+
See the [`examples/`](examples/) directory for more detailed usage patterns and advanced features.
|
|
79
|
+
|
|
80
|
+
## Development
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
git clone https://github.com/zzstoatzz/pretty-mod.git
|
|
84
|
+
cd pretty-mod
|
|
85
|
+
uv sync
|
|
86
|
+
uv run pytest
|
|
87
|
+
```
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# pretty-mod
|
|
2
|
+
|
|
3
|
+
A module tree explorer for humans and LLMs.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
uv add pretty-mod
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from pretty_mod.explorer import ModuleTreeExplorer
|
|
15
|
+
|
|
16
|
+
# Explore a module structure
|
|
17
|
+
explorer = ModuleTreeExplorer("json", max_depth=2)
|
|
18
|
+
explorer.explore()
|
|
19
|
+
print(explorer.get_tree_string())
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
<details>
|
|
23
|
+
<summary>Example output</summary>
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
📦 json
|
|
27
|
+
└── 📜 __all__: dump, dumps, load, loads, JSONDecoder, JSONDecodeError, JSONEncoder
|
|
28
|
+
├── ⚡ functions: dump, dumps, load, loads
|
|
29
|
+
├── 📦 decoder
|
|
30
|
+
├── 📜 __all__: JSONDecoder, JSONDecodeError
|
|
31
|
+
├── 🔷 classes: JSONDecodeError, JSONDecoder
|
|
32
|
+
├── 📦 encoder
|
|
33
|
+
├── 🔷 classes: JSONEncoder
|
|
34
|
+
├── ⚡ functions: py_encode_basestring, py_encode_basestring_ascii
|
|
35
|
+
├── 📦 scanner
|
|
36
|
+
├── 📜 __all__: make_scanner
|
|
37
|
+
└── 📦 tool
|
|
38
|
+
└── ⚡ functions: main
|
|
39
|
+
```
|
|
40
|
+
</details>
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
from pretty_mod.explorer import display_signature
|
|
46
|
+
|
|
47
|
+
# Display function signatures
|
|
48
|
+
print(display_signature("json:loads"))
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
<details>
|
|
52
|
+
<summary>Example output</summary>
|
|
53
|
+
|
|
54
|
+
```text
|
|
55
|
+
📎 loads
|
|
56
|
+
├── Parameters:
|
|
57
|
+
├── s
|
|
58
|
+
├── cls = None (keyword-only)
|
|
59
|
+
├── object_hook = None (keyword-only)
|
|
60
|
+
├── parse_float = None (keyword-only)
|
|
61
|
+
├── parse_int = None (keyword-only)
|
|
62
|
+
├── parse_constant = None (keyword-only)
|
|
63
|
+
├── object_pairs_hook = None (keyword-only)
|
|
64
|
+
└── kw (**kwargs)
|
|
65
|
+
```
|
|
66
|
+
</details>
|
|
67
|
+
|
|
68
|
+
## Examples
|
|
69
|
+
|
|
70
|
+
See the [`examples/`](examples/) directory for more detailed usage patterns and advanced features.
|
|
71
|
+
|
|
72
|
+
## Development
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
git clone https://github.com/zzstoatzz/pretty-mod.git
|
|
76
|
+
cd pretty-mod
|
|
77
|
+
uv sync
|
|
78
|
+
uv run pytest
|
|
79
|
+
```
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Pretty-Mod Examples
|
|
2
|
+
|
|
3
|
+
This directory contains practical examples demonstrating how to use `pretty-mod` for module exploration and code understanding.
|
|
4
|
+
|
|
5
|
+
## Examples
|
|
6
|
+
|
|
7
|
+
### 📚 `basic_usage.py`
|
|
8
|
+
Demonstrates core functionality:
|
|
9
|
+
- Exploring module structures with `ModuleTreeExplorer`
|
|
10
|
+
- Displaying function signatures with `display_signature`
|
|
11
|
+
- Dynamic imports with `import_object`
|
|
12
|
+
- Working with different exploration depths
|
|
13
|
+
|
|
14
|
+
**Run it:**
|
|
15
|
+
```bash
|
|
16
|
+
uv run python examples/basic_usage.py
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### 🚀 `advanced_exploration.py`
|
|
20
|
+
Shows practical use cases:
|
|
21
|
+
- Comparing APIs across related modules
|
|
22
|
+
- Generating module summaries
|
|
23
|
+
- Finding similar functions across codebases
|
|
24
|
+
- Interactive exploration patterns for unfamiliar code
|
|
25
|
+
|
|
26
|
+
**Run it:**
|
|
27
|
+
```bash
|
|
28
|
+
uv run python examples/advanced_exploration.py
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Key Use Cases
|
|
32
|
+
|
|
33
|
+
- **Code Discovery**: Quickly understand the structure of unfamiliar modules
|
|
34
|
+
- **API Comparison**: Compare similar libraries to understand differences
|
|
35
|
+
- **Documentation**: Generate overviews of module capabilities
|
|
36
|
+
- **LLM Integration**: Perfect for AI assistants exploring codebases
|
|
37
|
+
- **Interactive Development**: Dynamically explore and test code
|
|
38
|
+
|
|
39
|
+
## Tips
|
|
40
|
+
|
|
41
|
+
- Start with shallow exploration (`max_depth=1`) for quick overviews
|
|
42
|
+
- Use deeper exploration for detailed analysis
|
|
43
|
+
- Combine signature display with dynamic imports for testing
|
|
44
|
+
- Great for exploring both built-in and third-party modules
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Advanced exploration examples for pretty-mod.
|
|
3
|
+
|
|
4
|
+
This example shows practical use cases for exploring and understanding codebases,
|
|
5
|
+
particularly useful for LLMs and developers working with unfamiliar modules.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from pretty_mod.explorer import ModuleTreeExplorer, display_signature
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def compare_module_apis():
|
|
12
|
+
"""Compare APIs of related modules to understand their differences."""
|
|
13
|
+
print("🔄 Comparing related module APIs:")
|
|
14
|
+
print("=" * 60)
|
|
15
|
+
|
|
16
|
+
modules = ["json", "pickle", "csv"]
|
|
17
|
+
|
|
18
|
+
for module_name in modules:
|
|
19
|
+
print(f"\n📦 {module_name.upper()} module API:")
|
|
20
|
+
print("-" * 30)
|
|
21
|
+
|
|
22
|
+
explorer = ModuleTreeExplorer(module_name, max_depth=1)
|
|
23
|
+
tree = explorer.explore()
|
|
24
|
+
|
|
25
|
+
api = tree.get("api", {})
|
|
26
|
+
|
|
27
|
+
if api.get("functions"):
|
|
28
|
+
print(f"Functions: {', '.join(sorted(api['functions']))}")
|
|
29
|
+
if api.get("classes"):
|
|
30
|
+
print(f"Classes: {', '.join(sorted(api['classes']))}")
|
|
31
|
+
if api.get("constants"):
|
|
32
|
+
print(f"Constants: {', '.join(sorted(api['constants']))}")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def explore_third_party_module():
|
|
36
|
+
"""Example of exploring a third-party module (if available)."""
|
|
37
|
+
print("\n🌐 Exploring third-party modules:")
|
|
38
|
+
print("=" * 60)
|
|
39
|
+
|
|
40
|
+
# Try to explore common third-party modules
|
|
41
|
+
modules_to_try = ["requests", "numpy", "pandas", "pathlib"]
|
|
42
|
+
|
|
43
|
+
for module_name in modules_to_try:
|
|
44
|
+
try:
|
|
45
|
+
explorer = ModuleTreeExplorer(module_name, max_depth=1)
|
|
46
|
+
tree = explorer.explore()
|
|
47
|
+
|
|
48
|
+
if tree.get("api"):
|
|
49
|
+
print(f"\n✅ Found {module_name}:")
|
|
50
|
+
print(explorer.get_tree_string())
|
|
51
|
+
break
|
|
52
|
+
except Exception:
|
|
53
|
+
continue
|
|
54
|
+
else:
|
|
55
|
+
print("\n⚠️ No common third-party modules found.")
|
|
56
|
+
print("Try installing requests or another package to see this in action!")
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def function_signature_analysis():
|
|
60
|
+
"""Analyze function signatures to understand usage patterns."""
|
|
61
|
+
print("\n🔍 Function Signature Analysis:")
|
|
62
|
+
print("=" * 60)
|
|
63
|
+
|
|
64
|
+
# Functions with different signature patterns
|
|
65
|
+
functions = [
|
|
66
|
+
("builtins:print", "Built-in with *args"),
|
|
67
|
+
("json:dumps", "Serialization function"),
|
|
68
|
+
("os.path:join", "Path manipulation"),
|
|
69
|
+
("re:match", "Pattern matching"),
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
for func_path, description in functions:
|
|
73
|
+
try:
|
|
74
|
+
print(f"\n{description}:")
|
|
75
|
+
print(display_signature(func_path))
|
|
76
|
+
except Exception as e:
|
|
77
|
+
print(f"❌ Could not analyze {func_path}: {e}")
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def find_similar_functions():
|
|
81
|
+
"""Find functions with similar names across different modules."""
|
|
82
|
+
print("\n🎯 Finding similar functions across modules:")
|
|
83
|
+
print("=" * 60)
|
|
84
|
+
|
|
85
|
+
target_functions = ["loads", "dumps", "open"]
|
|
86
|
+
modules = ["json", "pickle", "os"]
|
|
87
|
+
|
|
88
|
+
for func_name in target_functions:
|
|
89
|
+
print(f"\nLooking for '{func_name}' functions:")
|
|
90
|
+
|
|
91
|
+
for module_name in modules:
|
|
92
|
+
try:
|
|
93
|
+
explorer = ModuleTreeExplorer(module_name, max_depth=1)
|
|
94
|
+
tree = explorer.explore()
|
|
95
|
+
functions = tree.get("api", {}).get("functions", [])
|
|
96
|
+
|
|
97
|
+
matching = [f for f in functions if func_name in f.lower()]
|
|
98
|
+
if matching:
|
|
99
|
+
print(f" 📦 {module_name}: {', '.join(matching)}")
|
|
100
|
+
except Exception:
|
|
101
|
+
continue
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def generate_module_summary():
|
|
105
|
+
"""Generate a comprehensive summary of a module."""
|
|
106
|
+
print("\n📊 Module Summary Generator:")
|
|
107
|
+
print("=" * 60)
|
|
108
|
+
|
|
109
|
+
module_name = "datetime"
|
|
110
|
+
explorer = ModuleTreeExplorer(module_name, max_depth=2)
|
|
111
|
+
tree = explorer.explore()
|
|
112
|
+
|
|
113
|
+
print(f"Summary for '{module_name}' module:")
|
|
114
|
+
print("-" * 40)
|
|
115
|
+
|
|
116
|
+
api = tree.get("api", {})
|
|
117
|
+
submodules = tree.get("submodules", {})
|
|
118
|
+
|
|
119
|
+
# Main module stats
|
|
120
|
+
print(f"Classes: {len(api.get('classes', []))}")
|
|
121
|
+
print(f"Functions: {len(api.get('functions', []))}")
|
|
122
|
+
print(f"Constants: {len(api.get('constants', []))}")
|
|
123
|
+
print(f"Submodules: {len(submodules)}")
|
|
124
|
+
|
|
125
|
+
if api.get("all"):
|
|
126
|
+
print(f"Public API (__all__): {len(api['all'])} items")
|
|
127
|
+
|
|
128
|
+
# Show class details
|
|
129
|
+
if api.get("classes"):
|
|
130
|
+
print(f"\nMain classes: {', '.join(api['classes'][:5])}")
|
|
131
|
+
if len(api["classes"]) > 5:
|
|
132
|
+
print(f"... and {len(api['classes']) - 5} more")
|
|
133
|
+
|
|
134
|
+
# Show submodule details
|
|
135
|
+
if submodules:
|
|
136
|
+
print("\nSubmodules:")
|
|
137
|
+
for sub_name, sub_tree in list(submodules.items())[:3]:
|
|
138
|
+
sub_api = sub_tree.get("api", {})
|
|
139
|
+
total_items = (
|
|
140
|
+
len(sub_api.get("classes", []))
|
|
141
|
+
+ len(sub_api.get("functions", []))
|
|
142
|
+
+ len(sub_api.get("constants", []))
|
|
143
|
+
)
|
|
144
|
+
print(f" 📦 {sub_name}: {total_items} public items")
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def interactive_exploration():
|
|
148
|
+
"""Show how to use pretty-mod for interactive exploration."""
|
|
149
|
+
print("\n🎮 Interactive Exploration Pattern:")
|
|
150
|
+
print("=" * 60)
|
|
151
|
+
|
|
152
|
+
print("Here's how you might explore an unfamiliar module step by step:")
|
|
153
|
+
print()
|
|
154
|
+
|
|
155
|
+
# Step 1: High-level overview
|
|
156
|
+
print("1. Get a high-level overview:")
|
|
157
|
+
print(" explorer = ModuleTreeExplorer('os', max_depth=1)")
|
|
158
|
+
print(" print(explorer.get_tree_string())")
|
|
159
|
+
print()
|
|
160
|
+
|
|
161
|
+
# Step 2: Deep dive
|
|
162
|
+
print("2. Deep dive into interesting submodules:")
|
|
163
|
+
print(" explorer = ModuleTreeExplorer('os.path', max_depth=2)")
|
|
164
|
+
print(" print(explorer.get_tree_string())")
|
|
165
|
+
print()
|
|
166
|
+
|
|
167
|
+
# Step 3: Function analysis
|
|
168
|
+
print("3. Analyze specific functions:")
|
|
169
|
+
print(" print(display_signature('os.path:join'))")
|
|
170
|
+
print(" print(display_signature('os:getcwd'))")
|
|
171
|
+
print()
|
|
172
|
+
|
|
173
|
+
# Step 4: Dynamic testing
|
|
174
|
+
print("4. Dynamically import and test:")
|
|
175
|
+
print(" join_func = import_object('os.path:join')")
|
|
176
|
+
print(" result = join_func('home', 'user', 'documents')")
|
|
177
|
+
print()
|
|
178
|
+
|
|
179
|
+
# Demonstrate this pattern
|
|
180
|
+
print("Let's run this pattern on the 'pathlib' module:")
|
|
181
|
+
try:
|
|
182
|
+
explorer = ModuleTreeExplorer("pathlib", max_depth=1)
|
|
183
|
+
explorer.explore()
|
|
184
|
+
print(explorer.get_tree_string())
|
|
185
|
+
except Exception as e:
|
|
186
|
+
print(f"Could not explore pathlib: {e}")
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
if __name__ == "__main__":
|
|
190
|
+
print("🚀 Advanced pretty-mod exploration examples")
|
|
191
|
+
print("=" * 70)
|
|
192
|
+
|
|
193
|
+
compare_module_apis()
|
|
194
|
+
explore_third_party_module()
|
|
195
|
+
function_signature_analysis()
|
|
196
|
+
find_similar_functions()
|
|
197
|
+
generate_module_summary()
|
|
198
|
+
interactive_exploration()
|
|
199
|
+
|
|
200
|
+
print("\n🎯 These patterns help you quickly understand any Python codebase!")
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Basic usage examples for pretty-mod.
|
|
3
|
+
|
|
4
|
+
This example demonstrates how to explore module structures and display function signatures.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from pretty_mod.explorer import ModuleTreeExplorer, display_signature, import_object
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def explore_json_module():
|
|
11
|
+
"""Example: Explore the built-in json module structure."""
|
|
12
|
+
print("🔍 Exploring the json module:")
|
|
13
|
+
print("=" * 50)
|
|
14
|
+
|
|
15
|
+
explorer = ModuleTreeExplorer("json", max_depth=2)
|
|
16
|
+
explorer.explore()
|
|
17
|
+
|
|
18
|
+
# Display the tree structure
|
|
19
|
+
tree_string = explorer.get_tree_string()
|
|
20
|
+
print(tree_string)
|
|
21
|
+
print()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def explore_function_signature():
|
|
25
|
+
"""Example: Display function signatures in a readable format."""
|
|
26
|
+
print("📋 Function Signature Examples:")
|
|
27
|
+
print("=" * 50)
|
|
28
|
+
|
|
29
|
+
# Example with a built-in function
|
|
30
|
+
print("Built-in function:")
|
|
31
|
+
print(display_signature("builtins:len"))
|
|
32
|
+
print()
|
|
33
|
+
|
|
34
|
+
# Example with a module function
|
|
35
|
+
print("Module function:")
|
|
36
|
+
print(display_signature("json:loads"))
|
|
37
|
+
print()
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def import_and_use_objects():
|
|
41
|
+
"""Example: Import objects dynamically using import paths."""
|
|
42
|
+
print("📦 Dynamic Import Examples:")
|
|
43
|
+
print("=" * 50)
|
|
44
|
+
|
|
45
|
+
# Import using colon syntax
|
|
46
|
+
json_loads = import_object("json:loads")
|
|
47
|
+
print(f"Imported json.loads: {json_loads}")
|
|
48
|
+
|
|
49
|
+
# Test the imported function
|
|
50
|
+
test_data = '{"name": "pretty-mod", "type": "module"}'
|
|
51
|
+
parsed = json_loads(test_data)
|
|
52
|
+
print(f"Parsed JSON: {parsed}")
|
|
53
|
+
print()
|
|
54
|
+
|
|
55
|
+
# Import using dot syntax
|
|
56
|
+
sys_version = import_object("sys.version_info")
|
|
57
|
+
print(
|
|
58
|
+
f"Python version: {sys_version.major}.{sys_version.minor}.{sys_version.micro}"
|
|
59
|
+
)
|
|
60
|
+
print()
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def explore_custom_depth():
|
|
64
|
+
"""Example: Explore modules with different depth limits."""
|
|
65
|
+
print("🏗️ Exploring with different depths:")
|
|
66
|
+
print("=" * 50)
|
|
67
|
+
|
|
68
|
+
# Shallow exploration
|
|
69
|
+
print("Shallow exploration (depth=1):")
|
|
70
|
+
explorer_shallow = ModuleTreeExplorer("urllib", max_depth=1)
|
|
71
|
+
explorer_shallow.explore()
|
|
72
|
+
print(explorer_shallow.get_tree_string())
|
|
73
|
+
print()
|
|
74
|
+
|
|
75
|
+
# Deeper exploration
|
|
76
|
+
print("Deeper exploration (depth=2):")
|
|
77
|
+
explorer_deep = ModuleTreeExplorer("urllib", max_depth=2)
|
|
78
|
+
explorer_deep.explore()
|
|
79
|
+
print(explorer_deep.get_tree_string())
|
|
80
|
+
print()
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
if __name__ == "__main__":
|
|
84
|
+
print("🎉 Welcome to pretty-mod examples!")
|
|
85
|
+
print("=" * 60)
|
|
86
|
+
print()
|
|
87
|
+
|
|
88
|
+
explore_json_module()
|
|
89
|
+
explore_function_signature()
|
|
90
|
+
import_and_use_objects()
|
|
91
|
+
explore_custom_depth()
|
|
92
|
+
|
|
93
|
+
print("✨ That's pretty-mod in action! ✨")
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Check for uv installation
|
|
2
|
+
check-uv:
|
|
3
|
+
#!/usr/bin/env sh
|
|
4
|
+
if ! command -v uv >/dev/null 2>&1; then
|
|
5
|
+
echo "uv is not installed or not found in expected locations."
|
|
6
|
+
case "$(uname)" in
|
|
7
|
+
"Darwin")
|
|
8
|
+
echo "To install uv on macOS, run one of:"
|
|
9
|
+
echo "• brew install uv"
|
|
10
|
+
echo "• curl -LsSf https://astral.sh/uv/install.sh | sh"
|
|
11
|
+
;;
|
|
12
|
+
"Linux")
|
|
13
|
+
echo "To install uv, run:"
|
|
14
|
+
echo "• curl -LsSf https://astral.sh/uv/install.sh | sh"
|
|
15
|
+
;;
|
|
16
|
+
*)
|
|
17
|
+
echo "To install uv, visit: https://github.com/astral-sh/uv"
|
|
18
|
+
;;
|
|
19
|
+
esac
|
|
20
|
+
exit 1
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
# Install development dependencies
|
|
24
|
+
install: check-uv
|
|
25
|
+
uv sync
|
|
26
|
+
|
|
27
|
+
typecheck: check-uv
|
|
28
|
+
uv run ty check
|
|
29
|
+
|
|
30
|
+
# Clean up environment
|
|
31
|
+
clean: check-uv
|
|
32
|
+
deactivate || true
|
|
33
|
+
rm -rf .venv
|
|
34
|
+
|
|
35
|
+
run-pre-commits: check-uv
|
|
36
|
+
uv run pre-commit run --all-files
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "pretty-mod"
|
|
3
|
+
description = "A module tree explorer for humans and LLMs"
|
|
4
|
+
readme = "README.md"
|
|
5
|
+
authors = [{ name = "zzstoatzz", email = "thrast36@gmail.com" }]
|
|
6
|
+
requires-python = ">=3.10"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
dependencies = []
|
|
9
|
+
|
|
10
|
+
[dependency-groups]
|
|
11
|
+
dev = ["pytest-sugar", "ruff", "ty", "ipython", "pre-commit"]
|
|
12
|
+
|
|
13
|
+
[build-system]
|
|
14
|
+
requires = ["hatchling>=1.21.0", "hatch-vcs>=0.4.0"]
|
|
15
|
+
build-backend = "hatchling.build"
|
|
16
|
+
|
|
17
|
+
[tool.hatch.build.targets.wheel]
|
|
18
|
+
packages = ["src/pretty_mod"]
|
|
19
|
+
|
|
20
|
+
[tool.hatch.metadata]
|
|
21
|
+
allow-direct-references = true
|
|
22
|
+
|
|
23
|
+
[tool.hatch.version]
|
|
24
|
+
source = "vcs"
|
|
25
|
+
|
|
26
|
+
[tool.ruff.lint]
|
|
27
|
+
extend-select = ["I", "UP"]
|
|
28
|
+
|
|
29
|
+
[tool.ty.src]
|
|
30
|
+
root = "./src"
|
|
31
|
+
|
|
32
|
+
[tool.pytest.ini_options]
|
|
33
|
+
testpaths = ["tests"]
|
|
34
|
+
addopts = ["-v", "--strict-markers"]
|