It seems that after uploading the package to PyPI using these instructions, pip install myscript
did place an executable in my python bin. Must have been a local issue.
entry_points does not create custom scripts with pip, only with easy_install in Python
-
11-10-2022 - |
Question
I'm packaging a script for the first time in python. It can be used both as a module, and an executable so I found out I could use
entry_points = {
'console_scripts': [
'myscript = myscript:main',
],
}
in my setup.py
to automatically generate a script in the user's python-x.x.x/bin
directory.
My python script ends with
if __name__ == '__main__': main()
where main()
parses command-line input.
I packaged this using the command:
python setup.py sdist
and then tested the distribution as:
easy_install dist/myscript-0.3.2.tar.gz
This puts a myscript
executable in my python-2.7.5/bin
as expected.
But this doesn't:
pip install dist/myscript-0.3.2.tar.gz
Any ideas why? My directory tree looks like:
Root/
|-- MANIFEST.in
|-- README.rst
|-- dist
| `-- myscript-0.3.2.tar.gz
|-- myscript.egg-info
| |-- ...
|-- myscript.py
|-- setup.cfg
|-- setup.py
`-- test
|-- ...
and my setup.py
roughly looks like:
import os
from setuptools import setup
def read(*paths):
"""Build a file path from *paths* and return the contents."""
with open(os.path.join(*paths), 'r') as f:
return f.read()
setup(
name='myscript',
version='0.3.2',
description='bla',
long_description=(read('README.rst')),
url='http://url',
license='LGPL',
author='Me',
author_email='me@me.com',
py_modules=['myscript'],
include_package_data=True,
classifiers=[
'Development Status :: 5 - Production/Stable',
'Intended Audience :: Developers',
'Natural Language :: English',
'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Topic :: Software Development :: Libraries :: Python Modules',
],
install_requires=['Texttable'],
entry_points = {
'console_scripts': [
'myscript = myscript:main',
],
}
)
Solution 3
OTHER TIPS
I had a similar experience of pip install .
not working from the project's directory. It turned out that pip wasn't executing all of setup.py logic because it assumed that the dependency to my project was already met since my package was in sys.path, which includes the working directory. I found three work-arounds. I could use the editable or upgrade flag to force it to install everything:
pip install --editable .
-- likely to work (but depends on local pip config)
pip install --upgrade .
-- works
pip install --upgrade-strategy=only-if-needed .
-- does not work
Or I could go to a different working directory and execute it with an absolute path to the project directory:
pip install $HOME/src/project_dir
Is the main
function truly in the mypackage
package? For that, it should be defined or imported in the __init__.py
file of that package.
If your project structure looks like this:
mypackage/
├── mypackage/
│ ├── __init__.py
│ └── main.py
└── setup.py
Then you need to either:
- use
mypackage.main:main
in yoursetup.py
- write
from main import main
in your__init__.py