Getting full path from the relative path with Argparse

Question:

I am writing a small command line utility for my script and I can’t figure out how to properly get the full path from the argument.

Here’s what I mean.

parser = ArgumentParser()
parser.add_argument("-src",
                    required = True, help="path to some folder")
args = parser.parse_args()
print(args.src)

If the user pass the full path, e.g. "/home/username/projectname/folder", everything is fine.

But if the user runs the script from let’s say "projectname" folder and pass the relative path "./folder" I get exactly the same string "./folder" while parsing the arguments instead of the full path "/home/username/projectname/folder".

So, I have been wondering if there is some kind of inbuilt functionality in Argparse that allows to get the full path from the relative path?

Asked By: Denis

||

Answers:

EDIT: The Alex’s answer shows how to make argparse manage relative-to-absolute path conversion by simply filling the add_argument‘s type parameter.


I do not think argparse provides such feature but you can achieve it using os.path.abspath:

abs_src = os.path.abspath(args.src)

Keep in mind that this will make an absolute path by concatenating the working directory with the relative path. Thus the path is considered relative to working directory.


If you want to make the path relative to the script directory, you can use os.path.dirname on the __file__ variable and os.path.join to build an absolute path from a path relative to your Python script:

script_dir = os.path.dirname(__file__)
abs_src = os.path.join(script_dir, args.src)

Finally, since joined path can contain tokens such as . and .., you can “prettify” your built path with os.path.normpath:

abs_path = os.path.normpath(os.path.join(script_dir, args.src))
Answered By: Tryph

To add onto Tryph’s answer, you can specify the type parameter in the argument declaration. It can take any callable that takes a single string argument and returns the converted value:

parser.add_argument("-src",
                    required=True,
                    help="path to some folder",
                    type=os.path.abspath)

This returns a string with the absolute path, you could specify your own function as well:

def my_full_path(string):
    script_dir = os.path.dirname(__file__)
    return  os.path.normpath(os.path.join(script_dir, string))


parser = ArgumentParser()
parser.add_argument("-src",
                    required=True,
                    help="path to some folder",
                    type=my_full_path)
Answered By: Alex

Wouldn’t our friend pathlib simplify this?

from pathlib import Path

abs_path = Path(args.src.name).resolve()

abs_path is now a pathlib.PosixPath object, but it easily casts to a string if needed.

Answered By: Geozeke
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.