|
4 | 4 | # This module is part of GitPython and is released under
|
5 | 5 | # the BSD License: http://www.opensource.org/licenses/bsd-license.php
|
6 | 6 | """Module for general utility functions"""
|
| 7 | + |
| 8 | + |
7 | 9 | from git.util import (
|
8 | 10 | IterableList,
|
9 | 11 | Actor
|
|
18 | 20 | from datetime import datetime, timedelta, tzinfo
|
19 | 21 |
|
20 | 22 | # typing ------------------------------------------------------------
|
21 |
| -from typing import Any, IO, TYPE_CHECKING, Tuple, Type, Union, cast |
| 23 | +from typing import Any, Callable, IO, Iterator, Sequence, TYPE_CHECKING, Tuple, Type, Union, cast, overload |
22 | 24 |
|
23 | 25 | if TYPE_CHECKING:
|
| 26 | + from .submodule.base import Submodule |
24 | 27 | from .commit import Commit
|
25 | 28 | from .blob import Blob
|
26 | 29 | from .tag import TagObject
|
@@ -115,7 +118,7 @@ def verify_utctz(offset: str) -> str:
|
115 | 118 |
|
116 | 119 |
|
117 | 120 | class tzoffset(tzinfo):
|
118 |
| - |
| 121 | + |
119 | 122 | def __init__(self, secs_west_of_utc: float, name: Union[None, str] = None) -> None:
|
120 | 123 | self._offset = timedelta(seconds=-secs_west_of_utc)
|
121 | 124 | self._name = name or 'fixed'
|
@@ -275,29 +278,61 @@ class Traversable(object):
|
275 | 278 | """Simple interface to perform depth-first or breadth-first traversals
|
276 | 279 | into one direction.
|
277 | 280 | Subclasses only need to implement one function.
|
278 |
| - Instances of the Subclass must be hashable""" |
| 281 | + Instances of the Subclass must be hashable |
| 282 | +
|
| 283 | + Defined subclasses = [Commit, Tree, SubModule] |
| 284 | + """ |
279 | 285 | __slots__ = ()
|
280 | 286 |
|
| 287 | + @overload |
| 288 | + @classmethod |
| 289 | + def _get_intermediate_items(cls, item: 'Commit') -> Tuple['Commit', ...]: |
| 290 | + ... |
| 291 | + |
| 292 | + @overload |
281 | 293 | @classmethod
|
282 |
| - def _get_intermediate_items(cls, item): |
| 294 | + def _get_intermediate_items(cls, item: 'Submodule') -> Tuple['Submodule', ...]: |
| 295 | + ... |
| 296 | + |
| 297 | + @overload |
| 298 | + @classmethod |
| 299 | + def _get_intermediate_items(cls, item: 'Tree') -> Tuple['Tree', ...]: |
| 300 | + ... |
| 301 | + |
| 302 | + @overload |
| 303 | + @classmethod |
| 304 | + def _get_intermediate_items(cls, item: 'Traversable') -> Tuple['Traversable', ...]: |
| 305 | + ... |
| 306 | + |
| 307 | + @classmethod |
| 308 | + def _get_intermediate_items(cls, item: 'Traversable' |
| 309 | + ) -> Sequence['Traversable']: |
283 | 310 | """
|
284 | 311 | Returns:
|
285 |
| - List of items connected to the given item. |
| 312 | + Tuple of items connected to the given item. |
286 | 313 | Must be implemented in subclass
|
| 314 | +
|
| 315 | + class Commit:: (cls, Commit) -> Tuple[Commit, ...] |
| 316 | + class Submodule:: (cls, Submodule) -> Iterablelist[Submodule] |
| 317 | + class Tree:: (cls, Tree) -> Tuple[Tree, ...] |
287 | 318 | """
|
288 | 319 | raise NotImplementedError("To be implemented in subclass")
|
289 | 320 |
|
290 |
| - def list_traverse(self, *args, **kwargs): |
| 321 | + def list_traverse(self, *args: Any, **kwargs: Any) -> IterableList: |
291 | 322 | """
|
292 | 323 | :return: IterableList with the results of the traversal as produced by
|
293 | 324 | traverse()"""
|
294 |
| - out = IterableList(self._id_attribute_) |
| 325 | + out = IterableList(self._id_attribute_) # type: ignore[attr-defined] # defined in sublcasses |
295 | 326 | out.extend(self.traverse(*args, **kwargs))
|
296 | 327 | return out
|
297 | 328 |
|
298 |
| - def traverse(self, predicate=lambda i, d: True, |
299 |
| - prune=lambda i, d: False, depth=-1, branch_first=True, |
300 |
| - visit_once=True, ignore_self=1, as_edge=False): |
| 329 | + def traverse(self, |
| 330 | + predicate: Callable[[object, int], bool] = lambda i, d: True, |
| 331 | + prune: Callable[[object, int], bool] = lambda i, d: False, |
| 332 | + depth: int = -1, |
| 333 | + branch_first: bool = True, |
| 334 | + visit_once: bool = True, ignore_self: int = 1, as_edge: bool = False |
| 335 | + ) -> Union[Iterator['Traversable'], Iterator[Tuple['Traversable', 'Traversable']]]: |
301 | 336 | """:return: iterator yielding of items found when traversing self
|
302 | 337 |
|
303 | 338 | :param predicate: f(i,d) returns False if item i at depth d should not be included in the result
|
@@ -329,13 +364,16 @@ def traverse(self, predicate=lambda i, d: True,
|
329 | 364 | destination, i.e. tuple(src, dest) with the edge spanning from
|
330 | 365 | source to destination"""
|
331 | 366 | visited = set()
|
332 |
| - stack = Deque() |
| 367 | + stack = Deque() # type: Deque[Tuple[int, Traversable, Union[Traversable, None]]] |
333 | 368 | stack.append((0, self, None)) # self is always depth level 0
|
334 | 369 |
|
335 |
| - def addToStack(stack, item, branch_first, depth): |
| 370 | + def addToStack(stack: Deque[Tuple[int, 'Traversable', Union['Traversable', None]]], |
| 371 | + item: 'Traversable', |
| 372 | + branch_first: bool, |
| 373 | + depth) -> None: |
336 | 374 | lst = self._get_intermediate_items(item)
|
337 | 375 | if not lst:
|
338 |
| - return |
| 376 | + return None |
339 | 377 | if branch_first:
|
340 | 378 | stack.extendleft((depth, i, item) for i in lst)
|
341 | 379 | else:
|
|
0 commit comments