OSError:[WinError 6]从Python 3.6调用子进程时句柄无效

时间:2017-11-28 15:52:30

标签: python python-3.x subprocess

我正在将项目移植到Python3,我在Windows上遇到意外错误:

基本上在Windows上的Python 3.6上,每次使用子进程创建进程时,我都会遇到以下异常:

d:\temp\backpack\venv\myvenv_py3.6\lib\site-packages\git\cmd.py:1011: in _call_process
    return self.execute(call, **exec_kwargs)
d:\temp\backpack\venv\myvenv_py3.6\lib\site-packages\git\cmd.py:732: in execute
    **subprocess_kwargs
D:\temp\cpython-3.6.3\Lib\subprocess.py:611: in __init__
    _cleanup()
D:\temp\cpython-3.6.3\Lib\subprocess.py:220: in _cleanup
    res = inst._internal_poll(_deadstate=sys.maxsize)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <subprocess.Popen object at 0x0000000004FD53C8>
_deadstate = 9223372036854775807
_WaitForSingleObject = <built-in function WaitForSingleObject>
_WAIT_OBJECT_0 = 0, _GetExitCodeProcess = <built-in function GetExitCodeProcess>

    def _internal_poll(self, _deadstate=None,
            _WaitForSingleObject=_winapi.WaitForSingleObject,
            _WAIT_OBJECT_0=_winapi.WAIT_OBJECT_0,
            _GetExitCodeProcess=_winapi.GetExitCodeProcess):
        """Check if child process has terminated.  Returns returncode
                attribute.

                This method is called by __del__, so it can only refer to objects
                in its local scope.

                """
        _log.debug('proc._internal_poll  self.pid=%s  self._handle=%s  self.returncode=%s  self=%s', self.pid, self._handle, self.returncode, self)
        if self.returncode is None:
>           if _WaitForSingleObject(self._handle, 0) == _WAIT_OBJECT_0:
E           OSError: [WinError 6] The handle is invalid

D:\temp\cpython-3.6.3\Lib\subprocess.py:1051: OSError

创建subprocess调用的位置无关紧要(在此项目中,GitPython包和plumbum包含了很多内容。

此执行发生在这个伞下:build script调用venv/Scripts/coverage run -m pytest -v tests/。但我也尝试pytest-covvenv/Scripts/pytest --cov=mypackage --cov-config .coveragerc - tests/ 在复制方面:

  • 在我的Win 7 PC上总是传递 :(
  • 在Win 7虚拟机上
    • 当[<build script>调用venv/Scripts/coverage run -m pytest]
    • 时,始终失败
    • 当直接从venv调用coverage run -m pytest总是失败
    • 但直接从virtualenv
    • 调用pytest时始终传递
  • 在Win 10 PC上,无论调用<build script>,还是直接调用coveragepytest,它总是失败 venv

我到目前为止唯一的线索来自这个StackOverflow线程:https://stackoverflow.com/a/43975118 更确切地说,它是第一个被接受的答案的评论,指出与_cleanup模块中的subprocess方法相关的有用的东西。

1 个答案:

答案 0 :(得分:2)

经过一段时间的停顿后,我很快找到了背后的原因。

这是因为项目中的GitPython用法未调用git.Repo.close()或使用git.Repo作为上下文管理器。 GitPython自述文件上有一个warning about this

subprocess的{​​{1}}方法中添加日志记录有助于了解哪个进程(_internal_poll)是罪魁祸首。对于args,它是GitPython ...