chaquo / chaquopy

Chaquopy: the Python SDK for Android
https://chaquo.com/chaquopy/
MIT License
749 stars 128 forks source link

[concurrent] concurrent.futures throws Exception. #1074

Closed Pairman closed 5 months ago

Pairman commented 5 months ago

Chaquopy version

py 3.8 chaquopy 14.0.2

Devices or emulators where the issue happens

Affected: Android 13, kernel 4.14.298.

Relevant parts of your code

I'm using concurrent.futures to generate a bunch of threads and wait for the final results. This function calls a wrapper function (of another function, which sends get requests):

import concurrent.futures
from traceback import print_exc

# ..., other parts of the class implementation.
    def course_get_activities(self):
        def wrapper(course: dict = {}):
            course_activities = self.course_get_course_activities(course = course)
            if course_activities:
                activities[course["class_id"]] = course_activities
        courses = (
            {
                "course_id": course[1]["course_id"],
                "class_id": course[0]
            } for course in tuple(self.courses.items())[: 48]
        )
        activities = {}
        try:
            with concurrent.futures.ThreadPoolExecutor() as executor: # line 448
                concurrent.futures.wait(executor.submit(wrapper, course) for course in courses) # line 449
            return activities # line 450
        except Exception:
            print_exc()
            return {}

Describe your issue

It's part of my briefcase project. On windows, this code runs without any exception captured, and returns the desired non-empty dict.

But on Android, this code always print the exception captured and returns empty dict. My logcat shows

01-11 20:36:35.786 14226 14402 W python.stderr:
File "/data/data/org.eu.pnxlr.git.xdcheckin/files/chaquopy/AssetFinder/app/backend/xdcheckin_py/chaoxing/chaoxing.py", line 449, in course_get_activities

I assume this is a platform issue, maybe there's something wrong with chaquopy or the libpython on Android.

And is there any way to capture more specific traceback so that I can provide more info?

Thanks in advance.

mhsmith commented 5 months ago

The rest of the traceback should be right there in the logcat. If you can't see it, maybe you're filtering the logcat too much.

And are you sure return activities really is line 449, and that the code you're looking at is the same version as the code you're running? I don't see how it's possible for that line to throw an exception.

Pairman commented 5 months ago

The rest of the traceback should be right there in the logcat. If you can't see it, maybe you're filtering the logcat too much.

And are you sure return activities really is line 449, and that the code you're looking at is the same version as the code you're running? I don't see how it's possible for that line to throw an exception.

Sorry for my wrong numbering! I have updated the line numbers of my code block (each increased by 1), the exception occurred at concurrent.futures.wait(executor.submit(wrapper, course) for course in courses). I'm using a real phone and not familiar with android debugging. I'm using a logcat app to capture the print message, but I didn't manually filter anything. It could be that the traceback print_exc() itself printed ambitiously.

mhsmith commented 5 months ago

The easiest way to see the full traceback is to use the Android Studio Logcat window.

Pairman commented 5 months ago

Finally found the real reason. concurrent.futures.wait() on linux or android throws TypeError: object of type 'generator' has no len() if passed in a generator. Still don't know why it works on windows.