26

I am trying to be a good Pythonista and following PEP 338 for my package I plan on deploying.

I am also trying to generate my executable scripts upon python setuptools install using setuptools entry_points{'console_scripts': ... } options.

How can I use entry_points to generate a binary that calls python -m mypackage (and passes *args, **kwargs) ?

Here are a few attempts I have made with no success:

setuptools(
...

(1)

entry_points=
       {'console_scripts': ['mypkg=mypkg.__main__'],},

(2)

entry_points=
       {'console_scripts': ['mypkg=mypkg.main'],},

(3)

entry_points=
       {'console_scripts': ['mypkg=python -m mypkg'],},

Primary resources I have been using:

1 Answers1

29

How can I use entry_points to generate a binary that calls python -m mypackage (and passes *args, **kwargs) ?

I think this is the wrong way to look at the problem. You don't want your script to call python -m mypackage, but you want the script to have the same entry point as python -m mypackage

Consider this simple example:

script_proj/
├── script_proj
│   ├── __init__.py
│   └── __main__.py
└── setup.py

and the minimalistic setup.py:

from setuptools import setup

setup(
    name="script_proj",
    packages=["script_proj"],
    entry_points = {
        "console_scripts": [
            "myscript = script_proj.__main__:main",
        ]
    }
)

__main__.py is a dummy module and contains the main method.

def main():
    print("Hello world!")

if __name__ == "__main__":
    main()

After installing, you have the executable myscript, which calls the main method in __main__.py. In this package design python -m script_proj also calls the same main method.

cel
  • 24,830
  • 16
  • 80
  • 107
  • This works for me, however when calling `myscript`, my main() function is called twice. My main function only contains a `print("Success!")` statement, and I get the output twice. – StrugglingProgrammer Jan 05 '15 at 18:02
  • To add to this, calling `python -m script_proj` will only produce 1 output – StrugglingProgrammer Jan 05 '15 at 18:04
  • @rm-rf_, it seems to work for me. `myscript` prints the same as `python -m script_proj` only one `Hello world!`... hmm – cel Jan 05 '15 at 18:07
  • 2
    @rm-rf_, did you use `if __name__ == "__main__":` to make sure your main is only called, when `__main__.py`is called as a script, and not as a module? – cel Jan 05 '15 at 18:14
  • 1
    Got it! Just needed the if `__name__ == "__main__"` in __main__.py. Silly mistake. Thanks so much. – StrugglingProgrammer Jan 05 '15 at 18:14
  • For those using a `setup.cfg`, see [this answer](https://stackoverflow.com/a/48891252/3388962) for how to set entry points. – normanius Mar 18 '21 at 19:31