【问题标题】:OSError: [WinError 6] The handle is invalid when calling subprocess from Python 3.6OSError: [WinError 6] 从 Python 3.6 调用子进程时句柄无效
【发布时间】:2018-05-12 03:39:15
【问题描述】:

我正在将一个项目移植到 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 虚拟机上:
    • 当 [&lt;build script&gt; 调用 venv/Scripts/coverage run -m pytest] 时,它总是失败
    • 当直接从 venv 调用 coverage run -m pytest 时,它总是失败
    • 但当直接从 virtualenv 调用 pytest 时,它总是通过
  • 在 Win 10 PC 上,无论是调用 &lt;build script&gt;,还是直接从 venv 调用 coveragepytest,它总是失败

到目前为止,我得到的唯一线索来自这个 StackOverflow 线程:https://stackoverflow.com/a/43975118 更准确地说,是第一个接受的答案中的 cmets 指向了与 subprocess 模块中的 _cleanup 方法相关的有用信息。

【问题讨论】:

标签: python python-3.x subprocess


【解决方案1】:

稍作停顿,我很快就找到了原因。

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

subprocess_internal_poll 方法中添加日志记录有助于了解哪个进程(args)是罪魁祸首。对于GitPython,它是git cat-file ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-24
    • 2017-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多