Pre-flight checks
What happened?
The typed-receiver arm of _resolve_python_member_calls (#4198) checks that the receiver's class is defined in, or imported into, the caller's file. It finds the caller's file with _file_node, which returns the caller's first contains parent. For a top-level function or a method that parent is the file, but for a nested function it is the enclosing function, and for a method of a nested class it is the outer class. The check then compares a function (or class) id with the file's imports, fails, and the call gets no edge, although the extractor stamped the right receiver_type.
Nested typed callbacks are common, e.g. click's option factories:
# click/decorators.py
def confirmation_option(*param_decls, **kwargs):
def callback(ctx: Context, param: Parameter, value: bool) -> None:
if not value:
ctx.abort() # receiver_type: Context, but no edge to Context.abort
Measured against jedi on 0.9.80: click has 10 such calls (ctx.exit(), ctx.abort(), ...), rich 4; all 14 are real calls jedi resolves to the same method.
Steps to reproduce
mkdir -p demo/pkg && cd demo
touch pkg/__init__.py
printf 'class Client:\n def send(self):\n return 1\n' > pkg/client.py
cat > pkg/use.py <<'EOF'
from .client import Client
def top(c: Client):
return c.send()
def outer():
def inner(c: Client):
return c.send()
return inner
EOF
graphify update . --no-cluster
python -c "import json; g=json.load(open('graphify-out/graph.json')); n={x['id']:x['label'] for x in g['nodes']}; [print(n[e['source']], '->', n[e['target']]) for e in g.get('links', g.get('edges', [])) if e['relation']=='calls']"
Error output or graph output
top() -> .send()
`inner() -> .send()` is missing. Same for `class Outer: class Inner: def go(self, c: Client): c.send()`.
Graphify version
0.9.80 (6478eb7)
Operating System
Windows
Python Version
3.12
Installation Method
built from source (git clone)
Additional Environment Details
No LLM keys; AST only. Clean checkout of v8 @ 6478eb7 reproduces.
Additional context
Follow-up to #4198 (where this arm was added). PR right after this issue.
Pre-flight checks
What happened?
The typed-receiver arm of
_resolve_python_member_calls(#4198) checks that the receiver's class is defined in, or imported into, the caller's file. It finds the caller's file with_file_node, which returns the caller's firstcontainsparent. For a top-level function or a method that parent is the file, but for a nested function it is the enclosing function, and for a method of a nested class it is the outer class. The check then compares a function (or class) id with the file's imports, fails, and the call gets no edge, although the extractor stamped the rightreceiver_type.Nested typed callbacks are common, e.g. click's option factories:
Measured against jedi on 0.9.80: click has 10 such calls (
ctx.exit(),ctx.abort(), ...), rich 4; all 14 are real calls jedi resolves to the same method.Steps to reproduce
Error output or graph output
Graphify version
0.9.80 (6478eb7)
Operating System
Windows
Python Version
3.12
Installation Method
built from source (git clone)
Additional Environment Details
No LLM keys; AST only. Clean checkout of v8 @ 6478eb7 reproduces.
Additional context
Follow-up to #4198 (where this arm was added). PR right after this issue.