0

I am getting to use 'argparse' for reading the command like arguments along with their corresponding string:

sample_script_2

"""Spreadsheet Column Printer
testing
"""

import argparse
import pandas as pd

def get_spreadsheet_cols(file_loc, print_cols=False):
   
    file_data = pd.read_csv(file_loc)
    col_headers = list(file_data.columns.values)
    if print_cols:
        print("\n".join(col_headers))
    return col_headers

def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("-input_file", type=argparse.FileType('r'), help='reading csv file')
    args = parser.parse_args()
    get_spreadsheet_cols(args.input_file, print_cols=True)

if __name__ == "__main__":
    main()

when I execute this file following way, it runs fine:

$ python3 sample_script_2.py -input_file test.csv
name
address
Salary

$ python3 sample_script_2.py -h
usage: sample_script_2.py [-h] [-input_file INPUT_FILE]
Testing
optional arguments:
  -h, --help            show this help message and exit
  -input_file INPUT_FILE
                        reading csv file

However, is start giving me error when I do following:

$ python3 sample_script_2.py
Traceback (most recent call last):
  File "test_area/sample_script_2.py", line 52, in <module>
    main()
  File "test_area/sample_script_2.py", line 49, in main
    get_spreadsheet_cols(args.input_file, print_cols=True)
  File "test_area/sample_script_2.py", line 38, in get_spreadsheet_cols
    file_data = pd.read_csv(file_loc)
  File "/opt/user/lib/python3.9/site-packages/pandas/util/_decorators.py", line 311, in wrapper
    return func(*args, **kwargs)
  File "/opt//user/lib/python3.9/site-packages/pandas/io/parsers/readers.py", line 586, in read_csv
    return _read(filepath_or_buffer, kwds)
  File "/opt/user/lib/python3.9/site-packages/pandas/io/parsers/readers.py", line 482, in _read
    parser = TextFileReader(filepath_or_buffer, **kwds)
  File "/opt//user/lib/python3.9/site-packages/pandas/io/parsers/readers.py", line 811, in __init__
    self._engine = self._make_engine(self.engine)
  File "/opt//user/lib/python3.9/site-packages/pandas/io/parsers/readers.py", line 1040, in _make_engine
    return mapping[engine](self.f, **self.options)  # type: ignore[call-arg]
  File "/opt//user/lib/python3.9/site-packages/pandas/io/parsers/c_parser_wrapper.py", line 51, in __init__
    self._open_handles(src, kwds)
  File "/opt//user/lib/python3.9/site-packages/pandas/io/parsers/base_parser.py", line 222, in _open_handles
    self.handles = get_handle(
  File "/opt//user/lib/python3.9/site-packages/pandas/io/common.py", line 609, in get_handle
    ioargs = _get_filepath_or_buffer(
  File "/opt//user/lib/python3.9/site-packages/pandas/io/common.py", line 396, in _get_filepath_or_buffer
    raise ValueError(msg)
ValueError: Invalid file path or buffer object type: <class 'NoneType'>

Surprisingly, the error disappear, if I change '-input_file' to 'input_file' in this line in sample_script_2.py:

-->   parser.add_argument("input_file", type=argparse.FileType('r'), help='reading csv file')

$ python3 sample_script_2.py
usage: sample_script_2.py [-h] input_file
sample_script_2.py: error: the following arguments are required: input_file

How could I get rid of the error while using the '-input_file' in my script?

1
  • What is your code supposed to do when args.input_file is None? When you don't specify a file? There isn't a problem with argparse, it's with what you do after. Commented Jul 21, 2022 at 12:22

1 Answer 1

1

The module argparse returns none when you are looking for an argument that's not supplied. And the error Invalid file path or buffer object type: <class 'NoneType'> means None can't point to a file(or its content). But when you use input_file instead of -input_file, argparse thinks it's a required parameter and exits the program with error 1 for you.

In the code of argparse, it says this: if no positional args are supplied or only one is supplied and it doesn't look like an option string, parse a positional argument. And it does so by using prefix_chars(defaults to '-'). Thus the argument -input_file is parsed as an optional one and defaults to None. Whereas when it's a positional argument, it exits with error 1 if not supplied.

So the answer to your question is: i) You want to use argparse's existing features: this is impossible unless you make it positional(required). ii) You can use a specific implementation for this program: try this

import argparse
def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("-input_file", type=argparse.FileType('r'), help='reading csv file')
    args = parser.parse_args()
    if args.input_file == None:
        parser.print_help() # or print_usage based on your choice
        parser.error("You should supply the input file")
    else:
        get_spreadsheet_cols(args.input_file, print_cols=True)

However, this will get messy when there are too many arguments

Sign up to request clarification or add additional context in comments.

5 Comments

thanks, it was useful. Still, there is no other library in python to fulfil my purpose 1.) providing arguments in command line "-input_file file.csv" and altogether happy with 2.) python3 script.py
What do you mean by 'happy' when you don't specify a file?
The author means that it throws a nice help & error message when not supplied.
Sorry for an error. There is actually a project-specific implementation. But for argparse, still no.
@jett8998 I really appreciate your help (though it would not fit my purpose entirely, since I got plenty of variables in real project, but I did gain insights). Thank you!!!

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.