GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-149113: Add option to copy back data from Android testbed emulator to build machine by timrid · Pull Request #149271 · python/cpython

Conversation

@timrid

@timrid timrid commented May 2, 2026 •
edited by bedevere-app Bot
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

Fixes #149113


To test this I used

python3 Platforms/Android test --managed maxVersion --pull hello.txt --pull .coverage --output-dir output -v -- -c "open('hello.txt','w').write('Hello World'); open('.coverage','w').write('SOME COVERAGE DATA')"

Then the output folder should contain the files hello.txt and .coverage.

  • Issue: Copy files back from Android testbed emulator to host #149113

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@timrid
Enhance Android test framework: add --pull and --output-dir options f…
19f78a6
…or file management
@timrid
timrid requested review from freakboy3742 and mhsmith as code owners May 2, 2026 08:05
@bedevere-app

bedevere-app Bot commented May 2, 2026

Copy link
Copy Markdown

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@python-cla-bot

python-cla-bot Bot commented May 2, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

All commit authors signed the Contributor License Agreement.

CLA signed

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot mentioned this pull request May 2, 2026
Copy files back from Android testbed emulator to host #149113
Open
@bedevere-app bedevere-app Bot added the awaiting review label May 2, 2026
@read-the-docs-community

read-the-docs-community Bot commented May 2, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

Documentation build overview

📚 cpython-previews | 🛠️ Build #33118577 | 📁 Comparing 376224c against main (bb5e41e)

  🔍 Preview build  

73 files changed · ± 72 modified · - 1 deleted

± Modified

  • c-api/concrete.html
  • deprecations/index.html
  • deprecations/pending-removal-in-3.15.html
  • deprecations/pending-removal-in-future.html
  • faq/programming.html
  • howto/descriptor.html
  • howto/perf_profiling.html
  • library/ast.html
  • library/asyncio-task.html
  • library/base64.html
  • and 62 more...

- Deleted

  • c-api/sentinel.html
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@blurb-it
📜🤖 Added by blurb_it.
231c3a8
mhsmith
mhsmith reviewed May 10, 2026
View reviewed changes

@mhsmith mhsmith left a comment •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this is very useful, I didn't know about this feature.

Apart from the more minor comments below, my main question is how this would integrate into cibuildwheel. Have you had any thoughts about that? There are some existing discussions about Docker containers that look relevant:

  • pypa/cibuildwheel#115
  • pypa/cibuildwheel#363
  • pypa/cibuildwheel#1030
  • pypa/cibuildwheel#1756

I think the most convenient solution from the package developer's point of view would be a cibuildwheel test-outputs option that maps directly to what you've implemented here: a list of paths to copy back from the temporary test directory. But since that directory has the same structure as the project directory (as it was created using test-sources), we can copy those paths back into the project directory, rather than a separate output directory.

This would make cibuildwheel much more transparent, allowing the developer to handle the output files in the same way as they would when running the tests directly. And it would allow more packages to have a single, portable test configuration which avoids platform-specific workarounds, {package} and {project} placeholders which don't work on mobile, and manual rearranging of files.

Since all cibuildwheel platforms run the tests from a temporary working directory, they would all support this option. On Linux it would copy the files from the temporary directory inside the Docker container to the project directory on the host. As the links above mention, there may be a use for another option (maybe build-outputs?) to copy out files from the build phase on Linux only. But that's not relevant to Android because only the test happens in a virtual machine, not the build.

@freakboy3742: This will probably come up on iOS at some point; what do you think? I guess it would be easier on iOS because the simulator doesn't have an isolated filesystem, but the command-line option in the testbed could be the same. Let's agree an approach and then discuss it with the cibuildwheel developers before we continue on this PR.

If we go this way, we can remove the --output-dir option from this PR. I would also rename --pull to --output, both for consistency with the cibuildwheel option name and to focus on the intent rather than the mechanism.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Platforms/Android/testbed/app/build.gradle.kts Outdated

// If the previous test run succeeded and nothing has changed,
// Gradle thinks there's no need to run it again. Override that.
afterEvaluate {

@mhsmith mhsmith May 9, 2026

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For clarity about when the code is run, this should be merged with the other afterEvaluate block below.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@timrid timrid Jun 12, 2026

Copy link
Copy Markdown
Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved the block into the other afterEvaluate block.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Platforms/Android/testbed/app/build.gradle.kts Outdated
return tasks.register<Copy>("${deviceName}CopyTestOutput") {
from(layout.buildDirectory.dir(additionalOutputPath))
// The subfolders of `connected_android_test_additional_output` contains
// names that are not equal to the serial of the device.

@mhsmith mhsmith May 9, 2026

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are their names?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@timrid timrid Jun 12, 2026

Copy link
Copy Markdown
Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

E.g. outputs/connected_android_test_additional_output/debugAndroidTest/connected/SM-S911B - 13/

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Platforms/Android/testbed/app/build.gradle.kts Outdated
// names that are not equal to the serial of the device.
// The subfolders of `managed_device_android_test_additional_output` are
// also unpredictable, because e.g. the subfolder for the "maxVersion" emulator
// is named "minVersion".

@mhsmith mhsmith May 9, 2026

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So what is the folder for minVersion called?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@timrid timrid Jun 12, 2026

Copy link
Copy Markdown
Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I now noticed, that minVersion has not worked at all. In my previous tests I probably saw an old output data from previous test runs. But even when I set minVersion to API level 29 it was also not working. Then I found out, that the output of the maxVersion device is always in the outputs folder:

outputs/managed_device_android_test_additional_output/debug/minVersion

and for minVersion (or other new devices I added) in the intermediates folder:

intermediates/managed_device_android_test_additional_output/debugAndroidTest/minVersionDebugAndroidTest

I am not quiet sure why, and on which factors this depends, but when searching in both directories it works much more stable if we would add new managed device configurations in the future.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Platforms/Android/testbed/app/build.gradle.kts Outdated
includeEmptyDirs = false
// Each android.py invocation runs only one device at a time,
// so there should never be more than one archive. Fail loudly
// if that assumption is violated.

@mhsmith mhsmith May 9, 2026

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This depends on __main__.py deleting the archive: if that fails for any reason, then subsequent runs may fail until the old archives are manually cleaned up. If the path really is unpredictable, then it would be safer for build.gradle.kts to delete any existing archives before running the tests.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@timrid timrid Jun 12, 2026

Copy link
Copy Markdown
Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right. I added a delete task before the tests are running.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Platforms/Android/testbed/app/src/androidTest/java/org/python/testbed/PythonSuite.kt Outdated
val pullPathsJson = args.getString("pythonPull") ?: return

// The output directory is created by AGP/UTP and points to a location inside
// the emulator's filesystem. AGP/UTP will pull everything from there back

@mhsmith mhsmith May 9, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"UTP" doesn't seem to be a widely used term; suggest removing it everywhere to avoid confusion.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@timrid timrid Jun 12, 2026

Copy link
Copy Markdown
Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed "UTP" everywhere.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Platforms/Android/testbed/app/build.gradle.kts Outdated
val archiveName = "org.python.testbed-output.zip"

return tasks.register<Copy>("${deviceName}CopyTestOutput") {
from(layout.buildDirectory.dir(additionalOutputPath))

@mhsmith mhsmith May 9, 2026

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the AGP source code, it looks like this feature might not be available below API level 29. So we should give an error if files were expected but weren't found.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@timrid timrid Jun 12, 2026

Copy link
Copy Markdown
Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, for managed devices this is only working for API level >= 29. So the minVersion device is not running at all. I added a check if there is no file found.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@freakboy3742

freakboy3742 commented May 10, 2026

Copy link
Copy Markdown
Contributor

Apart from the more minor comments below, my main question is how this would integrate into cibuildwheel.

I agree that cibuildwheel would be an obvious consumer for this sort of feature - but other than potentially consistency in language or option names, does the usage in cibuildwheel require any special consideration in the design here?

The Android (and potentially iOS) runners have arguments; the cibuildwheel interface may choose to provide a way to leverage that option to expose the capability. In some sense, that option already exists in the form of the TEST_RUNTIME setting.

To my mind, the feature analog here is really with Docker, not cibuildwheel - Docker is the "sandboxed test runner" from which files need to be exfiltrated; cibuildwheel calls docker, and a cibuildwheel user may need some of those files.

@freakboy3742: This will probably come up on iOS at some point; what do you think? I guess it would be easier on iOS because the simulator doesn't have an isolated filesystem, but the command-line option in the testbed could be the same. Let's agree an approach and then discuss it with the cibuildwheel developers before we continue on this PR.

Agreed that it could be useful, and it would make sense to attempt to maintain parity between the iOS and Android testbed runners parity wherever we can.

If we go this way, we can remove the --output-dir option from this PR. I would also rename --pull to --output, both for consistency with the cibuildwheel option name and to focus on the intent rather than the mechanism.

Fully aware this is a bike shed - but I'm not convinced by this; To me, --output is a flag you use to say where you want a tool to put its output, not a path to the output to be preserved.

AFAICT, it makes sense to preserve two flags - where the content is coming from, and where it's going to; with the latter being --output. --pull doesn't feel quite right to me... but ultimately it is a bikeshed, as long as the flag makes some sort of sense.

There would then be an obvious mapping to TEST_OUTPUTS et all from cibuildwheel, but that's a "plumbing" question, not a design question for this feature.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@timrid timrid mentioned this pull request May 21, 2026
Add support for Android and iOS platforms aio-libs/aiohttp#12220
Merged
2 of 5 tasks
@timrid timrid mentioned this pull request Jun 6, 2026
Feature request: Collect files generated during tests (e.g. coverage data) pypa/cibuildwheel#2899
Open
@timrid

timrid commented Jun 6, 2026

Copy link
Copy Markdown
Author

For further discussion about the integration in cibuildwheel, I created pypa/cibuildwheel#2899.

AFAICT, it makes sense to preserve two flags - where the content is coming from, and where it's going to; with the latter being --output

I think we need the --output-dir (or only --output) option for cibuildwheel because multiple wheels can be built at once in a single cibuildwheel call and thus the tests also run multiple times. If the output were always placed in the root directory, the files would overwrite each other. Therefore, there should be a separate folder for each test call, which could be named like the build identifier (e.g., cp314-android_arm64_v8a).

--pull doesn't feel quite right to me... but ultimately it is a bikeshed, as long as the flag makes some sort of sense.

I borrowed the name --pull from the adb pull command (even if we are not using this command). This makes some sense in an Android context, but not if you want to unify it with iOS. Alternatively, it could be called --copy-back or just --copy.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@freakboy3742

freakboy3742 commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

I think we need the --output-dir (or only --output) option for cibuildwheel because multiple wheels can be built at once in a single cibuildwheel call and thus the tests also run multiple times.

I agree the flag is needed; I'd lean to --output for simplicity.

--pull doesn't feel quite right to me... but ultimately it is a bikeshed, as long as the flag makes some sort of sense.

I borrowed the name --pull from the adb pull command (even if we are not using this command). This makes some sense in an Android context, but not if you want to unify it with iOS. Alternatively, it could be called --copy-back or just --copy.

I don't know that I have a better name than --pull - so I'm inclined to just go with that.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

timrid added 6 commits June 12, 2026 22:31
@timrid
use only one afterEvaluate block to simplify the code
13b9418
@timrid
remove UTP from the comments
4ccea67
@timrid
delete additional output folder before the run and check if it was ac…
a5ea1e1
…tually found
@timrid
fix kotlin warning
82251bb
> Task :app:compileDebugKotlin
w: cpython/Platforms/Android/testbed/app/src/main/java/org/python/testbed/MainActivity.kt:34:75 Parameter 'it' is never used, could be renamed to _
@timrid
also search "intermediates/managed_device_android_test_additional_out…
f77b435
…put" folder
@timrid
Add a hint in the docs, that --pull only works on managed devices sin…
376224c
…ce api level 29
@timrid

timrid commented Jun 12, 2026

Copy link
Copy Markdown
Author

@mhsmith I've addressed all the points you mentioned, so this PR is ready for another review.

I agree the flag is needed; I'd lean to --output for simplicity.

After thinking a bit more about the parameter name --output or --output-dir, I would still stick with --output-dir, because other tools like cibuildwheel also use --output-dir for a similar parameter.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@github-actions

github-actions Bot commented Sep 11, 2026

Copy link
Copy Markdown

This PR is stale because it has been open for 90 days with no activity.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@github-actions github-actions Bot added the stale Stale PR or inactive for long period of time. label Sep 11, 2026
@mhsmith

mhsmith commented Sep 14, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

Sorry for the slow response. I'll be busy for the next few weeks preparing my projects for Python 3.15, and then I'll have some time to come back to this.

Python 3.13 is about to go into security-only status, and even before that, the 2-month release cycle has been an inconvenience for cibuildwheel. So I'm also thinking of splitting out the testbed from CPython into a separate package so it's easier to update, and easier to use in other contexts (#158018). That should be done before adding any new features.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mhsmith mhsmith removed the stale Stale PR or inactive for long period of time. label Sep 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@mhsmith mhsmith mhsmith left review comments
@freakboy3742 freakboy3742 Awaiting requested review from freakboy3742 freakboy3742 is a code owner

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

awaiting review

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Copy files back from Android testbed emulator to host

Uh oh!

There was an error while loading. Please reload this page.

3 participants

@timrid @freakboy3742 @mhsmith
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.