Description
Crash report
What happened?
The following is a reproducer of (another) segfault discovered when trying to test Python 3.14 in CI for Sphinx:
class Spam:
def __new__(cls, x, y):
pass
if __name__ == '__main__':
assert Spam.__new__.__annotations__ == {}
obj = Spam.__dict__['__new__']
assert isinstance(obj, staticmethod)
getattr(obj, '__annotations__', None) # segfault here
try:
obj.__annotations__ # and here (absent the above)
except AttributeError:
pass
print('no segfault!')
Whilst checking __annotations__
directly is somewhat convoluted, it was originally triggered by inspect.isasyncgenfunction()
, which calls inspect._signature_is_functionlike()
via _has_code_flag()
.
A similar error occurs with __class_getitem__
and __init_subclass__
, but not with user-defined methdods declared with either classmethod
or staticmethod
. As the reproducer demonstrates, the segfault only happens with the descriptor object from __dict__
-- cls.__new__.__annotations__
is fine.
Bisection showed this to be due to d28afd3 (#119864), cc @JelleZijlstra
d28afd3fa064db10a2eb2a65bba33e8ea77a8fcf is the first bad commit
commit d28afd3fa064db10a2eb2a65bba33e8ea77a8fcf
Author: Jelle Zijlstra <[email protected]>
Date: Fri May 31 14:05:51 2024 -0700
gh-119180: Lazily wrap annotations on classmethod and staticmethod (#119864)
A
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Output from running 'python -VV' on the command line:
Python 3.14.0a0 (bisect/bad:d28afd3fa06, Oct 6 2024, 01:35:23) [GCC 13.2.0]