0

I'm writing a small utility function which takes in input arguments of the location of a Python file, and also a function to call within the Python file

For example src/path/to/file_a.py

def foo():
  ...

In the utility function, I'm parsing the arguments like so:

python ./util.py --path src/path/to/file_a.py --function foo

and the foo function needs to be used later in the util.py in another library:

def compile():
  compiler.compile(
    function=foo,
    etc
  )

What's the best way of importing the foo function via argparse?


Some initial thoughts:

util.py:

def get_args():
  parser = argparse.ArgumentParser()
  parser.add_argument("--path", type=str)
  parser.add_argument("--function", type=str)
  return parser.parse_args()

def compile(path, function):
  import path 
  compiler.compile(
    function=path.function,
    etc
  )

if __name__ == "__main__":
  args = get_args()
  compile(
    path=args.path
    function=args.function
  )

however importing via argparse, and adding it to the function does not seem to work nicely.

There's also the idea of using sys.path.append:

def compile(path, function):
  import sys
  sys.path.append(path)

but then I'm unsure of how to import the foo function from that.

1
  • State the actual error, not a vague 'does not work'. All arparse can do for you is get the two strings. What you do with the strings is not part of argparse Commented Jan 24, 2023 at 16:08

1 Answer 1

1

This problem can be rephrased as "how do I import a python file given a path?" To do that, we can use https://stackoverflow.com/a/67692/5666087. Here is a code example that incorporates the answer to that question with your needs.

import argparse
import importlib.util
import sys


def get_function_object(path_to_pyfile: str, funcname: str):
    spec = importlib.util.spec_from_file_location("tmpmodulename", path_to_pyfile)
    module = importlib.util.module_from_spec(spec)
    sys.modules["tmpmodulename"] = module
    spec.loader.exec_module(module)
    if not hasattr(module, funcname):
        raise AttributeError(f"Cannot find function '{funcname}'in imported module")
    # TODO: Consider testing whether this object is a callable.
    return getattr(module, funcname)


def get_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("--path", type=str)
    parser.add_argument("--function", type=str)
    return parser.parse_args()


if __name__ == "__main__":
    args = get_args()
    function = get_function_object(args.path, funcname=args.function)
    compiler.compile(function=funtion)
Sign up to request clarification or add additional context in comments.

Comments

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.