gh-132493: Avoid eager evaluation of annotations in @reprlib.recursive_repr() (#133411)

This commit is contained in:
Jelle Zijlstra 2025-05-05 19:20:11 -07:00 committed by GitHub
parent b936ccdb6f
commit dbee142a01
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 19 additions and 2 deletions

View File

@ -28,7 +28,7 @@ def recursive_repr(fillvalue='...'):
wrapper.__doc__ = getattr(user_function, '__doc__')
wrapper.__name__ = getattr(user_function, '__name__')
wrapper.__qualname__ = getattr(user_function, '__qualname__')
wrapper.__annotations__ = getattr(user_function, '__annotations__', {})
wrapper.__annotate__ = getattr(user_function, '__annotate__', None)
wrapper.__type_params__ = getattr(user_function, '__type_params__', ())
wrapper.__wrapped__ = user_function
return wrapper

View File

@ -3,6 +3,7 @@
Nick Mathewson
"""
import annotationlib
import sys
import os
import shutil
@ -11,7 +12,7 @@ import importlib.util
import unittest
import textwrap
from test.support import verbose
from test.support import verbose, EqualToForwardRef
from test.support.os_helper import create_empty_file
from reprlib import repr as r # Don't shadow builtin repr
from reprlib import Repr
@ -829,5 +830,19 @@ class TestRecursiveRepr(unittest.TestCase):
self.assertEqual(type_params[0].__name__, 'T')
self.assertEqual(type_params[0].__bound__, str)
def test_annotations(self):
class My:
@recursive_repr()
def __repr__(self, default: undefined = ...):
return default
annotations = annotationlib.get_annotations(
My.__repr__, format=annotationlib.Format.FORWARDREF
)
self.assertEqual(
annotations,
{'default': EqualToForwardRef("undefined", owner=My.__repr__)}
)
if __name__ == "__main__":
unittest.main()

View File

@ -0,0 +1,2 @@
Avoid eagerly evaluating annotations in functions decorated with
:func:`reprlib.recursive_repr`.