Skip to content

Commit 02b8ef0

Browse files
committed
Add missed types to Commit, uncomment to_native_path_linux()
1 parent 8fd5414 commit 02b8ef0

File tree

9 files changed

+85
-54
lines changed

9 files changed

+85
-54
lines changed

‎git/cmd.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -342,11 +342,11 @@ def polish_url(cls, url: str, is_cygwin: Literal[False] = ...) -> str:
342342

343343
@overload
344344
@classmethod
345-
def polish_url(cls, url: PathLike, is_cygwin: Union[None, bool] = None) -> str:
345+
def polish_url(cls, url: str, is_cygwin: Union[None, bool] = None) -> str:
346346
...
347347

348348
@classmethod
349-
def polish_url(cls, url: PathLike, is_cygwin: Union[None, bool] = None) -> PathLike:
349+
def polish_url(cls, url: str, is_cygwin: Union[None, bool] = None) -> PathLike:
350350
if is_cygwin is None:
351351
is_cygwin = cls.is_cygwin()
352352

‎git/config.py

+10
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,16 @@ def read_only(self) -> bool:
694694
""":return: True if this instance may change the configuration file"""
695695
return self._read_only
696696

697+
@overload
698+
def get_value(self, section: str, option: str, default: str
699+
) -> str:
700+
...
701+
702+
@overload
703+
def get_value(self, section: str, option: str, default: float
704+
) -> float:
705+
...
706+
697707
def get_value(self, section: str, option: str, default: Union[int, float, str, bool, None] = None
698708
) -> Union[int, float, str, bool]:
699709
# can default or return type include bool?

‎git/index/base.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
from subprocess import Popen
7676
from git.repo import Repo
7777
from git.refs.reference import Reference
78+
from git.util import Actor
7879

7980

8081
StageType = int
@@ -967,8 +968,8 @@ def move(self, items: Sequence[Union[PathLike, Blob, BaseIndexEntry, Submodule]]
967968

968969
return out
969970

970-
def commit(self, message: str, parent_commits=None, head: bool = True, author: str = None,
971-
committer: str = None, author_date: str = None, commit_date: str = None,
971+
def commit(self, message: str, parent_commits=None, head: bool = True, author: Union[None, 'Actor'] = None,
972+
committer: Union[None, 'Actor'] = None, author_date: str = None, commit_date: str = None,
972973
skip_hooks: bool = False) -> Commit:
973974
"""Commit the current default index file, creating a commit object.
974975
For more information on the arguments, see tree.commit.

‎git/objects/commit.py

+51-31
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#
44
# This module is part of GitPython and is released under
55
# the BSD License: http://www.opensource.org/licenses/bsd-license.php
6+
import datetime
7+
from subprocess import Popen
68
from gitdb import IStream
79
from git.util import (
810
hex_to_bin,
@@ -37,9 +39,9 @@
3739

3840
# typing ------------------------------------------------------------------
3941

40-
from typing import Any, Iterator, List, Sequence, Tuple, Union, TYPE_CHECKING
42+
from typing import Any, IO, Iterator, List, Sequence, Tuple, Union, TYPE_CHECKING
4143

42-
from git.types import PathLike
44+
from git.types import PathLike, TypeGuard
4345

4446
if TYPE_CHECKING:
4547
from git.repo import Repo
@@ -78,11 +80,17 @@ class Commit(base.Object, TraversableIterableObj, Diffable, Serializable):
7880
"message", "parents", "encoding", "gpgsig")
7981
_id_attribute_ = "hexsha"
8082

81-
def __init__(self, repo, binsha, tree=None, author: Union[Actor, None] = None,
82-
authored_date=None, author_tz_offset=None,
83-
committer=None, committed_date=None, committer_tz_offset=None,
84-
message=None, parents: Union[Tuple['Commit', ...], List['Commit'], None] = None,
85-
encoding=None, gpgsig=None):
83+
def __init__(self, repo: 'Repo', binsha: bytes, tree: 'Tree' = None,
84+
author: Union[Actor, None] = None,
85+
authored_date: Union[int, None] = None,
86+
author_tz_offset: Union[None, float] = None,
87+
committer: Union[Actor, None] = None,
88+
committed_date: Union[int, None] = None,
89+
committer_tz_offset: Union[None, float] = None,
90+
message: Union[str, None] = None,
91+
parents: Union[Sequence['Commit'], None] = None,
92+
encoding: Union[str, None] = None,
93+
gpgsig: Union[str, None] = None) -> None:
8694
"""Instantiate a new Commit. All keyword arguments taking None as default will
8795
be implicitly set on first query.
8896
@@ -164,7 +172,7 @@ def _calculate_sha_(cls, repo: 'Repo', commit: 'Commit') -> bytes:
164172
istream = repo.odb.store(IStream(cls.type, streamlen, stream))
165173
return istream.binsha
166174

167-
def replace(self, **kwargs):
175+
def replace(self, **kwargs: Any) -> 'Commit':
168176
'''Create new commit object from existing commit object.
169177
170178
Any values provided as keyword arguments will replace the
@@ -183,7 +191,7 @@ def replace(self, **kwargs):
183191

184192
return new_commit
185193

186-
def _set_cache_(self, attr):
194+
def _set_cache_(self, attr: str) -> None:
187195
if attr in Commit.__slots__:
188196
# read the data in a chunk, its faster - then provide a file wrapper
189197
_binsha, _typename, self.size, stream = self.repo.odb.stream(self.binsha)
@@ -193,19 +201,19 @@ def _set_cache_(self, attr):
193201
# END handle attrs
194202

195203
@property
196-
def authored_datetime(self):
204+
def authored_datetime(self) -> 'datetime.datetime':
197205
return from_timestamp(self.authored_date, self.author_tz_offset)
198206

199207
@property
200-
def committed_datetime(self):
208+
def committed_datetime(self) -> 'datetime.datetime':
201209
return from_timestamp(self.committed_date, self.committer_tz_offset)
202210

203211
@property
204-
def summary(self):
212+
def summary(self) -> str:
205213
""":return: First line of the commit message"""
206214
return self.message.split('\n', 1)[0]
207215

208-
def count(self, paths='', **kwargs):
216+
def count(self, paths: Union[PathLike, Sequence[PathLike]] = '', **kwargs: Any) -> int:
209217
"""Count the number of commits reachable from this commit
210218
211219
:param paths:
@@ -223,15 +231,15 @@ def count(self, paths='', **kwargs):
223231
return len(self.repo.git.rev_list(self.hexsha, **kwargs).splitlines())
224232

225233
@property
226-
def name_rev(self):
234+
def name_rev(self) -> str:
227235
"""
228236
:return:
229237
String describing the commits hex sha based on the closest Reference.
230238
Mostly useful for UI purposes"""
231239
return self.repo.git.name_rev(self)
232240

233241
@classmethod
234-
def iter_items(cls, repo: 'Repo', rev, # type: ignore
242+
def iter_items(cls, repo: 'Repo', rev: str, # type: ignore
235243
paths: Union[PathLike, Sequence[PathLike]] = '', **kwargs: Any
236244
) -> Iterator['Commit']:
237245
"""Find all commits matching the given criteria.
@@ -254,7 +262,7 @@ def iter_items(cls, repo: 'Repo', rev,
254262
# use -- in any case, to prevent possibility of ambiguous arguments
255263
# see https://github.com/gitpython-developers/GitPython/issues/264
256264

257-
args_list: List[Union[PathLike, Sequence[PathLike]]] = ['--']
265+
args_list: List[PathLike] = ['--']
258266

259267
if paths:
260268
paths_tup: Tuple[PathLike, ...]
@@ -286,7 +294,7 @@ def iter_parents(self, paths: Union[PathLike, Sequence[PathLike]] = '', **kwargs
286294
return self.iter_items(self.repo, self, paths, **kwargs)
287295

288296
@ property
289-
def stats(self):
297+
def stats(self) -> Stats:
290298
"""Create a git stat from changes between this commit and its first parent
291299
or from all changes done if this is the very first commit.
292300
@@ -303,16 +311,25 @@ def stats(self):
303311
return Stats._list_from_string(self.repo, text)
304312

305313
@ classmethod
306-
def _iter_from_process_or_stream(cls, repo, proc_or_stream):
314+
def _iter_from_process_or_stream(cls, repo: 'Repo', proc_or_stream: Union[Popen, IO]) -> Iterator['Commit']:
307315
"""Parse out commit information into a list of Commit objects
308316
We expect one-line per commit, and parse the actual commit information directly
309317
from our lighting fast object database
310318
311319
:param proc: git-rev-list process instance - one sha per line
312320
:return: iterator returning Commit objects"""
313-
stream = proc_or_stream
314-
if not hasattr(stream, 'readline'):
315-
stream = proc_or_stream.stdout
321+
322+
def is_proc(inp) -> TypeGuard[Popen]:
323+
return hasattr(proc_or_stream, 'wait') and not hasattr(proc_or_stream, 'readline')
324+
325+
def is_stream(inp) -> TypeGuard[IO]:
326+
return hasattr(proc_or_stream, 'readline')
327+
328+
if is_proc(proc_or_stream):
329+
if proc_or_stream.stdout is not None:
330+
stream = proc_or_stream.stdout
331+
elif is_stream(proc_or_stream):
332+
stream = proc_or_stream
316333

317334
readline = stream.readline
318335
while True:
@@ -330,19 +347,21 @@ def _iter_from_process_or_stream(cls, repo, proc_or_stream):
330347
# END for each line in stream
331348
# TODO: Review this - it seems process handling got a bit out of control
332349
# due to many developers trying to fix the open file handles issue
333-
if hasattr(proc_or_stream, 'wait'):
350+
if is_proc(proc_or_stream):
334351
finalize_process(proc_or_stream)
335352

336353
@ classmethod
337-
def create_from_tree(cls, repo, tree, message, parent_commits=None, head=False, author=None, committer=None,
338-
author_date=None, commit_date=None):
354+
def create_from_tree(cls, repo: 'Repo', tree: Union['Tree', str], message: str,
355+
parent_commits: Union[None, List['Commit']] = None, head: bool = False,
356+
author: Union[None, Actor] = None, committer: Union[None, Actor] = None,
357+
author_date: Union[None, str] = None, commit_date: Union[None, str] = None):
339358
"""Commit the given tree, creating a commit object.
340359
341360
:param repo: Repo object the commit should be part of
342361
:param tree: Tree object or hex or bin sha
343362
the tree of the new commit
344363
:param message: Commit message. It may be an empty string if no message is provided.
345-
It will be converted to a string in any case.
364+
It will be converted to a string , in any case.
346365
:param parent_commits:
347366
Optional Commit objects to use as parents for the new commit.
348367
If empty list, the commit will have no parents at all and become
@@ -476,7 +495,7 @@ def _serialize(self, stream: BytesIO) -> 'Commit':
476495
write(("encoding %s\n" % self.encoding).encode('ascii'))
477496

478497
try:
479-
if self.__getattribute__('gpgsig') is not None:
498+
if self.__getattribute__('gpgsig'):
480499
write(b"gpgsig")
481500
for sigline in self.gpgsig.rstrip("\n").split("\n"):
482501
write((" " + sigline + "\n").encode('ascii'))
@@ -526,7 +545,7 @@ def _deserialize(self, stream: BytesIO) -> 'Commit':
526545
# now we can have the encoding line, or an empty line followed by the optional
527546
# message.
528547
self.encoding = self.default_encoding
529-
self.gpgsig = None
548+
self.gpgsig = ""
530549

531550
# read headers
532551
enc = next_line
@@ -555,7 +574,7 @@ def _deserialize(self, stream: BytesIO) -> 'Commit':
555574
# decode the authors name
556575

557576
try:
558-
self.author, self.authored_date, self.author_tz_offset = \
577+
(self.author, self.authored_date, self.author_tz_offset) = \
559578
parse_actor_and_date(author_line.decode(self.encoding, 'replace'))
560579
except UnicodeDecodeError:
561580
log.error("Failed to decode author line '%s' using encoding %s", author_line, self.encoding,
@@ -571,11 +590,12 @@ def _deserialize(self, stream: BytesIO) -> 'Commit':
571590

572591
# a stream from our data simply gives us the plain message
573592
# The end of our message stream is marked with a newline that we strip
574-
self.message = stream.read()
593+
self.message_bytes = stream.read()
575594
try:
576-
self.message = self.message.decode(self.encoding, 'replace')
595+
self.message = self.message_bytes.decode(self.encoding, 'replace')
577596
except UnicodeDecodeError:
578-
log.error("Failed to decode message '%s' using encoding %s", self.message, self.encoding, exc_info=True)
597+
log.error("Failed to decode message '%s' using encoding %s",
598+
self.message_bytes, self.encoding, exc_info=True)
579599
# END exception handling
580600

581601
return self

‎git/objects/submodule/base.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -380,8 +380,8 @@ def add(cls, repo: 'Repo', name: str, path: PathLike, url: Union[str, None] = No
380380

381381
# assure we never put backslashes into the url, as some operating systems
382382
# like it ...
383-
# if url is not None:
384-
# url = to_native_path_linux(url) to_native_path_linux does nothing??
383+
if url is not None:
384+
url = to_native_path_linux(url)
385385
# END assure url correctness
386386

387387
# INSTANTIATE INTERMEDIATE SM
@@ -993,7 +993,7 @@ def set_parent_commit(self, commit: Union[Commit_ish, None], check=True):
993993
# If check is False, we might see a parent-commit that doesn't even contain the submodule anymore.
994994
# in that case, mark our sha as being NULL
995995
try:
996-
self.binsha = pctree[self.path].binsha
996+
self.binsha = pctree[str(self.path)].binsha
997997
except KeyError:
998998
self.binsha = self.NULL_BIN_SHA
999999
# end

‎git/objects/tree.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ def traverse(self, # type: ignore # overrides super()
321321
# assert is_tree_traversed(ret_tup), f"Type is {[type(x) for x in list(ret_tup[0])]}"
322322
# return ret_tup[0]"""
323323
return cast(Union[Iterator[IndexObjUnion], Iterator[TraversedTreeTup]],
324-
super(Tree, self).traverse(predicate, prune, depth, # type: ignore
324+
super(Tree, self).traverse(predicate, prune, depth, # type: ignore
325325
branch_first, visit_once, ignore_self))
326326

327327
# List protocol

‎git/objects/util.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def utctz_to_altz(utctz: str) -> int:
9999
return -1 * int(float(utctz) / 100 * 3600)
100100

101101

102-
def altz_to_utctz_str(altz: int) -> str:
102+
def altz_to_utctz_str(altz: float) -> str:
103103
"""As above, but inverses the operation, returning a string that can be used
104104
in commit objects"""
105105
utci = -1 * int((float(altz) / 3600) * 100)
@@ -323,8 +323,8 @@ def is_TraversableIterableObj(inp: 'Traversable') -> TypeGuard['TraversableItera
323323
return out
324324

325325
def traverse(self,
326-
predicate: Callable[[Union['Traversable', TraversedTup], int], bool] = lambda i, d: True,
327-
prune: Callable[[Union['Traversable', TraversedTup], int], bool] = lambda i, d: False,
326+
predicate: Callable[[Union['Traversable', 'Blob', TraversedTup], int], bool] = lambda i, d: True,
327+
prune: Callable[[Union['Traversable', 'Blob', TraversedTup], int], bool] = lambda i, d: False,
328328
depth: int = -1, branch_first: bool = True, visit_once: bool = True,
329329
ignore_self: int = 1, as_edge: bool = False
330330
) -> Union[Iterator[Union['Traversable', 'Blob']],
@@ -371,7 +371,7 @@ def traverse(self,
371371
ignore_self=False is_edge=False -> Iterator[Tuple[src, item]]"""
372372
class TraverseNT(NamedTuple):
373373
depth: int
374-
item: 'Traversable'
374+
item: Union['Traversable', 'Blob']
375375
src: Union['Traversable', None]
376376

377377
visited = set()
@@ -401,7 +401,7 @@ def addToStack(stack: Deque[TraverseNT],
401401
if visit_once:
402402
visited.add(item)
403403

404-
rval: Union['Traversable', Tuple[Union[None, 'Traversable'], 'Traversable']]
404+
rval: Union[TraversedTup, 'Traversable', 'Blob']
405405
if as_edge: # if as_edge return (src, item) unless rrc is None (e.g. for first item)
406406
rval = (src, item)
407407
else:
@@ -478,15 +478,15 @@ def traverse(self: T_TIobj,
478478
...
479479

480480
def traverse(self: T_TIobj,
481-
predicate: Callable[[Union[T_TIobj, Tuple[Union[T_TIobj, None], T_TIobj]], int],
481+
predicate: Callable[[Union[T_TIobj, TIobj_tuple], int],
482482
bool] = lambda i, d: True,
483-
prune: Callable[[Union[T_TIobj, Tuple[Union[T_TIobj, None], T_TIobj]], int],
483+
prune: Callable[[Union[T_TIobj, TIobj_tuple], int],
484484
bool] = lambda i, d: False,
485485
depth: int = -1, branch_first: bool = True, visit_once: bool = True,
486486
ignore_self: int = 1, as_edge: bool = False
487487
) -> Union[Iterator[T_TIobj],
488488
Iterator[Tuple[T_TIobj, T_TIobj]],
489-
Iterator[Tuple[Union[T_TIobj, None], T_TIobj]]]:
489+
Iterator[TIobj_tuple]]:
490490
"""For documentation, see util.Traversable._traverse()"""
491491

492492
"""

‎git/repo/base.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1036,7 +1036,7 @@ def _clone(cls, git: 'Git', url: PathLike, path: PathLike, odb_default_type: Typ
10361036
multi = None
10371037
if multi_options:
10381038
multi = ' '.join(multi_options).split(' ')
1039-
proc = git.clone(multi, Git.polish_url(url), clone_path, with_extended_output=True, as_process=True,
1039+
proc = git.clone(multi, Git.polish_url(str(url)), clone_path, with_extended_output=True, as_process=True,
10401040
v=True, universal_newlines=True, **add_progress(kwargs, git, progress))
10411041
if progress:
10421042
handle_process_output(proc, None, to_progress_instance(progress).new_message_handler(),

0 commit comments

Comments
 (0)