Skip to content

Commit a8ddf69

Browse files
committed
Type Traversable/list_traverse() better, make IterablleObj a protocol
1 parent 237966a commit a8ddf69

File tree

4 files changed

+22
-19
lines changed

4 files changed

+22
-19
lines changed

‎git/objects/util.py

+10-14
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from typing import (Any, Callable, Deque, Iterator, NamedTuple, overload, Sequence,
2424
TYPE_CHECKING, Tuple, Type, TypeVar, Union, cast)
2525

26-
from git.types import Literal
26+
from git.types import Literal, TypeGuard
2727

2828
if TYPE_CHECKING:
2929
from io import BytesIO, StringIO
@@ -306,24 +306,20 @@ class Tree:: (cls, Tree) -> Tuple[Tree, ...]
306306
"""
307307
raise NotImplementedError("To be implemented in subclass")
308308

309-
def list_traverse(self, *args: Any, **kwargs: Any
310-
) -> Union[IterableList['TraversableIterableObj'],
311-
IterableList[Tuple[Union[None, 'TraversableIterableObj'], 'TraversableIterableObj']]]:
309+
def list_traverse(self, *args: Any, **kwargs: Any) -> IterableList['TraversableIterableObj']:
312310
"""
313311
:return: IterableList with the results of the traversal as produced by
314312
traverse()
315313
List objects must be IterableObj and Traversable e.g. Commit, Submodule"""
316314

317-
out: Union[IterableList['TraversableIterableObj'],
318-
IterableList[Tuple[Union[None, 'TraversableIterableObj'], 'TraversableIterableObj']]]
319-
320-
# def is_TraversableIterableObj(inp: Union['Traversable', IterableObj]) -> TypeGuard['TraversableIterableObj']:
321-
# return isinstance(self, TraversableIterableObj)
322-
# assert is_TraversableIterableObj(self), f"{type(self)}"
323-
324-
self = cast('TraversableIterableObj', self)
325-
out = IterableList(self._id_attribute_)
326-
out.extend(self.traverse(*args, **kwargs)) # type: ignore
315+
def is_TraversableIterableObj(inp: 'Traversable') -> TypeGuard['TraversableIterableObj']:
316+
# return isinstance(self, TraversableIterableObj)
317+
# Can it be anythin else?
318+
return isinstance(self, Traversable)
319+
320+
assert is_TraversableIterableObj(self), f"{type(self)}"
321+
out: IterableList['TraversableIterableObj'] = IterableList(self._id_attribute_)
322+
out.extend(self.traverse(*args, **kwargs))
327323
return out
328324

329325
def traverse(self,

‎git/remote.py

+2
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ class PushInfo(IterableObj, object):
128128
info.summary # summary line providing human readable english text about the push
129129
"""
130130
__slots__ = ('local_ref', 'remote_ref_string', 'flags', '_old_commit_sha', '_remote', 'summary')
131+
_id_attribute_ = 'pushinfo'
131132

132133
NEW_TAG, NEW_HEAD, NO_MATCH, REJECTED, REMOTE_REJECTED, REMOTE_FAILURE, DELETED, \
133134
FORCED_UPDATE, FAST_FORWARD, UP_TO_DATE, ERROR = [1 << x for x in range(11)]
@@ -242,6 +243,7 @@ class FetchInfo(IterableObj, object):
242243
info.remote_ref_path # The path from which we fetched on the remote. It's the remote's version of our info.ref
243244
"""
244245
__slots__ = ('ref', 'old_commit', 'flags', 'note', 'remote_ref_path')
246+
_id_attribute_ = 'fetchinfo'
245247

246248
NEW_TAG, NEW_HEAD, HEAD_UPTODATE, TAG_UPDATE, REJECTED, FORCED_UPDATE, \
247249
FAST_FORWARD, ERROR = [1 << x for x in range(8)]

‎git/types.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
import sys
77
from typing import Dict, Union, Any, TYPE_CHECKING
88

9+
if sys.version_info[:2] >= (3, 7):
10+
from typing import Protocol # noqa: F401
11+
else:
12+
from typing_extensions import Protocol # noqa: F401
13+
914
if sys.version_info[:2] >= (3, 8):
1015
from typing import Final, Literal, SupportsIndex, TypedDict # noqa: F401
1116
else:
@@ -18,7 +23,6 @@
1823

1924

2025
if sys.version_info[:2] < (3, 9):
21-
# Python >= 3.6, < 3.9
2226
PathLike = Union[str, os.PathLike]
2327
elif sys.version_info[:2] >= (3, 9):
2428
# os.PathLike only becomes subscriptable from Python 3.9 onwards

‎git/util.py

+5-4
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828
# typing ---------------------------------------------------------
2929

30-
from typing import (Any, AnyStr, BinaryIO, Callable, Dict, Generator, IO, Iterable as typIter, Iterator, List,
30+
from typing import (Any, AnyStr, BinaryIO, Callable, Dict, Generator, IO, Iterator, List,
3131
Optional, Pattern, Sequence, Tuple, TypeVar, Union, cast, TYPE_CHECKING, overload)
3232

3333
import pathlib
@@ -37,9 +37,10 @@
3737
from git.repo.base import Repo
3838
from git.config import GitConfigParser, SectionConstraint
3939

40-
from .types import PathLike, Literal, SupportsIndex, HSH_TD, Total_TD, Files_TD
40+
from .types import (Literal, Protocol, SupportsIndex, # because behind py version guards
41+
PathLike, HSH_TD, Total_TD, Files_TD) # aliases
4142

42-
T_IterableObj = TypeVar('T_IterableObj', bound=Union['IterableObj', typIter], covariant=True)
43+
T_IterableObj = TypeVar('T_IterableObj', bound='IterableObj', covariant=True)
4344

4445
# So IterableList[Head] is subtype of IterableList[IterableObj]
4546
# ---------------------------------------------------------------------
@@ -1065,7 +1066,7 @@ def iter_items(cls, repo: 'Repo', *args: Any, **kwargs: Any):
10651066
raise NotImplementedError("To be implemented by Subclass")
10661067

10671068

1068-
class IterableObj():
1069+
class IterableObj(Protocol):
10691070
"""Defines an interface for iterable items which is to assure a uniform
10701071
way to retrieve and iterate items within the git repository
10711072

0 commit comments

Comments
 (0)