Found while fixing a call-graph defect in the CLDK python-sdk, against a live projection of odoo-slim-19.0.0 emitted by codeanalyzer-python 1.4.0.
Observation
PY_CALLS edges can originate at a :PyExternal node — 5,307 of them on this graph. Those are external→application calls: a library or framework callback invoking application code.
But :PyExternal nodes carry no _module property:
MATCH (e:PyExternal) RETURN count(e), count(e._module)
5715, 0
Every consumer query that scopes to an application does so with WHERE x._module IN $modules — that is the documented scoping mechanism, and #173 is already tracking replacing it with a can:// id prefix. Because external nodes have no _module, any such query drops these 5,307 edges before they are ever considered.
Why it matters
The dropped edges are exactly the ones a reachability consumer most needs. A framework callback calling into application code — a route dispatcher invoking a handler, an ORM hook invoking a model method — is the entry into the application. Those edges disappearing means the call graph shows the handler as unreachable from anything, which is the same false-negative shape as a missing entrypoint.
The SDK currently cannot include them: including externals means dropping application scoping, and in a database holding several applications that would return another project's edges. So the choice today is "wrong answer" or "wrong scope".
Ask
Give :PyExternal nodes an application anchor, so they can be scoped like every other node. Either a _module property, or — better, and aligned with #173 — rely on the can:// id prefix, which external ids already carry:
can://python/odoo-slim-19/@external/builtins.super/__init__
^^^^^^^^^^^^^ the application segment is already there
If #173 lands the id-prefix scoping, this resolves with it. Filing separately because the consequence — silently dropped external→app call edges — is worth stating on its own, and because a consumer reading the current schema has no way to know those edges exist but are unreachable.
Related
Found while fixing a call-graph defect in the CLDK python-sdk, against a live projection of
odoo-slim-19.0.0emitted bycodeanalyzer-python1.4.0.Observation
PY_CALLSedges can originate at a:PyExternalnode — 5,307 of them on this graph. Those are external→application calls: a library or framework callback invoking application code.But
:PyExternalnodes carry no_moduleproperty:Every consumer query that scopes to an application does so with
WHERE x._module IN $modules— that is the documented scoping mechanism, and #173 is already tracking replacing it with acan://id prefix. Because external nodes have no_module, any such query drops these 5,307 edges before they are ever considered.Why it matters
The dropped edges are exactly the ones a reachability consumer most needs. A framework callback calling into application code — a route dispatcher invoking a handler, an ORM hook invoking a model method — is the entry into the application. Those edges disappearing means the call graph shows the handler as unreachable from anything, which is the same false-negative shape as a missing entrypoint.
The SDK currently cannot include them: including externals means dropping application scoping, and in a database holding several applications that would return another project's edges. So the choice today is "wrong answer" or "wrong scope".
Ask
Give
:PyExternalnodes an application anchor, so they can be scoped like every other node. Either a_moduleproperty, or — better, and aligned with #173 — rely on thecan://id prefix, which external ids already carry:If #173 lands the id-prefix scoping, this resolves with it. Filing separately because the consequence — silently dropped external→app call edges — is worth stating on its own, and because a consumer reading the current schema has no way to know those edges exist but are unreachable.
Related
can://id prefix; retire_module