In a python virtualenv on Windows, I've installed a custom package that over-rides setuptools.command.install.easy_install.get_script_args to create a new custom type of entry point 'custom_entry'
I have another package that I want to prepare with setuptools exposing a custom entry point.
If I prepare an egg distribution of this package and install it with my modified easy_install.exe, this creates the custom entry points correctly.
However, if I prepare a wheel distribution and install it with a modified pip.exe, the custom entry points do not get added.
Why does pip not follow the same install procedure as easy_install?
Reading the source for pip, it seems that the function get_entrypoints in wheel.py excludes all entry points other than console_scripts and gui_scripts. Is this correct?
If so, how should I install custom entry points for pip installations?
---- Edit
It looks like I should provide more details.
In my first package, custom-installer
, I'm over-riding (monkey-patching, really) easy_install.get_script_args
, in custom_install.__init__.py
:
from setuptools.command import easy_install
_GET_SCRIPT_ARGS = easy_install.get_script_args
def get_script_args(dist, executable, wininst):
for script_arg in _GET_SCRIPT_ARGS(dist, executable, wininst):
yield script_arg # replicate existing behaviour, handles console_scripts and other entry points
for group in ['custom_entry']:
for name, _ in dist.get_entry_map(group).items():
script_text = (
## some custom stuff
)
## do something else
yield (## yield some other stuff) # to create adjunct files to the -custom.py script
yield (name + '-custom.py', script_text, 't')
easy_install.get_script_args = get_script_args
main = easy_install.main
And in that package's setup.py
, I provide a (console_script) entry point for my custom installer:
entry_points={
'console_scripts': [
'custom_install = custom_install.__init__:main'
]
}
Installing this package with pip correctly creates the installer script /venv/Scripts/custom_install.exe
With my second package, customized
, I have both regular and custom entry points to install from setup.py
, for two modules custom
and console
.
entry_points={
'console_scripts': [
'console = console.__main__:main'
],
'custom_entry': [
'custom = custom.__main__:main'
]
}
I would like to see both of these entry points installed regardless of the install procedure.
If I build the package customized
as an egg distribution and install this with custom_install.exe
created by custom-installer
, then both entry points of customized
are installed.
I would like to be able to install this package as a wheel file using pip, but from reading the source code, pip seems to explicitly skip and any entry points other than 'console_scripts' and 'gui_scripts':
def get_entrypoints(filename):
if not os.path.exists(filename):
return {}, {}
# This is done because you can pass a string to entry_points wrappers which
# means that they may or may not be valid INI files. The attempt here is to
# strip leading and trailing whitespace in order to make them valid INI
# files.
with open(filename) as fp:
data = StringIO()
for line in fp:
data.write(line.strip())
data.write("\n")
data.seek(0)
cp = configparser.RawConfigParser()
cp.readfp(data)
console = {}
gui = {}
if cp.has_section('console_scripts'):
console = dict(cp.items('console_scripts'))
if cp.has_section('gui_scripts'):
gui = dict(cp.items('gui_scripts'))
return console, gui
Subsequently, pip generates entry point scripts using a completely different set of code to easy_install. Presumably, I could over-ride pip's implementations of these, as done with easy_install, to create my custom entry points, but I feel like I'm going the wrong way.
Can anyone suggest a simpler way of implementing my custom entry points that is compatible with pip? If not, I can override get_entrypoints
and move_wheel_files
.
You will probably need to use the keyword
console_scripts
in yoursetup.py
file. See the following answer:It basically states that you need to do the following in your
setup.py
script:See also: http://calvinx.com/2012/09/09/python-packaging-define-an-entry-point-for-console-commands/