POSIX signals are broken by design, alas: https://lwn.net/Articles/414618/ Python or not, almost nothing is safe inside a signal handler.
>almost nothing is safe That's a bit of an overstatement? There's a list of things that you _can_ call, and fairly useful ones too like `write` https://man7.org/linux/man-pages/man7/signal-safety.7.html
If the signal occurs other than as the result of calling abort(), raise(),
[CX] [Option Start] kill(), pthread_kill(), or sigqueue(), [Option End] the
behavior is undefined if the signal handler refers to any object with static
storage duration other than by assigning a value to an object declared as
volatile sig_atomic_t, or if the signal handler calls any function in the
standard library other than one of the functions listed in Signal Concepts.
You literally can't read any global/static variables and you can only write to global/static variables that are declared to be volatile sig_atomic_t. This tremendously shrinks the amount of useful work you can do with the signal-safe functions from the standard library.