Search code examples
pythontensorflowflags

Exception thrown when running tf.app.run()


I am toying around with flags at the moment and came across some weird behavior when using tf.app.run(). The following code snippet should simply print the string given via the command line.

import tensorflow as tf

# command line flags
tf.app.flags.DEFINE_string('mystring', 'Hello World!',
                           '''String to print to console.''')

FLAGS = tf.app.flags.FLAGS


def main():

    print(FLAGS.mystring)

if __name__ == '__main__':
    tf.app.run()

During execution, this error is thrown:

Traceback (most recent call last):

File "", line 1, in runfile('/path/flags.py', wdir='/path')

File "/home/abc/anaconda3/envs/tensorflow/lib/python3.5/site-packages/spyder/utils/site/sitecustomize.py", line 710, in runfile execfile(filename, namespace)

File "/home/abc/anaconda3/envs/tensorflow/lib/python3.5/site-packages/spyder/utils/site/sitecustomize.py", line 101, in execfile exec(compile(f.read(), filename, 'exec'), namespace)

File "/path/flags.py", line 19, in tf.app.run()

File "/home/abc/anaconda3/envs/tensorflow/lib/python3.5/site-packages/tensorflow/python/platform/app.py", line 126, in run _sys.exit(main(argv))

TypeError: main() takes 0 positional arguments but 1 was given

...which is strange because I do not give a single argument to main(). However, if I add an underscore def main(_):, it works without any errors.

I couldn't find a doc where this is use of the underscore is described. Does anybody know what happens here? Thank you!


Solution

  • The error message I see in Pycharm IDE when I execute your code is clearer.

    Traceback (most recent call last):
      File "D:/PycharmProjects/TensorFlow/self.py", line 30, in <module>
        tf.app.run()
      File "D:\\Anaconda\envs\tensorflow\lib\site-packages\tensorflow\python\platform\app.py", 
    line 48, in run
        _sys.exit(main(_sys.argv[:1] + flags_passthrough))
    TypeError: main() takes 0 positional arguments but 1 was given
    

    _sys.exit(main(_sys.argv[:1] + flags_passthrough)) is trying to call our main method with one argument.

    This is the run method in app.py

    A stripped down version of the run method can be used to test.

    import tensorflow as tf
    import sys as _sys
    from tensorflow.python.platform import flags
    
    
    # command line flags
    tf.app.flags.DEFINE_string('mystring', 'Hello World!',
                               '''String to print to console.''')
    
    FLAGS = tf.app.flags.FLAGS
    
    def run(main=None, argv=None):
      """Runs the program with an optional 'main' function and 'argv' list."""
      f = flags.FLAGS
    
      # Extract the args from the optional `argv` list.
      args = argv[1:] if argv else None
    
      # Parse the known flags from that list, or from the command
      # line otherwise.
      # pylint: disable=protected-access
      flags_passthrough = f._parse_flags(args=args)
      # pylint: enable=protected-access
    
      main = main or _sys.modules['__main__'].main
    
      print (_sys.argv[:1])
    
      # Call the main function, passing through any arguments
      # to the final program.
      #_sys.exit(main(_sys.argv[:1] + flags_passthrough))
    
      # Call the main function with no arguments
      #_sys.exit(main())
    
    
    def main():
        print(FLAGS.mystring)
    
    if __name__ == '__main__':
        #tf.app.run()
        run()
    

    print(_sys.argv[1:]) prints ['D:/PycharmProjects/TensorFlow/self.py'] since argv[0] is the script name passed to the interpreter.