yappi
yappi copied to clipboard
SystemError using Yappi for Python3.13 Free Threaded
I am having trouble getting Yappi to work with Python 3.13t Free Threading. Attempting to isolate the issue, the smallest example was using unittest.patch. However I am able to see it with other libraries, notably a c binary accessed via ctypes. The issue occurs whether the GIL is disabled or not.
Code
#!/usr/bin/env python3.13t
import yappi
import unittest
from unittest.mock import patch
import sys
print(sys.version)
class TestReadFile(unittest.TestCase):
def setUp(self):
yappi.start()
@patch('builtins.open')
def test_read_file(self, mock_file):
pass
if __name__ == '__main__':
unittest.main()
Command
./test_yappi.py
PYTHON_GIL=1 ./test_yappi.py
Output
# ./test_yappi.py
3.13.0 experimental free-threading build (main, Oct 8 2024, 08:51:27) [GCC 9.4.0]
E
======================================================================
ERROR: test_read_file (__main__.TestReadFile.test_read_file)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/lib/python3.13/unittest/mock.py", line 686, in __getattr__
elif self._mock_methods is not None:
^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.13/unittest/mock.py", line 685, in __getattr__
raise AttributeError(name)
AttributeError: _mock_methods
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/lib/python3.13/unittest/mock.py", line 1420, in patched
with self.decoration_helper(patched,
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
args,
^^^^^
keywargs) as (newargs, newkeywargs):
^^^^^^^^^
File "/usr/lib/python3.13/contextlib.py", line 141, in __enter__
return next(self.gen)
File "/usr/lib/python3.13/unittest/mock.py", line 1402, in decoration_helper
arg = exit_stack.enter_context(patching)
File "/usr/lib/python3.13/contextlib.py", line 530, in enter_context
result = _enter(cm)
File "/usr/lib/python3.13/unittest/mock.py", line 1549, in __enter__
new = Klass(**_kwargs)
File "/usr/lib/python3.13/unittest/mock.py", line 2156, in __init__
def __init__(self, /, *args, **kw):
SystemError: <sys.legacy_event_handler object at 0x48614a4a950> returned a result with an exception set
----------------------------------------------------------------------
Ran 1 test in 0.005s
FAILED (errors=1)
Dockerfile
FROM ubuntu:20.04
ENV DEBIAN_FRONTEND=noninteractive
RUN add-apt-repository -y ppa:deadsnakes/ppa
RUN apt-get install -y \
python3.13-nogil \
libpython3.13-nogil \
libpython3.13-dev
Thanks for the reproducer!
I will look into this.
@sumerc are you interested in some help to get yappi working on the free-threaded build? My team @quansight-labs is working on ecosystem support for free-threaded python and yappi came up on our list of packages we'd like to work on to unblock work in the ecosystem.
We'd appreciate your thoughts, if any, on whether an outside contributor could take this on and what ideas you have about this.
Hi,
Sure I will be pretty much interested and ok with an outside contributor.
But, my question would be:
There is lots of global data structures and implicit assumptions that rely on GIL being held. Do you think it's worth the effort? My mental model is: I am skeptical about having a true parallelism in a profiler that tries to do as little as possible for each function entry/exit would add any benefit? No? I mean adding locks(if we are going to do that) might even make perf. worse?
Maybe I am missing some parts/implementation details...etc.
There is lots of global data structures
You weren't kidding!
I am skeptical about having a true parallelism in a profiler that tries to do as little as possible for each function entry/exit would add any benefit? No? I mean adding locks(if we are going to do that) might even make perf. worse?
It may be possible to do it in a lock-free way with atomics or thread-locals.
That said, I'm not super familiar with this tool and would need some time to get acquainted with the codebase to see what makes sense. I know that some of the Memray team have recently been spending a lot of effort getting that tool working under the free-threaded build. There are also some new tracing APIs that may be useful. I'll sync back with our team and with some of the CPython core devs we're working with to get their opinion.
Fair enough!
Pls also don't hesitate to ping/discuss/involve me for anything! This is really an interesting direction.
We talked about this and found that the dependency on yappi we encountered wasn’t actually in the critical path for any other projects, so we decided to not focus on this given the expected technical complexity. I’ll let you know if that changes in the future.