问题
I have a package called clana (Github, PyPI) with the following structure:
.
├── clana
│ ├── cli.py
│ ├── config.yaml
│ ├── __init__.py
│ ├── utils.py
│ └── visualize_predictions.py
├── docs/
├── setup.cfg
├── setup.py
├── tests/
└── tox.ini
The setup.py looks like this:
from setuptools import find_packages
from setuptools import setup
requires_tests = [...]
install_requires = [...]
config = {
"name": "clana",
"version": "0.3.6",
"author": "Martin Thoma",
"author_email": "info@martin-thoma.de",
"maintainer": "Martin Thoma",
"maintainer_email": "info@martin-thoma.de",
"packages": find_packages(),
"entry_points": {"console_scripts": ["clana=clana.cli:entry_point"]},
"install_requires": install_requires,
"tests_require": requires_tests,
"package_data": {"clana": ["clana/config.yaml"]},
"include_package_data": True,
"zip_safe": False,
}
setup(**config)
How to check that it didn't work
Quick
python3 setup.py sdist
open dist/clana-0.3.8.tar.gz # config.yaml is not in this file
The real check
I thought this would make sure that the config.yaml is in the same directory as the cli.py when the package is installed. But when I try this:
virtualenv venv
source venv/bin/activate
pip install clana
cd venv/lib/python3.6/site-packages/clana
ls
I get:
cli.py __init__.py __pycache__ utils.py visualize_predictions.py
The way I upload it to PyPI:
python3 setup.py sdist bdist_wheel && twine upload dist/*
So the config.yaml is missing. How can I make sure it is there?
回答1:
You can add a file name MANIFEST.in next to setup.py with a list of the file you want to add, wildcard allowed (ex: include *.yaml or include clana/config.yaml)
then the option include_package_data=True will activate the manifest file
回答2:
In short: add config.yaml to MANIFEST.in, and set include_package_data. One without the other is not enough.
Basically it goes like this:
MANIFEST.inadds files tosdist(source distribution).include_package_dataadds these same files tobdist(built distribution), i.e. it extends the effect ofMANIFEST.intobdist.exclude_package_dataprevents files insdistto be added tobdist, i.e. it filters the effect ofinclude_package_data.package_dataadds files tobdist, i.e. it adds build artifacts (typically the products of custom build steps) to yourbdistand has of course no effect onsdist.
So in your case, the file config.yaml is not installed, because it is not added to your bdist (built distribution). There are 2 ways to fix this depending on where the file comes from:
either the file is a build artifact (typically it is somehow created during the
./setup.py buildphase), then you need to add it topackage_data;or the file is part of your source (typically it is in your source code repository), then you need to add it to
MANIFEST.in, setinclude_package_data, and leave it out ofexclude_package_data(this seems to be your case here).
See:
- https://stackoverflow.com/a/54953494/11138259
- https://setuptools.readthedocs.io/en/latest/setuptools.html#including-data-files
回答3:
Following from the documentation on including data files, if your package has data files such as .yaml files, you may include them like so:
setup(
...
package_data={
"": ["*.yaml"],
},
...
)
This will allow any file in your package with the file extension .yaml to be included.
来源:https://stackoverflow.com/questions/58038169/how-can-i-make-pip-install-package-data-a-config-file