-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BUG] options.packages.find.exclude
not taking effect when include_package_data = True
#3260
Comments
options.packages.find.exclude
not making effect when include_package_data = True
options.packages.find.exclude
not taking effect when include_package_data = True
The issue I see with this expectation is that under other circumstances, a subfolder in a package is data. Consider if all you had is:
In that case, the test file would be included as package data. Then if you add a python file to the directory:
Now neither file gets included as data. That behavior would be counterintuitive and conflates two concerns. Moreover, it seems perfectly legitimate to have a directory of python files as data, especially if they're not intended to be imported through the package, but used in another way (such as a template or scripts or other non-module behavior in a Python syntax). I don't see a good solution here, except for Setuptools to get out of the business of managing packages, modules, and their data and to instead model discovery of files for the build that could be packages or modules or data, and provide mechanisms to include/exclude those generally. |
Thank you very much for the detailed explanation @jaraco. I think that if we change With this change it is more obvious that In this case, the existing implementation would still behave in an unexpected way and include the directory that is supposed to be excluded. |
Would it be better if we consider all the subfolders as nested packages and then require the users to explicitly include this package? I am OK with this assumption. This would also be coherent with Python's existing behaviour1.
This is a bit tricky... How do we know which Python files are meant to be data files or actual modules?
Please let me know what are your thoughts about this matter. I would be more than happy to participate in this discussion and see if I can help somehow. Footnotes
|
It's intentional. During the design, we considered requiring a namespace package to have some sort of indicator that it's a Python package, but ultimately decided that the simpler approach of recognizing any directory as a package was more elegant. That's why:
That is, an empty directory is an empty Python package. Simple and elegant, though somewhat ambiguous (because a directory of rust code is also a Python package whose sole contents is rust files as data).
I very much want to avoid users having to uniquely indicate items to be included. I'd like for there to be a discovery mechanism that works for 99% of cases and have options to tweak when the discovery is inaccurate. This is part of the zero-config vision... a user should be able to create a null distribution with no config, then add a folder to it, which creates an empty Python package, then add modules to that package, all having to duplicately tell Setuptools what they just did. That is, Setuptools should infer the same thing that Python does for imports. So by default, what you create for Python gets packaged.
I guess we can't reliably. I'd say we'd have to assume everything is a legitimate Python package unless indicated otherwise (such as through an exclusion directive or heuristic). |
Thank you very much for the information Jason.
If the users adopt The difference is that we currently have 2 mechanisms to "trim the excesses":
The second mechanism is broken by the current implementation of Maybe going forward we would want:
|
Status update: In v62.3.0, we introduce a deprecation warning about the conflicting behaviour. After some time we can start tackling this issue. |
Just as another voice to illustrate the current situation: I try to use What I find irritating is that the Example
|
Hi @bittner, please note that the link you referenced mentions Have you also tried to use the field mentioned by the documentation you linked? > docker run --rm -it python:3.9-bullseye /bin/bash
mkdir -p /tmp/myproj/myproj/
cd /tmp/myproj
touch myproj/.foobarignore
touch myproj/.foobarconfig
touch myproj/.helloworld.yml
touch myproj/__init__.py
touch myproj/tests123
cat <<EOF > pyproject.toml
[build-system]
requires = ["setuptools", "setuptools_scm[toml]>=7"]
build-backend = "setuptools.build_meta"
[project]
name = "hello_world"
dynamic = ["version"]
[tool.setuptools]
exclude-package-data = { "*" = ["tests*", ".*config", ".*ignore", ".*.yml"]}
EOF
git init .
git add .
git config --global user.email "you@example.com"
git commit -m "Initial commit"
python -m pip install -U build
python -m build
unzip -l dist/*.whl
# ...
# Successfully built hello_world-0.0.0.tar.gz and hello_world-0.0.0-py3-none-any.whl
# Archive: dist/hello_world-0.0.0-py3-none-any.whl
# Length Date Time Name
# --------- ---------- ----- ----
# 0 2023-06-30 12:39 myproj/__init__.py
# 56 2023-06-30 12:39 hello_world-0.0.0.dist-info/METADATA
# 92 2023-06-30 12:39 hello_world-0.0.0.dist-info/WHEEL
# 7 2023-06-30 12:39 hello_world-0.0.0.dist-info/top_level.txt
# 383 2023-06-30 12:39 hello_world-0.0.0.dist-info/RECORD
# --------- -------
# 538 5 files |
Sure, the wheel is fine. It's the sdist that doesn't work for excluding tests and configuration files. tar tvfz dist/*.tar.gz
# drwxr-xr-x 0 hello_world-0.0.0/
# -rw-r--r-- 55 hello_world-0.0.0/PKG-INFO
# drwxr-xr-x 0 hello_world-0.0.0/hello_world.egg-info/
# -rw-r--r-- 55 hello_world-0.0.0/hello_world.egg-info/PKG-INFO
# -rw-r--r-- 254 hello_world-0.0.0/hello_world.egg-info/SOURCES.txt
# -rw-r--r-- 1 hello_world-0.0.0/hello_world.egg-info/dependency_links.txt
# -rw-r--r-- 7 hello_world-0.0.0/hello_world.egg-info/top_level.txt
# drwxr-xr-x 0 hello_world-0.0.0/myproj/
# -rw-r--r-- 0 hello_world-0.0.0/myproj/.foobarconfig
# -rw-r--r-- 0 hello_world-0.0.0/myproj/.foobarignore
# -rw-r--r-- 0 hello_world-0.0.0/myproj/.helloworld.yml
# -rw-r--r-- 0 hello_world-0.0.0/myproj/__init__.py
# -rw-r--r-- 0 hello_world-0.0.0/myproj/tests123
# -rw-r--r-- 258 hello_world-0.0.0/pyproject.toml
# -rw-r--r-- 38 hello_world-0.0.0/setup.cfg Shouldn't the result be roughly the same? In my understanding, the |
Not really. The interpretation of what There is a line of thought (to which I personally subscribe), that considers According to this particular definition,
That is exactly what happens, The packaging process for Python is particular, but you can think about about it in 2 stages: flowchart LR
0[working dir] -->|"(A) build_sdist"| sdist
sdist -->|"(B) build_wheel"| wheel
If you want to modify the contents of the
Please note that the original problem reported in this issue is not about contents of Footnotes
|
setuptools version
62.1.0
Python version
Python 3.10.4 (main, Mar 30 2022, 23:50:39) [GCC 10.2.1 20210110]
OS
Tested in Alpine Linux 3.14, Debian bullseye and Ubuntu 20.04.4 LTS
Additional environment information
Description
For some reason, when
include_package_data = True
, subpackages excluded viaoptions.packages.find.exclude
are still added to the wheel.Expected behavior
When listed via
options.packages.find.exclude
a subpackage should not be added to the wheel.How to Reproduce
Output
The expected output should not include:
[Related: https://github.com//issues/3340]
The text was updated successfully, but these errors were encountered: