From 31ac93b2f38f2410e41bf90ad28dff31e79b114e Mon Sep 17 00:00:00 2001 From: Bodo Graumann Date: Thu, 20 Jul 2023 16:25:10 +0200 Subject: [PATCH 1/7] Do not typecheck submodule It has too many errors. Fixing them should be done in the separate project. --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 0d5ebf012..4d2014afb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,6 +29,7 @@ implicit_reexport = true # strict = true # TODO: remove when 'gitdb' is fully annotated +exclude = ["^git/ext/gitdb"] [[tool.mypy.overrides]] module = "gitdb.*" ignore_missing_imports = true From b55cf65cc96740c6128987ab0c07b43112bdfe31 Mon Sep 17 00:00:00 2001 From: Bodo Graumann Date: Thu, 20 Jul 2023 16:34:39 +0200 Subject: [PATCH 2/7] Define supported version for mypy --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 4d2014afb..57988372a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,6 +19,7 @@ filterwarnings = 'ignore::DeprecationWarning' # filterwarnings ignore::WarningType # ignores those warnings [tool.mypy] +python_version = "3.7" disallow_untyped_defs = true no_implicit_optional = true warn_redundant_casts = true From 76394d42ce2a33b4db71fd64763c1e9dae136747 Mon Sep 17 00:00:00 2001 From: Bodo Graumann Date: Thu, 20 Jul 2023 16:39:32 +0200 Subject: [PATCH 3/7] Ignore remaining [unreachable] type errors --- git/__init__.py | 2 +- git/config.py | 4 ++-- git/repo/base.py | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/git/__init__.py b/git/__init__.py index cd6602bf0..6196a42d7 100644 --- a/git/__init__.py +++ b/git/__init__.py @@ -76,7 +76,7 @@ def refresh(path: Optional[PathLike] = None) -> None: if not Git.refresh(path=path): return if not FetchInfo.refresh(): - return + return # type: ignore [unreachable] GIT_OK = True diff --git a/git/config.py b/git/config.py index e05a297af..caf1f6241 100644 --- a/git/config.py +++ b/git/config.py @@ -265,8 +265,8 @@ def get_config_path(config_level: Lit_config_levels) -> str: raise ValueError("No repo to get repository configuration from. Use Repo._get_config_path") else: # Should not reach here. Will raise ValueError if does. Static typing will warn missing elifs - assert_never( - config_level, # type: ignore[unreachable] + assert_never( # type: ignore[unreachable] + config_level, ValueError(f"Invalid configuration level: {config_level!r}"), ) diff --git a/git/repo/base.py b/git/repo/base.py index 1fa98d8c7..4bfead46f 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -549,8 +549,8 @@ def _get_config_path(self, config_level: Lit_config_levels, git_dir: Optional[Pa return osp.normpath(osp.join(repo_dir, "config")) else: - assert_never( - config_level, # type:ignore[unreachable] + assert_never( # type:ignore[unreachable] + config_level, ValueError(f"Invalid configuration level: {config_level!r}"), ) From c6dab191d1f96373aaae5c6c117f13c1006631de Mon Sep 17 00:00:00 2001 From: Bodo Graumann Date: Thu, 20 Jul 2023 16:49:02 +0200 Subject: [PATCH 4/7] Allow explicit casting even when slightly redundant --- git/cmd.py | 2 +- git/objects/commit.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/git/cmd.py b/git/cmd.py index dfce9024d..5b0b6b816 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -154,7 +154,7 @@ def pump_stream( p_stdout = process.proc.stdout if process.proc else None p_stderr = process.proc.stderr if process.proc else None else: - process = cast(Popen, process) + process = cast(Popen, process) # type: ignore [redundant-cast] cmdline = getattr(process, "args", "") p_stdout = process.stdout p_stderr = process.stderr diff --git a/git/objects/commit.py b/git/objects/commit.py index 138db0afe..6cca65c1f 100644 --- a/git/objects/commit.py +++ b/git/objects/commit.py @@ -460,7 +460,7 @@ def _iter_from_process_or_stream(cls, repo: "Repo", proc_or_stream: Union[Popen, if proc_or_stream.stdout is not None: stream = proc_or_stream.stdout elif hasattr(proc_or_stream, "readline"): - proc_or_stream = cast(IO, proc_or_stream) + proc_or_stream = cast(IO, proc_or_stream) # type: ignore [redundant-cast] stream = proc_or_stream readline = stream.readline From 6035db092decf72e6a01e175d044f0343818b51c Mon Sep 17 00:00:00 2001 From: Bodo Graumann Date: Thu, 20 Jul 2023 16:51:50 +0200 Subject: [PATCH 5/7] Run black and exclude submodule --- README.md | 2 ++ git/cmd.py | 7 ++----- git/config.py | 3 +-- git/diff.py | 3 +-- git/exc.py | 2 -- git/index/fun.py | 1 - git/objects/commit.py | 4 +--- git/objects/fun.py | 1 - git/objects/util.py | 2 +- git/remote.py | 1 - git/repo/base.py | 3 +-- git/util.py | 2 -- pyproject.toml | 1 + 13 files changed, 10 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 676d2c6d6..30c54b57f 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,8 @@ To typecheck, run: `mypy -p git` To test, run: `pytest` +For automatic code formatting run: `black git` + Configuration for flake8 is in the ./.flake8 file. Configurations for mypy, pytest and coverage.py are in ./pyproject.toml. diff --git a/git/cmd.py b/git/cmd.py index 5b0b6b816..84d888494 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -122,6 +122,7 @@ def handle_process_output( To specify a timeout in seconds for the git command, after which the process should be killed. """ + # Use 2 "pump" threads and wait for both to finish. def pump_stream( cmdline: List[str], @@ -488,10 +489,7 @@ def check_unsafe_options(cls, options: List[str], unsafe_options: List[str]) -> """ # Options can be of the form `foo` or `--foo bar` `--foo=bar`, # so we need to check if they start with "--foo" or if they are equal to "foo". - bare_unsafe_options = [ - option.lstrip("-") - for option in unsafe_options - ] + bare_unsafe_options = [option.lstrip("-") for option in unsafe_options] for option in options: for unsafe_option, bare_option in zip(unsafe_options, bare_unsafe_options): if option.startswith(unsafe_option) or option == bare_option: @@ -1194,7 +1192,6 @@ def transform_kwargs(self, split_single_char_options: bool = True, **kwargs: Any @classmethod def _unpack_args(cls, arg_list: Sequence[str]) -> List[str]: - outlist = [] if isinstance(arg_list, (list, tuple)): for arg in arg_list: diff --git a/git/config.py b/git/config.py index caf1f6241..1973111eb 100644 --- a/git/config.py +++ b/git/config.py @@ -248,7 +248,6 @@ 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": @@ -655,7 +654,7 @@ def write_section(name: str, section_dict: _OMD) -> None: values: Sequence[str] # runtime only gets str in tests, but should be whatever _OMD stores v: str - for (key, values) in section_dict.items_all(): + for key, values in section_dict.items_all(): if key == "__name__": continue diff --git a/git/diff.py b/git/diff.py index c1a5bd26f..1424ff3ad 100644 --- a/git/diff.py +++ b/git/diff.py @@ -145,7 +145,7 @@ def diff( args.append("--full-index") # get full index paths, not only filenames # remove default '-M' arg (check for renames) if user is overriding it - if not any(x in kwargs for x in ('find_renames', 'no_renames', 'M')): + if not any(x in kwargs for x in ("find_renames", "no_renames", "M")): args.append("-M") if create_patch: @@ -338,7 +338,6 @@ def __init__( change_type: Optional[Lit_change_type], score: Optional[int], ) -> None: - assert a_rawpath is None or isinstance(a_rawpath, bytes) assert b_rawpath is None or isinstance(b_rawpath, bytes) self.a_rawpath = a_rawpath diff --git a/git/exc.py b/git/exc.py index 9b69a5889..775528bf6 100644 --- a/git/exc.py +++ b/git/exc.py @@ -139,7 +139,6 @@ def __init__( valid_files: Sequence[PathLike], failed_reasons: List[str], ) -> None: - Exception.__init__(self, message) self.failed_files = failed_files self.failed_reasons = failed_reasons @@ -170,7 +169,6 @@ def __init__( stderr: Union[bytes, str, None] = None, stdout: Union[bytes, str, None] = None, ) -> None: - super(HookExecutionError, self).__init__(command, status, stderr, stdout) self._msg = "Hook('%s') failed%s" diff --git a/git/index/fun.py b/git/index/fun.py index d0925ed51..3dc5e96d2 100644 --- a/git/index/fun.py +++ b/git/index/fun.py @@ -394,7 +394,6 @@ def aggressive_tree_merge(odb: "GitCmdObjectDB", tree_shas: Sequence[bytes]) -> out.append(_tree_entry_to_baseindexentry(theirs, 0)) # END handle modification else: - if ours[0] != base[0] or ours[1] != base[1]: # they deleted it, we changed it, conflict out.append(_tree_entry_to_baseindexentry(base, 1)) diff --git a/git/objects/commit.py b/git/objects/commit.py index 6cca65c1f..6db3ea0f3 100644 --- a/git/objects/commit.py +++ b/git/objects/commit.py @@ -345,9 +345,7 @@ def trailers(self) -> Dict[str, str]: Dictionary containing whitespace stripped trailer information. Only contains the latest instance of each trailer key. """ - return { - k: v[0] for k, v in self.trailers_dict.items() - } + return {k: v[0] for k, v in self.trailers_dict.items()} @property def trailers_list(self) -> List[Tuple[str, str]]: diff --git a/git/objects/fun.py b/git/objects/fun.py index e91403a8b..043eec721 100644 --- a/git/objects/fun.py +++ b/git/objects/fun.py @@ -190,7 +190,6 @@ def traverse_trees_recursive( # is a tree. If the match is a non-tree item, put it into the result. # Processed items will be set None for ti, tree_data in enumerate(trees_data): - for ii, item in enumerate(tree_data): if not item: continue diff --git a/git/objects/util.py b/git/objects/util.py index af279154c..d72c04d17 100644 --- a/git/objects/util.py +++ b/git/objects/util.py @@ -143,7 +143,7 @@ def utctz_to_altz(utctz: str) -> int: :param utctz: git utc timezone string, i.e. +0200 """ int_utctz = int(utctz) - seconds = ((abs(int_utctz) // 100) * 3600 + (abs(int_utctz) % 100) * 60) + seconds = (abs(int_utctz) // 100) * 3600 + (abs(int_utctz) % 100) * 60 return seconds if int_utctz < 0 else -seconds diff --git a/git/remote.py b/git/remote.py index 5886a69f0..95a2b8ac6 100644 --- a/git/remote.py +++ b/git/remote.py @@ -826,7 +826,6 @@ def _get_fetch_info_from_stderr( progress: Union[Callable[..., Any], RemoteProgress, None], kill_after_timeout: Union[None, float] = None, ) -> IterableList["FetchInfo"]: - progress = to_progress_instance(progress) # skip first line as it is some remote info we are not interested in diff --git a/git/repo/base.py b/git/repo/base.py index 4bfead46f..723613c6f 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -498,7 +498,7 @@ def delete_head(self, *heads: "Union[str, Head]", **kwargs: Any) -> None: def create_tag( self, path: PathLike, - ref: Union[str, 'SymbolicReference'] = "HEAD", + ref: Union[str, "SymbolicReference"] = "HEAD", message: Optional[str] = None, force: bool = False, **kwargs: Any, @@ -548,7 +548,6 @@ def _get_config_path(self, config_level: Lit_config_levels, git_dir: Optional[Pa else: return osp.normpath(osp.join(repo_dir, "config")) else: - assert_never( # type:ignore[unreachable] config_level, ValueError(f"Invalid configuration level: {config_level!r}"), diff --git a/git/util.py b/git/util.py index 30028b1c2..5bfe11cd8 100644 --- a/git/util.py +++ b/git/util.py @@ -1083,7 +1083,6 @@ def __getattr__(self, attr: str) -> T_IterableObj: return list.__getattribute__(self, attr) def __getitem__(self, index: Union[SupportsIndex, int, slice, str]) -> T_IterableObj: # type: ignore - assert isinstance(index, (int, str, slice)), "Index of IterableList should be an int or str" if isinstance(index, int): @@ -1098,7 +1097,6 @@ def __getitem__(self, index: Union[SupportsIndex, int, slice, str]) -> T_Iterabl # END handle getattr def __delitem__(self, index: Union[SupportsIndex, int, slice, str]) -> None: - assert isinstance(index, (int, str)), "Index of IterableList should be an int or str" delindex = cast(int, index) diff --git a/pyproject.toml b/pyproject.toml index 57988372a..32c9d4a26 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,3 +45,4 @@ omit = ["*/git/ext/*"] [tool.black] line-length = 120 target-version = ['py37'] +exclude = "git/ext/gitdb" From 3908e79baf27b3d65265ca75db216f9368748351 Mon Sep 17 00:00:00 2001 From: Bodo Graumann Date: Thu, 20 Jul 2023 16:54:10 +0200 Subject: [PATCH 6/7] Add missing type annotation --- git/index/fun.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/index/fun.py b/git/index/fun.py index 3dc5e96d2..4a2f3cb6d 100644 --- a/git/index/fun.py +++ b/git/index/fun.py @@ -76,7 +76,7 @@ def hook_path(name: str, git_dir: PathLike) -> str: return osp.join(git_dir, "hooks", name) -def _has_file_extension(path): +def _has_file_extension(path: str) -> str: return osp.splitext(path)[1] From f01ee4f8d0b83f06fc7ba5458ac896ac3b81184a Mon Sep 17 00:00:00 2001 From: Bodo Graumann Date: Thu, 20 Jul 2023 17:21:41 +0200 Subject: [PATCH 7/7] Apply straight-forward typing fixes --- git/cmd.py | 2 +- git/index/base.py | 2 +- git/index/fun.py | 8 ++++---- git/objects/util.py | 2 +- git/util.py | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/git/cmd.py b/git/cmd.py index 84d888494..3d170facd 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -211,7 +211,7 @@ def dashify(string: str) -> str: return string.replace("_", "-") -def slots_to_dict(self: object, exclude: Sequence[str] = ()) -> Dict[str, Any]: +def slots_to_dict(self: "Git", exclude: Sequence[str] = ()) -> Dict[str, Any]: return {s: getattr(self, s) for s in self.__slots__ if s not in exclude} diff --git a/git/index/base.py b/git/index/base.py index dd8f9aa2e..193baf3ad 100644 --- a/git/index/base.py +++ b/git/index/base.py @@ -656,7 +656,7 @@ def _store_path(self, filepath: PathLike, fprogress: Callable) -> BaseIndexEntry def _entries_for_paths( self, paths: List[str], - path_rewriter: Callable, + path_rewriter: Union[Callable, None], fprogress: Callable, entries: List[BaseIndexEntry], ) -> List[BaseIndexEntry]: diff --git a/git/index/fun.py b/git/index/fun.py index 4a2f3cb6d..b50f1f465 100644 --- a/git/index/fun.py +++ b/git/index/fun.py @@ -102,7 +102,7 @@ def run_commit_hook(name: str, index: "IndexFile", *args: str) -> None: relative_hp = Path(hp).relative_to(index.repo.working_dir).as_posix() cmd = ["bash.exe", relative_hp] - cmd = subprocess.Popen( + process = subprocess.Popen( cmd + list(args), env=env, stdout=subprocess.PIPE, @@ -116,13 +116,13 @@ def run_commit_hook(name: str, index: "IndexFile", *args: str) -> None: else: stdout_list: List[str] = [] stderr_list: List[str] = [] - handle_process_output(cmd, stdout_list.append, stderr_list.append, finalize_process) + handle_process_output(process, stdout_list.append, stderr_list.append, finalize_process) stdout = "".join(stdout_list) stderr = "".join(stderr_list) - if cmd.returncode != 0: + if process.returncode != 0: stdout = force_text(stdout, defenc) stderr = force_text(stderr, defenc) - raise HookExecutionError(hp, cmd.returncode, stderr, stdout) + raise HookExecutionError(hp, process.returncode, stderr, stdout) # end handle return code diff --git a/git/objects/util.py b/git/objects/util.py index d72c04d17..56938507e 100644 --- a/git/objects/util.py +++ b/git/objects/util.py @@ -147,7 +147,7 @@ def utctz_to_altz(utctz: str) -> int: return seconds if int_utctz < 0 else -seconds -def altz_to_utctz_str(altz: int) -> str: +def altz_to_utctz_str(altz: float) -> str: """Convert a timezone offset west of UTC in seconds into a git timezone offset string :param altz: timezone offset in seconds west of UTC diff --git a/git/util.py b/git/util.py index 5bfe11cd8..0ef8bdeb7 100644 --- a/git/util.py +++ b/git/util.py @@ -1049,7 +1049,7 @@ class IterableList(List[T_IterableObj]): __slots__ = ("_id_attr", "_prefix") - def __new__(cls, id_attr: str, prefix: str = "") -> "IterableList[IterableObj]": + def __new__(cls, id_attr: str, prefix: str = "") -> "IterableList[T_IterableObj]": return super(IterableList, cls).__new__(cls) def __init__(self, id_attr: str, prefix: str = "") -> None: 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