最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

Python, search from where import is call - Stack Overflow

matteradmin9PV0评论

For managing transition from an old import to a new import, I search to log from where my module is used.

By example, my old is name m_old.py. With a simple print in file m_old.py, I display a message "used of old module". So each time there is "import m_old.py", I have a message "used of old module" in execution ?

If it was a function, I will use module inspect and traceback to log in execution from where this function is call, by exemple "call of old function from file.py line XXX".

Is-it possible to display a message like : "this old import is call from file.py line XXX" ?

For managing transition from an old import to a new import, I search to log from where my module is used.

By example, my old is name m_old.py. With a simple print in file m_old.py, I display a message "used of old module". So each time there is "import m_old.py", I have a message "used of old module" in execution ?

If it was a function, I will use module inspect and traceback to log in execution from where this function is call, by exemple "call of old function from file.py line XXX".

Is-it possible to display a message like : "this old import is call from file.py line XXX" ?

Share Improve this question edited Mar 27 at 7:31 Emmanuel DUMAS asked Mar 26 at 12:51 Emmanuel DUMASEmmanuel DUMAS 73911 silver badges28 bronze badges 3
  • if you know the the module is imported you can use module.__file__ to get its path – cards Commented Mar 26 at 13:00
  • Wouldn't it be simpler to just search your codebase for occurrences of import m_old? – John Gordon Commented Mar 26 at 13:24
  • Only the first time. Every subsequent import will see that the module m_old was already created and not execute your code again. – chepner Commented Mar 26 at 13:44
Add a comment  | 

2 Answers 2

Reset to default 1

I have a similar problem: I want to know which module import which library/module, so I wrote a short script:

#!/usr/bin/env python3
"""show_imports.py: Show imports from files"""

import argparse
import ast
from collections import defaultdict
from pathlib import Path

def find_imports(path: Path, found: dict):
    content = path.read_text()
    module = ast.parse(content, path)
    for entity in ast.walk(module):
        if isinstance(entity, ast.Import):
            for alias in entity.names:
                found[alias.name].add((path, entity.lineno))
        elif isinstance(entity, ast.ImportFrom):
            found[entity.module].add((path, entity.lineno))

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("dir")
    options = parser.parse_args()
    root = Path(options.dir).resolve().relative_to(Path.cwd())

    if root.is_file():
        paths = [root]
    elif root.is_dir():
        paths = root.rglob("*.py")
    else:
        raise SystemExit(f"{root} is not a valid dir or file")

    found = defaultdict(set)
    for path in paths:
        find_imports(path, found)

    for mod, paths in found.items():
        print(mod)
        for path, lineno in sorted(paths):
            print(f"  {path}({lineno})")


if __name__ == "__main__":
    main()

You can run this script and pass in either a single python script, or a directory. In the case of directory, all python scripts in there will be analyzed. Here is a sample run of the script against itself:

$ ./show_imports.py show_imports.py
argparse
  show_imports.py(4)
ast
  show_imports.py(5)
collections
  show_imports.py(6)
pathlib
  show_imports.py(7)

Notes

  • I use the ast library to parse each Python script
  • The ast.walk() will walk through all entities in the script, but I only care about the ast.Import and ast.ImportFrom entities

After investigation on module traceback, I found my solution :

traceback.extract_stack()

And analyse list in many level (around 10) and I have found file and line of import.

Can also use inspect, by example like this :

import inspect

fl = inspect.stack()
cnt = 0
for f in fl:
    # print("f=", f.filename, " l=", f.lineno)
    if f.filename[0:7] != "<frozen":
        # print("          >>>>> f=", f.filename, " l=", f.lineno)
        cnt += 1
        if cnt == 2:
            print("WARNING : %s(%d) replace import m_old by import m_new" % (f.filename, f.lineno))
Post a comment

comment list (0)

  1. No comments so far