OSError: [WinError 6] дескриптор недопустим при вызове подпроцесса из Python 3.6

я портирую проект на Python3, и я сталкиваюсь с неожиданной ошибкой в Windows:

в основном на Python 3.6 В Windows, каждый раз, когда процесс создается с подпроцессом, у меня есть это исключение:

d:tempbackpackvenvmyvenv_py3.6libsite-packagesgitcmd.py:1011: in _call_process
    return self.execute(call, **exec_kwargs)
d:tempbackpackvenvmyvenv_py3.6libsite-packagesgitcmd.py:732: in execute
    **subprocess_kwargs
D:tempcpython-3.6.3Libsubprocess.py:611: in __init__
    _cleanup()
D:tempcpython-3.6.3Libsubprocess.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:tempcpython-3.6.3Libsubprocess.py:1051: OSError

не имеет значения, где subprocess вызов создается из (в этом проекте это много из GitPython пакета из plumbum).

это исполнение происходит под этим зонтиком:build script вызывает venv/Scripts/coverage run -m pytest -v tests/. Но Я также пробовал pytest-cov С venv/Scripts/pytest --cov=mypackage --cov-config .coveragerc - tests/ В плане воспроизводства:

  • на моем Win 7 PC это всегда передает: (
  • на виртуальной машине Win 7:
    • всегда не когда [<build script> вызывает venv/Scripts/coverage run -m pytest]
    • всегда не, когда coverage run -m pytest вызывается непосредственно из venv
    • но это всегда передает, когда pytest вызывается непосредственно из виртуальное окружение
  • на ПК Win 10 он всегда будет не, ни в <build script> вызывается, или если coverage или pytest вызываются непосредственно из venv

единственная подсказка, которую я получил до сих пор, - это поток StackOverflow:https://stackoverflow.com/a/43975118 а если быть более точным, это-комментарии от первого принятого ответа, которые указывают на что-то полезное, связанных с _cleanup метод из subprocess модуль.

1 ответов


после небольшой паузы, я быстро нашел причину этого.

это было из-за GitPython использование в проекте, который не называл git.Repo.close() или использовать git.Repo как контекст-менеджера. Есть предупреждение об этом on GitPython's readme.

было полезно добавить вход в subprocess ' s _internal_poll метод, чтобы узнать, какой процесс (args) является виновником. Для GitPython Он был git cat-file ...