-
-
Notifications
You must be signed in to change notification settings - Fork 951
Open
Labels
Description
Since GitPython 3.1.45 was released, we've had mypy
reporting pre-checkin errors for code that has been stable and functional for years:
error: "SymbolicReference" has no attribute "checkout" [attr-defined]
error: "SymbolicReference" has no attribute "tracking_branch" [attr-defined]
error: "SymbolicReference" has no attribute "tracking_branch" [attr-defined]
The code failing mypy
checks is doing things like getting the active branch, so we can switch back to it after doing other stuff:
@contextmanager
def checkout(self, branch: Branch) -> typing.Generator[None]:
new_branch = self.api.create_head(branch.name)
current = self.api.head.ref
try:
new_branch.checkout()
yield
finally:
current.checkout()
... or ensuring that the active branch has a remote tracking branch set:
tracking_branch = repo.head.reference.tracking_branch()
if tracking_branch is None:
raise GitConfigException(
'Error: Upstream branch not set; use "git branch '
'--set-upstream-to=<remote/branch>" to fix.'
)
if tracking_branch.remote_name == ".":
raise GitConfigException(
'Error: Upstream branch is local rather than remote; use "git '
'branch --set-upstream-to=<remote/branch>" to fix.'
)
The immediate cause of these new mypy
errors appears to be this commit, which added a new type hint for the return value of SymbolicReference.reference
:
@property
def reference(self) -> "SymbolicReference":
return self._get_reference()
In manual testing I've found that the reference
method doesn't actually return a SymbolicReference
object when the the symbolic reference is HEAD
. Instead, a Head
object is returned:
>>> import git
>>> git.__version__
'3.1.45'
>>> testrepo = git.repo.Repo.init(".")
>>> type(testrepo.head)
<class 'git.refs.head.HEAD'>
>>> type(testrepo.head.ref)
<class 'git.refs.head.Head'>
>>> testrepo.head.ref.tracking_branch()
<git.RemoteReference "refs/remotes/./master">
>>> testrepo.head.ref.checkout()
<git.Head "refs/heads/bar">