pydry-cli 0.0.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.
@@ -0,0 +1,22 @@
1
+
2
+ MIT License
3
+
4
+ Copyright (c) 2026 Really Him
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
@@ -0,0 +1,216 @@
1
+ Metadata-Version: 2.4
2
+ Name: pydry-cli
3
+ Version: 0.0.3
4
+ Summary: AST-based duplicate and structural similarity detector for Python
5
+ Author: Really Him
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/hesreallyhim/pydry
8
+ Project-URL: Repository, https://github.com/hesreallyhim/pydry
9
+ Project-URL: Issues, https://github.com/hesreallyhim/pydry/issues
10
+ Keywords: ast,cli,code-analysis,duplicates,refactoring
11
+ Classifier: Development Status :: 2 - Pre-Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Software Development :: Quality Assurance
19
+ Classifier: Topic :: Utilities
20
+ Requires-Python: >=3.11
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Provides-Extra: dev
24
+ Requires-Dist: build>=1.2; extra == "dev"
25
+ Requires-Dist: pytest>=8.0; extra == "dev"
26
+ Requires-Dist: pytest-cov>=6.0; extra == "dev"
27
+ Requires-Dist: ruff>=0.9; extra == "dev"
28
+ Requires-Dist: mypy>=1.14; extra == "dev"
29
+ Requires-Dist: pre-commit>=4.0; extra == "dev"
30
+ Requires-Dist: twine>=6.0; extra == "dev"
31
+ Dynamic: license-file
32
+
33
+ # pydry
34
+
35
+ `pydry` is a small Python CLI for finding exact duplicate functions and structurally similar functions in Python code.
36
+
37
+ ## Features
38
+
39
+ - Finds exact duplicate functions using AST normalization.
40
+ - Ranks near matches by structural similarity and refactorability.
41
+ - Flags likely abstraction candidates and common risk signals.
42
+ - Emits text output for quick inspection and JSON output for automation.
43
+ - Runs without third-party runtime dependencies.
44
+
45
+ ## Installation
46
+
47
+ ```bash
48
+ python -m pip install pydry-cli
49
+ ```
50
+
51
+ For local development from a checkout:
52
+
53
+ ```bash
54
+ make venv
55
+ source venv/bin/activate
56
+ make install
57
+ make check
58
+ ```
59
+
60
+ ## Quick start
61
+
62
+ Run a compact summary for the current directory:
63
+
64
+ ```bash
65
+ pydry showcase
66
+ ```
67
+
68
+ Find exact duplicates:
69
+
70
+ ```bash
71
+ pydry exact ./src --normalize-local-names --normalize-constants
72
+ ```
73
+
74
+ Find near matches:
75
+
76
+ ```bash
77
+ pydry near ./src --threshold 0.85 --top-k 25
78
+ ```
79
+
80
+ Write a full JSON report:
81
+
82
+ ```bash
83
+ pydry report ./src --output reports/pydry-report.json
84
+ ```
85
+
86
+ ## Commands
87
+
88
+ ### `pydry exact`
89
+
90
+ Find exact duplicate functions after AST normalization.
91
+
92
+ ```bash
93
+ pydry exact ./src
94
+ pydry exact ./src --min-count 3
95
+ pydry exact ./src --normalize-local-names --normalize-constants
96
+ pydry exact ./src --format json
97
+ ```
98
+
99
+ Useful options:
100
+
101
+ - `--min-count`: minimum group size, default `2`.
102
+ - `--top-level-only`: ignore nested functions and methods.
103
+ - `--normalize-local-names`: treat local variable renames as equivalent.
104
+ - `--normalize-constants`: treat many literal value changes as equivalent.
105
+ - `--include-canonical`: include canonical AST dumps in JSON output.
106
+ - `--strict`: fail on files that cannot be read or parsed.
107
+
108
+ ### `pydry near`
109
+
110
+ Rank structurally similar function pairs.
111
+
112
+ ```bash
113
+ pydry near ./src
114
+ pydry near ./src --threshold 0.85 --top-k 25
115
+ pydry near ./src --format json --output reports/near.json
116
+ ```
117
+
118
+ Useful options:
119
+
120
+ - `--threshold`: similarity threshold from `0` to `1`, default `0.8`.
121
+ - `--top-k`: cap the number of returned pairs.
122
+ - `--top-level-only`: ignore nested functions and methods.
123
+ - `--strict`: fail on files that cannot be read or parsed.
124
+
125
+ ### `pydry abstract`
126
+
127
+ Filter near matches to pairs that look like plausible refactor candidates.
128
+
129
+ ```bash
130
+ pydry abstract ./src
131
+ pydry abstract ./src --threshold 0.86 --format json
132
+ ```
133
+
134
+ ### `pydry report`
135
+
136
+ Generate one JSON document with exact, near, and abstract sections.
137
+
138
+ ```bash
139
+ pydry report ./src
140
+ pydry report ./src --threshold 0.82 --top-k 250 --output reports/pydry-report.json
141
+ ```
142
+
143
+ ### `pydry showcase` and `pydry simulate`
144
+
145
+ Run a compact terminal summary. Both commands use the same analysis pipeline. With no path, they scan the current directory.
146
+
147
+ ```bash
148
+ pydry showcase
149
+ pydry showcase ./src --top-k 10 --threshold 0.8
150
+ pydry showcase ./src --format json
151
+ pydry simulate ./src
152
+ ```
153
+
154
+ ## JSON output
155
+
156
+ JSON-capable commands return an envelope:
157
+
158
+ ```json
159
+ {
160
+ "results": [],
161
+ "diagnostics": {
162
+ "scan_errors_count": 0,
163
+ "scan_error_samples": [],
164
+ "plugin_errors_count": 0,
165
+ "plugin_error_samples": []
166
+ }
167
+ }
168
+ ```
169
+
170
+ Near and abstract entries include:
171
+
172
+ - `similarity_score`
173
+ - `refactorability_score`
174
+ - `pattern_labels`
175
+ - `shared_structure_summary`
176
+ - `key_differences`
177
+ - `risk_flags`
178
+ - `suggested_refactor_kind`
179
+ - `evidence`
180
+
181
+ ## Python API
182
+
183
+ The CLI is the primary interface, but the core functions are importable:
184
+
185
+ ```python
186
+ from pathlib import Path
187
+
188
+ from pydry.engine import exact_groups, near_matches
189
+
190
+ groups = exact_groups(
191
+ Path("src"),
192
+ normalize_local_names=True,
193
+ normalize_constants=True,
194
+ )
195
+ rows = near_matches(Path("src"), threshold=0.85, top_k=25)
196
+ ```
197
+
198
+ ## Limitations
199
+
200
+ - Similarity is heuristic. It does not prove semantic equivalence.
201
+ - Cross-file import resolution is not attempted.
202
+ - Generated abstraction templates are suggestions, not executable patches.
203
+
204
+ ## Development
205
+
206
+ ```bash
207
+ make check
208
+ make coverage
209
+ make check-dist
210
+ ```
211
+
212
+ The package supports Python 3.11 and newer.
213
+
214
+ ## License
215
+
216
+ `pydry` is released under the MIT License. See [LICENSE](LICENSE).
@@ -0,0 +1,184 @@
1
+ # pydry
2
+
3
+ `pydry` is a small Python CLI for finding exact duplicate functions and structurally similar functions in Python code.
4
+
5
+ ## Features
6
+
7
+ - Finds exact duplicate functions using AST normalization.
8
+ - Ranks near matches by structural similarity and refactorability.
9
+ - Flags likely abstraction candidates and common risk signals.
10
+ - Emits text output for quick inspection and JSON output for automation.
11
+ - Runs without third-party runtime dependencies.
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ python -m pip install pydry-cli
17
+ ```
18
+
19
+ For local development from a checkout:
20
+
21
+ ```bash
22
+ make venv
23
+ source venv/bin/activate
24
+ make install
25
+ make check
26
+ ```
27
+
28
+ ## Quick start
29
+
30
+ Run a compact summary for the current directory:
31
+
32
+ ```bash
33
+ pydry showcase
34
+ ```
35
+
36
+ Find exact duplicates:
37
+
38
+ ```bash
39
+ pydry exact ./src --normalize-local-names --normalize-constants
40
+ ```
41
+
42
+ Find near matches:
43
+
44
+ ```bash
45
+ pydry near ./src --threshold 0.85 --top-k 25
46
+ ```
47
+
48
+ Write a full JSON report:
49
+
50
+ ```bash
51
+ pydry report ./src --output reports/pydry-report.json
52
+ ```
53
+
54
+ ## Commands
55
+
56
+ ### `pydry exact`
57
+
58
+ Find exact duplicate functions after AST normalization.
59
+
60
+ ```bash
61
+ pydry exact ./src
62
+ pydry exact ./src --min-count 3
63
+ pydry exact ./src --normalize-local-names --normalize-constants
64
+ pydry exact ./src --format json
65
+ ```
66
+
67
+ Useful options:
68
+
69
+ - `--min-count`: minimum group size, default `2`.
70
+ - `--top-level-only`: ignore nested functions and methods.
71
+ - `--normalize-local-names`: treat local variable renames as equivalent.
72
+ - `--normalize-constants`: treat many literal value changes as equivalent.
73
+ - `--include-canonical`: include canonical AST dumps in JSON output.
74
+ - `--strict`: fail on files that cannot be read or parsed.
75
+
76
+ ### `pydry near`
77
+
78
+ Rank structurally similar function pairs.
79
+
80
+ ```bash
81
+ pydry near ./src
82
+ pydry near ./src --threshold 0.85 --top-k 25
83
+ pydry near ./src --format json --output reports/near.json
84
+ ```
85
+
86
+ Useful options:
87
+
88
+ - `--threshold`: similarity threshold from `0` to `1`, default `0.8`.
89
+ - `--top-k`: cap the number of returned pairs.
90
+ - `--top-level-only`: ignore nested functions and methods.
91
+ - `--strict`: fail on files that cannot be read or parsed.
92
+
93
+ ### `pydry abstract`
94
+
95
+ Filter near matches to pairs that look like plausible refactor candidates.
96
+
97
+ ```bash
98
+ pydry abstract ./src
99
+ pydry abstract ./src --threshold 0.86 --format json
100
+ ```
101
+
102
+ ### `pydry report`
103
+
104
+ Generate one JSON document with exact, near, and abstract sections.
105
+
106
+ ```bash
107
+ pydry report ./src
108
+ pydry report ./src --threshold 0.82 --top-k 250 --output reports/pydry-report.json
109
+ ```
110
+
111
+ ### `pydry showcase` and `pydry simulate`
112
+
113
+ Run a compact terminal summary. Both commands use the same analysis pipeline. With no path, they scan the current directory.
114
+
115
+ ```bash
116
+ pydry showcase
117
+ pydry showcase ./src --top-k 10 --threshold 0.8
118
+ pydry showcase ./src --format json
119
+ pydry simulate ./src
120
+ ```
121
+
122
+ ## JSON output
123
+
124
+ JSON-capable commands return an envelope:
125
+
126
+ ```json
127
+ {
128
+ "results": [],
129
+ "diagnostics": {
130
+ "scan_errors_count": 0,
131
+ "scan_error_samples": [],
132
+ "plugin_errors_count": 0,
133
+ "plugin_error_samples": []
134
+ }
135
+ }
136
+ ```
137
+
138
+ Near and abstract entries include:
139
+
140
+ - `similarity_score`
141
+ - `refactorability_score`
142
+ - `pattern_labels`
143
+ - `shared_structure_summary`
144
+ - `key_differences`
145
+ - `risk_flags`
146
+ - `suggested_refactor_kind`
147
+ - `evidence`
148
+
149
+ ## Python API
150
+
151
+ The CLI is the primary interface, but the core functions are importable:
152
+
153
+ ```python
154
+ from pathlib import Path
155
+
156
+ from pydry.engine import exact_groups, near_matches
157
+
158
+ groups = exact_groups(
159
+ Path("src"),
160
+ normalize_local_names=True,
161
+ normalize_constants=True,
162
+ )
163
+ rows = near_matches(Path("src"), threshold=0.85, top_k=25)
164
+ ```
165
+
166
+ ## Limitations
167
+
168
+ - Similarity is heuristic. It does not prove semantic equivalence.
169
+ - Cross-file import resolution is not attempted.
170
+ - Generated abstraction templates are suggestions, not executable patches.
171
+
172
+ ## Development
173
+
174
+ ```bash
175
+ make check
176
+ make coverage
177
+ make check-dist
178
+ ```
179
+
180
+ The package supports Python 3.11 and newer.
181
+
182
+ ## License
183
+
184
+ `pydry` is released under the MIT License. See [LICENSE](LICENSE).
@@ -0,0 +1,92 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77.0.3", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "pydry-cli"
7
+ version = "0.0.3"
8
+ description = "AST-based duplicate and structural similarity detector for Python"
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{name = "Really Him"}]
14
+ keywords = ["ast", "cli", "code-analysis", "duplicates", "refactoring"]
15
+ classifiers = [
16
+ "Development Status :: 2 - Pre-Alpha",
17
+ "Environment :: Console",
18
+ "Intended Audience :: Developers",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Programming Language :: Python :: 3.13",
23
+ "Topic :: Software Development :: Quality Assurance",
24
+ "Topic :: Utilities",
25
+ ]
26
+
27
+ [project.optional-dependencies]
28
+ dev = [
29
+ "build>=1.2",
30
+ "pytest>=8.0",
31
+ "pytest-cov>=6.0",
32
+ "ruff>=0.9",
33
+ "mypy>=1.14",
34
+ "pre-commit>=4.0",
35
+ "twine>=6.0",
36
+ ]
37
+
38
+ [project.scripts]
39
+ pydry = "pydry.cli:main"
40
+
41
+ [project.urls]
42
+ Homepage = "https://github.com/hesreallyhim/pydry"
43
+ Repository = "https://github.com/hesreallyhim/pydry"
44
+ Issues = "https://github.com/hesreallyhim/pydry/issues"
45
+
46
+ [tool.setuptools]
47
+ package-dir = {"" = "src"}
48
+
49
+ [tool.setuptools.packages.find]
50
+ where = ["src"]
51
+
52
+ [tool.ruff]
53
+ target-version = "py311"
54
+ line-length = 88
55
+ src = ["src", "tests"]
56
+ extend-exclude = ["demo"]
57
+
58
+ [tool.ruff.lint]
59
+ select = [
60
+ "E", # pycodestyle errors
61
+ "F", # pyflakes
62
+ "I", # isort
63
+ "N", # pep8-naming
64
+ "UP", # pyupgrade
65
+ "B", # flake8-bugbear
66
+ "SIM", # flake8-simplify
67
+ "TC", # flake8-type-checking
68
+ ]
69
+
70
+ [tool.ruff.lint.isort]
71
+ known-first-party = ["pydry"]
72
+
73
+ [tool.mypy]
74
+ python_version = "3.11"
75
+ strict = true
76
+ warn_return_any = true
77
+ warn_unused_configs = true
78
+ packages = ["pydry"]
79
+ mypy_path = "src"
80
+ exclude = ["^demo/"]
81
+
82
+ [tool.pytest.ini_options]
83
+ testpaths = ["tests"]
84
+
85
+ [tool.coverage.run]
86
+ source = ["src/pydry"]
87
+ branch = true
88
+
89
+ [tool.coverage.report]
90
+ show_missing = true
91
+ skip_empty = true
92
+ fail_under = 0
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,5 @@
1
+ from .cli import main
2
+
3
+ __version__ = "0.0.3"
4
+
5
+ __all__ = ["__version__", "main"]
@@ -0,0 +1,5 @@
1
+ from __future__ import annotations
2
+
3
+ from .cli import main
4
+
5
+ raise SystemExit(main())