neurosity-sdk-python
neurosity-sdk-python copied to clipboard
OOB Failure - Example Does not Run on Windows
I would like to report a pair of out-of-the-box issues with example.py / the "SDK".
In a Python 3.10.2 venv on Windows 11 Pro x64, trying to run the example will yield the following output:
C:\Projects\neurosity-python-sdk\venv\Scripts\python.exe C:\Projects\neurosity-python-sdk\examples\example.py
Traceback (most recent call last):
File "C:\Projects\neurosity-python-sdk\examples\example.py", line 7, in <module>
neurosity = NeurositySDK({
File "C:\Projects\neurosity-python-sdk\neurosity\neurosity.py", line 27, in __init__
signal.signal(signal.SIGHUP, self.exit_handler)
AttributeError: module 'signal' has no attribute 'SIGHUP'
Exception ignored in atexit callback: <bound method NeurositySDK.exit_handler of <neurosity.neurosity.NeurositySDK object at 0x0000020CBA085B70>>
Traceback (most recent call last):
File "C:\Projects\neurosity-python-sdk\neurosity\neurosity.py", line 30, in exit_handler
self.remove_client()
File "C:\Projects\neurosity-python-sdk\neurosity\neurosity.py", line 61, in remove_client
client_id = self.client_id
AttributeError: 'NeurositySDK' object has no attribute 'client_id'
Process finished with exit code 1
Issue diagnosis
The main issue is that it appears as if the signal
library is not used correctly in a portable way. For platform portability, only signals from dir(signal)
are valid, or at runtime, signal.valid_signals()
.
On Windows 11 pro x64, this notably excludes SIGHUP, which is only available on Unix and on most BSD flavors (including OSX).
Python 3.10.2 (tags/v3.10.2:a58ebcc, Jan 17 2022, 14:12:15) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import signal
>>> dir(signal)
['CTRL_BREAK_EVENT', 'CTRL_C_EVENT', 'Handlers', 'NSIG', 'SIGABRT', 'SIGBREAK', 'SIGFPE', 'SIGILL', 'SIGINT', 'SIGSEGV', 'SIGTERM', 'SIG_DFL', 'SIG_IGN', 'Signals', '_IntEnum', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_enum_to_int', '_int_to_enum', '_signal', 'default_int_handler', 'getsignal', 'raise_signal', 'set_wakeup_fd', 'signal', 'strsignal', 'valid_signals']
The other issue show that some failure state cannot be handled, probably because it uses the dangerous JavaScript pattern of equating nonexistent properties to undefined on access. I think hasattr()
is a better way to implement this logic here, rather than client_id = self.client_id
followed by a branch on if(client_id):
. A general recommendation would be to never allow the application to represent a state where this attribute doesn't exist on the class.
Experimental remedy Removing the offending use of SIGHUP from the library code, the example appears to run as expected. However, it doesn't listen to CTRL-C or other keyboard interrupts (not the best behaviour, I had plane for that terminal session :D), and it will likely not receive the expected signal if I close the terminal now. (Windows Terminal, for that matter)