This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: sys.addaudithook(hook) loops indefinitely on mismatch for hook
Type: behavior Stage:
Components: Versions: Python 3.9, Python 3.8
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Dutcho, christian.heimes, steve.dower, terry.reedy
Priority: normal Keywords:

Created on 2020-01-01 17:23 by Dutcho, last changed 2022-04-11 14:59 by admin.

Messages (5)
msg359164 - (view) Author: (Dutcho) Date: 2020-01-01 17:23
When hook is not a compatible callable, addaudithook() will loop forever. At the minimum, a check for being callable should be executed. Preferably, a non-compatible (i.e. signature != [[str, tuple], Any]) hook callable should also be detected.

>py
Python 3.8.1 (tags/v3.8.1:1b293b6, Dec 18 2019, 23:11:46) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.addaudithook(0)
error=10
Exception ignored in audit hook:
TypeError: 'int' object is not callable
  File "<stdin>", line 0
SyntaxError: unknown parsing error
error=10
Exception ignored in audit hook:
TypeError: 'int' object is not callable
  File "<stdin>", line 0
SyntaxError: unknown parsing error
error=10
Exception ignored in audit hook:
TypeError: 'int' object is not callable
  File "<stdin>", line 0
SyntaxError: unknown parsing error
... etc. ...
msg359247 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2020-01-03 18:48
I think this is specific to the interactive prompt. Under normal circumstances, any error in calling the hook at the point where an event is being audited (which is immediate when using interactive mode) needs to propagate.

Probably the best way to handle it is to call the hook with a new event indicating it's being added, but before it actually gets put into the list. A hook could then set up a different kind of loop, but it would be much harder to do it by accident.

Perhaps "sys.addaudithook/self" with itself as an argument. We can't just use "sys.addaudithook" in case there are hooks that blindly abort this event (which there are, because I've written them ;) ). But this will at least make sure that the signature is correct and shouldn't send the interactive parser into a loop.
msg359279 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2020-01-04 06:44
> I think this is specific to the interactive prompt.
In IDLE, which simulates interactive mode with repeated 'exec(user_code, namespace)', no error is printed, let alone a loop.

>>> import sys
>>> sys.addaudithook(0)
>>>
msg359280 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2020-01-04 06:51
I wrote too soon.  Entering anything at the next line prints
TypeError: 'int' object is not callable
twice and a lot of IDLE specific stuff, and not another prompt.  I have to restart the remote execution process.
msg359307 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2020-01-04 19:40
Right, IDLE doesn't call exec/compile until _after_ the code is submitted, while the regular prompt calls it first and passes stdin as the source file (which then does a buffered read).

The loop occurs because the next action after an invalid input is to read another input, which is correct, it just doesn't (and cannot) detect the case where an error is raised _before_ the user presses Enter.
History
Date User Action Args
2022-04-11 14:59:24adminsetgithub: 83363
2020-01-04 19:40:23steve.dowersetmessages: + msg359307
2020-01-04 06:51:48terry.reedysetmessages: + msg359280
2020-01-04 06:44:18terry.reedysetnosy: + terry.reedy
messages: + msg359279
2020-01-03 18:48:49steve.dowersetmessages: + msg359247
versions: + Python 3.9
2020-01-01 19:19:58xtreaksetnosy: + christian.heimes, steve.dower
2020-01-01 17:23:00Dutchocreate