codeanalyzer-python 1.1.0__tar.gz → 1.1.1__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.
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/PKG-INFO +1 -1
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/builder.py +58 -1
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/pyproject.toml +1 -1
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/.gitignore +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/LICENSE +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/NOTICE +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/README.md +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/__init__.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/__main__.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/config/__init__.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/config/config.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/core.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/__init__.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/access_paths.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/alias.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/cfg.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/defuse.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/dominance.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/identity.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/pdg.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/scalpel/LICENSE +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/scalpel/README.md +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/scalpel/SSA/__init__.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/scalpel/SSA/const.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/scalpel/__init__.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/scalpel/cfg/__init__.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/scalpel/cfg/builder.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/scalpel/cfg/model.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/scalpel/core/__init__.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/scalpel/core/func_call_visitor.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/scalpel/core/vars_visitor.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/scalpel_oracle.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/scc.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/sdg.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/slicing.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/summaries.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/syntactic.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/jedi/__init__.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/jedi/jedi.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/neo4j/__init__.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/neo4j/bolt.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/neo4j/cypher.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/neo4j/emit.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/neo4j/project.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/neo4j/rows.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/neo4j/schema.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/options/__init__.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/options/options.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/provenance.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/py.typed +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/schema/__init__.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/schema/assign_ids.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/schema/call_graph_ids.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/schema/ids.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/schema/l1_body.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/schema/l2_callees.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/schema/py_schema.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/semantic_analysis/__init__.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/semantic_analysis/call_graph.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/semantic_analysis/pycg/__init__.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/semantic_analysis/pycg/pycg_analysis.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/semantic_analysis/pycg/pycg_exceptions.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/semantic_analysis/pycg/shard_planner.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/syntactic_analysis/__init__.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/syntactic_analysis/exceptions.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/syntactic_analysis/import_resolver.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/syntactic_analysis/symbol_table_builder.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/utils/__init__.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/utils/logging.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/utils/progress_bar.py +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/docs/handoff/README.md +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/docs/handoff/schema.neo4j.json +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/schema-uml.drawio +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/schema.neo4j.json +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/test/fixtures/whole_applications/flask/README.md +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/test/fixtures/whole_applications/flask/examples/celery/README.md +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/test/fixtures/whole_applications/flask/requirements-skip/README.md +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/test/fixtures/whole_applications/flask/src/flask/sansio/README.md +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/test/fixtures/whole_applications/requests/LICENSE +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/test/fixtures/whole_applications/requests/NOTICE +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/test/fixtures/whole_applications/requests/README.md +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/test/fixtures/whole_applications/requests/docs/_themes/LICENSE +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/test/fixtures/whole_applications/requests/ext/LICENSE +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/test/fixtures/whole_applications/xarray/LICENSE +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/test/fixtures/whole_applications/xarray/README.md +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/test/fixtures/whole_applications/xarray/properties/README.md +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/test/fixtures/whole_applications/xarray/xarray/datatree_/LICENSE +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/test/fixtures/whole_applications/xarray/xarray/datatree_/README.md +0 -0
- {codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/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.1.
|
|
3
|
+
Version: 1.1.1
|
|
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
|
|
@@ -283,6 +283,23 @@ def emit_l3_body(
|
|
|
283
283
|
continue
|
|
284
284
|
pycallable.body[local] = BodyNode(kind=node.kind, span=span)
|
|
285
285
|
|
|
286
|
+
# #115: anchor nested call vertices to their statement. A bare-call
|
|
287
|
+
# statement shares its key with its CFG node (handled above); a call
|
|
288
|
+
# nested inside a larger statement (`y = f(x)`) has its own key and
|
|
289
|
+
# no cfg contact, so it carries `parent` = the enclosing statement's
|
|
290
|
+
# local id — the same anchoring actual_in/actual_out vertices use.
|
|
291
|
+
for node in pdg.cfg.nodes:
|
|
292
|
+
if node.ast_node is None:
|
|
293
|
+
continue
|
|
294
|
+
stmt_local = im.local(node.id)
|
|
295
|
+
for call in _calls_in(node.ast_node):
|
|
296
|
+
call_key = f"{call.lineno}:{call.col_offset}"
|
|
297
|
+
child = pycallable.body.get(call_key)
|
|
298
|
+
if child is None or call_key == stmt_local:
|
|
299
|
+
continue
|
|
300
|
+
if child.kind == "call":
|
|
301
|
+
child.parent = stmt_local
|
|
302
|
+
|
|
286
303
|
if want_cfg:
|
|
287
304
|
pycallable.cfg = [
|
|
288
305
|
CfgEdge(
|
|
@@ -437,7 +454,12 @@ def emit_l4(
|
|
|
437
454
|
points-to provenance and taint are *not* emitted here (later tasks).
|
|
438
455
|
"""
|
|
439
456
|
from codeanalyzer.dataflow.identity import IdentityMap
|
|
440
|
-
from codeanalyzer.schema.py_schema import
|
|
457
|
+
from codeanalyzer.schema.py_schema import (
|
|
458
|
+
BodyNode,
|
|
459
|
+
DdgEdge,
|
|
460
|
+
ParamEdge,
|
|
461
|
+
SummaryEdge,
|
|
462
|
+
)
|
|
441
463
|
|
|
442
464
|
# L4 emission is additive (it *appends* summary/param edges), so it must
|
|
443
465
|
# first clear any L4 state a reused cache left on these live objects —
|
|
@@ -517,6 +539,41 @@ def emit_l4(
|
|
|
517
539
|
)
|
|
518
540
|
(app.param_in if e.type == "PARAM_IN" else app.param_out).append(edge)
|
|
519
541
|
|
|
542
|
+
# (e) statement ↔ port ddg wiring (#115). The IR's ``extra_edges`` — the
|
|
543
|
+
# def→actual_in, actual_out→callsite, formal_in→use and def→formal_out
|
|
544
|
+
# bindings ``assemble_sdg`` wires — are what connect the port lattice to
|
|
545
|
+
# the statement-level ddg; without them the SDG is two disconnected
|
|
546
|
+
# graphs and no end-to-end flows_to walk can cross a call. Emitted with
|
|
547
|
+
# ``prov=["reaching-defs"]`` (the label codeanalyzer-typescript ships for
|
|
548
|
+
# its port-routing ddg edges, so the vocabulary stays keystone-shared).
|
|
549
|
+
# CDG-typed extras (callsite → actual_in containment) are skipped — the
|
|
550
|
+
# actual vertices already carry that anchoring in ``parent``.
|
|
551
|
+
for sig, fg in ir.functions.items():
|
|
552
|
+
pycallable = sig_to_callable.get(sig)
|
|
553
|
+
im = ims.get(sig)
|
|
554
|
+
if pycallable is None or im is None:
|
|
555
|
+
continue
|
|
556
|
+
# Idempotency under cache reuse, mirroring the points-to delta: strip
|
|
557
|
+
# any reaching-defs edges a prior run appended before re-emitting.
|
|
558
|
+
pycallable.ddg = [e for e in pycallable.ddg if e.prov != ["reaching-defs"]]
|
|
559
|
+
seen: set = set()
|
|
560
|
+
rows = []
|
|
561
|
+
for e in fg.extra_edges:
|
|
562
|
+
if e.type != "DDG":
|
|
563
|
+
continue
|
|
564
|
+
src, dst = im.local(e.source), im.local(e.target)
|
|
565
|
+
if src not in pycallable.body or dst not in pycallable.body:
|
|
566
|
+
continue
|
|
567
|
+
key = (src, dst, e.var)
|
|
568
|
+
if key in seen:
|
|
569
|
+
continue
|
|
570
|
+
seen.add(key)
|
|
571
|
+
rows.append(
|
|
572
|
+
DdgEdge(src=src, dst=dst, var=e.var, prov=["reaching-defs"])
|
|
573
|
+
)
|
|
574
|
+
rows.sort(key=lambda r: (r.src, r.dst, r.var or ""))
|
|
575
|
+
pycallable.ddg.extend(rows)
|
|
576
|
+
|
|
520
577
|
|
|
521
578
|
def _ddg_local_set(im, pdg) -> Set[Tuple[str, str, Optional[str]]]:
|
|
522
579
|
"""The DDG edges of ``pdg`` as a set of ``(local_src, local_dst, var)``.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "codeanalyzer-python"
|
|
3
|
-
version = "1.1.
|
|
3
|
+
version = "1.1.1"
|
|
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 = [
|
|
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
|
{codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/access_paths.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/scalpel/LICENSE
RENAMED
|
File without changes
|
{codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/scalpel/README.md
RENAMED
|
File without changes
|
|
File without changes
|
{codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/scalpel/SSA/const.py
RENAMED
|
File without changes
|
{codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/scalpel/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/scalpel/cfg/builder.py
RENAMED
|
File without changes
|
{codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/scalpel/cfg/model.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/dataflow/scalpel_oracle.py
RENAMED
|
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
|
{codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/schema/call_graph_ids.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/semantic_analysis/__init__.py
RENAMED
|
File without changes
|
{codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/semantic_analysis/call_graph.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codeanalyzer_python-1.1.0 → codeanalyzer_python-1.1.1}/codeanalyzer/syntactic_analysis/__init__.py
RENAMED
|
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
|