Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing console_script entry point interpreter for packaging

I'm packaging some python packages using a well known third party packaging system, and I'm encountering an issue with the way entry points are created.

When I install an entry point on my machine, the entry point will contain a shebang pointed at whatever python interpreter, like so:

in /home/me/development/test/setup.py

from setuptools import setup
setup(
    entry_points={
        "console_scripts": [
            'some-entry-point = test:main',
        ]
    }
)        

in /home/me/.virtualenvs/test/bin/some-entry-point:

#!/home/me/.virtualenvs/test/bin/python
# EASY-INSTALL-ENTRY-SCRIPT: 'test==1.0.0','console_scripts','some-entry-point'
__requires__ = 'test==1.0.0'
import sys
from pkg_resources import load_entry_point

sys.exit(
   load_entry_point('test==1.0.0', 'console_scripts', 'some-entry-point')()
)

As you can see, the entry point boilerplate contains a hard-coded path to the python interpreter that's in the virtual environment that I'm using to create my third party package.

Installing this entry point using my third-party packaging system results in the entry point being installed on the machine. However, with this hard-coded reference to a python interpreter which doesn't exist on the target machine, the user must run python /path/to/some-entry-point.

The shebang makes this pretty unportable. (which isn't a design goal of virtualenv for sure; but I just need to MAKE it a little more portable here.)

I'd rather not resort to crazed find/xargs/sed commands. (Although that's my fallback.)

Is there some way that I can change the interpreter path after the shebang using setuptools flags or configs?

like image 775
gepoch Avatar asked Jun 21 '13 14:06

gepoch


People also ask

What is entry point in setup py?

Entry points are a type of metadata that can be exposed by packages on installation. They are a very useful feature of the Python ecosystem, and come specially handy in two scenarios: 1. The package would like to provide commands to be run at the terminal. This functionality is known as console scripts.

What is console_scripts?

The console_scripts Entry Point Setuptools allows modules to register entrypoints which other packages can hook into to provide certain functionality. It also provides a few itself, including the console_scripts entry point.

What is Load_entry_point?

exit( load_entry_point('rss2sms==0.0.1', 'console_scripts', 'rss2sms')() ) This executable is just a simple python module which, when we call it, uses the pkg_resources library to look up what python module our setup.py says we should call.

What is an entry point script?

In NetSuite terminology, an "Entry Point Script" is the module you write that will be assigned as the source file on a Script record. If your module requires an @NScriptType tag, then it is most certainly an Entry Point Script.


2 Answers

You can customize the console_scripts' shebang line by setting 'sys.executable' (learned this from a debian bug report). That is to say...

sys.executable = '/bin/custom_python'

setup(
  entry_points={
    'console_scripts': [
       ... etc...
    ]
  }
)

Better though would be to include the 'execute' argument when building...

setup(
  entry_points={
    'console_scripts': [
       ... etc...
    ]
  },
  options={
      'build_scripts': {
          'executable': '/bin/custom_python',
      },
  }
)
like image 160
Damian Avatar answered Oct 24 '22 18:10

Damian


For future reference for someone who wants to do this at runtime without modifying the setup.py, it's possible to pass the interpreter path to setup.py build via pip with:

$ ./venv/bin/pip install --global-option=build \
--global-option='--executable=/bin/custom_python' .
...
$ head -1 ./venv/bin/some-entry-point
#!/bin/custom_python
like image 40
imiric Avatar answered Oct 24 '22 18:10

imiric