I am attempting to create a Python package that can be used as a terminal command. My setup.py file looks like
import setuptools
# If the package is being updated (and not installed for the first time),
# save user-defined data.
try:
import checklist
update = True
except ModuleNotFoundError:
update = False
if update:
import os
import pickle
dir = os.path.join(os.path.dirname(checklist.__file__), 'user_settings')
files = {}
for file in os.listdir(dir):
files[file] = pickle.load(open(os.path.join(dir, file), "rb"))
with open("README.md", "r") as fh:
long_description = fh.read()
setuptools.setup(
name="SampleName",
version="0.2.0",
author="Author1, Author2",
author_email="email@email.com",
description="words words words.",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/samplesample/sample1",
packages=setuptools.find_packages(),
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
"Operating System :: OS Independent",
],
entry_points='''
[console_scripts]
checklist=checklist.checklist:cli
''',
python_requires='>=3.7',
package_data={"checklist":["user_settings/*.pkl"]},
include_package_data=True,
)
if update:
for key in files:
pickle.dump(files[key], open(os.path.join(dir, key), "wb"))
When I attempt to create the checklist
package with the command
python setup.py sdist bdist_wheel
I get the message
Error: Got unexpected extra arguments (sdist bdist_wheel)
When I remove click
from my environment, the wheel is created without a problem. This seems strange because my code uses click
.
import os
import sys
import csv
import click
import datetime as dt
from datetime import datetime
from contextlib import suppress
import pickle
class UI:
def __init__(self):
<set variables>...
<some methods>...
# noinspection SpellCheckingInspection
class Checklist(UI):
def __init__(self):
<set variables>...
# start the process...
while self.step_index < len(self.to_do):
with suppress(ExitException):
self.step()
def step(self):
self.__getattribute__(self.to_do[self.step_index])()
self.step_index += 1
self.overwrite = False
<some methods>...
@click.command()
def cli():
Checklist()
cli()
What could be causing this? How do I fix it?
It's amazing how a few small deviations from the best practice are chained together producing a major problem. :-)
The problem with click
is the following. If click
is installed your setup.py
imports the module you shown us above. And the module when imported runs cli()
, said cli()
calls @click.command()
and that parses the command line (intended for setup.py
, not for click
) and produces the error.
If click
is NOT installed your setup.py
tries import checklist
and failed with ModuleNotFoundError
. The exception is caught and ignored in setup.py
and setup continues.
To fix the problem make checklist
a module that can be both run (to call cli()
) and imported without calling cli()
:
def main():
cli()
if __name__ == '__main__':
main()