Source code for pkglts.option.reqs.find_requirements

"""
This tool will display all dependencies used by this package.
"""

import ast
import logging
from pathlib import Path

from pkglts.local import src_dir

LOGGER = logging.getLogger(__name__)

stdpkgs = set(
    line.strip()
    for line in open(Path(__file__).parent / "stdpkgs.txt").readlines()
    if len(line.strip()) > 0 and not line.startswith("#")
)


[docs] def iter_ext_imports(body): for node in body: if isinstance(node, ast.Import): for alias in node.names: yield alias.name elif isinstance(node, ast.ImportFrom): if node.level == 0: # only external imports yield node.module
# elif isinstance(node, ast.FunctionDef): # for name, level in iter_imports(node.body): # yield name, level
[docs] def find_reqs(pth): """Find all requirements (imports) used by a script. Args: pth (Path): path to file to parse Returns: (list): list of package names """ pt = ast.parse(pth.read_bytes(), str(pth)) # TODO pb with namespaces pkgs = set(pkgname.split(".")[0] for pkgname in iter_ext_imports(pt.body)) return pkgs
def _iter_find_reqs(fld): for pth in fld.glob("*.py"): if not pth.name.startswith("_"): for req in find_reqs(pth): yield req for subfld in fld.glob("*/"): if subfld.name[0] not in ["_", "."]: for req in _iter_find_reqs(subfld): yield req
[docs] def action_find_reqs(cfg, **kwds): """Find dependencies used by this package.""" LOGGER.info("Find requirements") this_pkgname = cfg["base"]["pkgname"] for dname in (src_dir(cfg), "doc", "example", "script", "test"): dirpth = Path(dname) if dirpth.exists(): print(f"############\n# {dirpth}\n############") reqs = set(_iter_find_reqs(dirpth)) reqs -= {this_pkgname} print("standard", sorted(reqs & stdpkgs)) print("external", sorted(reqs - stdpkgs)) print("")
[docs] def parser_find_reqs(subparsers): """Associate a CLI to this tool. Notes: The CLI will be a subcommand of pmg. Args: subparsers (ArgumentParser): entity to create a subparsers Returns: (string): a unique id for this parser (callable): the action to perform """ subparsers.add_parser("reqs", help=action_find_reqs.__doc__) return "reqs", action_find_reqs