codelexity 0.2.2__tar.gz → 0.2.4__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.
- {codelexity-0.2.2 → codelexity-0.2.4}/PKG-INFO +15 -24
- {codelexity-0.2.2 → codelexity-0.2.4}/README.md +14 -23
- {codelexity-0.2.2 → codelexity-0.2.4}/pyproject.toml +2 -2
- {codelexity-0.2.2 → codelexity-0.2.4}/pyproject.toml.orig +2 -2
- {codelexity-0.2.2 → codelexity-0.2.4}/src/codelexity/calculations.py +1 -5
- {codelexity-0.2.2 → codelexity-0.2.4}/src/codelexity/graph.py +4 -1
- {codelexity-0.2.2 → codelexity-0.2.4}/LICENSE +0 -0
- {codelexity-0.2.2 → codelexity-0.2.4}/src/codelexity/__init__.py +0 -0
- {codelexity-0.2.2 → codelexity-0.2.4}/src/codelexity/halstead.py +0 -0
- {codelexity-0.2.2 → codelexity-0.2.4}/src/codelexity/main.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codelexity
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: A package that measures code complexity in the age of AI slop.
|
|
5
5
|
Keywords: complexity,halstead,maintainability,cyclomatic,static-analysis,metrics
|
|
6
6
|
License-Expression: MIT
|
|
@@ -42,6 +42,12 @@ In the age of AI, codebases are becoming messier and more difficult to maintain.
|
|
|
42
42
|

|
|
43
43
|
_Codelexity HTML report on the `codelexity` repo_
|
|
44
44
|
|
|
45
|
+
**If you have an older version of python you can still run this package** on your codebase with `uv`:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
uvx --python 3.11 codelexity <my-package-path>
|
|
49
|
+
```
|
|
50
|
+
|
|
45
51
|
|
|
46
52
|
## Intuition
|
|
47
53
|
|
|
@@ -70,7 +76,7 @@ $$M=E-N+2P$$
|
|
|
70
76
|
|
|
71
77
|
where $M$ the complexity, $E$ and $N$ the number of edges and nodes in the computation graph and $P$ the number of connected components.
|
|
72
78
|
|
|
73
|
-
With Halstead's volume and McCabe's complexity one can compute the [
|
|
79
|
+
With Halstead's volume and McCabe's complexity one can compute the [Maintainability Index](https://ieeexplore.ieee.org/document/242525) computed as:
|
|
74
80
|
|
|
75
81
|
$$ 171 - 5.2 * log_2(V) - 0.23 * M- 16.2 * log_2(SLOC)+ 50 * \sqrt{2.4 * perCOM}$$
|
|
76
82
|
|
|
@@ -103,17 +109,18 @@ The `codelexity.json` containts aggregate analytics for the whole package and pe
|
|
|
103
109
|
```json
|
|
104
110
|
{
|
|
105
111
|
"analytics": {
|
|
106
|
-
"total_lines":
|
|
107
|
-
"total_functions":
|
|
108
|
-
"total_modules":
|
|
112
|
+
"total_lines": 330993,
|
|
113
|
+
"total_functions": 11740,
|
|
114
|
+
"total_modules": 862,
|
|
115
|
+
"total_man_hours": 13956
|
|
109
116
|
},
|
|
110
117
|
"modules": {
|
|
111
118
|
"conftest.py": {
|
|
112
119
|
"imports": [
|
|
120
|
+
"<site-packages>/networkx/__init__.py",
|
|
113
121
|
"<stdlib>/importlib/metadata/__init__.py",
|
|
114
122
|
"<stdlib>/os.py",
|
|
115
|
-
"<stdlib>/warnings.py"
|
|
116
|
-
"__init__.py"
|
|
123
|
+
"<stdlib>/warnings.py"
|
|
117
124
|
],
|
|
118
125
|
"total_lines": 262,
|
|
119
126
|
"empty_lines": 39,
|
|
@@ -121,20 +128,4 @@ The `codelexity.json` containts aggregate analytics for the whole package and pe
|
|
|
121
128
|
"code_length": 211,
|
|
122
129
|
...
|
|
123
130
|
}
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
## Running the tests
|
|
127
|
-
|
|
128
|
-
The suite lives in `tests/` and uses the standard library's `unittest` — no test dependencies to install.
|
|
129
|
-
|
|
130
|
-
```sh
|
|
131
|
-
uv run python -m unittest discover # all tests
|
|
132
|
-
uv run python -m unittest discover -v # verbose, one line per test
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
Coverage, which needs no dev dependency either:
|
|
136
|
-
|
|
137
|
-
```sh
|
|
138
|
-
uv run --with coverage coverage run --source=src -m unittest discover
|
|
139
|
-
uv run --with coverage coverage report
|
|
140
|
-
```
|
|
131
|
+
```
|
|
@@ -20,6 +20,12 @@ In the age of AI, codebases are becoming messier and more difficult to maintain.
|
|
|
20
20
|

|
|
21
21
|
_Codelexity HTML report on the `codelexity` repo_
|
|
22
22
|
|
|
23
|
+
**If you have an older version of python you can still run this package** on your codebase with `uv`:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
uvx --python 3.11 codelexity <my-package-path>
|
|
27
|
+
```
|
|
28
|
+
|
|
23
29
|
|
|
24
30
|
## Intuition
|
|
25
31
|
|
|
@@ -48,7 +54,7 @@ $$M=E-N+2P$$
|
|
|
48
54
|
|
|
49
55
|
where $M$ the complexity, $E$ and $N$ the number of edges and nodes in the computation graph and $P$ the number of connected components.
|
|
50
56
|
|
|
51
|
-
With Halstead's volume and McCabe's complexity one can compute the [
|
|
57
|
+
With Halstead's volume and McCabe's complexity one can compute the [Maintainability Index](https://ieeexplore.ieee.org/document/242525) computed as:
|
|
52
58
|
|
|
53
59
|
$$ 171 - 5.2 * log_2(V) - 0.23 * M- 16.2 * log_2(SLOC)+ 50 * \sqrt{2.4 * perCOM}$$
|
|
54
60
|
|
|
@@ -81,17 +87,18 @@ The `codelexity.json` containts aggregate analytics for the whole package and pe
|
|
|
81
87
|
```json
|
|
82
88
|
{
|
|
83
89
|
"analytics": {
|
|
84
|
-
"total_lines":
|
|
85
|
-
"total_functions":
|
|
86
|
-
"total_modules":
|
|
90
|
+
"total_lines": 330993,
|
|
91
|
+
"total_functions": 11740,
|
|
92
|
+
"total_modules": 862,
|
|
93
|
+
"total_man_hours": 13956
|
|
87
94
|
},
|
|
88
95
|
"modules": {
|
|
89
96
|
"conftest.py": {
|
|
90
97
|
"imports": [
|
|
98
|
+
"<site-packages>/networkx/__init__.py",
|
|
91
99
|
"<stdlib>/importlib/metadata/__init__.py",
|
|
92
100
|
"<stdlib>/os.py",
|
|
93
|
-
"<stdlib>/warnings.py"
|
|
94
|
-
"__init__.py"
|
|
101
|
+
"<stdlib>/warnings.py"
|
|
95
102
|
],
|
|
96
103
|
"total_lines": 262,
|
|
97
104
|
"empty_lines": 39,
|
|
@@ -99,20 +106,4 @@ The `codelexity.json` containts aggregate analytics for the whole package and pe
|
|
|
99
106
|
"code_length": 211,
|
|
100
107
|
...
|
|
101
108
|
}
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
## Running the tests
|
|
105
|
-
|
|
106
|
-
The suite lives in `tests/` and uses the standard library's `unittest` — no test dependencies to install.
|
|
107
|
-
|
|
108
|
-
```sh
|
|
109
|
-
uv run python -m unittest discover # all tests
|
|
110
|
-
uv run python -m unittest discover -v # verbose, one line per test
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
Coverage, which needs no dev dependency either:
|
|
114
|
-
|
|
115
|
-
```sh
|
|
116
|
-
uv run --with coverage coverage run --source=src -m unittest discover
|
|
117
|
-
uv run --with coverage coverage report
|
|
118
|
-
```
|
|
109
|
+
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "codelexity"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.4"
|
|
4
4
|
description = "A package that measures code complexity in the age of AI slop."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
@@ -43,7 +43,7 @@ path = "src"
|
|
|
43
43
|
editable = true
|
|
44
44
|
|
|
45
45
|
[tool.bumpver]
|
|
46
|
-
current_version = "0.2.
|
|
46
|
+
current_version = "0.2.4"
|
|
47
47
|
version_pattern = "MAJOR.MINOR.PATCH"
|
|
48
48
|
push = false
|
|
49
49
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "codelexity"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.4"
|
|
4
4
|
description = "A package that measures code complexity in the age of AI slop."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
@@ -48,7 +48,7 @@ dev = [
|
|
|
48
48
|
]
|
|
49
49
|
|
|
50
50
|
[tool.bumpver]
|
|
51
|
-
current_version = "0.2.
|
|
51
|
+
current_version = "0.2.4"
|
|
52
52
|
version_pattern = "MAJOR.MINOR.PATCH"
|
|
53
53
|
push = false # inspect the tag before it leaves the machine
|
|
54
54
|
|
|
@@ -70,8 +70,6 @@ def maintainability_index(module_source: str):
|
|
|
70
70
|
- 16.2 * log(sloc)
|
|
71
71
|
+ 50 * sin(sqrt(2.4 * comments / sloc))
|
|
72
72
|
)
|
|
73
|
-
# ponytail: clamped to 0-100 so it reads as a percentage. The comment term can push raw above
|
|
74
|
-
# 171, which is why the upper bound is here and not just a max(0, ...).
|
|
75
73
|
return min(100.0, max(0.0, raw * 100 / 171))
|
|
76
74
|
|
|
77
75
|
|
|
@@ -96,8 +94,6 @@ def _resolve(name, search):
|
|
|
96
94
|
try:
|
|
97
95
|
found = locations and importlib.machinery.PathFinder.find_spec(".".join(parts[: i + 1]), locations)
|
|
98
96
|
except KeyError:
|
|
99
|
-
# ponytail: namespace packages need their own parent in sys.modules
|
|
100
|
-
# to build a submodule spec; we never import, so treat as unresolved.
|
|
101
97
|
found = None
|
|
102
98
|
if not found:
|
|
103
99
|
break
|
|
@@ -113,7 +109,7 @@ def imports(module_path, root=None):
|
|
|
113
109
|
search = sys.path + [str(root), *(str(d) for d in root.rglob("*") if d.is_dir())]
|
|
114
110
|
names = {n for n in _import_names(code) if n.split(".")[0] not in sys.builtin_module_names}
|
|
115
111
|
specs = (_resolve(n, search) for n in names)
|
|
116
|
-
return sorted({s.origin for s in specs if s and s.origin})
|
|
112
|
+
return sorted({Path(s.origin).as_posix() for s in specs if s and s.origin})
|
|
117
113
|
|
|
118
114
|
|
|
119
115
|
def analyze_module(path, root=None):
|
|
@@ -90,4 +90,7 @@ def create_viz(package_data: dict, fpath: str):
|
|
|
90
90
|
f"Total comprehension time (h): {package_data['analytics']['total_man_hours']}</div>"
|
|
91
91
|
)
|
|
92
92
|
path = Path(fpath)
|
|
93
|
-
|
|
93
|
+
# encoding pinned both ways: pyvis writes UTF-8, but Windows defaults to cp1252, which raises
|
|
94
|
+
# UnicodeDecodeError on read and produces mojibake on write.
|
|
95
|
+
html = path.read_text(encoding="utf-8")
|
|
96
|
+
path.write_text(html.replace("<body>", f"<body>\n{legend}", 1), encoding="utf-8")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|