Imported python module overrides option parser
Asked Answered
K

2

6

I have written a python utility script that uses optparse to include options and flags at script launch.

Everything works great, but when I import google API oauth2client and run its execute function, it overrides my add_options into the options it uses.

When I say 'overrides' I mean that even though my script add options to my option parser, when I execute the script like so:

./myscript --help

I get a detailed response of the options I added to my script:

Usage: myscript [options]

Options:
    -h, --help            show this help message and exit
    -u USER, --user=USER  resources owned by this username

But, when I actually execute my script like so:

./myscript --user myuser

I get the following error:

usage: smyscript [-h] [--auth_host_name AUTH_HOST_NAME]
               [--noauth_local_webserver]
               [--auth_host_port [AUTH_HOST_PORT     
               [AUTH_HOST_PORT  ...]]]
               [--logging_level 
               {DEBUG,INFO,WARNING,ERROR,CRITICAL}]
 myscript: error: unrecognized arguments: --user myuser

Another important thing to know is that I'm using my own module that wraps oauth2client like so:

import oauth2client
import argparse

def execute():

    parser = argparse.ArgumentParser(
            description=__doc__,
            formatter_class=argparse.RawDescriptionHelpFormatter,
            parents=[tools.argparser])
            # don't use any flags                                                                           
    flags = parser.parse_args(None)

    flow = client.flow_from_clientsecrets(
             client_secret_path,
             scope=scope_path,
             message=tools.message_if_missing(client_secret))
    # open credential storage path                                                                                                                                                                 
     credential_storage =  file.Storage(self._credential_storage_path)
     credentials = credential_storage.get()
     # get credentails if necessary                                                                                                                                                                 
     if credentials is None or credentials.invalid:
          credentials = tools.run_flow(flow, credential_storage, flags)                                                                                       

Then my script looks something like that:

import myown_oauth2client_wrapper

from optparse import OptionParser

if __name__ == "__main__":
    usage = "something"
    parser_ = OptionParser(usage)

    parser_.add_option("-u","--user")
    (options_, args) = parser_.parse_args()

    myown_oauth2client_wrapper.execute()

How can I avoid this option override?

Shahar

Kun answered 31/12, 2015 at 18:0 Comment(4)
Be more specific about the errors you get. I doubt if it is changing your parser_. More likely it is implementing its own parser (based on argparse), and parsing the same sys.argv. The error message will give a clue. There are have been other argparse questions involving the google api.Pindaric
How about telling us which module you are importing, what function you are calling and why you think add_option has been overriden?Wirra
There is not enough information to answer this question and since poster won't even tell us which function is being called, it needs to be closed.Wirra
Hey @Wirra , thanks for your reply. I have edited my question to add missing details. hope It is better nowKun
P
7

In a previous question, Getting Youtube data using Python

I found that the google api uses argparse.

from outh2client.tools import argparser

My deduction is that it is parsing the sys.argv when imported.

As I asked in the comment, we need to know what errors you are getting. What do mean by 'overrides'? What's the indication of that? Are you getting a parser error message, the kind produced by argparse or optparse? If so, what message.

Show us the commandline that gives the error, along with the error message.

You might want to call the script with -h to see who/what prints parsing help message.


So tools.argparser is an argparse parser with those auth and logging arguments defined. In the question I answered earlier, the user used that parser directly (with an addition of their own). You are using that parser as a parent.

parser = argparse.ArgumentParser(...
        parents=[tools.argparser])                                                                    
flags = parser.parse_args(None)

It now parses sys.argv. Since --user was not defined for this parser, it raises the myscript: error: unrecognized arguments: --user myuser.

One solution is to use:

flags, extras = parser.parse_known_args(None)

Now I expect it to run, and for extras to equal ['--user', 'myuser'].

Another option is to define a --user argument for this parser.

parser.add_argument('-u','--user',help='dummy user argument')
Pindaric answered 31/12, 2015 at 20:20 Comment(0)
C
0

I had an identical problem. The problem happens because the google authorization module also uses argparse. What you should achieve is not to share that memory space. I solved it by receiving the arguments via argparse, loading them into another object, but then before calling google modules I did the following:

import sys


sys.argv = [sys.argv[0]]

and my problem was solved.

Cartwright answered 21/7, 2020 at 23:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.