Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork33.3k
Description
Bug report
Bug description:
Given the following code:
importasyncioimporttimeclassFoo:def__repr__(self):time.sleep(1)print('i am a repr, i should not be called. ')return'<Foo>'asyncdefget_foo():returnFoo()asyncio.run(get_foo())print('Done')
Output:
$ python t.pyi am a repr, i should not be called.i am a repr, i should not be called.Done
This was caused by the new SIGINT handler installed by asyncio.run here:f08a191
Upon investigation, changing the code with:
importasyncioimporttimeclassFoo:def__repr__(self):time.sleep(1)print('i am a repr, i should not be called. ')raiseBaseException('where is this called???????')return'<Foo>'asyncdefget_foo():returnFoo()asyncio.run(get_foo())print('Done')
It shows:
i am a repr, i should not be called.Traceback (most recent call last): File "t.py", line 15, in <module> asyncio.run(get_foo()) File "lib/python3.12/asyncio/runners.py", line 194, in run return runner.run(main) ^^^^^^^^^^^^^^^^ File "lib/python3.12/asyncio/runners.py", line 127, in run and signal.getsignal(signal.SIGINT) is sigint_handler ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "lib/python3.12/signal.py", line 63, in getsignal return _int_to_enum(handler, Handlers) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "lib/python3.12/signal.py", line 29, in _int_to_enum return enum_klass(value) ^^^^^^^^^^^^^^^^^ File "lib/python3.12/enum.py", line 740, in __call__ return cls.__new__(cls, value) ^^^^^^^^^^^^^^^^^^^^^^^ File "lib/python3.12/enum.py", line 1152, in __new__ ve_exc = ValueError("%r is not a valid %s" % (value, cls.__qualname__)) ^^^^^ File "lib/python3.12/reprlib.py", line 21, in wrapper result = user_function(self) ^^^^^^^^^^^^^^^^^^^ File "lib/python3.12/asyncio/base_tasks.py", line 30, in _task_repr info = ' '.join(_task_repr_info(task)) ^^^^^^^^^^^^^^^^^^^^^ File "lib/python3.12/asyncio/base_tasks.py", line 10, in _task_repr_info info = base_futures._future_repr_info(task) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "lib/python3.12/asyncio/base_futures.py", line 54, in _future_repr_info result = reprlib.repr(future._result) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "lib/python3.12/reprlib.py", line 58, in repr return self.repr1(x, self.maxlevel) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "lib/python3.12/reprlib.py", line 68, in repr1 return self.repr_instance(x, level) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "lib/python3.12/reprlib.py", line 170, in repr_instance s = builtins.repr(x) ^^^^^^^^^^^^^^^^ File "t.py", line 8, in __repr__ raise BaseException('where is this called???????')BaseException: where is this called???????This looks like a series unfortunate events, running on 3.12.0:
- signal.getsignal tries to convert the handler function to enum in case this is part of Handlers:
Line 29 in0fb18b0
returnenum_klass(value) - enum raises a ValueError with the repr of the handler function:
Line 1152 in0fb18b0
ve_exc=ValueError("%r is not a valid %s"% (value,cls.__qualname__)) - the handler asyncio.run installs uses a functools.partial, it's repr will include the repr of the task:
cpython/Lib/asyncio/runners.py
Line 105 in0fb18b0
sigint_handler=functools.partial(self._on_sigint,main_task=task) - when the repr is actually called at the end (one in
signal.getsignal, the other insignal.signal), the repr of the asyncio task will include the repr of the result:cpython/Lib/asyncio/runners.py
Lines 127 to 129 in0fb18b0
andsignal.getsignal(signal.SIGINT)issigint_handler ): signal.signal(signal.SIGINT,signal.default_int_handler)
While one can argument calling__repr__ shouldn't cause issues, but Ithink we could avoid them in thesignal._int_to_enum function completely, by only trying to convert to enum when it's an integer:
def_int_to_enum(value,enum_klass):"""Convert a numeric value to an IntEnum member. If it's not a known member, return the numeric value itself. """ifnotisinstance(value,int):returnvaluetry:returnenum_klass(value)exceptValueError:returnvalue
This should be more efficient on its own anyway.
This function's doc is also inaccurate, since it also accepts non integers (usually a callable).
Am I missing something?
CPython versions tested on:
3.11, 3.12
Operating systems tested on:
Linux
Linked PRs
Metadata
Metadata
Assignees
Labels
Projects
Status