The Python module I'm writing has some functionalities available from command line interface via python -m fun_module -p ....
argument -p
, --path
takes multiple paths. Presently I'm defining this argument in the following manner:
parser = argparse.ArgumentParser(prog="FunProg", add_help=True)
parser.add_argument(
"-p",
"--path",
type=utils.dir_path,
nargs="+",
help="Start path(s) used to conduct the search. Multiple paths should be separated with spaces.",
)
args = parser.parse_args()
dir_path
function available via utils.py
fileimport os
def dir_path(str_path):
if os.path.isdir(str_path):
return str_path
else:
raise NotADirectoryError(str_path)
main
methoddef main(args):
for iarg in args.path:
print("Searching path: " + iarg)
Handling multiple paths separated with spaces and surrounded with inverted commas doesn't return the desired results.
python -m fun_module -p ~/Documents ~/Downloads/
Searching path: /Users/thisuser/Documents
Searching path: /Users/thisuser/Downloads/
python -m fun_module -p '~/Documents' '~/Downloads/'
Searching path: /Users/thisuser/Documents
Searching path: /Users/thisuser/Downloads/
python -m fun_module -p "~/Documents" "~/Downloads/"
Searching path: /Users/thisuser/Documents
Searching path: /Users/thisuser/Downloads/
python -m fun_module -p '~/Documents' '~/Downloads/'
Traceback (most recent call last):
File "/Users/thisuser/.pyenv/versions/3.9.0/lib/python3.9/runpy.py", line 197, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/Users/thisuser/.pyenv/versions/3.9.0/lib/python3.9/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "/Users/thisuser/Dev/Python/FileLister/filelister/__main__.py", line 25, in <module>
args = parser.parse_args()
File "/Users/thisuser/.pyenv/versions/3.9.0/lib/python3.9/argparse.py", line 1818, in parse_args
args, argv = self.parse_known_args(args, namespace)
File "/Users/thisuser/.pyenv/versions/3.9.0/lib/python3.9/argparse.py", line 1851, in parse_known_args
namespace, args = self._parse_known_args(args, namespace)
File "/Users/thisuser/.pyenv/versions/3.9.0/lib/python3.9/argparse.py", line 2060, in _parse_known_args
start_index = consume_optional(start_index)
File "/Users/thisuser/.pyenv/versions/3.9.0/lib/python3.9/argparse.py", line 2000, in consume_optional
take_action(action, args, option_string)
File "/Users/thisuser/.pyenv/versions/3.9.0/lib/python3.9/argparse.py", line 1912, in take_action
argument_values = self._get_values(action, argument_strings)
File "/Users/thisuser/.pyenv/versions/3.9.0/lib/python3.9/argparse.py", line 2461, in _get_values
value = [self._get_value(action, v) for v in arg_strings]
File "/Users/thisuser/.pyenv/versions/3.9.0/lib/python3.9/argparse.py", line 2461, in <listcomp>
value = [self._get_value(action, v) for v in arg_strings]
File "/Users/thisuser/.pyenv/versions/3.9.0/lib/python3.9/argparse.py", line 2476, in _get_value
result = type_func(arg_string)
File "/Users/thisuser/Dev/Python/FileLister/filelister/utils.py", line 7, in dir_path
raise NotADirectoryError(str_path)
NotADirectoryError: ~/Documents
The problem was two folded:
os.path.expanduser
when using the ~
.'
or "
), the os.path.expanduser
won't properly handle the input.To solve the issues, first replace the quotes by empty strings. Using python 3.9 this can be done with:
for quote in ['"', "'"]:
str_path = str_path.removeprefix(quote).removesuffix(quote)
otherwise you have to manually check and remove:
for quote in ['"', "'"]:
if str_path.startswith(quote):
str_path = str_path[1:-1]
And then you have to check for a tilde start:
if str_path.startswith('~'):
str_path = os.path.expanduser(str_path)
Full code:
def dir_path(str_path: str):
for quote in ['"', "'"]:
if str_path.startswith(quote):
str_path = str_path[1:-1]
if str_path.startswith('~'):
str_path = os.path.expanduser(str_path)
if os.path.isdir(str_path):
return str_path
raise NotADirectoryError(str_path)
And testing with any of the following inputs will result in a full path:
python -m fun_module -p '~/Documents' '~/Downloads'
python -m fun_module -p "~/Documents" "~/Downloads"
python -m fun_module -p ~/Documents ~/Downloads