Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork940
Description
GitPython supports and can be installed on native Windows systems (not just Cygwin), but theTestInstallation.test_installation
test intest/test_installation.py
always fails with aFileNotFoundError
. This is not caught on CI because, for Windows, only Cygwin currently has CI coverage. The test failure happens for two reasons:
- The test relies on the virtual environment having a
bin
directory, but on Windows this is calledScripts
. This is the immediate cause of the error, but if only this is fixed, a second, closely related incompatibility will cause the test to fail. - The test relies on the virtual environment having
python3
andpip3
commands, but Windows does not have these in virtual environments. Python virtual environments on all systems havepython
andpip
commands (even on systems such as Debian and Ubuntu where those commands are not available globally or whose global versions are part of a legacy Python 2 installation).
The following output is produced on Windows 10 using Python 3.11.5, installing GitPython from the tip of the main branch (c8e303f), but I believe the test would fail on all Windows systems with all versions of Python in the same way:
(.venv) C:\Users\ek\source\repos\GitPython [main ≡]> pytest --no-cov -k test_installationTest session starts (platform: win32, Python 3.11.5, pytest 7.4.2, pytest-sugar 0.9.7)rootdir: C:\Users\ek\source\repos\GitPythonconfigfile: pyproject.tomltestpaths: testplugins: cov-4.1.0, sugar-0.9.7collected 504 items / 503 deselected / 1 selected――――――――――――――――――――――――――――――――――――――――― TestInstallation.test_installation ――――――――――――――――――――――――――――――――――――――――――self = <test.test_installation.TestInstallation testMethod=test_installation>rw_dir = 'C:\\Users\\ek\\AppData\\Local\\Temp\\test_installatione9rg39ma' @with_rw_directory def test_installation(self, rw_dir): self.setUp_venv(rw_dir)> result = subprocess.run( [self.pip, "install", "-r", "requirements.txt"], stdout=subprocess.PIPE, cwd=self.sources, )test\test_installation.py:24:_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.1520.0_x64__qbz5n2kfra8p0\Lib\subprocess.py:548: in run with Popen(*popenargs, **kwargs) as process:C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.1520.0_x64__qbz5n2kfra8p0\Lib\subprocess.py:1026: in __init__ self._execute_child(args, executable, preexec_fn, close_fds,_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _self = <Popen: returncode: None args: ['C:\\Users\\ek\\AppData\\Local\\Temp\\test_i...>args = 'C:\\Users\\ek\\AppData\\Local\\Temp\\test_installatione9rg39ma\\bin/pip3 install -r requirements.txt'executable = None, preexec_fn = None, close_fds = False, pass_fds = ()cwd = 'C:\\Users\\ek\\AppData\\Local\\Temp\\test_installatione9rg39ma\\src', env = Nonestartupinfo = <subprocess.STARTUPINFO object at 0x000001B4D625B390>, creationflags = 0, shell = Falsep2cread = Handle(1292), p2cwrite = -1, c2pread = 15, c2pwrite = Handle(1396), errread = -1, errwrite = Handle(1416)unused_restore_signals = True, unused_gid = None, unused_gids = None, unused_uid = None, unused_umask = -1unused_start_new_session = False, unused_process_group = -1 def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, unused_restore_signals, unused_gid, unused_gids, unused_uid, unused_umask, unused_start_new_session, unused_process_group): """Execute program (MS Windows version)""" assert not pass_fds, "pass_fds not supported on Windows." if isinstance(args, str): pass elif isinstance(args, bytes): if shell: raise TypeError('bytes args is not allowed on Windows') args = list2cmdline([args]) elif isinstance(args, os.PathLike): if shell: raise TypeError('path-like args is not allowed when ' 'shell is true') args = list2cmdline([args]) else: args = list2cmdline(args) if executable is not None: executable = os.fsdecode(executable) # Process startup details if startupinfo is None: startupinfo = STARTUPINFO() else: # bpo-34044: Copy STARTUPINFO since it is modified above, # so the caller can reuse it multiple times. startupinfo = startupinfo.copy() use_std_handles = -1 not in (p2cread, c2pwrite, errwrite) if use_std_handles: startupinfo.dwFlags |= _winapi.STARTF_USESTDHANDLES startupinfo.hStdInput = p2cread startupinfo.hStdOutput = c2pwrite startupinfo.hStdError = errwrite attribute_list = startupinfo.lpAttributeList have_handle_list = bool(attribute_list and "handle_list" in attribute_list and attribute_list["handle_list"]) # If we were given an handle_list or need to create one if have_handle_list or (use_std_handles and close_fds): if attribute_list is None: attribute_list = startupinfo.lpAttributeList = {} handle_list = attribute_list["handle_list"] = \ list(attribute_list.get("handle_list", [])) if use_std_handles: handle_list += [int(p2cread), int(c2pwrite), int(errwrite)] handle_list[:] = self._filter_handle_list(handle_list) if handle_list: if not close_fds: warnings.warn("startupinfo.lpAttributeList['handle_list'] " "overriding close_fds", RuntimeWarning) # When using the handle_list we always request to inherit # handles but the only handles that will be inherited are # the ones in the handle_list close_fds = False if shell: startupinfo.dwFlags |= _winapi.STARTF_USESHOWWINDOW startupinfo.wShowWindow = _winapi.SW_HIDE if not executable: # gh-101283: without a fully-qualified path, before Windows # checks the system directories, it first looks in the # application directory, and also the current directory if # NeedCurrentDirectoryForExePathW(ExeName) is true, so try # to avoid executing unqualified "cmd.exe". comspec = os.environ.get('ComSpec') if not comspec: system_root = os.environ.get('SystemRoot', '') comspec = os.path.join(system_root, 'System32', 'cmd.exe') if not os.path.isabs(comspec): raise FileNotFoundError('shell not found: neither %ComSpec% nor %SystemRoot% is set') if os.path.isabs(comspec): executable = comspec else: comspec = executable args = '{} /c "{}"'.format (comspec, args) if cwd is not None: cwd = os.fsdecode(cwd) sys.audit("subprocess.Popen", executable, args, cwd, env) # Start the process try:> hp, ht, pid, tid = _winapi.CreateProcess(executable, args, # no special security None, None, int(not close_fds), creationflags, env, cwd, startupinfo)E FileNotFoundError: [WinError 2] The system cannot find the file specifiedC:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.1520.0_x64__qbz5n2kfra8p0\Lib\subprocess.py:1538: FileNotFoundError test/test_installation.py ⨯ 100% ██████████=============================================== short test summary info ===============================================FAILED test/test_installation.py::TestInstallation::test_installation - FileNotFoundError: [WinError 2] The system cannot find the file specifiedResults (7.00s): 1 failed - test/test_installation.py:21 TestInstallation.test_installation 503 deselected
I have also verified that this occurs on Python 3.12.0rc2 on Windows.#1640 affects Windows as much as other systems, but this specific issue causes the test to fail first.
I think it would make sense to fix this together with#1640, since a fix for that would include related changes totest_installation
. I've opened#1654 for this (which also fixes#1652 and#1653).