-
Notifications
You must be signed in to change notification settings - Fork 239
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
Add a test-sources configuration option. #2062
base: main
Are you sure you want to change the base?
Conversation
I'll look at it in more detail later, but quick note: the "run in an isolated dir" feature isn't helpful for projects that follow a src structure (which many, but not all, compiled projects do follow, since there are a lot of issues running a compiled project that is not in a src structure). It's also not as important now with PYTHONSAFEPATH. So one option could be to allow this to be disabled, and maybe even do that by default in the future (3.0)? |
True; that doesn't really change the situation for iOS/Android though, except in as much that "copy the entire project into the app" becomes a viable option. Even then, I'd argue being able to say "just copy these files/folders for the test" is a potentially useful feature, as there's lot of content in a project folder that you probably don't want to be copied into an app bundle, even for testing purposes. |
Thanks for this and especially the great patch notes @freakboy3742 ! I'd be a bit reticent to change the testing behaviour across the board, especially moving test sources 'out-of-tree', because pytest does (sadly) add a bunch of stuff to PYTHONPATH that lots of users end up relying on. See #1534 for some notes on the pytest default imports. The behaviour that I think would be problematic is So I'd concur with @henryiii in that I'm very open to removing the 'tests run in a different dir' feature, as it doesn't actually protect us from the problem that it attempts to solve - in fact since 3.0 is coming up I'd be open to just removing that 'feature' regardless. I'm very curious how that might change the feature design outlined here. One thing that I wonder is whether leave the |
What I am thinking for 3.0 is:
|
Travis is failing with:
I bet this is due to the recent removal of pypy38 and pypy39 from the pre-installed versions in manylinux. I thought we were supposed to be using the |
We are. Error handling/reporting should be updated to get a different error message when it fails (though I guess the log would be much clearer in a real execution than in the tests). The failure is probably related to a network related issue. Restarting the job now. |
To make sure I'm understanding this correctly - you're suggesting
Again, if I'm understanding correctly, this is the same to what I've got in this PR, except for setting
It turns out that literally "copy everything" poses a problem, because that will frequently pick up virtual environments, tox/nox environments, GitHub configurations etc that are in the developer's project directory - and those usually contain symbolic links to locations outside the source tree (e.g., to the actual Python install). In the iOS case, these links aren't just inconvenient or excessive - they actually cause the iOS simulator conniptions because they link to filesystem locations that don't exist on the device. In my WIP iOS branch, I've been using an sdist as a proxy for "copy all sources". My guess would be that we add a special case for the literal |
Ahh, that's clever. I like it. That way we actually get the protection that we were aiming for originally, but as an opt-in, with the current behaviour backward-compatible. |
I wish there was a more elegant way to indicate the sdist-copy mechanism, which is really nice as a "copy all" replacement. But can't think of one. |
The sdist-copy is only really useful on the iOS/Android platforms, though? So perhaps we have a special case where |
iOS/Android requires a "copy sources" option. In that world, sdist-copy is a helpful default (and maps well to the " As for other platforms - I'd argue sdist-copy isn't necessary, but it might be a nice safety mechanism. If a test suite does anything destructive to a filesystem (e.g., creating temp files in the test folder), using a copy of all sources guarantees there's no leakage between tests.
The complication would be differentiating between "Not defined" and "Empty", especially in the environment variable manifestation. I guess that's resolvable; it's then a question of whether |
SDist-copy isn't that useful outside of the embedded systems, though - it only protects you from local artifacts, not from importing local files. So I think having |
Yes, this is what I meant, er, well, I think. For clarity, proposal A
|
My preference is Proposal A, above, because there's no room for invalid configuration - you can't set Also, it just looks simpler, there's less to explain in the docs IMO. |
I was thinking proposal A too. I don't think having access to SDist copy for other platforms is that important. |
Looks like there's some sort of consensus around option A (which I agree looks like the best option - the benefits to copy-sdist for non-embedded projects are minimal). In terms of implementation - AFAICT, this PR as written implements the "add a new Would the preferred approach be to roll that changes into this PR, or to make a separate PR? Also - given that this would be a backwards incompatible change, is there any additional paperwork required in the PR? |
@henryiii @joerick I've taken the liberty of implementing "option A" (at least as I understand it) - that is:
As noted during the discussion about, this is a change in behavior; I'm not sure what procedures you have around documenting that for change notes. The Any project that has a Any test suite that was relying on running with the working directory set to the temp folder will break - but I'm not sure I see how any project would be doing that in practice, as any relative file references in the test suite would have been failing. |
Hrm - I wasn't getting those test failures locally on macOS... investigating... |
I've now resolved the issue with CI failures - turns out I was somehow missing the exiting test of the "run pytest in the project directory". I've updated that test to validate a test suite will run in the project folder. |
When cibuildwheel runs a test suite for a wheel, it sets the working directory to a temporary folder. This ensures that the test suite is isolated from the project code, ensuring that the test suite is executed with only the code packaged in the wheel, and not code that is present in the project folder but not packaged.
Documentation for wheel testing encourages test suites to be run as
test-command = "pytest {project}"
(or similar) - that is, running pytest, but pointing pytest at the project directory for test discovery purposes. To make this pattern clear to the user, a dummytest_fail.py
file is created in the test working directory; in the "naïve configuration case", this test will be discovered as the only test in the working directory, and will fail with a message about cibuildwheel's usage of a working directory.This pattern guarantees that tests are run against the code in the packaged wheel, but ignores any test suite configuration in pyproject.toml (or other test configuration files), and can require additional code to support running tests via cibuildwheel, tox/nox, and local invocation from a single test codebase.
This leads to the use of patterns such as `test-command = "cd {project} && pytest" (used by Pillow, amongst others), which undoes the benefits of using an isolated test folder in the first place.
It is also a pattern that can't work for mobile environments (i.e., iOS and Android, as supported by PEP 730 and PEP 738). In a mobile app, the test must run on device (or simulated device), and any code to be executed must be bundled with the app. When running on the device with an installed wheel,
{project}
isn't a visible file system location; and shell commands (likecd {project}
) can't be used.To help prevent the
cd {project} && pytest
pattern, and to facilitate future PRs adding support for iOS and Android to cibuildwheel, this PR adds a new configuration item -test-sources
. This setting is a list of files and folders, relative to{project}
, that should be copied into the test working folder (including, if necessary,pyproject.toml
or any other test configuration files).The allows a simple test configuration to be specified as:
A more complicated configuration, providing additional data plus a pytest.ini configuration file, would be something like:
If
test-sources
is not defined, the historical behavior (i.e., copying in thetest_fail.py
shim) is preserved.Support for platform-specific variants (
macos.test-sources
), as well as environment variable configuration (CIBW_TEST_SOURCES
,CIBW_TEST_SOURCES_MACOS
etc) is also included.