Skip to content
This repository has been archived by the owner on Nov 26, 2023. It is now read-only.

[need help] Is this uncomplete call graph within expectation? #24

Closed
LeeSureman opened this issue Mar 1, 2022 · 8 comments
Closed

[need help] Is this uncomplete call graph within expectation? #24

LeeSureman opened this issue Mar 1, 2022 · 8 comments

Comments

@LeeSureman
Copy link

LeeSureman commented Mar 1, 2022

Hello, I have read your work "PyCG: Practical Call Graph Generation in Python", and think it is valuable, helpful and insightful. However, when I try to scan this file as following:

class tmp_C:
    def tmp_f_in_c(self):
        print('tmp_f_in_c called')
        return None

def tmp_f():
    a = tmp_C
    returned = a()
    return returned


def f_sample():

    tmp_c = tmp_f()
    tmp_c.tmp_f_in_c()

the extracted callgraph is
{"small": ["small.f_sample"], "small.tmp_C.tmp_f_in_c": ["<builtin>.print"], "<builtin>.print": [], "small.tmp_f": [], "small.f_sample": ["small.tmp_f"]}
there is not 'small.tmp_C.tmp_f_in_c' in 'small.f_sample' 's calling function while 'small.f_sample' has called 'small.tmp_C.tmp_f_in_c'. So I'd ask whether your callgraph generator could extract this complete callgraph within expectation? It will be a great and wonderful help if you response me. Thank you!

@LeeSureman LeeSureman changed the title Is this uncomplete call graph in your expectation [need help] Is this uncomplete call graph within expectation? Mar 1, 2022
@vitsalis
Copy link
Owner

vitsalis commented Mar 1, 2022

PyCG should produce a complete call graph in this case. This is probably a bug with the generator, I'll investigate when I got the bandwidth and get back to you.

@LeeSureman
Copy link
Author

Very thank you for your quick response!! It will be a great help for me. Actually I can provide another code snippet which may be related to the code above or an extension (about external library) of the code above. This code sample is as following:

def f_sample_2():
    import numpy
    import torch

    numpy_array = numpy.ones(shape=[2,3])
    torch_tensor = torch.ones(size=[2,3])

    numpy_array.max()
    torch_tensor.max()

The extracted callgraph is
["numpy.ones", "torch.ones"]
I think it maybe lack
numpy.ndarray.max and torch.Tensor.max (Am I right? or is it within expectation? )

this new case involves the external library like numpy and torch. (I see your code involves handling external library, so in expectation your code can give the complete callgraph in this case?)
Looking forward to receiving your response.

@seanxiaoyan
Copy link
Contributor

seanxiaoyan commented Mar 6, 2022

Hello, I have read your work "PyCG: Practical Call Graph Generation in Python", and think it is valuable, helpful and insightful. However, when I try to scan this file as following:

class tmp_C:
    def tmp_f_in_c(self):
        print('tmp_f_in_c called')
        return None

def tmp_f():
    a = tmp_C
    returned = a()
    return returned


def f_sample():

    tmp_c = tmp_f()
    tmp_c.tmp_f_in_c()

the extracted callgraph is {"small": ["small.f_sample"], "small.tmp_C.tmp_f_in_c": ["<builtin>.print"], "<builtin>.print": [], "small.tmp_f": [], "small.f_sample": ["small.tmp_f"]} there is not 'small.tmp_C.tmp_f_in_c' in 'small.f_sample' 's calling function while 'small.f_sample' has called 'small.tmp_C.tmp_f_in_c'. So I'd ask whether your callgraph generator could extract this complete callgraph within expectation? It will be a great and wonderful help if you response me. Thank you!

I think PyCG is trying to look for class tmp_c but tmp_c is not defined anywhere in scope.
It will work if you change tmp_c.tmp_f_in_c() to tmp_C.tmp_f_in_c()

{"small": [], "small.tmp_C.tmp_f_in_c": ["<builtin>.print"], "<builtin>.print": [], "small.tmp_f": [], "small.f_sample": ["small.tmp_f", "small.tmp_C.tmp_f_in_c"]}

@LeeSureman
Copy link
Author

Hello, I have read your work "PyCG: Practical Call Graph Generation in Python", and think it is valuable, helpful and insightful. However, when I try to scan this file as following:

class tmp_C:
    def tmp_f_in_c(self):
        print('tmp_f_in_c called')
        return None

def tmp_f():
    a = tmp_C
    returned = a()
    return returned


def f_sample():

    tmp_c = tmp_f()
    tmp_c.tmp_f_in_c()

the extracted callgraph is {"small": ["small.f_sample"], "small.tmp_C.tmp_f_in_c": ["<builtin>.print"], "<builtin>.print": [], "small.tmp_f": [], "small.f_sample": ["small.tmp_f"]} there is not 'small.tmp_C.tmp_f_in_c' in 'small.f_sample' 's calling function while 'small.f_sample' has called 'small.tmp_C.tmp_f_in_c'. So I'd ask whether your callgraph generator could extract this complete callgraph within expectation? It will be a great and wonderful help if you response me. Thank you!

I think PyCG is trying to look for class tmp_c but tmp_c is not defined anywhere in scope. It will work if you change tmp_c.tmp_f_in_c() to tmp_C.tmp_f_in_c()

{"small": [], "small.tmp_C.tmp_f_in_c": ["<builtin>.print"], "<builtin>.print": [], "small.tmp_f": [], "small.f_sample": ["small.tmp_f", "small.tmp_C.tmp_f_in_c"]}

Thank you for your response and help!
Since 'tmp_c' is the instance of 'tmp_C' as defined in 'tmp_f', do you mean PYCG technically can not detect 'tmp_c' is the instance of 'tmp_C'?

@seanxiaoyan
Copy link
Contributor

seanxiaoyan commented Mar 6, 2022

Hello, I have read your work "PyCG: Practical Call Graph Generation in Python", and think it is valuable, helpful and insightful. However, when I try to scan this file as following:

class tmp_C:
    def tmp_f_in_c(self):
        print('tmp_f_in_c called')
        return None

def tmp_f():
    a = tmp_C
    returned = a()
    return returned


def f_sample():

    tmp_c = tmp_f()
    tmp_c.tmp_f_in_c()

the extracted callgraph is {"small": ["small.f_sample"], "small.tmp_C.tmp_f_in_c": ["<builtin>.print"], "<builtin>.print": [], "small.tmp_f": [], "small.f_sample": ["small.tmp_f"]} there is not 'small.tmp_C.tmp_f_in_c' in 'small.f_sample' 's calling function while 'small.f_sample' has called 'small.tmp_C.tmp_f_in_c'. So I'd ask whether your callgraph generator could extract this complete callgraph within expectation? It will be a great and wonderful help if you response me. Thank you!

I think PyCG is trying to look for class tmp_c but tmp_c is not defined anywhere in scope. It will work if you change tmp_c.tmp_f_in_c() to tmp_C.tmp_f_in_c()

{"small": [], "small.tmp_C.tmp_f_in_c": ["<builtin>.print"], "<builtin>.print": [], "small.tmp_f": [], "small.f_sample": ["small.tmp_f", "small.tmp_C.tmp_f_in_c"]}

Thank you for your response and help! Since 'tmp_c' is the instance of 'tmp_C' as defined in 'tmp_f', do you mean PYCG technically can not detect 'tmp_c' is the instance of 'tmp_C'?

This is causing issue

    a = tmp_C
    returned = a()

PyCG can detect instance if the code looks like this

class tmp_C:
    def tmp_f_in_c(self):
        print('tmp_f_in_c called')
        return None

def tmp_f():
    a = tmp_C()
    return a


def f_sample():
    tmp_c = tmp_f()
    tmp_c.tmp_f_in_c()

@LeeSureman
Copy link
Author

@seanxiaoyan yes, it is rare but it is grammatical in python.. Since the author says PYCG should detect it, I will wait for him to figure out it..

@LeeSureman
Copy link
Author

hello, would you mind me asking when this bug can be fixed?

@vitsalis
Copy link
Owner

Closing due to archival of repository.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants