Solved using click instead of argparse, see below..
I'm building a Python command line tool, following a great tutorial by Thomas Stringer. My tool is used like so
$ python rsearch.py -f foo -b bar
I packaged it with python setup.py sdist and python setup.py install, following the docs. All working great! Now I install it as a pip package with pip install -e . and my executable is ready to roll, right?
$ which rsearch
/usr/local/bin/rsearch
Problem is
$ rsearch -f foo.txt -b bar/
Searching...
Searching...
Found item from foo.txt in bar/path/to/target/
Searching...
Done!
Traceback (most recent call last):
File "/usr/local/bin/rsearch", line 11, in <module>
load_entry_point('rsearch', 'console_scripts', 'rsearch')()
TypeError: main() missing 2 required positional arguments: 'foo' and 'bar'
I think the issue is that my entry_points are not specified correctly:
from setuptools import setup
setup(
name='rsearch',
version='0.0.1',
py_modules=['rsearch'],
entry_points={
'console_scripts': [
'rsearch=rsearch.__main__:main'
]
})
Based on the tutorial I followed, albeit from 2016, this should work. I know distutils.core is the preferred setup() method for Python 3.7, but I've tried that as well and I am getting the same result.
My __main__.py looks like this:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument(
'--foo',
'-f',
help='Foo help'
)
parser.add_argument(
'--bar',
'-b',
help='Bar help'
)
def main(foi, gras):
# code code code
# code code..
args = parser.parse_args()
main(args.foo, args.bar)
and my project is structured like this:
rsearch
├── rsearch
│ └── __main__.py
└── setup.py
Side note: the python script runs as expected:
$ python __main__.py -f foo.txt -b bar/
Searching...
Searching...
Found item from foo.txt in bar/path/to/target/
Searching...
Done!
So the script doesn't appear to be the problem. This error only occurs when trying to run executable built with setuptools.setup()
I'm using Python 3.7.3 and pip 19.1.1. Any help or suggestions are much appreciated.
UPDATE
Per @techouse's suggestion, I replicated this CLI using click and updated the entry_points assignment in setup.py, following their documentation.
setup(
name='rsearch',
version='0.0.1',
py_modules=['rsearch'],
install_requires=[
'Click',
],
entry_points='''
[console_scripts]
rsearch=rsearch_script:cli
''',
)
I renamed the script to rsearch_script.py and used the click decorators instead of argparse:
@click.command()
@click.option('--foo', '-f')
@click.option('--bar', '-b')
def cli(foo, bar):
# code code code
# code code..
I also moved the files (from the docs, might not matter)
rsearch
├── rsearch_script.py
└── setup.py
In this directory I ran pip install -e . and boom!
No errors, working.
$ rsearch -f foo.txt -b bar
Searching...
Searching...
# ...
$ rsearch --help
Usage: rsearch [OPTIONS]
Options:
-f, --foo TEXT
-b, --bar TEXT
--help
Thanks for the tip @techouse - You were right, I'll use Click for developing Python CLIs from now on.