28

I want to implement my pypy.py script on commandline, I need to work with setup tools but the console_script does not work properly as my pypy.py needs two arguments, please guide me how can I modify it properly to work on commendline.

python.py

def main(agru1, argu2):

    "do something"

 if __name__ == "__main__":
        main()

when I include it in my setup.py file, as console_script as follow

setup( 
     entry_points={
        'console_scripts': ['pypy = pypy.pypy:main'],
    }

)

And I get the following error when I run it on commandline:

Traceback (most recent call last):
File "/usr/local/bin/python", line 9, in <module>
load_entry_point('Pypy==0.1', 'console_scripts', 'pypy')()
TypeError: main() takes at least 2 arguments (0 given)
1
  • You are meant to get the arguments from sys.argv. They are not passed in. You can apply the argument parsing library to it to make it deal with options etc etc. Commented Nov 23, 2016 at 0:14

3 Answers 3

28

The entry point must be a function that may be invoked using exactly zero arguments. If you want to pass in arguments from the command line, say you want to invoke it like:

$ pypy a1 a2

You need to read them from sys.argv instead. So your python module should contain this:

def program(arg1, arg2):
    print(arg1, arg2)

def main():
    import sys
    arg1, arg2 = sys.argv[1], sys.argv[2]
    program(arg1, arg2)

if __name__ == "__main__":
    main()

Alternatively, the main function may instead take an argv argument that defaults to sys.argv if importing sys is desirable at the top level of the module:

def main(argv=sys.argv):
    program(argv[1], argv[2])

Running that command as above should print out a1 a2 into the console. Error handling on user input is your own exercise.

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

4 Comments

Thanks, how should I include main(sys.argv[1], sys.argv[2]) in the setup.py ( as mentioned above) ? error still the same if I use your explanation .... !
setup.py hooks into either distutils or setuptools and the underlying library have their own handling of sys.argv to process the commands, which will almost certainly clash with however you want to do this. Have you tried running my code as is?
Yes I have after that I responded and its the same error as mentioned above in the question.
Right, your setup.py calls main directly, not the script directly as such; So modify the main method to not take anything and pass it to the actual program with the arguments.
2

Similar to the answer of metatoaster, instead of using sys.argv you can use argsparse https://docs.python.org/3/library/argparse.html, which makes the passing of argumnets a bit more user-friendly.

import argparse


if __name__ == "__main__":
  parser = argparse.ArgumentParser()
  parser.add_argument('--arg1', help='arg1 help')
  parser.add_argument('--arg2', help='arg2 help')
  args = parser.parse_args()
  print("arg1 {}, arg2 {}".format(args.arg1, args.arg2)

Call it like:

pypy --arg1 1 --arg2 2

2 Comments

While this is a clear example of using argparse it doesn't address how to use it in context of a setup.py using console_script.
This should be the accepted answer if it is modified to use an entrypoint function, rather than the if __name__ == "__main__" method. The options here are to modify your entrypoint function to get args from sys.argv(as in the accepted answer), or argparse. Using argparse is more pythonic, and it works with console_script.
0

Recently I was facing a similar problem. The way I solved it was by calling the script directly using python -m <complete_script_path> arg1 arg2.

For example if my script file name is bar and it is present inside the package foo and the contents are as follows:

foo.py

def f1(a,b):
    return a+b
if __name__=="__main__":
   a = sys.argv[1]
   b = sys.argv[2]
   f1(a,b)

I can invoke foo as follows:

python -m foo.bar arg1 arg2

I dont have to pass it as a console_script inside setup function of setuptools.This solves problem of not being able to pass arguments to console scripts. Also I can package it inside the whl file during distribution.

Comments

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.