Search code examples
pythonglob

How to pass files to script with glob AND specific path, with error if path does not exist?


I have a script that usually needs to perform one of two tasks:

1) process a bunch of files with paths expanded from a wildcard expansion.
2) process specific files with definite paths.

I've been using glob to handle the wildcard expansion, but this raises a problem. Because glob only returns paths that actually exist, the code won't generate an error if a specific path to a nonexistent file is given by the user.

Below is a minimal working example (MWE) of the code. The MWE happily processes existing files expanded from the wildcard, but does not generate the desired error message because glob only returns existing paths.

#!/usr/bin/env python3

import argparse, glob, sys, os

parser = argparse.ArgumentParser()
parser.add_argument("src_path", metavar="path", type=str,
    help="Path to files to be merged; enclose in quotes, accepts * as wildcard for directories or filenames")

args = parser.parse_args()
files = glob.iglob(args.src_path)

for file in files:
    try:    
        with open(file, 'r') as f:
            sys.stdout.write('File exists: ' + file + '\n') 
    except IOError:
        sys.stderr.write('File does not exist: ' + file + '\n') 

How can I modify this to behave as desired?


Solution

  • If you want to stick with glob.iglob:

    #!/usr/bin/env python3
    
    import argparse, glob, sys, itertools
    
    parser = argparse.ArgumentParser()
    parser.add_argument("src_path", metavar="path", type=str,
        help="Path to files to be merged; enclose in quotes, accepts * as wildcard for directories or filenames")
    
    args = parser.parse_args()
    files = glob.iglob(args.src_path)
    
    try:
        first_file = files.next()
    except StopIteration:
        print('File does not exist: ' + args.src_path, file=sys.stderr)
        sys.exit(1)
    for file in itertools.chain([first_file], files):
        print('File exists: ' + file)
    

    If glob.glob is acceptable:

    #!/usr/bin/env python3
    
    import argparse, glob, sys
    
    parser = argparse.ArgumentParser()
    parser.add_argument("src_path", metavar="path", type=str,
        help="Path to files to be merged; enclose in quotes, accepts * as wildcard for directories or filenames")
    
    args = parser.parse_args()
    files = glob.glob(args.src_path)
    
    if not files:
        print('File does not exist: ' + args.src_path, file=sys.stderr)
    for file in files:
        print('File exists: ' + file)