问题
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.in
adds files tosdist
(source distribution).include_package_data
adds these same files tobdist
(built distribution), i.e. it extends the effect ofMANIFEST.in
tobdist
.exclude_package_data
prevents files insdist
to be added tobdist
, i.e. it filters the effect ofinclude_package_data
.package_data
adds files tobdist
, i.e. it adds build artifacts (typically the products of custom build steps) to yourbdist
and 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 build
phase), 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