interlinked-mapper 0.3.12__tar.gz → 0.3.13__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.
Files changed (48) hide show
  1. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/PKG-INFO +1 -1
  2. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/analyzer/graph.py +11 -1
  3. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked_mapper.egg-info/PKG-INFO +1 -1
  4. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/pyproject.toml +1 -1
  5. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/tests/test_accuracy.py +61 -0
  6. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/__init__.py +0 -0
  7. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/analyzer/__init__.py +0 -0
  8. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/analyzer/dead_code.py +0 -0
  9. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/analyzer/embeddings.py +0 -0
  10. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/analyzer/parser.py +0 -0
  11. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/analyzer/similarity.py +0 -0
  12. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/cli.py +0 -0
  13. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/commander/__init__.py +0 -0
  14. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/commander/llm.py +0 -0
  15. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/commander/query.py +0 -0
  16. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/commander/repl.py +0 -0
  17. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/mcp_server.py +0 -0
  18. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/models.py +0 -0
  19. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/visualizer/__init__.py +0 -0
  20. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/visualizer/frontend/dist/assets/index-CyhrxsQU.css +0 -0
  21. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/visualizer/frontend/dist/assets/index-Dh01aXoE.js +0 -0
  22. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/visualizer/frontend/dist/index.html +0 -0
  23. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/visualizer/frontend/index.html +0 -0
  24. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/visualizer/frontend/index.html.d3-legacy +0 -0
  25. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/visualizer/frontend/package-lock.json +0 -0
  26. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/visualizer/frontend/package.json +0 -0
  27. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/visualizer/frontend/src/App.tsx +0 -0
  28. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/visualizer/frontend/src/graph/GraphCanvas.tsx +0 -0
  29. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/visualizer/frontend/src/graph/nodePrograms.ts +0 -0
  30. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/visualizer/frontend/src/index.css +0 -0
  31. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/visualizer/frontend/src/main.tsx +0 -0
  32. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/visualizer/frontend/src/state/graphStore.ts +0 -0
  33. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/visualizer/frontend/src/state/sseClient.ts +0 -0
  34. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/visualizer/frontend/src/theme.ts +0 -0
  35. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/visualizer/frontend/src/types.ts +0 -0
  36. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/visualizer/frontend/src/vite-env.d.ts +0 -0
  37. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/visualizer/frontend/tsconfig.json +0 -0
  38. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/visualizer/frontend/vite.config.ts +0 -0
  39. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/visualizer/layouts.py +0 -0
  40. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked/visualizer/server.py +0 -0
  41. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked_mapper.egg-info/SOURCES.txt +0 -0
  42. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked_mapper.egg-info/dependency_links.txt +0 -0
  43. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked_mapper.egg-info/entry_points.txt +0 -0
  44. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked_mapper.egg-info/requires.txt +0 -0
  45. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/interlinked_mapper.egg-info/top_level.txt +0 -0
  46. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/setup.cfg +0 -0
  47. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/tests/test_query_completeness.py +0 -0
  48. {interlinked_mapper-0.3.12 → interlinked_mapper-0.3.13}/tests/test_watcher.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: interlinked-mapper
3
- Version: 0.3.12
3
+ Version: 0.3.13
4
4
  Summary: A Python program topology explorer — visualize the shape of your codebase
5
5
  License: MIT
6
6
  Project-URL: Homepage, https://github.com/austerecryptid/interlinked
@@ -2,6 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ from itertools import islice
5
6
  from typing import Any, Iterator
6
7
 
7
8
  import networkx as nx
@@ -445,17 +446,26 @@ class CodeGraph:
445
446
  if k not in ("contains", "inherits")]
446
447
  )
447
448
 
449
+ _MAX_PAIRS = 50
450
+ _MAX_PATHS_PER_PAIR = 10
451
+ pairs_checked = 0
448
452
  for w in writers:
449
453
  for r in readers:
450
454
  if w == r:
451
455
  continue
456
+ if pairs_checked >= _MAX_PAIRS:
457
+ break
452
458
  for src, tgt in [(w, r), (r, w)]:
453
459
  if src in flow_graph and tgt in flow_graph:
454
460
  try:
455
- for path in nx.all_simple_paths(flow_graph, src, tgt, cutoff=5):
461
+ for path in islice(nx.all_simple_paths(flow_graph, src, tgt, cutoff=5), _MAX_PATHS_PER_PAIR):
456
462
  path_nodes.update(path)
457
463
  except nx.NetworkXError:
458
464
  pass
465
+ pairs_checked += 1
466
+ else:
467
+ continue
468
+ break
459
469
 
460
470
  # Also add ancestors/descendants of each writer/reader within the trace
461
471
  for nid in list(trace_func_ids):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: interlinked-mapper
3
- Version: 0.3.12
3
+ Version: 0.3.13
4
4
  Summary: A Python program topology explorer — visualize the shape of your codebase
5
5
  License: MIT
6
6
  Project-URL: Homepage, https://github.com/austerecryptid/interlinked
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "interlinked-mapper"
7
- version = "0.3.12"
7
+ version = "0.3.13"
8
8
  description = "A Python program topology explorer — visualize the shape of your codebase"
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
@@ -1399,6 +1399,67 @@ class TestFalsePositiveEdges:
1399
1399
  f"calls_shared_helper resolved to foreign _shared_helper: {foreign_match}"
1400
1400
 
1401
1401
 
1402
+ # ══════════════════════════════════════════════════════════════════════
1403
+ # REGRESSION: trace_variable must not hang on ubiquitous variables
1404
+ # ══════════════════════════════════════════════════════════════════════
1405
+
1406
+
1407
+ class TestTraceVariable:
1408
+ """Regression test for trace_variable combinatorial explosion.
1409
+
1410
+ trace_variable previously called nx.all_simple_paths for every
1411
+ (writer, reader) pair with no cap on path count. For common
1412
+ variables with many readers/writers this caused an infinite loop.
1413
+ """
1414
+
1415
+ @pytest.fixture(autouse=True)
1416
+ def setup(self):
1417
+ self.graph, self.engine, _, _ = _build(FIXTURES)
1418
+
1419
+ def test_trace_common_variable_terminates(self):
1420
+ """Tracing a variable that appears in many scopes must complete quickly."""
1421
+ import signal
1422
+
1423
+ class _Timeout(Exception):
1424
+ pass
1425
+
1426
+ def _handler(signum, frame):
1427
+ raise _Timeout("trace_variable did not terminate within timeout")
1428
+
1429
+ # Pick a variable with many readers/writers across fixtures
1430
+ # 'result' appears in 13+ read/write edges — enough to trigger
1431
+ # the old combinatorial explosion in all_simple_paths
1432
+ old = signal.signal(signal.SIGALRM, _handler)
1433
+ signal.alarm(30) # 30 second hard limit
1434
+ try:
1435
+ nodes, edges, node_roles, edge_roles = self.graph.trace_variable("result")
1436
+ except _Timeout:
1437
+ pytest.fail("trace_variable('result') hung — combinatorial explosion regression")
1438
+ finally:
1439
+ signal.alarm(0)
1440
+ signal.signal(signal.SIGALRM, old)
1441
+
1442
+ assert len(nodes) > 0, "trace_variable('result') should find nodes"
1443
+
1444
+ def test_trace_returns_valid_roles(self):
1445
+ """trace_variable must return well-formed role dicts."""
1446
+ nodes, edges, node_roles, edge_roles = self.graph.trace_variable("result")
1447
+ valid_node_roles = {"origin", "mutator", "passthrough", "destination"}
1448
+ for nid, role in node_roles.items():
1449
+ assert role in valid_node_roles, f"Invalid node role '{role}' for {nid}"
1450
+ valid_edge_roles = {"read", "write", "flow"}
1451
+ for key, role in edge_roles.items():
1452
+ assert role in valid_edge_roles, f"Invalid edge role '{role}' for {key}"
1453
+
1454
+ def test_trace_nonexistent_variable_returns_empty(self):
1455
+ """Tracing a variable that doesn't exist should return empty, not crash."""
1456
+ nodes, edges, node_roles, edge_roles = self.graph.trace_variable("zzz_no_such_var_zzz")
1457
+ assert nodes == []
1458
+ assert edges == []
1459
+ assert node_roles == {}
1460
+ assert edge_roles == {}
1461
+
1462
+
1402
1463
  class TestMCPFidelity:
1403
1464
  """Verify MCP dispatch produces the same results as direct engine calls."""
1404
1465