3

Let's say I have a module with some code in it and I want to find the imported libraries for this module.

import os
import pandas as pd
import numpy as np
from os.path import basename, join

def export(df, folder):
    """some export thing (not really important)"""
    f = join(folder, "test.csv")
    df.to_csv(f)
    return f

So this is just a dummy example. What the methods do aren't really important in this context of the question

From a previous question, I was able to get the import statements that import modules, not realizing that the from foo import bar will not show.

[(x, y.__name__) for x,y in inspect.getmembers(sys.modules[__name__], inspect.ismodule)]

This will return a tuple:

[('inspect', 'inspect'), ('np', 'numpy'), ('os', 'os'), ('pd', 'pandas'), ('sys', 'sys')]

I can then take that list and if the tuple position 0 != position 1 then it's an import foo as f situation. What is missing are situations where the from os.path impor basename, join and situations where from os import path. How do I include this types of imports?

Thanks

5
  • 2
    Are you trying do this determination at runtime for some particular reason? Or are you trying to do static code analysis, and just doing it at runtime so you can utilize inspect and Python's runtime import information? Commented May 29, 2018 at 12:41
  • why? you want to find the dependencies of a particular module perhaps? Commented May 29, 2018 at 13:19
  • relevant? github.com/mgedmin/findimports Commented May 29, 2018 at 13:20
  • @Chris_Rands to move code from local machine to a server at runtime. Commented May 29, 2018 at 14:15
  • @PaulMcG i want to do it at runtime. Commented May 29, 2018 at 14:15

1 Answer 1

1

You need to create a custom predicate function that accepts both modules and function. In that case you'll be able to get the name of all the function as well and then by filtering the members based on your need you can get the desired result.

def get_members(module):
    predicate = lambda x: inspect.ismodule or  inspect.function

    for x,y in inspect.getmembers(module, predicate):
        try:
            md = y.__module__
            if md != "__main__":
                yield (x, y.__name__, y.__module__)
        except:
            if inspect.ismodule(y):
                yield (x, y.__name__) 

Demo:

# test.py

import os
import pandas as pd
import numpy as np
from os.path import basename, join
from itertools import product
import inspect
import sys

def export(df, folder):
    """some export thing (not really important)"""
    f = join(folder, "test.csv")
    df.to_csv(f)
    return f

def get_members(module):
    predicate = lambda x: inspect.ismodule or  inspect.function

    for x,y in inspect.getmembers(module, predicate):
        try:
            md = y.__module__
            if md != "__main__":
                yield (x, y.__name__, y.__module__)
        except:
            if inspect.ismodule(y):
                yield (x, y.__name__)    


print(list(get_members(sys.modules[__name__])))

Output:

~/Desktop$ python3 test.py 
[('__builtins__', 'builtins'), ('basename', 'basename', 'posixpath'), ('inspect', 'inspect'), ('join', 'join', 'posixpath'), ('np', 'numpy'), ('os', 'os'), ('pd', 'pandas'), ('product', 'product', 'itertools'), ('sys', 'sys')]
Sign up to request clarification or add additional context in comments.

2 Comments

can you explain the output?
@codebase5000 It's exactly like your code except for imported functions there is an extra y.__module__.

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.