Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ValueError: Unsupported signal: 2 #42

Closed
dmwyatt opened this issue Nov 8, 2021 · 5 comments
Closed

ValueError: Unsupported signal: 2 #42

dmwyatt opened this issue Nov 8, 2021 · 5 comments
Labels
bug Something isn't working help wanted Extra attention is needed

Comments

@dmwyatt
Copy link

dmwyatt commented Nov 8, 2021

For a complicated, multi-threaded application that uses zmq, I get the following error when I Ctrl-C the application that I started using poe to run the task "poetry run python .\\main.py"

Traceback (most recent call last):
  File "C:\Users\dmwyatt\AppData\Local\Programs\Python\Python39\lib\runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Users\dmwyatt\AppData\Local\Programs\Python\Python39\lib\runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "C:\Users\dmwyatt\AppData\Local\pypoetry\Cache\virtualenvs\win-backup-exclude-MbZQpObE-py3.9\Scripts\poe.exe\__main__.py", line 7, in <module>
  File "C:\Users\dmwyatt\AppData\Local\pypoetry\Cache\virtualenvs\win-backup-exclude-MbZQpObE-py3.9\lib\site-packages\poethepoet\__init__.py", line 32, in main
    result = app(cli_args=sys.argv[1:])
  File "C:\Users\dmwyatt\AppData\Local\pypoetry\Cache\virtualenvs\win-backup-exclude-MbZQpObE-py3.9\lib\site-packages\poethepoet\app.py", line 52, in __call__
    return self.run_task() or 0
  File "C:\Users\dmwyatt\AppData\Local\pypoetry\Cache\virtualenvs\win-backup-exclude-MbZQpObE-py3.9\lib\site-packages\poethepoet\app.py", line 80, in run_task
    return self.task.run(
  File "C:\Users\dmwyatt\AppData\Local\pypoetry\Cache\virtualenvs\win-backup-exclude-MbZQpObE-py3.9\lib\site-packages\poethepoet\task\base.py", line 142, in run
    return self._handle_run(context, extra_args, env)
  File "C:\Users\dmwyatt\AppData\Local\pypoetry\Cache\virtualenvs\win-backup-exclude-MbZQpObE-py3.9\lib\site-packages\poethepoet\task\cmd.py", line 39, in _handle_run
    return context.get_executor(env, self.options.get("executor")).execute(cmd)
  File "C:\Users\dmwyatt\AppData\Local\pypoetry\Cache\virtualenvs\win-backup-exclude-MbZQpObE-py3.9\lib\site-packages\poethepoet\executor\poetry.py", line 31, in execute
    return self._execute_cmd(cmd, input)
  File "C:\Users\dmwyatt\AppData\Local\pypoetry\Cache\virtualenvs\win-backup-exclude-MbZQpObE-py3.9\lib\site-packages\poethepoet\executor\poetry.py", line 64, in _execute_cmd
    return self._exec_via_subproc(
  File "C:\Users\dmwyatt\AppData\Local\pypoetry\Cache\virtualenvs\win-backup-exclude-MbZQpObE-py3.9\lib\site-packages\poethepoet\executor\base.py", line 134, in _exec_via_subproc
    proc.communicate(input)
  File "C:\Users\dmwyatt\AppData\Local\Programs\Python\Python39\lib\subprocess.py", line 1126, in communicate
    self.wait()
  File "C:\Users\dmwyatt\AppData\Local\Programs\Python\Python39\lib\subprocess.py", line 1189, in wait
    return self._wait(timeout=timeout)
  File "C:\Users\dmwyatt\AppData\Local\Programs\Python\Python39\lib\subprocess.py", line 1470, in _wait
    result = _winapi.WaitForSingleObject(self._handle,
  File "C:\Users\dmwyatt\AppData\Local\pypoetry\Cache\virtualenvs\win-backup-exclude-MbZQpObE-py3.9\lib\site-packages\poethepoet\executor\base.py", line 129, in handle_signal
    proc.send_signal(signum)
  File "C:\Users\dmwyatt\AppData\Local\Programs\Python\Python39\lib\subprocess.py", line 1545, in send_signal
    raise ValueError("Unsupported signal: {}".format(sig))
ValueError: Unsupported signal: 2

Other notes

  • Other sorts of tasks like format = "black ." run just fine, so it has something to do with how poe is running my application.
  • If I don't use poe to run my application it exits just fine without a traceback.
  • The last things my application does when exiting via a try...finally block is terminating the zmq context and closing several sockets...but removing those actions doesn't solve this traceback popping up.
  • I can try to come up with a minimal reproduction, but I expect that to be difficult so I wanted to see if anyone had any ideas first.
@nat-n
Copy link
Owner

nat-n commented Nov 8, 2021

Hi @dmwyatt, thanks for the feedback.

I made a quick investigation, and it looks like this is an issue with how SIGTERM signals work on windows (i.e. they don't), reference: https://stackoverflow.com/questions/47306805/signal-sigterm-not-received-by-subprocess-on-windows

I don't really know much about windows, and the links from that discussion on stack overflow seem to suggest that it's non-trivial to get this to work properly. So since I don't have a proper windows dev environment to hand, I'll need some help with this one. The relevant code is around here.

@nat-n nat-n added help wanted Extra attention is needed bug Something isn't working labels Nov 8, 2021
@JCapul
Copy link

JCapul commented Dec 13, 2022

Hi, I just got hit with the issue trying to run a "docker compose up" through poe on windows.

It looks like from the send_signal implementation for windows that there're only a few signals you can send to a subproc:

def send_signal(self, sig):
    """Send a signal to the process."""
    # Don't signal a process that we know has already died.
    if self.returncode is not None:
        return
    if sig == signal.SIGTERM:
        self.terminate()
    elif sig == signal.CTRL_C_EVENT:
        os.kill(self.pid, signal.CTRL_C_EVENT)
    elif sig == signal.CTRL_BREAK_EVENT:
        os.kill(self.pid, signal.CTRL_BREAK_EVENT)
    else:
        raise ValueError("Unsupported signal: {}".format(sig))

Considering this and the fact that a SIGTERM actually calls terminate() on the subprocess, I managed to make my use case work by hacking the SIGINT handler handle_signal into sending a SIGTERM signal instead to the subprocess. My subprocess (docker compose up) and poe are all terminating gracefully.

With a check on the platform first, that could be one way to solve it, though I have no idea if and how it would work on a more general basis.

@JCapul
Copy link

JCapul commented Dec 13, 2022

Actually, it might be better to send a CTRL_C_EVENT than a SIGTERM.

So the code modification could look like this:

  # signal pass through
  def handle_signal(signum, _frame):
      # sigint is not handled on windows
      signum = signal.CTRL_C_EVENT if self._is_windows else signum
      proc.send_signal(signum)

  old_signal_handler = signal.signal(signal.SIGINT, handle_signal)

@nat-n
Copy link
Owner

nat-n commented Dec 13, 2022

Hi @JCapul,

Thanks for the investigation. That sounds reasonable. I'll add this to be TODO list for the next release. Or feel free to open a PR for it :)

JCapul added a commit to JCapul/poethepoet that referenced this issue Dec 14, 2022
send_signal() implementation on windows only supports SIGTERM,
CTRL_C_EVENT and CTRL_BREAK_EVENT

Ref: nat-n#42
nat-n added a commit that referenced this issue Dec 26, 2022
@nat-n
Copy link
Owner

nat-n commented Dec 26, 2022

The fix is now available in 0.17.1

Thanks for the support @JCapul !

@nat-n nat-n closed this as completed Dec 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants