Using the built-in Python, hundreds of modules are imported the first time an exception is raised at the REPL

I don’t know why I didn’t notice this before.

$ python
Python 3.8.10 (default, Nov 22 2023, 10:22:35) 
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> len(sys.modules.keys())
38
>>> raise Exception
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Exception
>>> len(sys.modules.keys())
378
>>> 

After raising the exception, sys.modules has 340 new entries. Seems like it might be the entire dist-packages folder, which apparently includes things like requests.

It doesn’t happen with Python that I built myself from source:

$ python3.11
Python 3.11.2 (main, Apr  5 2023, 03:08:14) [GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> len(sys.modules.keys())
70
>>> raise Exception
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Exception
>>> len(sys.modules.keys())
70
>>> 

Nor with a virtual environment based off the system Python:

$ source SANDBOX/bin/activate
$ python
Python 3.8.10 (default, Nov 22 2023, 10:22:35) 
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> len(sys.modules.keys())
61
>>> raise Exception
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Exception
>>> len(sys.modules.keys())
61
>>> 

Is there a known, general reason for this sort of thing to happen? Or do I have an OS support question instead?

1 Like

Because this function gets called when an exception is printed: apport/apport_python_hook.py at e0839a7f0c8867eed0d6aa4085e218393f6c44bb · canonical/apport · GitHub

Found this by checking sys.excepthook, which points to apport_python_hook.apport_excepthook

2 Likes

Weird. It’s probably your distro too. I couldn’t reproduce it in a pyenv Python 3.8.10 on Windows (even with requests installed), but I could do so in Python 3.10.12 on Ubuntu 22.04:

Python 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> len(sys.modules)
71
>>> raise Exception
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Exception
>>> len(sys.modules)
199
>>>

That tracks. I’m on Mint, so I’m downstream of this. It makes sense that the system Python would be using something like this, to help figure out issues in system scripts. Although I’m not sure I like the implication of crash dumps being sent silently…

I guess the rest really is an OS support question, then.