uvloop fails to import on SPARC64: OverflowError: Python int too large to convert to C long
- uvloop version: 4b803b155ed30a30f34c208133a431587272f81e
- Python version: 3.9.5
- Platform: Gentoo Linux
-
Can you reproduce the bug with
PYTHONASYNCIODEBUGin env?: yes - Does uvloop behave differently from vanilla asyncio? How?: n/a
When built on SPARC64, the uvloop module fails to load:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/home/mgorny/uvloop/uvloop/__init__.py", line 7, in <module>
from .loop import Loop as __BaseLoop # NOQA
File "uvloop/includes/stdlib.pxi", line 138, in init uvloop.loop
cdef uint64_t MAIN_THREAD_ID = <uint64_t><int64_t>threading.main_thread().ident
OverflowError: Python int too large to convert to C long
From my short testing, it seems that the Python thread identifiers on sparc are simply bigger than they are on my amd64 machine, and don't fit into int64_t (though I wouldn't be surprised if amd64 didn't have the same problem, just we're lucky not to experience large enough thread IDs). If I remove the intermediate int64_t cast, thing seems to work just fine. The cast seems to have been introduced in b5b4abb16ba558cf957cf40120dfd4937c53aea5.
I don't think we have resources to debug SPARC64 compatibility. But you're welcome to submit PRs to fix it!
Well, removing <int64_t> from that line fixes it but I'm afraid it's going to break some other platforms :-(. I've asked Gentoo arch teams to test whether its removal breaks any of the 32-bit platforms we test on but it will probably take a few days before they report back.
@mgorny after all why do we need int64_t cast? I have no access to my sparc now :( but it should work very close to AMD64 if it's Linux (on Solaris much more different).
We shouldn't need it. Gentoo's running with my patch since then, and all arch teams have confirmed no regressions (at least as far as the test suite is concerned).
after all why do we need int64_t cast?
I think this was because Python < 3.7 still return long instead of unsigned long. Now that we don't support Python 3.6, it should be safe to drop the <int64_t> cast. I'll create a PR.
Cython will check if integer overflows when converting a Python int to a C integer type, and because the thread ident can be a negative number in Python 3.6, that's why we needed the <int64_t> conversion in the first place. But still it was buggy on 64-bit platforms just like what you ran into.