103

There are basically two ways to install Python console scripts to my path by setup.py:

setup(
    ...
    entry_points = {
        'console_scripts': [
            'foo = package.module:func',
        ],
    }
)

and

setup(
    ...
    scripts = [
        'scripts/myscript.sh'
    ]
)

What are the differences? I see the first approach allows me to choose nice, specific name for my script, but are there any other differences? Different original purposes, compatibility (setuptools, distutils, ...?), usage, ...? I am quite confused and a nice elaborated reply could help me (and probably also others) to properly understand all this.

Update: Since I asked the question PyPA published these cool docs on the topic.

Honza Javorek
  • 8,566
  • 8
  • 47
  • 66
  • 1
    The [update] link broken. I believe https://packaging.python.org/distributing/#scripts is the replacement(?) – matt wilkie Jul 03 '16 at 23:00
  • 1
    The link in your update has updated again: https://python-packaging-user-guide.readthedocs.io/guides/distributing-packages-using-setuptools/?highlight=scripts#scripts – Bart van Oort Mar 04 '21 at 11:10

4 Answers4

60

The docs for the (awesome) Click package suggest a few reasons to use entry points instead of scripts, including

  1. cross-platform compatibility and
  2. avoiding having the interpreter assign __name__ to __main__, which could cause code to be imported twice (if another module imports your script)

Click is a nice way to implement functions for use as entry_points, btw.

Slam
  • 8,112
  • 1
  • 36
  • 44
jfeala
  • 616
  • 6
  • 3
  • 14
    This is the right answer. Basically there where a lot of problems with the old distutils. A bunch of really smart people created setuptools to supersede it. They collaborated and came up with the entry_points/console_scripts mechanism to be the standard for executable distribution so you don't have to think about the problems with all the other options. Don't be a hero. Use what you've been given. – Bruno Bronosky Mar 26 '15 at 08:09
  • I would like to add that since I asked the question, these awesome docs emerged: http://python-packaging-user-guide.readthedocs.org/en/latest/distributing/#scripts – Honza Javorek Apr 08 '16 at 09:33
  • 1
    Unfortunately @HonzaJavorek - those "awesome docs" are now a 404 / non-existent :/ – Dan Feb 03 '18 at 21:29
  • They exist, only the structure has changed. New link: https://python-packaging-user-guide.readthedocs.io/search/?q=scripts – Honza Javorek Feb 04 '18 at 00:37
  • 2
    Can you further explain 'imported twice'? I was under the impression that "if __name__ == '__main__':'" is used to solve this problem? – tribbloid May 21 '19 at 18:47
  • @tribbloid: Explanation: https://ncoghlan-devs-python-notes.readthedocs.io/en/latest/python_concepts/import_traps.html#executing-the-main-module-twice – user1071847 Nov 05 '19 at 21:39
  • 1
    `entry_points.console_scripts` is now officially recommended over `scripts` https://packaging.python.org/guides/distributing-packages-using-setuptools/?highlight=scripts#scripts – Roy Hyunjin Han Sep 23 '21 at 21:24
15

One key difference between these two ways of creating command line executables is that with the setuptools approach (your first example), you have to call a function inside of the script -- in your case this is the func inside of your module. However, in the distutils approach (your second example) you call the script directly (which allows being listed with or without an extension).

plessthanpt05
  • 179
  • 2
  • 7
  • 11
    I think this answer misses the main point. The entry_point approach is the new way that we should all be using. Anytime there is a setuptools alternative to a distutils functionality, it's for a very good reason. – Bruno Bronosky Mar 26 '15 at 08:11
  • 6
    Alternatively, it would seem that `scripts` is the only way to include a custom script, for example a WSGI script instead of a command line script. `entry_points` will always generate a command line executable of some kind. (Whether that's a *good* idea, I'm not sure, but it is an observation.) – jpmc26 Jul 09 '15 at 02:09
10

The setup tools entry point approach (#1) also has the benefit that on windows an .exe will be created that can be double clicked and invoked like a regular windows program. This is in addition to having a script placed in the bin path on posix-like systems.

Kaushik Ghose
  • 1,024
  • 12
  • 16
4

One more difference is that when using console_scripts, my module's __init__ file was run. When just using scripts, the module __init__ was not run, only the script was run.

spacether
  • 2,136
  • 1
  • 21
  • 28