I am trying to make my Python project importable by people who install it using pip
. Although it contains a __init__.py
and works as a package locally, it seems that I am misunderstanding how setuptools works.
I run the following three commands to upload the package.
python3 setup.py sdist bdist_wheel
python3 -m pip install --upgrade twine
python3 -m twine upload dist/*
Then on a different machine, I run pip3 install smux.py
. The result is that I can access smux.py
as a command, but I get an import error when trying to import it.
python3
Python 3.8.5 (default, Jul 28 2020, 12:59:40)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import smux
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'smux'
After running the setup.py
commands above, I examined smux.py.egg-info/SOURCES.txt
in the current directory and find it contains the following:
README.md
setup.py
smux.py
smux.py.egg-info/PKG-INFO
smux.py.egg-info/SOURCES.txt
smux.py.egg-info/dependency_links.txt
smux.py.egg-info/top_level.txt
The file __init__.py
is missing.
How do I either get that file into the package, or modify the setup call to make smux
importable?
Your setup
call looks like this:
setup(
name="smux.py",
version='0.1.1',
scripts=['smux.py'],
author="Henry Qin",
author_email="[email protected]",
description="Simple tmux launcher that will take less than 2 minutes to learn and should work across all versions of tmux",
long_description=long_description,
platforms=["All platforms that tmux runs on."],
license="MIT",
url="https://github.com/hq6/smux"
)
With the scripts
argument, you've told setuptools that smux.py
is a script, not a module. Accordingly, it gets installed as a script, not a module.
Your code does not need an __init__.py
and should not have one. Having an __init__.py
will not help. You need to tell setuptools to install your file as a module rather than a script, and register an entry point separately, with a console_scripts
entry in the entry_points
argument:
setup(
...
# no scripts= line
py_modules=['smux'],
entry_points={
'console_scripts': ['smux=smux:main']
}
)
Then when your code is installed, smux
will be importable, and there will be a smux
script available from the command line that calls smux.main
.