References.get and Branches.get return None for an invalid name - #1495
Merged
Merged
Conversation
Both are documented to return None when the lookup fails, and both catch
only KeyError. libgit2 reports two codes for a failed lookup:
GIT_ENOTFOUND, which errors.py maps to NotFoundError (a KeyError), and
GIT_EINVALIDSPEC, which maps to InvalidSpecError (a ValueError). Only the
first reaches the handler.
repo.references.get('master') InvalidSpecError
'master' in repo.references InvalidSpecError
repo.branches.get('my branch') InvalidSpecError
'my branch' in repo.branches InvalidSpecError
__contains__ is built on get() in both collections, so it raises too.
Branches.get is now typed Branch | None, dropping a "# type:ignore #
next commit". That makes mypy see what the signature always meant, so
the tests that call it and then use the result assert it is not None.
Same shape as the SubmoduleCollection.get fix in libgit2#1487.
Closes libgit2#1489
rawsun007
force-pushed
the
get-invalid-spec
branch
from
September 18, 2026 05:37
376e12f to
58d8134
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
References.get()andBranches.get()are documented to returnNonewhen the lookup fails:Both catch only
KeyError. libgit2 reports two codes for a failed lookup, anderrors.pymaps them to different Python hierarchies —GIT_ENOTFOUNDtoNotFoundError(aKeyError),GIT_EINVALIDSPECtoInvalidSpecError(aValueError). Only the first reaches the handler.On 1.20.1 with libgit2 1.9.7, in a fresh repository with one commit:
repo.references.get('master')InvalidSpecErrorNone'master' in repo.referencesInvalidSpecErrorFalserepo.branches.get('my branch')InvalidSpecErrorNone'my branch' in repo.branchesInvalidSpecErrorFalserepo.references.get('refs/heads/nope')NoneNonerepo.branches.get('nope')NoneNone'master'is the interesting one: it is an entirely ordinary thing to pass, and it fails only because it is not a full reference name, which libgit2 classifies as an invalid spec rather than a miss.__contains__is built onget()in both collections, so the membership test raises as well.This is the same shape as
SubmoduleCollection.get, fixed in #1487, and it is what I described in #1489 eleven days ago while offering to send the patch.__getitem__still raises for both kinds of failure; only theget()/incontract changes.Branches.get's return type also becomesBranch | None, which drops a# type:ignorethat was marked "next commit".Verification:
pytest test/is 665 passed, 12 skipped, 1 xpassed against a local build (LIBGIT2=$(brew --prefix libgit2) pip install -e ., libgit2 1.9.7). Reverting only the two source files fails exactly the two new tests.stubtestclean,ruff checkandruff format --checkclean.Closes #1489
Assisted-by: Claude Opus 5 (Claude Code), written and verified under my account.