Skip to content

PyExternal nodes have no application anchor, so external→app PY_CALLS edges are unscopable #179

Description

@rahlk

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions