Repository: openai/gym

Issue:
noisy KeyboardInterrupt with VectorEnv
Baselines SubprocVecEnv has some code to make Keyboard Interrupts less noisy:  https://github.com/openai/baselines/blob/master/baselines/common/vec_env/subproc_vec_env.py#L30

This is great when you kill your program, otherwise you see the stack traces of all your envs:

```
(3, 210, 160, 3) [0. 0. 0.] [False False False] ({'ale.lives': 0}, {'ale.lives': 0}, {'ale.lives': 0})
(3, 210, 160, 3) [0. 0. 0.] [False False False] ({'ale.lives': 0}, {'ale.lives': 0}, {'ale.lives': 0})
^CProcess Worker<AsyncVectorEnv>-1:
Process Worker<AsyncVectorEnv>-2:
Traceback (most recent call last):
  File "/Users/csh/miniconda3/envs/py37/lib/python3.7/runpy.py", line 193, in _run_module_as_main
Process Worker<AsyncVectorEnv>-0:
    "__main__", mod_spec)
  File "/Users/csh/miniconda3/envs/py37/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/Users/csh/agi/sandbox/oneoff/try_vec_env.py", line 28, in <module>
    main()
  File "/Users/csh/agi/sandbox/oneoff/try_vec_env.py", line 22, in main
    obs, rews, dones, infos = venv.step(venv.action_space.sample())
  File "/Users/csh/agi/gym/gym/vector/vector_env.py", line 54, in step
    return self.step_wait()
  File "/Users/csh/agi/gym/gym/vector/async_vector_env.py", line 223, in step_wait
    if not self._poll(timeout):
  File "/Users/csh/agi/gym/gym/vector/async_vector_env.py", line 296, in _poll
    if pipe.closed or (not pipe.poll(delta)):
  File "/Users/csh/miniconda3/envs/py37/lib/python3.7/multiprocessing/connection.py", line 257, in poll
    return self._poll(timeout)
  File "/Users/csh/miniconda3/envs/py37/lib/python3.7/multiprocessing/connection.py", line 414, in _poll
Traceback (most recent call last):
  File "/Users/csh/miniconda3/envs/py37/lib/python3.7/multiprocessing/process.py", line 297, in _bootstrap
    self.run()
  File "/Users/csh/miniconda3/envs/py37/lib/python3.7/multiprocessing/process.py", line 99, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/csh/agi/gym/gym/vector/async_vector_env.py", line 387, in _worker_shared_memory
    observation_space)
  File "/Users/csh/agi/gym/gym/vector/utils/shared_memory.py", line 131, in write_to_shared_memory
    write_base_to_shared_memory(index, value, shared_memory, space)
  File "/Users/csh/agi/gym/gym/vector/utils/shared_memory.py", line 142, in write_base_to_shared_memory
    dtype=space.dtype).flatten()
  File "/Users/csh/miniconda3/envs/py37/lib/python3.7/multiprocessing/sharedctypes.py", line 227, in __setitem__
    self._obj[i] = value
KeyboardInterrupt
    r = wait([self], timeout)
  File "/Users/csh/miniconda3/envs/py37/lib/python3.7/multiprocessing/connection.py", line 920, in wait
    ready = selector.select(timeout)
  File "/Users/csh/miniconda3/envs/py37/lib/python3.7/selectors.py", line 415, in select
Traceback (most recent call last):
  File "/Users/csh/miniconda3/envs/py37/lib/python3.7/multiprocessing/process.py", line 297, in _bootstrap
    self.run()
  File "/Users/csh/miniconda3/envs/py37/lib/python3.7/multiprocessing/process.py", line 99, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/csh/agi/gym/gym/vector/async_vector_env.py", line 387, in _worker_shared_memory
    observation_space)
Traceback (most recent call last):
  File "/Users/csh/agi/gym/gym/vector/utils/shared_memory.py", line 131, in write_to_shared_memory
    write_base_to_shared_memory(index, value, shared_memory, space)
  File "/Users/csh/agi/gym/gym/vector/utils/shared_memory.py", line 142, in write_base_to_shared_memory
    dtype=space.dtype).flatten()
  File "/Users/csh/miniconda3/envs/py37/lib/python3.7/multiprocessing/sharedctypes.py", line 226, in __setitem__
    with self:
  File "/Users/csh/miniconda3/envs/py37/lib/python3.7/multiprocessing/sharedctypes.py", line 193, in __enter__
    return self._lock.__enter__()
  File "/Users/csh/miniconda3/envs/py37/lib/python3.7/multiprocessing/synchronize.py", line 95, in __enter__
    return self._semlock.__enter__()
KeyboardInterrupt
  File "/Users/csh/miniconda3/envs/py37/lib/python3.7/multiprocessing/process.py", line 297, in _bootstrap
    self.run()
  File "/Users/csh/miniconda3/envs/py37/lib/python3.7/multiprocessing/process.py", line 99, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/csh/agi/gym/gym/vector/async_vector_env.py", line 387, in _worker_shared_memory
    observation_space)
  File "/Users/csh/agi/gym/gym/vector/utils/shared_memory.py", line 131, in write_to_shared_memory
    write_base_to_shared_memory(index, value, shared_memory, space)
  File "/Users/csh/agi/gym/gym/vector/utils/shared_memory.py", line 142, in write_base_to_shared_memory
    dtype=space.dtype).flatten()
  File "/Users/csh/miniconda3/envs/py37/lib/python3.7/multiprocessing/sharedctypes.py", line 226, in __setitem__
    with self:
  File "/Users/csh/miniconda3/envs/py37/lib/python3.7/multiprocessing/sharedctypes.py", line 193, in __enter__
    return self._lock.__enter__()
  File "/Users/csh/miniconda3/envs/py37/lib/python3.7/multiprocessing/synchronize.py", line 95, in __enter__
    return self._semlock.__enter__()
KeyboardInterrupt
    fd_event_list = self._selector.poll(timeout)
KeyboardInterrupt
/Users/csh/agi/gym/gym/logger.py:30: UserWarning: WARN: Calling `close` while waiting for a pending call to `step` to complete.
  warnings.warn(colorize('%s: %s'%('WARN', msg % args), 'yellow'))
Exception ignored in: <function AsyncVectorEnv.__del__ at 0x10903f950>
Traceback (most recent call last):
  File "/Users/csh/agi/gym/gym/vector/async_vector_env.py", line 332, in __del__
    self.close(terminate=True)
  File "/Users/csh/agi/gym/gym/vector/async_vector_env.py", line 265, in close
    function(timeout)
  File "/Users/csh/agi/gym/gym/vector/async_vector_env.py", line 229, in step_wait
    results = [pipe.recv() for pipe in self.parent_pipes]
  File "/Users/csh/agi/gym/gym/vector/async_vector_env.py", line 229, in <listcomp>
    results = [pipe.recv() for pipe in self.parent_pipes]
  File "/Users/csh/miniconda3/envs/py37/lib/python3.7/multiprocessing/connection.py", line 250, in recv
    buf = self._recv_bytes()
  File "/Users/csh/miniconda3/envs/py37/lib/python3.7/multiprocessing/connection.py", line 407, in _recv_bytes
    buf = self._recv(4)
  File "/Users/csh/miniconda3/envs/py37/lib/python3.7/multiprocessing/connection.py", line 383, in _recv
    raise EOFError
EOFError: 
```


Discussion:

Resolving patch:
diff --git a/gym/vector/async_vector_env.py b/gym/vector/async_vector_env.py
--- a/gym/vector/async_vector_env.py
+++ b/gym/vector/async_vector_env.py
@@ -359,7 +359,7 @@ def _worker(index, env_fn, pipe, parent_pipe, shared_memory, error_queue):
                 raise RuntimeError('Received unknown command `{0}`. Must '
                     'be one of {`reset`, `step`, `seed`, `close`, '
                     '`_check_observation_space`}.'.format(command))
-    except Exception:
+    except (KeyboardInterrupt, Exception):
         error_queue.put((index,) + sys.exc_info()[:2])
         pipe.send(None)
     finally:
@@ -398,7 +398,7 @@ def _worker_shared_memory(index, env_fn, pipe, parent_pipe, shared_memory, error
                 raise RuntimeError('Received unknown command `{0}`. Must '
                     'be one of {`reset`, `step`, `seed`, `close`, '
                     '`_check_observation_space`}.'.format(command))
-    except Exception:
+    except (KeyboardInterrupt, Exception):
         error_queue.put((index,) + sys.exc_info()[:2])
         pipe.send(None)
     finally:


Test patch: