cpython icon indicating copy to clipboard operation
cpython copied to clipboard

signal.strsignal(...) doesn't really return None if signal is not recognized

Open misterwilliam opened this issue 3 years ago • 2 comments

Documentation

The documentation for signal.strsignal(...) says Returns None if the signal is not recognized. This a misleading way to describe what actually happens.

Suggested better wording would be Throws ValueError if signalnum is invalid, and returns None if there is no canonical name for signalnum for the platform.

From reading the implementation in cpython, this is my best understanding of what happens.

If the signal number is less than 1 or greater (or equal) to signal.NSIG (ie 65) a ValueError exception is thrown. (ie signal.strsignal(65) throws a ValueError exception and does not return None). This scenario is what I found most confusing about the documentation.

If there is no suitable canonical name for the signal, then signal.strsignal(..) will return None. For example on Linux, signal 32 doesn't have a canonical name. In that case signal.strsignal(...) does return None. I am not an expert in Linux, but I did the following test, and it appears to me that signal 32 is pretty normal behaving signal, its usage is just deprecated and no longer has a standard name.

$ bash
$ echo $$  # Get pid of current shell
120846
# In another terminal
$ kill -s 65 120846  # Send signal 65 which is an invalid signal, and show that nothing happens.
-bash: kill: 65: invalid signal specification
$ kill -s 32 120846  # Send signal 32 which is a valid signal with no canonical name, and show that signal is sent
# Above shell exits with message
Unknown signal 32

It is pretty easy to verify that what I said about the cpython implementation is correct if HAVE_STRSIGNAL is true, however for HAVE_STRSIGNAL false, it depends a lot more on what strsignal() (from glibc) returns.

From looking at the implementation in glibc glibc returns a string with a name of the signal or "Unknown signal". If glibc "Unknown signal" then cpython will return None.

The one caveat is that I am not fully clear how well my analysis carries over to the Windows platform. But at least for the Linux platform, I do feel that my suggested wording Throws ValueError if signalnum is invalid, and returns None if there is no canonical name for signalnum for the platform. is a good representation of what happens.

  • PR: gh-99290

misterwilliam avatar Oct 31 '22 22:10 misterwilliam

I am not fully clear how well my analysis carries over to the Windows platform.

On Windows, the signal module implements descriptions for the standard signals that are required by C -- SIGINT (2), SIGILL (4), SIGFPE (8), SIGSEGV (11), SIGTERM (15), and SIGABRT (22). No description is provided for the non-standard signal SIGBREAK (21). The value of NSIG is 23.

Throws ValueError if signalnum is invalid, and returns None if there is no canonical name for signalnum for the platform.

I suggest the following:

   Return the system description of the signal *signalnum*, such as
   "Interrupt" for :const:`SIGINT`. Returns :const:`None` if *signalnum* has
   no description. Raises :exc:`ValueError` if *signalnum* is invalid.

eryksun avatar Nov 01 '22 00:11 eryksun

I did the changes sir

ramvikrams avatar Nov 09 '22 13:11 ramvikrams

thanks!

gpshead avatar Nov 13 '22 19:11 gpshead