3

I am trying to identify the import module name which is dependent by a variable in the script.

ex:

import module1

import module2

x = module1.func()
    
y = x.func()

given y, my output should be y -> x -> module1 and the respective line num.

Can someone help me figure this out? Just now started exploring this with AST.

2
  • All the AST module does is parse. To figure out code dependencies, you need to do control flow analysis, which is far outside of the scope of parsing. I don't think the Python library comes with a tool which does that. Commented May 16, 2021 at 15:23
  • @rici thanks for your reply, is there any way to group the ast.names by expression, so that i can identify they belong in one expression. ex : y= x+z; randomfunction(y). the output should group, y,x and z to group 1.randomfunction and y to group 2. Commented May 16, 2021 at 16:21

3 Answers 3

2

Just using ast is not going to be helpful in a lot of situations. You need to include some kind of (simulated) execution, akin of exec().

For example, what can the ast tell from this Python program, which outputs a string of digits? The identifier "digits" seems to come out of thin air in the syntax tree.

exec('from string import digits')
mystr = digits
print(mystr)

And, to support the argument of execution needed, the following program would have to result in output nums -> int, but just using a syntax tree, it would probably output nums -> string | int.

import string
nums = string.digits
if True:
    nums = 0
print(nums)

Now, what you are asking can still be done, but rather than solve it with abstract syntax trees, you would have more success using trace as a starting point, and enhance the data collected in the various tracing calls.

Sign up to request clarification or add additional context in comments.

3 Comments

thanks for your reply. I wanted to do this analysis for more than 1k scripts which I cant execute it. is this trace is a package or do you mean to trace all the variables and calls?
It's a standard library package. Looking at it's source code, you might be able to use that as a starting point for your work. BTW, I've used ast for listing "where used" of libraries. But that's the easy part. Evaluating true library dependency for each variable is much harder.
Ohh okay. thanks for your reply, will try it :)
1

Your problem would be that your dependencies change dynamically. They are simply static dependencies and keeping tap on every variable running around would be more heftier that your script/program load.

If you want to include only static dependencies you can do it using my tool:

https://github.com/bedbad/pyimports

In particular you work around ast like this:

def get_imports(path):
    imports = dict()
    with open(path) as fh:
        root = ast.parse(fh.read(), path)
        for node in ast.iter_child_nodes(root):
            if isinstance(node, ast.Import):
                temp = imports
                for n in node.names:
                    namelist = n.name.split('.')
                    if len(namelist) > 1:
                        for st in namelist:
                            temp[st] = dict()
                            temp = temp[st]
                    else:
                        temp[n.name] = dict()
            elif isinstance(node, ast.ImportFrom):
                temp = imports
                namelist = node.module.split('.')
                for n in namelist:
                    temp[n] = dict()
                    temp = temp[n]
                for n in node.names:
                    temp[n.name] = dict()
            else:
                continue
 return imports

Comments

0

use __name__ attribute

>>> import numpy
>>> x = numpy
>>> y = x.__name__
>>> y
'numpy'

Edit:

import numpy

arr = []

def a(strofwanted, library, varname):
    global arr
    arr.append([varname, library])
    return exec(strofwanted)

x = a("numpy.array([1, 2])", "numpy", "x")
>>>x
[1,2]
>>>arr
[["x", "numpy"]]

2 Comments

Hi thanks for your reply, I am not trying to assign a import module and checking it. I am trying to find the variables which uses the import module. ___
No, import ast tree = ast.parse(code) x=tree.value[0] if x is given my ouput should be ast

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.