diff --git a/.github/workflows/cygwin-test.yml b/.github/workflows/cygwin-test.yml index 89c03a394..96728e51a 100644 --- a/.github/workflows/cygwin-test.yml +++ b/.github/workflows/cygwin-test.yml @@ -72,7 +72,7 @@ jobs: python --version python -c 'import sys; print(sys.platform)' python -c 'import os; print(os.name)' - python -c 'import git; print(git.compat.is_win)' + python -c 'import git; print(git.compat.is_win)' # NOTE: Deprecated. Use os.name directly. - name: Test with pytest run: | diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index 2dd97183b..35fecf16c 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -63,7 +63,7 @@ jobs: python --version python -c 'import sys; print(sys.platform)' python -c 'import os; print(os.name)' - python -c 'import git; print(git.compat.is_win)' + python -c 'import git; print(git.compat.is_win)' # NOTE: Deprecated. Use os.name directly. - name: Check types with mypy run: | diff --git a/git/cmd.py b/git/cmd.py index fd39a8eeb..f052c72cf 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -17,19 +17,21 @@ import threading from textwrap import dedent -from git.compat import ( - defenc, - force_bytes, - safe_decode, - is_posix, - is_win, +from git.compat import defenc, force_bytes, safe_decode +from git.exc import ( + CommandError, + GitCommandError, + GitCommandNotFound, + UnsafeOptionError, + UnsafeProtocolError, ) -from git.exc import CommandError -from git.util import is_cygwin_git, cygpath, expand_path, remove_password_if_present, patch_env - -from .exc import GitCommandError, GitCommandNotFound, UnsafeOptionError, UnsafeProtocolError -from .util import ( +from git.util import ( LazyMixin, + cygpath, + expand_path, + is_cygwin_git, + patch_env, + remove_password_if_present, stream_copy, ) @@ -180,14 +182,13 @@ def pump_stream( t.start() threads.append(t) - ## FIXME: Why Join?? Will block if `stdin` needs feeding... - # + # FIXME: Why join? Will block if stdin needs feeding... for t in threads: t.join(timeout=kill_after_timeout) if t.is_alive(): if isinstance(process, Git.AutoInterrupt): process._terminate() - else: # Don't want to deal with the other case + else: # Don't want to deal with the other case. raise RuntimeError( "Thread join() timed out in cmd.handle_process_output()." f" kill_after_timeout={kill_after_timeout} seconds" @@ -197,11 +198,11 @@ def pump_stream( "error: process killed because it timed out." f" kill_after_timeout={kill_after_timeout} seconds" ) if not decode_streams and isinstance(p_stderr, BinaryIO): - # Assume stderr_handler needs binary input + # Assume stderr_handler needs binary input. error_str = cast(str, error_str) error_str = error_str.encode() # We ignore typing on the next line because mypy does not like - # the way we inferred that stderr takes str or bytes + # the way we inferred that stderr takes str or bytes. stderr_handler(error_str) # type: ignore if finalizer: @@ -228,14 +229,12 @@ def dict_to_slots_and__excluded_are_none(self: object, d: Mapping[str, Any], exc ## -- End Utilities -- @} -# value of Windows process creation flag taken from MSDN -CREATE_NO_WINDOW = 0x08000000 - -## CREATE_NEW_PROCESS_GROUP is needed to allow killing it afterwards, -# see https://docs.python.org/3/library/subprocess.html#subprocess.Popen.send_signal -PROC_CREATIONFLAGS = ( - CREATE_NO_WINDOW | subprocess.CREATE_NEW_PROCESS_GROUP if is_win else 0 # type: ignore[attr-defined] -) # mypy error if not Windows. +if os.name == "nt": + # CREATE_NEW_PROCESS_GROUP is needed to allow killing it afterwards. See: + # https://docs.python.org/3/library/subprocess.html#subprocess.Popen.send_signal + PROC_CREATIONFLAGS = subprocess.CREATE_NO_WINDOW | subprocess.CREATE_NEW_PROCESS_GROUP +else: + PROC_CREATIONFLAGS = 0 class Git(LazyMixin): @@ -551,7 +550,7 @@ def _terminate(self) -> None: # For some reason, providing None for stdout/stderr still prints something. This is why # we simply use the shell and redirect to nul. Slower than CreateProcess. The question # is whether we really want to see all these messages. It's annoying no matter what. - if is_win: + if os.name == "nt": call( ("TASKKILL /F /T /PID %s 2>nul 1>nul" % str(proc.pid)), shell=True, @@ -967,7 +966,7 @@ def execute( if inline_env is not None: env.update(inline_env) - if is_win: + if os.name == "nt": cmd_not_found_exception = OSError if kill_after_timeout is not None: raise GitCommandError( @@ -999,11 +998,11 @@ def execute( env=env, cwd=cwd, bufsize=-1, - stdin=istream or DEVNULL, + stdin=(istream or DEVNULL), stderr=PIPE, stdout=stdout_sink, shell=shell, - close_fds=is_posix, # Unsupported on Windows. + close_fds=(os.name == "posix"), # Unsupported on Windows. universal_newlines=universal_newlines, creationflags=PROC_CREATIONFLAGS, **subprocess_kwargs, @@ -1073,7 +1072,7 @@ def kill_process(pid: int) -> None: ) if not universal_newlines: stderr_value = stderr_value.encode(defenc) - # strip trailing "\n" + # Strip trailing "\n". if stdout_value.endswith(newline) and strip_newline_in_stdout: # type: ignore stdout_value = stdout_value[:-1] if stderr_value.endswith(newline): # type: ignore @@ -1147,11 +1146,11 @@ def update_environment(self, **kwargs: Any) -> Dict[str, Union[str, None]]: """ old_env = {} for key, value in kwargs.items(): - # set value if it is None + # Set value if it is None. if value is not None: old_env[key] = self._environment.get(key) self._environment[key] = value - # remove key from environment if its value is None + # Remove key from environment if its value is None. elif key in self._environment: old_env[key] = self._environment[key] del self._environment[key] @@ -1330,7 +1329,8 @@ def _parse_object_header(self, header_line: str) -> Tuple[str, str, int]: :return: (hex_sha, type_string, size_as_int) :raise ValueError: If the header contains indication for an error due to - incorrect input sha""" + incorrect input sha + """ tokens = header_line.split() if len(tokens) != 3: if not tokens: diff --git a/git/compat.py b/git/compat.py index f17e52f7b..629be075a 100644 --- a/git/compat.py +++ b/git/compat.py @@ -34,9 +34,17 @@ # --------------------------------------------------------------------------- -is_win: bool = os.name == "nt" +# DEPRECATED attributes providing shortcuts to operating system checks based on os.name. +# +# These are deprecated because it is clearer, and helps avoid bugs, to write out the +# os.name or sys.platform checks explicitly, especially in cases where it matters which +# is used. For example, is_win is False on Cygwin, but is often assumed True. To detect +# Cygwin, use sys.platform == "cygwin". (Also, in the past, is_darwin was unreliable.) +# +is_win = os.name == "nt" is_posix = os.name == "posix" -is_darwin = os.name == "darwin" +is_darwin = sys.platform == "darwin" + defenc = sys.getfilesystemencoding() diff --git a/git/config.py b/git/config.py index 2cb057021..0846bbf94 100644 --- a/git/config.py +++ b/git/config.py @@ -7,28 +7,21 @@ """Module containing module parser implementation able to properly read and write configuration files.""" -import sys import abc +import configparser as cp +import fnmatch from functools import wraps import inspect from io import BufferedReader, IOBase import logging import os +import os.path as osp import re -import fnmatch - -from git.compat import ( - defenc, - force_text, - is_win, -) +import sys +from git.compat import defenc, force_text from git.util import LockFile -import os.path as osp - -import configparser as cp - # typing------------------------------------------------------- from typing import ( @@ -250,7 +243,7 @@ def items_all(self) -> List[Tuple[str, List[_T]]]: def get_config_path(config_level: Lit_config_levels) -> str: # We do not support an absolute path of the gitconfig on Windows. # Use the global config instead. - if is_win and config_level == "system": + if os.name == "nt" and config_level == "system": config_level = "global" if config_level == "system": diff --git a/git/index/fun.py b/git/index/fun.py index a35990d6d..fe8f373d8 100644 --- a/git/index/fun.py +++ b/git/index/fun.py @@ -2,8 +2,9 @@ # NOTE: Autodoc hates it if this is a docstring. from io import BytesIO -from pathlib import Path import os +import os.path as osp +from pathlib import Path from stat import ( S_IFDIR, S_IFLNK, @@ -16,26 +17,17 @@ import subprocess from git.cmd import PROC_CREATIONFLAGS, handle_process_output -from git.compat import ( - defenc, - force_text, - force_bytes, - is_posix, - is_win, - safe_decode, -) -from git.exc import UnmergedEntriesError, HookExecutionError +from git.compat import defenc, force_bytes, force_text, safe_decode +from git.exc import HookExecutionError, UnmergedEntriesError from git.objects.fun import ( - tree_to_stream, traverse_tree_recursive, traverse_trees_recursive, + tree_to_stream, ) from git.util import IndexFileSHA1Writer, finalize_process from gitdb.base import IStream from gitdb.typ import str_tree_type -import os.path as osp - from .typ import BaseIndexEntry, IndexEntry, CE_NAMEMASK, CE_STAGESHIFT from .util import pack, unpack @@ -96,7 +88,7 @@ def run_commit_hook(name: str, index: "IndexFile", *args: str) -> None: env["GIT_EDITOR"] = ":" cmd = [hp] try: - if is_win and not _has_file_extension(hp): + if os.name == "nt" and not _has_file_extension(hp): # Windows only uses extensions to determine how to open files # (doesn't understand shebangs). Try using bash to run the hook. relative_hp = Path(hp).relative_to(index.repo.working_dir).as_posix() @@ -108,7 +100,7 @@ def run_commit_hook(name: str, index: "IndexFile", *args: str) -> None: stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=index.repo.working_dir, - close_fds=is_posix, + close_fds=(os.name == "posix"), creationflags=PROC_CREATIONFLAGS, ) except Exception as ex: diff --git a/git/index/util.py b/git/index/util.py index 08e49d860..5c2270abd 100644 --- a/git/index/util.py +++ b/git/index/util.py @@ -2,15 +2,11 @@ from functools import wraps import os +import os.path as osp import struct import tempfile from types import TracebackType -from git.compat import is_win - -import os.path as osp - - # typing ---------------------------------------------------------------------- from typing import Any, Callable, TYPE_CHECKING, Optional, Type @@ -58,7 +54,7 @@ def __exit__( exc_tb: Optional[TracebackType], ) -> bool: if osp.isfile(self.tmp_file_path): - if is_win and osp.exists(self.file_path): + if os.name == "nt" and osp.exists(self.file_path): os.remove(self.file_path) os.rename(self.tmp_file_path, self.file_path) diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index 1516306ec..d88524ecb 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -7,7 +7,7 @@ import git from git.cmd import Git -from git.compat import defenc, is_win +from git.compat import defenc from git.config import GitConfigParser, SectionConstraint, cp from git.exc import ( BadName, @@ -353,9 +353,8 @@ def _write_git_file_and_module_config(cls, working_tree_dir: PathLike, module_ab """ git_file = osp.join(working_tree_dir, ".git") rela_path = osp.relpath(module_abspath, start=working_tree_dir) - if is_win: - if osp.isfile(git_file): - os.remove(git_file) + if os.name == "nt" and osp.isfile(git_file): + os.remove(git_file) with open(git_file, "wb") as fp: fp.write(("gitdir: %s" % rela_path).encode(defenc)) diff --git a/git/repo/base.py b/git/repo/base.py index 4790ea4e7..bbbf242db 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -6,24 +6,21 @@ from __future__ import annotations +import gc import logging import os +import os.path as osp +from pathlib import Path import re import shlex import warnings -from pathlib import Path - +import gitdb from gitdb.db.loose import LooseObjectDB - from gitdb.exc import BadObject from git.cmd import Git, handle_process_output -from git.compat import ( - defenc, - safe_decode, - is_win, -) +from git.compat import defenc, safe_decode from git.config import GitConfigParser from git.db import GitCmdObjectDB from git.exc import ( @@ -43,7 +40,6 @@ expand_path, remove_password_if_present, ) -import os.path as osp from .fun import ( rev_parse, @@ -52,8 +48,6 @@ touch, find_worktree_git_dir, ) -import gc -import gitdb # typing ------------------------------------------------------ @@ -322,10 +316,10 @@ def close(self) -> None: # they are collected by the garbage collector, thus preventing deletion. # TODO: Find these references and ensure they are closed and deleted # synchronously rather than forcing a gc collection. - if is_win: + if os.name == "nt": gc.collect() gitdb.util.mman.collect() - if is_win: + if os.name == "nt": gc.collect() def __eq__(self, rhs: object) -> bool: @@ -571,7 +565,7 @@ def _get_config_path(self, config_level: Lit_config_levels, git_dir: Optional[Pa git_dir = self.git_dir # We do not support an absolute path of the gitconfig on Windows. # Use the global config instead. - if is_win and config_level == "system": + if os.name == "nt" and config_level == "system": config_level = "global" if config_level == "system": diff --git a/git/util.py b/git/util.py index bd1fbe247..be267fc9f 100644 --- a/git/util.py +++ b/git/util.py @@ -22,8 +22,6 @@ from urllib.parse import urlsplit, urlunsplit import warnings -from .compat import is_win - # typing --------------------------------------------------------- from typing import ( @@ -110,7 +108,18 @@ log = logging.getLogger(__name__) -def _read_env_flag(name: str, default: bool) -> bool: +def _read_win_env_flag(name: str, default: bool) -> bool: + """Read a boolean flag from an environment variable on Windows. + + :return: + On Windows, the flag, or the ``default`` value if absent or ambiguous. + On all other operating systems, ``False``. + + :note: This only accesses the environment on Windows. + """ + if os.name != "nt": + return False + try: value = os.environ[name] except KeyError: @@ -134,8 +143,8 @@ def _read_env_flag(name: str, default: bool) -> bool: #: We need an easy way to see if Appveyor TCs start failing, #: so the errors marked with this var are considered "acknowledged" ones, awaiting remedy, #: till then, we wish to hide them. -HIDE_WINDOWS_KNOWN_ERRORS = is_win and _read_env_flag("HIDE_WINDOWS_KNOWN_ERRORS", True) -HIDE_WINDOWS_FREEZE_ERRORS = is_win and _read_env_flag("HIDE_WINDOWS_FREEZE_ERRORS", True) +HIDE_WINDOWS_KNOWN_ERRORS = _read_win_env_flag("HIDE_WINDOWS_KNOWN_ERRORS", True) +HIDE_WINDOWS_FREEZE_ERRORS = _read_win_env_flag("HIDE_WINDOWS_FREEZE_ERRORS", True) # { Utility Methods @@ -220,7 +229,7 @@ def handler(function: Callable, path: PathLike, _excinfo: Any) -> None: def rmfile(path: PathLike) -> None: """Ensure file deleted also on *Windows* where read-only files need special treatment.""" if osp.isfile(path): - if is_win: + if os.name == "nt": os.chmod(path, 0o777) os.remove(path) @@ -260,7 +269,7 @@ def join_path(a: PathLike, *p: PathLike) -> PathLike: return path -if is_win: +if os.name == "nt": def to_native_path_windows(path: PathLike) -> PathLike: path = str(path) @@ -308,9 +317,12 @@ def assure_directory_exists(path: PathLike, is_file: bool = False) -> bool: def _get_exe_extensions() -> Sequence[str]: PATHEXT = os.environ.get("PATHEXT", None) - return ( - tuple(p.upper() for p in PATHEXT.split(os.pathsep)) if PATHEXT else (".BAT", "COM", ".EXE") if is_win else ("") - ) + if PATHEXT: + return tuple(p.upper() for p in PATHEXT.split(os.pathsep)) + elif os.name == "nt": + return (".BAT", "COM", ".EXE") + else: + return () def py_where(program: str, path: Optional[PathLike] = None) -> List[str]: @@ -418,8 +430,8 @@ def is_cygwin_git(git_executable: PathLike) -> bool: def is_cygwin_git(git_executable: Union[None, PathLike]) -> bool: - if is_win: - # is_win is only True on native Windows systems. On Cygwin, os.name == "posix". + if os.name == "nt": + # This is Windows-native Python, since Cygwin has os.name == "posix". return False if git_executable is None: diff --git a/test/lib/helper.py b/test/lib/helper.py index 8725cd13f..950ca3c0b 100644 --- a/test/lib/helper.py +++ b/test/lib/helper.py @@ -10,17 +10,15 @@ import io import logging import os +import os.path as osp import tempfile import textwrap import time import unittest -from git.compat import is_win -from git.util import rmtree, cwd import gitdb -import os.path as osp - +from git.util import rmtree, cwd TestCase = unittest.TestCase SkipTest = unittest.SkipTest @@ -177,7 +175,7 @@ def git_daemon_launched(base_path, ip, port): gd = None try: - if is_win: + if os.name == "nt": # On MINGW-git, daemon exists in Git\mingw64\libexec\git-core\, # but if invoked as 'git daemon', it detaches from parent `git` cmd, # and then CANNOT DIE! @@ -201,7 +199,7 @@ def git_daemon_launched(base_path, ip, port): as_process=True, ) # Yes, I know... fortunately, this is always going to work if sleep time is just large enough. - time.sleep(0.5 * (1 + is_win)) + time.sleep(1.0 if os.name == "nt" else 0.5) except Exception as ex: msg = textwrap.dedent( """ diff --git a/test/test_base.py b/test/test_base.py index e4704c7d8..302d696fe 100644 --- a/test/test_base.py +++ b/test/test_base.py @@ -11,7 +11,6 @@ from git import Repo from git.objects import Blob, Tree, Commit, TagObject -from git.compat import is_win from git.objects.util import get_object_type_by_name from test.lib import TestBase as _TestBase, with_rw_repo, with_rw_and_rw_remote_repo from git.util import hex_to_bin, HIDE_WINDOWS_FREEZE_ERRORS @@ -131,7 +130,7 @@ def test_add_unicode(self, rw_repo): with open(file_path, "wb") as fp: fp.write(b"something") - if is_win: + if os.name == "nt": # On Windows, there is no way this works, see images on: # https://github.com/gitpython-developers/GitPython/issues/147#issuecomment-68881897 # Therefore, it must be added using the Python implementation. diff --git a/test/test_git.py b/test/test_git.py index 06f8f5c97..b85be6359 100644 --- a/test/test_git.py +++ b/test/test_git.py @@ -23,7 +23,6 @@ import ddt from git import Git, refresh, GitCommandError, GitCommandNotFound, Repo, cmd -from git.compat import is_win from git.util import cwd, finalize_process from test.lib import TestBase, fixture_path, with_rw_directory @@ -139,7 +138,7 @@ def test_it_executes_git_and_returns_result(self): def test_it_executes_git_not_from_cwd(self): with TemporaryDirectory() as tmpdir: - if is_win: + if os.name == "nt": # Copy an actual binary executable that is not git. other_exe_path = os.path.join(os.getenv("WINDIR"), "system32", "hostname.exe") impostor_path = os.path.join(tmpdir, "git.exe") @@ -154,7 +153,10 @@ def test_it_executes_git_not_from_cwd(self): with cwd(tmpdir): self.assertRegex(self.git.execute(["git", "version"]), r"^git version\b") - @skipUnless(is_win, "The regression only affected Windows, and this test logic is OS-specific.") + @skipUnless( + os.name == "nt", + "The regression only affected Windows, and this test logic is OS-specific.", + ) def test_it_avoids_upcasing_unrelated_environment_variable_names(self): old_name = "28f425ca_d5d8_4257_b013_8d63166c8158" if old_name == old_name.upper(): @@ -268,7 +270,7 @@ def test_refresh(self): self.assertRaises(GitCommandNotFound, refresh, "yada") # Test a good path refresh. - which_cmd = "where" if is_win else "command -v" + which_cmd = "where" if os.name == "nt" else "command -v" path = os.popen("{0} git".format(which_cmd)).read().strip().split("\n")[0] refresh(path) diff --git a/test/test_index.py b/test/test_index.py index 3357dc880..b9d1e78ab 100644 --- a/test/test_index.py +++ b/test/test_index.py @@ -25,7 +25,6 @@ GitCommandError, CheckoutError, ) -from git.compat import is_win from git.exc import HookExecutionError, InvalidGitRepositoryError from git.index.fun import hook_path from git.index.typ import BaseIndexEntry, IndexEntry @@ -43,9 +42,9 @@ def _found_in(cmd, directory): return path and Path(path).parent == Path(directory) -is_win_without_bash = is_win and not shutil.which("bash.exe") +is_win_without_bash = os.name == "nt" and not shutil.which("bash.exe") -is_win_with_wsl_bash = is_win and _found_in( +is_win_with_wsl_bash = os.name == "nt" and _found_in( cmd="bash.exe", directory=Path(os.getenv("WINDIR")) / "System32", ) @@ -614,7 +613,7 @@ def mixed_iterator(): self.assertNotEqual(entries[0].hexsha, null_hex_sha) # Add symlink. - if not is_win: + if os.name != "nt": for target in ("/etc/nonexisting", "/etc/passwd", "/etc"): basename = "my_real_symlink" @@ -672,7 +671,7 @@ def mixed_iterator(): index.checkout(fake_symlink_path) # On Windows, we will never get symlinks. - if is_win: + if os.name == "nt": # Symlinks should contain the link as text (which is what a # symlink actually is). with open(fake_symlink_path, "rt") as fd: diff --git a/test/test_installation.py b/test/test_installation.py index e7774d29d..8e5f55d28 100644 --- a/test/test_installation.py +++ b/test/test_installation.py @@ -6,7 +6,6 @@ import subprocess import sys -from git.compat import is_win from test.lib import TestBase from test.lib.helper import with_rw_directory @@ -15,7 +14,7 @@ class TestInstallation(TestBase): def setUp_venv(self, rw_dir): self.venv = rw_dir subprocess.run([sys.executable, "-m", "venv", self.venv], stdout=subprocess.PIPE) - bin_name = "Scripts" if is_win else "bin" + bin_name = "Scripts" if os.name == "nt" else "bin" self.python = os.path.join(self.venv, bin_name, "python") self.pip = os.path.join(self.venv, bin_name, "pip") self.sources = os.path.join(self.venv, "src") diff --git a/test/test_submodule.py b/test/test_submodule.py index f63db1495..f706769c0 100644 --- a/test/test_submodule.py +++ b/test/test_submodule.py @@ -3,17 +3,17 @@ import contextlib import os -import shutil -import tempfile +import os.path as osp from pathlib import Path +import shutil import sys +import tempfile from unittest import mock, skipUnless import pytest import git from git.cmd import Git -from git.compat import is_win from git.config import GitConfigParser, cp from git.exc import ( GitCommandError, @@ -25,11 +25,8 @@ from git.objects.submodule.base import Submodule from git.objects.submodule.root import RootModule, RootUpdateProgress from git.repo.fun import find_submodule_git_dir, touch -from test.lib import TestBase, with_rw_repo -from test.lib import with_rw_directory -from git.util import HIDE_WINDOWS_KNOWN_ERRORS -from git.util import to_native_path_linux, join_path_native -import os.path as osp +from git.util import HIDE_WINDOWS_KNOWN_ERRORS, join_path_native, to_native_path_linux +from test.lib import TestBase, with_rw_directory, with_rw_repo @contextlib.contextmanager @@ -1040,7 +1037,7 @@ def test_branch_renames(self, rw_dir): assert sm_mod.commit() == sm_pfb.commit, "Now head should have been reset" assert sm_mod.head.ref.name == sm_pfb.name - @skipUnless(is_win, "Specifically for Windows.") + @skipUnless(os.name == "nt", "Specifically for Windows.") def test_to_relative_path_with_super_at_root_drive(self): class Repo: working_tree_dir = "D:\\" diff --git a/test/test_util.py b/test/test_util.py index d345247b1..4ef98fd73 100644 --- a/test/test_util.py +++ b/test/test_util.py @@ -20,7 +20,6 @@ import pytest from git.cmd import dashify -from git.compat import is_win from git.objects.util import ( altz_to_utctz_str, from_timestamp, @@ -364,7 +363,7 @@ def test_blocking_lock_file(self): self.assertRaises(IOError, wait_lock._obtain_lock) elapsed = time.time() - start extra_time = 0.02 - if is_win or sys.platform == "cygwin": + if os.name == "nt" or sys.platform == "cygwin": extra_time *= 6 # NOTE: Indeterministic failures without this... self.assertLess(elapsed, wait_time + extra_time) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy