Generating entry_points launch script

I have a package which defines an entry point in pyproject.toml:

[project.scripts]
mypkg = "mypkg.__main__:main"

When I build a wheel of this project, a file named “entry_points.txt” is created in the wheel’s dist-info/ directory, with the following contents:

[console_scripts]
mypkg=mypkg.__main__:main

When I pip install the wheel, an executable script named “mypkg” is placed in my environment’s bin/ directory, with the following contents:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import re
import sys
from mypkg.__main__ import main
if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
    sys.exit(main())

I would like to programmatically generate this script outside of the normal build/install process. How can I do that?

(The reason I want to do this is that I want to create a stand-alone CLI application using pyinstaller. Running pyinstaller directly on mypkg.__main__.py does not produce a functioning executable, but giving it this launch script does.)

The code that creates entry points is in pip somewhere. I think it’s pretty much a copy and paste for Posix (in Windows it’s more complicated but a small .exe is constructed). GitHub - pypa/pip: The Python package installer

I’m not sure there’s a convenient function that’s part of a public API though, if maintainability is important. But it’s regular Python code that’s importable.

It’s interesting, but it took me a fair while to understand. If the goal is simply to create a CLI app, it would be a lot more time efficient to restructure your project to however pyinstaller requires it.

[edit]. It’s here

possibly via here:

1 Like

I could just take the pip-generated launch script and include it in my project. That’s probably what I will do.

If it were reasonable easy to autogenerate the script I would prefer to do that as part of a custom build step. But it looks like the maintenance burden of doing so would be greater than just putting the script itself under version control.

A two stage build using pip to install into a temporary build environment, then pointing pyinstaller at that seems most straightforward to me.

1 Like

I ended up creating a tox environment to build the executable:

[testenv:build]
deps =
    pyinstaller
commands =
    pyinstaller --onefile .tox/build/bin/mypkg
1 Like