graphlint 0.3.2__tar.gz → 0.3.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.
- {graphlint-0.3.2 → graphlint-0.3.3}/CHANGELOG.md +11 -0
- {graphlint-0.3.2/graphlint.egg-info → graphlint-0.3.3}/PKG-INFO +1 -1
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/__init__.py +1 -1
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/analyzer/_graph_algo.py +85 -48
- {graphlint-0.3.2 → graphlint-0.3.3/graphlint.egg-info}/PKG-INFO +1 -1
- {graphlint-0.3.2 → graphlint-0.3.3}/pyproject.toml +1 -1
- {graphlint-0.3.2 → graphlint-0.3.3}/CONTRIBUTING.md +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/LICENSE +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/MANIFEST.in +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/README.md +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/README_PYPI.md +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/docs/en/api/build.md +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/docs/en/api/configure.md +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/docs/en/api/exceptions.md +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/docs/en/api/query.md +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/docs/en/architecture/overview.md +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/docs/en/cli/usage.md +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/docs/en/guide/agent-integration.md +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/docs/en/guide/configuration.md +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/docs/en/guide/entry-detection.md +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/docs/en/guide/getting-started.md +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/docs/en/guide/warnings.md +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/docs/en/index.md +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/docs/zh/README.md +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/docs/zh/api/build.md +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/docs/zh/api/configure.md +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/docs/zh/api/exceptions.md +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/docs/zh/api/query.md +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/docs/zh/architecture/overview.md +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/docs/zh/cli/usage.md +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/docs/zh/guide/agent-integration.md +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/docs/zh/guide/configuration.md +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/docs/zh/guide/entry-detection.md +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/docs/zh/guide/getting-started.md +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/docs/zh/guide/warnings.md +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/docs/zh/index.md +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/agent_tools.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/analyzer/__init__.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/analyzer/_types.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/analyzer/graph.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/analyzer/language/__init__.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/analyzer/language/base.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/analyzer/language/python/__init__.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/analyzer/language/python/constants.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/analyzer/language/python/decorators.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/analyzer/language/python/entry.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/analyzer/language/python/imports.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/analyzer/language/python/parser.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/analyzer/language/python/visitor.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/analyzer/language/registry.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/analyzer/language/rust/__init__.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/analyzer/language/rust/constants.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/analyzer/language/rust/entry.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/analyzer/language/rust/imports.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/analyzer/language/rust/parser.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/analyzer/language/rust/visitor.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/analyzer/warnings.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/api.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/cli.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/config/__init__.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/config/defaults.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/config/manager.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/exceptions.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/i18n/__init__.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/i18n/en.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/i18n/zh_CN.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/incremental/__init__.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/incremental/_db_ops.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/incremental/indexer.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/params.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/query/__init__.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/query/engine.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/query/formatter.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/query/volume.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/storage/__init__.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/storage/db.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/storage/hashing.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint/storage/schema.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint.egg-info/SOURCES.txt +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint.egg-info/dependency_links.txt +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint.egg-info/entry_points.txt +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint.egg-info/requires.txt +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/graphlint.egg-info/top_level.txt +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/setup.cfg +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/__init__.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/integration/__init__.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/integration/test_api.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/integration/test_cli.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/integration/test_data_transfer.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/integration/test_dead_code_query.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/integration/test_full_pipeline.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/integration/test_incremental.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/integration/test_json_output.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/performance/__init__.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/performance/test_large_codebase.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/unit/__init__.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/unit/test_auto_build.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/unit/test_config.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/unit/test_db.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/unit/test_db_ops.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/unit/test_decorators.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/unit/test_engine.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/unit/test_entry_detect.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/unit/test_exceptions.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/unit/test_formatter.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/unit/test_graph.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/unit/test_graph_algo.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/unit/test_hashing.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/unit/test_i18n.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/unit/test_imports.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/unit/test_mock_boundary.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/unit/test_params.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/unit/test_parser.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/unit/test_schema.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/unit/test_volume.py +0 -0
- {graphlint-0.3.2 → graphlint-0.3.3}/tests/unit/test_warnings.py +0 -0
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.3.3] - 2026-07-25
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
- Pre-built entry indexes (`nid_to_entries`, `fid_to_entries`) for O(1)
|
|
9
|
+
per-component entry matching, eliminating repeated linear scans in
|
|
10
|
+
`_match_entries` during connected component analysis
|
|
11
|
+
- Connected component BFS now collects reachable node seeds in a single
|
|
12
|
+
traversal pass instead of a post-hoc set comprehension
|
|
13
|
+
- Dead-code component merge loop replaced with BFS-based group merging,
|
|
14
|
+
eliminating repeated list scans and improving large-codebase performance
|
|
15
|
+
|
|
5
16
|
## [0.3.2] - 2026-07-25
|
|
6
17
|
|
|
7
18
|
### Changed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: graphlint
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: A static analysis tool for identifying dead code in a codebase. It provides Python API and CLI for use by agents.
|
|
5
5
|
Author-email: Yutong Zou <yutong.zou.24@alumni.ucl.ac.uk>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -258,6 +258,17 @@ def find_connected_components(
|
|
|
258
258
|
elif _e.target_id == 0 and _e.source_id:
|
|
259
259
|
_zero_sources.add(_e.source_id)
|
|
260
260
|
|
|
261
|
+
# Pre-build entry indexes for O(1) per-component matching
|
|
262
|
+
_nid_to_entries: dict[int, list[EntryInfo]] = {}
|
|
263
|
+
_fid_to_entries: dict[int, list[EntryInfo]] = {}
|
|
264
|
+
for entry in entries:
|
|
265
|
+
if entry.node_id:
|
|
266
|
+
_nid_to_entries.setdefault(entry.node_id, []).append(entry)
|
|
267
|
+
elif file_id_map:
|
|
268
|
+
fid = file_id_map.get(entry.file_path, 0)
|
|
269
|
+
if fid:
|
|
270
|
+
_fid_to_entries.setdefault(fid, []).append(entry)
|
|
271
|
+
|
|
261
272
|
visited: set[int] = set()
|
|
262
273
|
component_map: dict[int, int] = {}
|
|
263
274
|
components: list[ComponentInfo] = []
|
|
@@ -268,9 +279,13 @@ def find_connected_components(
|
|
|
268
279
|
if nid in visited:
|
|
269
280
|
continue
|
|
270
281
|
|
|
282
|
+
# discover component nodes and initial reachable seeds
|
|
271
283
|
queue: deque[int] = deque([nid])
|
|
272
284
|
visited.add(nid)
|
|
273
285
|
comp_nodes: set[int] = {nid}
|
|
286
|
+
comp_reachable: set[int] = set()
|
|
287
|
+
if nid in reachable:
|
|
288
|
+
comp_reachable.add(nid)
|
|
274
289
|
|
|
275
290
|
while queue:
|
|
276
291
|
current = queue.popleft()
|
|
@@ -279,15 +294,19 @@ def find_connected_components(
|
|
|
279
294
|
visited.add(neighbor)
|
|
280
295
|
queue.append(neighbor)
|
|
281
296
|
comp_nodes.add(neighbor)
|
|
297
|
+
if neighbor in reachable:
|
|
298
|
+
comp_reachable.add(neighbor)
|
|
282
299
|
|
|
283
|
-
comp_entries = _match_entries(
|
|
300
|
+
comp_entries = _match_entries(
|
|
301
|
+
entries, comp_nodes, node_id_map, file_id_map,
|
|
302
|
+
nid_to_entries=_nid_to_entries, fid_to_entries=_fid_to_entries,
|
|
303
|
+
)
|
|
284
304
|
has_entry = len(comp_entries) > 0
|
|
285
|
-
comp_nodes.discard(0)
|
|
286
|
-
comp_reachable
|
|
305
|
+
comp_nodes.discard(0)
|
|
306
|
+
comp_reachable.discard(0)
|
|
287
307
|
comp_unreachable = comp_nodes - comp_reachable
|
|
288
308
|
|
|
289
|
-
# BFS expansion from reachable
|
|
290
|
-
# Node 0 (module pseudo-node): only expand via read/call edges.
|
|
309
|
+
# BFS expansion from reachable seeds via undirected edges
|
|
291
310
|
seed = comp_reachable
|
|
292
311
|
if noprop_ids:
|
|
293
312
|
seed = seed - noprop_ids
|
|
@@ -296,13 +315,13 @@ def find_connected_components(
|
|
|
296
315
|
cur = q.popleft()
|
|
297
316
|
if cur == 0:
|
|
298
317
|
continue
|
|
299
|
-
for
|
|
300
|
-
if
|
|
318
|
+
for nb in adj.get(cur, set()):
|
|
319
|
+
if nb == 0 or nb in comp_reachable:
|
|
301
320
|
continue
|
|
302
|
-
if
|
|
303
|
-
comp_reachable.add(
|
|
304
|
-
comp_unreachable.discard(
|
|
305
|
-
q.append(
|
|
321
|
+
if nb in comp_unreachable:
|
|
322
|
+
comp_reachable.add(nb)
|
|
323
|
+
comp_unreachable.discard(nb)
|
|
324
|
+
q.append(nb)
|
|
306
325
|
if cur in class_special_map:
|
|
307
326
|
for sm_nid in class_special_map[cur]:
|
|
308
327
|
if sm_nid in comp_unreachable:
|
|
@@ -370,51 +389,52 @@ def find_connected_components(
|
|
|
370
389
|
component_map.update(sub_map)
|
|
371
390
|
components.extend(sub_comps)
|
|
372
391
|
|
|
373
|
-
# Post-process: merge dead
|
|
374
|
-
|
|
392
|
+
# Post-process: merge dead components into live ones via inherit/decorate edges.
|
|
393
|
+
comp_adj: dict[int, set[int]] = {}
|
|
375
394
|
for e in edges:
|
|
376
395
|
if e.edge_type not in ("inherit", "decorate"):
|
|
377
396
|
continue
|
|
378
397
|
cs = component_map.get(e.source_id)
|
|
379
398
|
ct = component_map.get(e.target_id)
|
|
380
399
|
if cs is not None and ct is not None and cs != ct:
|
|
381
|
-
|
|
382
|
-
|
|
400
|
+
comp_adj.setdefault(cs, set()).add(ct)
|
|
401
|
+
comp_adj.setdefault(ct, set()).add(cs)
|
|
383
402
|
|
|
384
403
|
comp_by_id: dict[int, ComponentInfo] = {c.component_id: c for c in components}
|
|
404
|
+
live_comp_ids: set[int] = {c.component_id for c in components if not c.is_dead_code}
|
|
385
405
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
for
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
406
|
+
# each connected group containing a live
|
|
407
|
+
# component merges all its dead members into the largest live one.
|
|
408
|
+
comp_visited: set[int] = set()
|
|
409
|
+
for live_cid in sorted(live_comp_ids):
|
|
410
|
+
if live_cid in comp_visited:
|
|
411
|
+
continue
|
|
412
|
+
group: set[int] = {live_cid}
|
|
413
|
+
comp_visited.add(live_cid)
|
|
414
|
+
q_comp: deque[int] = deque([live_cid])
|
|
415
|
+
while q_comp:
|
|
416
|
+
cur_cid = q_comp.popleft()
|
|
417
|
+
for nb_cid in comp_adj.get(cur_cid, set()):
|
|
418
|
+
if nb_cid not in comp_visited:
|
|
419
|
+
comp_visited.add(nb_cid)
|
|
420
|
+
q_comp.append(nb_cid)
|
|
421
|
+
group.add(nb_cid)
|
|
422
|
+
|
|
423
|
+
group_live = group & live_comp_ids
|
|
424
|
+
group_dead = group - group_live
|
|
425
|
+
if not group_dead:
|
|
426
|
+
continue
|
|
427
|
+
|
|
428
|
+
target_cid = max(group_live, key=lambda cid: len(comp_by_id[cid].node_ids))
|
|
429
|
+
target_comp = comp_by_id[target_cid]
|
|
430
|
+
for dead_cid in group_dead:
|
|
431
|
+
dead_comp = comp_by_id.pop(dead_cid, None)
|
|
432
|
+
if dead_comp is None:
|
|
402
433
|
continue
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
for other in list(neighbors):
|
|
408
|
-
if other == target.component_id:
|
|
409
|
-
continue
|
|
410
|
-
x_edges.setdefault(other, set()).discard(comp.component_id)
|
|
411
|
-
x_edges.setdefault(other, set()).add(target.component_id)
|
|
412
|
-
x_edges.setdefault(target.component_id, set()).add(other)
|
|
413
|
-
x_edges.pop(comp.component_id, None)
|
|
414
|
-
comp_by_id.pop(comp.component_id, None)
|
|
415
|
-
components.remove(comp)
|
|
416
|
-
changed = True
|
|
417
|
-
break
|
|
434
|
+
target_comp.node_ids.update(dead_comp.node_ids)
|
|
435
|
+
for _nid in dead_comp.node_ids:
|
|
436
|
+
component_map[_nid] = target_cid
|
|
437
|
+
components.remove(dead_comp)
|
|
418
438
|
|
|
419
439
|
return component_map, components
|
|
420
440
|
|
|
@@ -512,11 +532,28 @@ def _match_entries(
|
|
|
512
532
|
comp_nodes: set[int],
|
|
513
533
|
node_id_map: dict[int, NodeInfo],
|
|
514
534
|
file_id_map: Optional[dict[str, int]] = None,
|
|
535
|
+
nid_to_entries: Optional[dict[int, list[EntryInfo]]] = None,
|
|
536
|
+
fid_to_entries: Optional[dict[int, list[EntryInfo]]] = None,
|
|
515
537
|
) -> list[EntryInfo]:
|
|
516
|
-
"""Match entry points to connected components.
|
|
538
|
+
"""Match entry points to connected components.
|
|
539
|
+
"""
|
|
540
|
+
matched: list[EntryInfo] = []
|
|
541
|
+
|
|
542
|
+
if nid_to_entries is not None and fid_to_entries is not None:
|
|
543
|
+
comp_file_ids: set[int] = set()
|
|
544
|
+
for nid in comp_nodes:
|
|
545
|
+
for entry in nid_to_entries.get(nid, []):
|
|
546
|
+
matched.append(entry)
|
|
547
|
+
enode = node_id_map.get(nid)
|
|
548
|
+
if enode:
|
|
549
|
+
comp_file_ids.add(enode.file_id)
|
|
550
|
+
for fid in comp_file_ids:
|
|
551
|
+
for entry in fid_to_entries.get(fid, []):
|
|
552
|
+
matched.append(entry)
|
|
553
|
+
return matched
|
|
554
|
+
|
|
517
555
|
if file_id_map is None:
|
|
518
556
|
file_id_map = {}
|
|
519
|
-
matched: list[EntryInfo] = []
|
|
520
557
|
for entry in entries:
|
|
521
558
|
if entry.node_id in comp_nodes:
|
|
522
559
|
matched.append(entry)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: graphlint
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: A static analysis tool for identifying dead code in a codebase. It provides Python API and CLI for use by agents.
|
|
5
5
|
Author-email: Yutong Zou <yutong.zou.24@alumni.ucl.ac.uk>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "graphlint"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.3"
|
|
8
8
|
description = "A static analysis tool for identifying dead code in a codebase. It provides Python API and CLI for use by agents."
|
|
9
9
|
readme = "README_PYPI.md"
|
|
10
10
|
license = "MIT"
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|