Search code examples
pythonbashseqoptparse

passing bash seq sequence to python option parser: TypeError: '<' not supported between instances of 'int' and 'str'


I'm juste trying to have this work:

def main(argv):
    parser = OptionParser()
    parser.add_option("-v", "--variables", nargs="*", default=['dem'], type="str", dest="variables")
    parser.add_option("-t", "--timesID", nargs="*", default=range(20,-200,-1), type="float", dest="timesID")
    (options, args) = parser.parse_args(argv)
    try:
        return get_chelsa(
            inputFile = options.input,
            variables = options.variables,
            timesID = options.timesID)
    except Exception as e:
        print(e)

if __name__ == '__main__':
    import sys
    main(sys.argv[1:])

And then I would like to call this with:

python3 script.py -t seq -100 -1 20

But it returns an error:

Traceback (most recent call last):
  File "script.py", line 203, in <module>
    main(sys.argv[1:])
  File ".script.py", line 186, in main
    (options, args) = parser.parse_args(argv)
  File "/usr/lib/python3.8/optparse.py", line 1387, in parse_args
    stop = self._process_args(largs, rargs, values)
  File "/usr/lib/python3.8/optparse.py", line 1431, in _process_args
    self._process_short_opts(rargs, values)
  File "/usr/lib/python3.8/optparse.py", line 1522, in _process_short_opts
    if len(rargs) < nargs:
TypeError: '<' not supported between instances of 'int' and 'str'

What am I doing wrong ?


Solution

  • I ended up using callbacks. It's still weird to me there is nothing more direct. I am not entirely happy with this solution because I can not define default sequences as options.

    def get_variables_args(option, opt, value, parser):
        setattr(parser.values, option.dest, value.split(','))
    
    def get_timesID_args(option, opt, value, parser, type='float'):
        setattr(parser.values, option.dest, [float(s) for s in value.split(',')])
    
    def main(argv):
    
        parser = OptionParser()
    
        parser.add_option("-v", "--variables",
                            dest="variables",
                            type='str',
                            action='callback',
                            callback=get_variables_args)
    
        parser.add_option("-t", "--timesID",
                            dest="timesID",
                            type='str',
                            action='callback',
                            callback=get_timesID_args)
        (options, args) = parser.parse_args(argv)
        try:
            return my_function(
                variables = options.variables,
                timesID = options.timesID)
        except Exception as e:
            print(e)
    
    if __name__ == '__main__':
        import sys
        main(sys.argv[1:])
    

    Callable in bash with:

    myscript.py -v dem -t $(seq -s ',' -100 1 20)