depcycle 0.2.2__tar.gz → 0.2.3__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.
- {depcycle-0.2.2/src/depcycle.egg-info → depcycle-0.2.3}/PKG-INFO +12 -3
- {depcycle-0.2.2 → depcycle-0.2.3}/README.md +11 -2
- {depcycle-0.2.2 → depcycle-0.2.3}/pyproject.toml +1 -1
- {depcycle-0.2.2 → depcycle-0.2.3}/src/depcycle/graph/dependency_graph.py +37 -10
- {depcycle-0.2.2 → depcycle-0.2.3/src/depcycle.egg-info}/PKG-INFO +12 -3
- {depcycle-0.2.2 → depcycle-0.2.3}/LICENSE +0 -0
- {depcycle-0.2.2 → depcycle-0.2.3}/setup.cfg +0 -0
- {depcycle-0.2.2 → depcycle-0.2.3}/src/depcycle/__init__.py +0 -0
- {depcycle-0.2.2 → depcycle-0.2.3}/src/depcycle/__main__.py +0 -0
- {depcycle-0.2.2 → depcycle-0.2.3}/src/depcycle/cli.py +0 -0
- {depcycle-0.2.2 → depcycle-0.2.3}/src/depcycle/config.py +0 -0
- {depcycle-0.2.2 → depcycle-0.2.3}/src/depcycle/graph/__init__.py +0 -0
- {depcycle-0.2.2 → depcycle-0.2.3}/src/depcycle/graph/module_node.py +0 -0
- {depcycle-0.2.2 → depcycle-0.2.3}/src/depcycle/parsing/__init__.py +0 -0
- {depcycle-0.2.2 → depcycle-0.2.3}/src/depcycle/parsing/ast_parser.py +0 -0
- {depcycle-0.2.2 → depcycle-0.2.3}/src/depcycle/parsing/project.py +0 -0
- {depcycle-0.2.2 → depcycle-0.2.3}/src/depcycle/rendering/__init__.py +0 -0
- {depcycle-0.2.2 → depcycle-0.2.3}/src/depcycle/rendering/interface.py +0 -0
- {depcycle-0.2.2 → depcycle-0.2.3}/src/depcycle/rendering/visualizers.py +0 -0
- {depcycle-0.2.2 → depcycle-0.2.3}/src/depcycle.egg-info/SOURCES.txt +0 -0
- {depcycle-0.2.2 → depcycle-0.2.3}/src/depcycle.egg-info/dependency_links.txt +0 -0
- {depcycle-0.2.2 → depcycle-0.2.3}/src/depcycle.egg-info/entry_points.txt +0 -0
- {depcycle-0.2.2 → depcycle-0.2.3}/src/depcycle.egg-info/requires.txt +0 -0
- {depcycle-0.2.2 → depcycle-0.2.3}/src/depcycle.egg-info/top_level.txt +0 -0
- {depcycle-0.2.2 → depcycle-0.2.3}/tests/test_ast_parser.py +0 -0
- {depcycle-0.2.2 → depcycle-0.2.3}/tests/test_dependency_graph.py +0 -0
- {depcycle-0.2.2 → depcycle-0.2.3}/tests/test_project.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: depcycle
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: Command-line tool to visualize Python project dependencies.
|
|
5
5
|
Author: DepCycle Maintainers
|
|
6
6
|
License: MIT License
|
|
@@ -54,8 +54,13 @@ Dynamic: license-file
|
|
|
54
54
|
|
|
55
55
|
# DepCycle
|
|
56
56
|
|
|
57
|
-
[](https://www.python.org/downloads/)
|
|
59
|
+
[](https://opensource.org/licenses/MIT)
|
|
61
|
+
[](https://pepy.tech/project/depcycle)
|
|
62
|
+
[](https://pypi.org/project/depcycle/)
|
|
59
64
|
|
|
60
65
|
**DepCycle** is a command-line tool to visualize Python project dependencies. It helps developers understand complex codebases by automatically generating visual maps of how modules are connected, making it easy to spot architectural problems like **circular dependencies** and untangle coupled code.
|
|
61
66
|
|
|
@@ -251,6 +256,10 @@ If circular dependencies are found:
|
|
|
251
256
|
Cycle 2: app.core.database → app.core.config → app.core.database
|
|
252
257
|
```
|
|
253
258
|
|
|
259
|
+
## Analytics
|
|
260
|
+
- https://pepy.tech/project/depcycle
|
|
261
|
+
- https://pypistats.org/packages/depcycle
|
|
262
|
+
|
|
254
263
|
## Contributing
|
|
255
264
|
|
|
256
265
|
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
# DepCycle
|
|
2
2
|
|
|
3
|
-
[](https://www.python.org/downloads/)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://pepy.tech/project/depcycle)
|
|
8
|
+
[](https://pypi.org/project/depcycle/)
|
|
5
10
|
|
|
6
11
|
**DepCycle** is a command-line tool to visualize Python project dependencies. It helps developers understand complex codebases by automatically generating visual maps of how modules are connected, making it easy to spot architectural problems like **circular dependencies** and untangle coupled code.
|
|
7
12
|
|
|
@@ -197,6 +202,10 @@ If circular dependencies are found:
|
|
|
197
202
|
Cycle 2: app.core.database → app.core.config → app.core.database
|
|
198
203
|
```
|
|
199
204
|
|
|
205
|
+
## Analytics
|
|
206
|
+
- https://pepy.tech/project/depcycle
|
|
207
|
+
- https://pypistats.org/packages/depcycle
|
|
208
|
+
|
|
200
209
|
## Contributing
|
|
201
210
|
|
|
202
211
|
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
"""DependencyGraph class representing the core graph data structure."""
|
|
2
2
|
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
from
|
|
5
|
-
|
|
6
|
-
from .module_node import ModuleNode, ModuleType
|
|
4
|
+
from ..config import Config
|
|
7
5
|
from ..parsing.project import Project
|
|
8
6
|
from ..parsing.ast_parser import ASTParser
|
|
9
|
-
from
|
|
10
|
-
|
|
7
|
+
from typing import Dict, List, Set, Optional
|
|
8
|
+
from .module_node import ModuleNode, ModuleType
|
|
11
9
|
|
|
12
10
|
class DependencyGraph:
|
|
13
11
|
"""
|
|
@@ -21,6 +19,7 @@ class DependencyGraph:
|
|
|
21
19
|
"""Initialize an empty dependency graph."""
|
|
22
20
|
self.nodes: Dict[str, ModuleNode] = {}
|
|
23
21
|
self._project_root: Optional[Path] = None
|
|
22
|
+
self._analysis_root: Optional[Path] = None
|
|
24
23
|
|
|
25
24
|
def build(self, project: Project, parser: ASTParser, config: Config):
|
|
26
25
|
"""
|
|
@@ -39,9 +38,13 @@ class DependencyGraph:
|
|
|
39
38
|
config: Configuration settings for filtering.
|
|
40
39
|
"""
|
|
41
40
|
self._project_root = project.root_path
|
|
41
|
+
self._analysis_root = project.root_path
|
|
42
42
|
|
|
43
43
|
# Step 1: Discover all Python files
|
|
44
|
-
python_files = project.get_python_files(
|
|
44
|
+
python_files = project.get_python_files(
|
|
45
|
+
config.exclude_patterns,
|
|
46
|
+
not config.include_all
|
|
47
|
+
)
|
|
45
48
|
|
|
46
49
|
# Step 2: Create nodes for each Python file
|
|
47
50
|
for file_path in python_files:
|
|
@@ -105,6 +108,7 @@ class DependencyGraph:
|
|
|
105
108
|
- Absolute imports: 'os' -> looks for 'os' in graph
|
|
106
109
|
- Relative imports: '.utils' -> resolves relative to current_module
|
|
107
110
|
- Dotted imports: 'app.models' -> tries to find exact or parent module
|
|
111
|
+
- Absolute imports with project prefix when analyzing subdirectories
|
|
108
112
|
|
|
109
113
|
Args:
|
|
110
114
|
import_str: The raw import string.
|
|
@@ -124,12 +128,36 @@ class DependencyGraph:
|
|
|
124
128
|
if import_str in self.nodes:
|
|
125
129
|
return self.nodes[import_str]
|
|
126
130
|
|
|
131
|
+
# NEW: Handle absolute imports that reference parent package
|
|
132
|
+
# When analyzing subdirectory, imports like "app.models" might actually mean "models"
|
|
133
|
+
if self._project_root and '.' in import_str:
|
|
134
|
+
# Get the project root name (last part of the path)
|
|
135
|
+
project_root_name = self._project_root.name
|
|
136
|
+
|
|
137
|
+
# Check if import starts with project root name
|
|
138
|
+
if import_str.startswith(project_root_name + '.'):
|
|
139
|
+
# Strip the project root prefix and try again
|
|
140
|
+
stripped_import = import_str[len(project_root_name) + 1:]
|
|
141
|
+
if stripped_import in self.nodes:
|
|
142
|
+
return self.nodes[stripped_import]
|
|
143
|
+
|
|
144
|
+
# Also try variants of the stripped import
|
|
145
|
+
for variant in self._get_import_variants(stripped_import):
|
|
146
|
+
if variant in self.nodes:
|
|
147
|
+
return self.nodes[variant]
|
|
148
|
+
|
|
127
149
|
# Try to find the parent module of the import
|
|
128
|
-
# e.g., 'os.path.join' -> look for 'os' or 'os.path' or 'os.path.join'
|
|
129
|
-
# e.g., 'config.Config' -> look for 'config'
|
|
130
150
|
for potential_module in self._get_import_variants(import_str):
|
|
131
151
|
if potential_module in self.nodes:
|
|
132
152
|
return self.nodes[potential_module]
|
|
153
|
+
|
|
154
|
+
# NEW: Also try stripping project root from variants
|
|
155
|
+
if self._project_root and '.' in potential_module:
|
|
156
|
+
project_root_name = self._project_root.name
|
|
157
|
+
if potential_module.startswith(project_root_name + '.'):
|
|
158
|
+
stripped_variant = potential_module[len(project_root_name) + 1:]
|
|
159
|
+
if stripped_variant in self.nodes:
|
|
160
|
+
return self.nodes[stripped_variant]
|
|
133
161
|
|
|
134
162
|
return None
|
|
135
163
|
|
|
@@ -337,5 +365,4 @@ class DependencyGraph:
|
|
|
337
365
|
|
|
338
366
|
def __iter__(self):
|
|
339
367
|
"""Allow iteration over nodes."""
|
|
340
|
-
return iter(self.nodes.values())
|
|
341
|
-
|
|
368
|
+
return iter(self.nodes.values())
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: depcycle
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: Command-line tool to visualize Python project dependencies.
|
|
5
5
|
Author: DepCycle Maintainers
|
|
6
6
|
License: MIT License
|
|
@@ -54,8 +54,13 @@ Dynamic: license-file
|
|
|
54
54
|
|
|
55
55
|
# DepCycle
|
|
56
56
|
|
|
57
|
-
[](https://www.python.org/downloads/)
|
|
59
|
+
[](https://opensource.org/licenses/MIT)
|
|
61
|
+
[](https://pepy.tech/project/depcycle)
|
|
62
|
+
[](https://pypi.org/project/depcycle/)
|
|
59
64
|
|
|
60
65
|
**DepCycle** is a command-line tool to visualize Python project dependencies. It helps developers understand complex codebases by automatically generating visual maps of how modules are connected, making it easy to spot architectural problems like **circular dependencies** and untangle coupled code.
|
|
61
66
|
|
|
@@ -251,6 +256,10 @@ If circular dependencies are found:
|
|
|
251
256
|
Cycle 2: app.core.database → app.core.config → app.core.database
|
|
252
257
|
```
|
|
253
258
|
|
|
259
|
+
## Analytics
|
|
260
|
+
- https://pepy.tech/project/depcycle
|
|
261
|
+
- https://pypistats.org/packages/depcycle
|
|
262
|
+
|
|
254
263
|
## Contributing
|
|
255
264
|
|
|
256
265
|
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|