codeanalyzer-python 1.0.1__tar.gz → 1.0.2__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 (78) hide show
  1. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/PKG-INFO +1 -1
  2. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/neo4j/project.py +29 -14
  3. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/pyproject.toml +1 -1
  4. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/.gitignore +0 -0
  5. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/LICENSE +0 -0
  6. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/NOTICE +0 -0
  7. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/README.md +0 -0
  8. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/__init__.py +0 -0
  9. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/__main__.py +0 -0
  10. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/config/__init__.py +0 -0
  11. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/config/config.py +0 -0
  12. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/core.py +0 -0
  13. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/dataflow/__init__.py +0 -0
  14. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/dataflow/access_paths.py +0 -0
  15. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/dataflow/alias.py +0 -0
  16. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/dataflow/builder.py +0 -0
  17. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/dataflow/cfg.py +0 -0
  18. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/dataflow/defuse.py +0 -0
  19. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/dataflow/dominance.py +0 -0
  20. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/dataflow/identity.py +0 -0
  21. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/dataflow/pdg.py +0 -0
  22. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/dataflow/scalpel_oracle.py +0 -0
  23. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/dataflow/scc.py +0 -0
  24. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/dataflow/sdg.py +0 -0
  25. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/dataflow/slicing.py +0 -0
  26. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/dataflow/summaries.py +0 -0
  27. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/dataflow/syntactic.py +0 -0
  28. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/jedi/__init__.py +0 -0
  29. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/jedi/jedi.py +0 -0
  30. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/neo4j/__init__.py +0 -0
  31. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/neo4j/bolt.py +0 -0
  32. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/neo4j/cypher.py +0 -0
  33. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/neo4j/emit.py +0 -0
  34. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/neo4j/rows.py +0 -0
  35. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/neo4j/schema.py +0 -0
  36. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/options/__init__.py +0 -0
  37. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/options/options.py +0 -0
  38. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/provenance.py +0 -0
  39. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/py.typed +0 -0
  40. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/schema/__init__.py +0 -0
  41. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/schema/assign_ids.py +0 -0
  42. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/schema/call_graph_ids.py +0 -0
  43. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/schema/ids.py +0 -0
  44. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/schema/l1_body.py +0 -0
  45. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/schema/l2_callees.py +0 -0
  46. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/schema/py_schema.py +0 -0
  47. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/semantic_analysis/__init__.py +0 -0
  48. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/semantic_analysis/call_graph.py +0 -0
  49. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/semantic_analysis/pycg/__init__.py +0 -0
  50. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/semantic_analysis/pycg/pycg_analysis.py +0 -0
  51. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/semantic_analysis/pycg/pycg_exceptions.py +0 -0
  52. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/semantic_analysis/pycg/shard_planner.py +0 -0
  53. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/syntactic_analysis/__init__.py +0 -0
  54. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/syntactic_analysis/exceptions.py +0 -0
  55. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/syntactic_analysis/import_resolver.py +0 -0
  56. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/syntactic_analysis/symbol_table_builder.py +0 -0
  57. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/utils/__init__.py +0 -0
  58. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/utils/logging.py +0 -0
  59. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/codeanalyzer/utils/progress_bar.py +0 -0
  60. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/docs/handoff/README.md +0 -0
  61. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/docs/handoff/schema.neo4j.json +0 -0
  62. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/schema-uml.drawio +0 -0
  63. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/schema.neo4j.json +0 -0
  64. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/test/fixtures/whole_applications/flask/README.md +0 -0
  65. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/test/fixtures/whole_applications/flask/examples/celery/README.md +0 -0
  66. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/test/fixtures/whole_applications/flask/requirements-skip/README.md +0 -0
  67. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/test/fixtures/whole_applications/flask/src/flask/sansio/README.md +0 -0
  68. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/test/fixtures/whole_applications/requests/LICENSE +0 -0
  69. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/test/fixtures/whole_applications/requests/NOTICE +0 -0
  70. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/test/fixtures/whole_applications/requests/README.md +0 -0
  71. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/test/fixtures/whole_applications/requests/docs/_themes/LICENSE +0 -0
  72. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/test/fixtures/whole_applications/requests/ext/LICENSE +0 -0
  73. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/test/fixtures/whole_applications/xarray/LICENSE +0 -0
  74. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/test/fixtures/whole_applications/xarray/README.md +0 -0
  75. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/test/fixtures/whole_applications/xarray/properties/README.md +0 -0
  76. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/test/fixtures/whole_applications/xarray/xarray/datatree_/LICENSE +0 -0
  77. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/test/fixtures/whole_applications/xarray/xarray/datatree_/README.md +0 -0
  78. {codeanalyzer_python-1.0.1 → codeanalyzer_python-1.0.2}/test/fixtures/whole_applications/xarray/xarray/datatree_/docs/README.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codeanalyzer-python
3
- Version: 1.0.1
3
+ Version: 1.0.2
4
4
  Summary: Static analysis for Python — canonical schema v2 (symbol table, call graph, and native CFG/PDG/SDG dataflow) as analysis.json or a Neo4j property graph.
5
5
  Author-email: Rahul Krishna <i.m.ralk@gmail.com>
6
6
  License-File: LICENSE
@@ -290,9 +290,11 @@ def _project_module_body(
290
290
  externals: dict, sig_to_id: dict, module_id_by_key: dict,
291
291
  ) -> None:
292
292
  for fn in (mod.functions or {}).values():
293
- _project_callable(b, file_key, mod_ref, "PY_DECLARES", fn, externals, sig_to_id)
293
+ _project_callable(b, file_key, mod_ref, "PY_DECLARES", fn, externals, sig_to_id,
294
+ mod.source)
294
295
  for cl in (mod.types or {}).values():
295
- _project_class(b, file_key, mod_ref, "PY_DECLARES", cl, externals, sig_to_id)
296
+ _project_class(b, file_key, mod_ref, "PY_DECLARES", cl, externals, sig_to_id,
297
+ mod.source)
296
298
  for v in mod.variables or []:
297
299
  _project_variable(b, file_key, mod_ref, file_key, v)
298
300
  _project_imports(b, mod_ref, mod, module_id_by_key)
@@ -360,10 +362,10 @@ def _project_imports(b: RowBuilder, mod_ref: NodeRef, mod: PyModule,
360
362
 
361
363
  def _project_class(
362
364
  b: RowBuilder, file_key: str, parent: NodeRef, parent_rel: str, cl: PyClass,
363
- externals: dict, sig_to_id: dict,
365
+ externals: dict, sig_to_id: dict, source: str,
364
366
  ) -> None:
365
367
  ref = b.node(
366
- ["PySymbol", "PyClass"], "id", cl.id, _class_props(cl, file_key)
368
+ ["PySymbol", "PyClass"], "id", cl.id, _class_props(cl, file_key, source)
367
369
  )
368
370
  b.edge(parent_rel, parent, ref)
369
371
 
@@ -372,22 +374,23 @@ def _project_class(
372
374
  b.edge_to_symbol("PY_EXTENDS", ref, _symbol_ref(base, externals, sig_to_id))
373
375
 
374
376
  for m in (cl.callables or {}).values():
375
- _project_callable(b, file_key, ref, "PY_HAS_METHOD", m, externals, sig_to_id)
377
+ _project_callable(b, file_key, ref, "PY_HAS_METHOD", m, externals, sig_to_id,
378
+ source)
376
379
  for a in (cl.attributes or {}).values():
377
380
  _project_attribute(b, file_key, ref, cl.signature, a)
378
381
  for ic in (cl.types or {}).values():
379
- _project_class(b, file_key, ref, "PY_DECLARES", ic, externals, sig_to_id)
382
+ _project_class(b, file_key, ref, "PY_DECLARES", ic, externals, sig_to_id, source)
380
383
 
381
384
 
382
385
  def _project_callable(
383
386
  b: RowBuilder, file_key: str, owner: NodeRef, owner_rel: str, c: PyCallable,
384
- externals: dict, sig_to_id: dict,
387
+ externals: dict, sig_to_id: dict, source: str,
385
388
  ) -> None:
386
389
  ref = b.node(
387
390
  ["PySymbol", "PyCallable"],
388
391
  "id",
389
392
  c.id,
390
- _callable_props(c, file_key),
393
+ _callable_props(c, file_key, source),
391
394
  )
392
395
  b.edge(owner_rel, owner, ref)
393
396
 
@@ -410,9 +413,10 @@ def _project_callable(
410
413
  for v in c.local_variables or []:
411
414
  _project_variable(b, file_key, ref, c.signature, v)
412
415
  for ic in (c.callables or {}).values():
413
- _project_callable(b, file_key, ref, "PY_DECLARES", ic, externals, sig_to_id)
416
+ _project_callable(b, file_key, ref, "PY_DECLARES", ic, externals, sig_to_id,
417
+ source)
414
418
  for cl in (c.types or {}).values():
415
- _project_class(b, file_key, ref, "PY_DECLARES", cl, externals, sig_to_id)
419
+ _project_class(b, file_key, ref, "PY_DECLARES", cl, externals, sig_to_id, source)
416
420
 
417
421
 
418
422
  def _project_attribute(
@@ -459,13 +463,24 @@ def _module_props(mod: PyModule, file_key: str) -> Props:
459
463
  )
460
464
 
461
465
 
462
- def _class_props(cl: PyClass, file_key: str) -> Props:
466
+ def _span_code(source: str, span) -> str | None:
467
+ """A declaration's text: the owning module's ``source`` sliced by the node's
468
+ utf-8 byte span. Schema v2 stores source once per module, so the graph's
469
+ ``code`` property (declared on :PyClass/:PyCallable and indexed by
470
+ ``py_code_fts``) is derived here at projection time (#104)."""
471
+ if span is None or not source:
472
+ return None
473
+ lo, hi = span.bytes
474
+ return source.encode("utf-8")[lo:hi].decode("utf-8")
475
+
476
+
477
+ def _class_props(cl: PyClass, file_key: str, source: str) -> Props:
463
478
  return prune(
464
479
  {
465
480
  "id": cl.id,
466
481
  "signature": cl.signature,
467
482
  "name": cl.name,
468
- "code": getattr(cl, "code", None),
483
+ "code": _span_code(source, cl.span),
469
484
  "base_classes": list(cl.base_classes or []),
470
485
  "docstring": _docstring_of(cl.comments),
471
486
  "start_line": cl.start_line,
@@ -475,7 +490,7 @@ def _class_props(cl: PyClass, file_key: str) -> Props:
475
490
  )
476
491
 
477
492
 
478
- def _callable_props(c: PyCallable, file_key: str) -> Props:
493
+ def _callable_props(c: PyCallable, file_key: str, source: str) -> Props:
479
494
  return prune(
480
495
  {
481
496
  "id": c.id,
@@ -484,7 +499,7 @@ def _callable_props(c: PyCallable, file_key: str) -> Props:
484
499
  "path": c.path,
485
500
  "return_type": c.return_type,
486
501
  "cyclomatic_complexity": c.cyclomatic_complexity,
487
- "code": getattr(c, "code", None),
502
+ "code": _span_code(source, c.span),
488
503
  "code_start_line": c.code_start_line,
489
504
  "start_line": c.start_line,
490
505
  "end_line": c.end_line,
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "codeanalyzer-python"
3
- version = "1.0.1"
3
+ version = "1.0.2"
4
4
  description = "Static analysis for Python — canonical schema v2 (symbol table, call graph, and native CFG/PDG/SDG dataflow) as analysis.json or a Neo4j property graph."
5
5
  readme = "README.md"
6
6
  authors = [