From 5f4b4dbff46fae4c899f5573aea5a7266a41eeeb Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Mon, 20 Sep 2021 13:53:42 -0700 Subject: [PATCH] Fix typing issues with delete_head and Remote.add delete_head and Head.delete historically accept either Head objects or a str name of a head. Adjust the typing to match. This unfortunately requires suppressing type warnings in the signature of RemoteReference.delete, since it inherits from Head but does not accept str (since it needs access to the richer data of RemoteReference). Using assignment to make add an alias for create unfortunately confuses mypy, since it loses track of the fact that it's a classmethod and starts treating it like a staticmethod. Replace with a stub wrapper instead. --- git/refs/head.py | 2 +- git/refs/remote.py | 7 ++++++- git/remote.py | 4 +++- git/repo/base.py | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/git/refs/head.py b/git/refs/head.py index 56a87182f..d1d72c7bd 100644 --- a/git/refs/head.py +++ b/git/refs/head.py @@ -129,7 +129,7 @@ class Head(Reference): k_config_remote_ref = "merge" # branch to merge from remote @classmethod - def delete(cls, repo: 'Repo', *heads: 'Head', force: bool = False, **kwargs: Any) -> None: + def delete(cls, repo: 'Repo', *heads: 'Union[Head, str]', force: bool = False, **kwargs: Any) -> None: """Delete the given heads :param force: diff --git a/git/refs/remote.py b/git/refs/remote.py index 9b74d87fb..1b416bd0a 100644 --- a/git/refs/remote.py +++ b/git/refs/remote.py @@ -37,8 +37,13 @@ def iter_items(cls, repo: 'Repo', common_path: Union[PathLike, None] = None, # super is Reference return super(RemoteReference, cls).iter_items(repo, common_path) + # The Head implementation of delete also accepts strs, but this + # implementation does not. mypy doesn't have a way of representing + # tightening the types of arguments in subclasses and recommends Any or + # "type: ignore". (See https://github.com/python/typing/issues/241) @ classmethod - def delete(cls, repo: 'Repo', *refs: 'RemoteReference', **kwargs: Any) -> None: + def delete(cls, repo: 'Repo', *refs: 'RemoteReference', # type: ignore + **kwargs: Any) -> None: """Delete the given remote references :note: diff --git a/git/remote.py b/git/remote.py index 9917c4310..2cf5678b6 100644 --- a/git/remote.py +++ b/git/remote.py @@ -665,7 +665,9 @@ def create(cls, repo: 'Repo', name: str, url: str, **kwargs: Any) -> 'Remote': return cls(repo, name) # add is an alias - add = create + @ classmethod + def add(cls, repo: 'Repo', name: str, url: str, **kwargs: Any) -> 'Remote': + return cls.create(repo, name, url, **kwargs) @ classmethod def remove(cls, repo: 'Repo', name: str) -> str: diff --git a/git/repo/base.py b/git/repo/base.py index e308fd8a2..7713c9152 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -429,7 +429,7 @@ def create_head(self, path: PathLike, commit: str = 'HEAD', :return: newly created Head Reference""" return Head.create(self, path, commit, logmsg, force) - def delete_head(self, *heads: 'Head', **kwargs: Any) -> None: + def delete_head(self, *heads: 'Union[str, Head]', **kwargs: Any) -> None: """Delete the given heads :param kwargs: Additional keyword arguments to be passed to git-branch"""