Skip to content

Commit 3686b6a

Browse files
Byroncodex
andcommitted
review
- also fixup typing Assisted-by: GPT 6.0 Co-authored-by: GPT 6.0 <codex@openai.com>
1 parent fa93137 commit 3686b6a

20 files changed

Lines changed: 273 additions & 550 deletions

File tree

.basedpyright/baseline.json

Lines changed: 1 addition & 465 deletions
Large diffs are not rendered by default.

git/cmd.py

Lines changed: 86 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@
100100

101101

102102
def handle_process_output(
103-
process: "Git.AutoInterrupt" | Popen,
103+
process: Union["Git.AutoInterrupt", Popen],
104104
stdout_handler: Union[
105105
None,
106106
Callable[[AnyStr], None],
@@ -395,9 +395,7 @@ def wait(self, stderr: Union[None, str, bytes] = b"") -> int:
395395
:raise git.exc.GitCommandError:
396396
If the return status is not 0.
397397
"""
398-
if stderr is None:
399-
stderr_b = b""
400-
stderr_b = force_bytes(data=stderr, encoding="utf-8")
398+
stderr_b = force_bytes(data=stderr, encoding="utf-8") or b""
401399
status: Union[int, None]
402400
if self.proc is not None:
403401
status = self.proc.wait()
@@ -1180,52 +1178,112 @@ def version_info(self) -> Tuple[int, ...]:
11801178
def execute(
11811179
self,
11821180
command: Union[str, Sequence[Any]],
1181+
istream: Union[None, int, BinaryIO] = None,
11831182
*,
11841183
as_process: Literal[True],
1184+
**subprocess_kwargs: Any,
11851185
) -> "AutoInterrupt": ...
11861186

11871187
@overload
11881188
def execute(
11891189
self,
11901190
command: Union[str, Sequence[Any]],
1191+
istream: Union[None, int, BinaryIO] = None,
11911192
*,
11921193
as_process: Literal[False] = False,
1193-
stdout_as_string: Literal[True],
1194-
) -> Union[str, Tuple[int, str, str]]: ...
1194+
with_extended_output: Literal[False] = False,
1195+
stdout_as_string: Literal[True] = True,
1196+
with_stdout: Literal[True] = True,
1197+
**subprocess_kwargs: Any,
1198+
) -> str: ...
11951199

11961200
@overload
11971201
def execute(
11981202
self,
11991203
command: Union[str, Sequence[Any]],
1204+
istream: Union[None, int, BinaryIO] = None,
12001205
*,
12011206
as_process: Literal[False] = False,
1202-
stdout_as_string: Literal[False] = False,
1203-
) -> Union[bytes, Tuple[int, bytes, str]]: ...
1207+
with_extended_output: Literal[False] = False,
1208+
stdout_as_string: Literal[False],
1209+
universal_newlines: Literal[False] = False,
1210+
with_stdout: Literal[True] = True,
1211+
**subprocess_kwargs: Any,
1212+
) -> bytes: ...
12041213

12051214
@overload
12061215
def execute(
12071216
self,
12081217
command: Union[str, Sequence[Any]],
1218+
istream: Union[None, int, BinaryIO] = None,
12091219
*,
1210-
with_extended_output: Literal[False],
1211-
as_process: Literal[False],
1212-
stdout_as_string: Literal[True],
1213-
) -> str: ...
1220+
as_process: Literal[False] = False,
1221+
with_extended_output: Literal[True],
1222+
stdout_as_string: Literal[True] = True,
1223+
with_stdout: Literal[True] = True,
1224+
**subprocess_kwargs: Any,
1225+
) -> Tuple[int, str, str]: ...
12141226

12151227
@overload
12161228
def execute(
12171229
self,
12181230
command: Union[str, Sequence[Any]],
1231+
istream: Union[None, int, BinaryIO] = None,
12191232
*,
1220-
with_extended_output: Literal[False],
1221-
as_process: Literal[False],
1233+
as_process: Literal[False] = False,
1234+
with_extended_output: Literal[True],
12221235
stdout_as_string: Literal[False],
1223-
) -> bytes: ...
1236+
universal_newlines: Literal[False] = False,
1237+
with_stdout: Literal[True] = True,
1238+
**subprocess_kwargs: Any,
1239+
) -> Tuple[int, bytes, str]: ...
1240+
1241+
@overload
1242+
def execute(
1243+
self,
1244+
command: Union[str, Sequence[Any]],
1245+
istream: Union[None, int, BinaryIO] = None,
1246+
*,
1247+
as_process: Literal[False] = False,
1248+
with_extended_output: Literal[True],
1249+
**subprocess_kwargs: Any,
1250+
) -> Tuple[int, Union[str, bytes, None], str]: ...
1251+
1252+
@overload
1253+
def execute(
1254+
self,
1255+
command: Union[str, Sequence[Any]],
1256+
istream: Union[None, int, BinaryIO] = None,
1257+
*,
1258+
as_process: Literal[False] = False,
1259+
with_extended_output: Literal[False] = False,
1260+
**subprocess_kwargs: Any,
1261+
) -> Union[str, bytes, None]: ...
1262+
1263+
@overload
1264+
def execute(
1265+
self,
1266+
command: Union[str, Sequence[Any]],
1267+
istream: Union[None, int, BinaryIO] = None,
1268+
with_extended_output: bool = False,
1269+
with_exceptions: bool = True,
1270+
as_process: bool = False,
1271+
output_stream: Union[None, BinaryIO] = None,
1272+
stdout_as_string: bool = True,
1273+
kill_after_timeout: Union[None, float] = None,
1274+
with_stdout: bool = True,
1275+
universal_newlines: bool = False,
1276+
shell: Union[None, bool] = None,
1277+
env: Union[None, Mapping[str, str]] = None,
1278+
max_chunk_size: int = io.DEFAULT_BUFFER_SIZE,
1279+
strip_newline_in_stdout: bool = True,
1280+
**subprocess_kwargs: Any,
1281+
) -> Union[None, str, bytes, Tuple[int, Union[str, bytes, None], str], AutoInterrupt]: ...
12241282

12251283
def execute(
12261284
self,
12271285
command: Union[str, Sequence[Any]],
1228-
istream: Union[None, BinaryIO] = None,
1286+
istream: Union[None, int, BinaryIO] = None,
12291287
with_extended_output: bool = False,
12301288
with_exceptions: bool = True,
12311289
as_process: bool = False,
@@ -1239,7 +1297,7 @@ def execute(
12391297
max_chunk_size: int = io.DEFAULT_BUFFER_SIZE,
12401298
strip_newline_in_stdout: bool = True,
12411299
**subprocess_kwargs: Any,
1242-
) -> Union[str, bytes, Tuple[int, Union[str, bytes], str], AutoInterrupt]:
1300+
) -> Union[None, str, bytes, Tuple[int, Union[str, bytes, None], str], AutoInterrupt]:
12431301
R"""Handle executing the command, and consume and return the returned
12441302
information (stdout).
12451303
@@ -1503,7 +1561,7 @@ def make_timeout_error() -> Union[str, bytes]:
15031561
err = f'Timeout: the command "{" ".join(redacted_command)}" did not complete in {timeout:g} secs.'
15041562
return err if universal_newlines else err.encode(defenc)
15051563

1506-
def communicate() -> Tuple[AnyStr, AnyStr]:
1564+
def communicate() -> Tuple[Union[str, bytes, None], Union[str, bytes, None]]:
15071565
assert watchdog is not None
15081566
assert kill_check is not None
15091567
watchdog.start()
@@ -1523,8 +1581,8 @@ def communicate() -> Tuple[AnyStr, AnyStr]:
15231581

15241582
# Wait for the process to return.
15251583
status = 0
1526-
stdout_value: Union[str, bytes] = b""
1527-
stderr_value: Union[str, bytes] = b""
1584+
stdout_value: Union[str, bytes, None] = b""
1585+
stderr_value: Union[str, bytes, None] = b""
15281586
newline = "\n" if universal_newlines else b"\n"
15291587
try:
15301588
if output_stream is None:
@@ -1566,7 +1624,7 @@ def communicate() -> Tuple[AnyStr, AnyStr]:
15661624
if self.GIT_PYTHON_TRACE == "full":
15671625
cmdstr = " ".join(redacted_command)
15681626

1569-
def as_text(stdout_value: Union[bytes, str]) -> str:
1627+
def as_text(stdout_value: Union[bytes, str, None]) -> str:
15701628
return not output_stream and safe_decode(stdout_value) or "<OUTPUT_STREAM>"
15711629

15721630
# END as_text
@@ -1591,6 +1649,8 @@ def as_text(stdout_value: Union[bytes, str]) -> str:
15911649
if isinstance(stdout_value, bytes) and stdout_as_string: # Could also be output_stream.
15921650
stdout_value = safe_decode(stdout_value)
15931651

1652+
# stderr is always captured through PIPE.
1653+
assert stderr_value is not None
15941654
# Allow access to the command's status code.
15951655
if with_extended_output:
15961656
return (status, stdout_value, safe_decode(stderr_value))
@@ -1829,7 +1889,7 @@ def _parse_object_header(self, header_line: str) -> Tuple[str, str, int]:
18291889
raise ValueError("Failed to parse header: %r" % header_line)
18301890
return (tokens[0], tokens[1], int(tokens[2]))
18311891

1832-
def _prepare_ref(self, ref: AnyStr) -> bytes:
1892+
def _prepare_ref(self, ref: object) -> bytes:
18331893
# Required for command to separate refs on stdin, as bytes.
18341894
if isinstance(ref, bytes):
18351895
# Assume 40 bytes hexsha - bin-to-ascii for some reason returns bytes, not text.
@@ -1856,15 +1916,15 @@ def _get_persistent_cmd(self, attr_name: str, cmd_name: str, *args: Any, **kwarg
18561916
cmd = cast("Git.AutoInterrupt", cmd)
18571917
return cmd
18581918

1859-
def __get_object_header(self, cmd: "Git.AutoInterrupt", ref: AnyStr) -> Tuple[str, str, int]:
1919+
def __get_object_header(self, cmd: "Git.AutoInterrupt", ref: Union[str, bytes]) -> Tuple[str, str, int]:
18601920
if cmd.stdin and cmd.stdout:
18611921
cmd.stdin.write(self._prepare_ref(ref))
18621922
cmd.stdin.flush()
18631923
return self._parse_object_header(cmd.stdout.readline())
18641924
else:
18651925
raise ValueError("cmd stdin was empty")
18661926

1867-
def get_object_header(self, ref: str) -> Tuple[str, str, int]:
1927+
def get_object_header(self, ref: Union[str, bytes]) -> Tuple[str, str, int]:
18681928
"""Use this method to quickly examine the type and size of the object behind the
18691929
given ref.
18701930
@@ -1878,7 +1938,7 @@ def get_object_header(self, ref: str) -> Tuple[str, str, int]:
18781938
cmd = self._get_persistent_cmd("cat_file_header", "cat_file", batch_check=True)
18791939
return self.__get_object_header(cmd, ref)
18801940

1881-
def get_object_data(self, ref: str) -> Tuple[str, str, int, bytes]:
1941+
def get_object_data(self, ref: Union[str, bytes]) -> Tuple[str, str, int, bytes]:
18821942
"""Similar to :meth:`get_object_header`, but returns object data as well.
18831943
18841944
:return:
@@ -1892,7 +1952,7 @@ def get_object_data(self, ref: str) -> Tuple[str, str, int, bytes]:
18921952
del stream
18931953
return (hexsha, typename, size, data)
18941954

1895-
def stream_object_data(self, ref: str) -> Tuple[str, str, int, "Git.CatFileContentStream"]:
1955+
def stream_object_data(self, ref: Union[str, bytes]) -> Tuple[str, str, int, "Git.CatFileContentStream"]:
18961956
"""Similar to :meth:`get_object_data`, but returns the data as a stream.
18971957
18981958
:return:

git/index/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1235,7 +1235,7 @@ def _read_commit_editmsg(self) -> str:
12351235
def _commit_editmsg_filepath(self) -> str:
12361236
return osp.join(self.repo.common_dir, "COMMIT_EDITMSG")
12371237

1238-
def _flush_stdin_and_wait(cls, proc: "Popen[bytes]", ignore_stdout: bool = False) -> bytes:
1238+
def _flush_stdin_and_wait(self, proc: "Popen[bytes]", ignore_stdout: bool = False) -> bytes:
12391239
stdin_IO = proc.stdin
12401240
if stdin_IO:
12411241
stdin_IO.flush()

git/index/fun.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
from git.types import PathLike
4747

4848
if TYPE_CHECKING:
49-
from git.db import GitCmdObjectDB
49+
from gitdb.db.base import ObjectDBR, ObjectDBW
5050
from git.objects.tree import TreeCacheTup
5151

5252
from .base import IndexFile
@@ -412,7 +412,7 @@ def read_cache(
412412

413413

414414
def write_tree_from_cache(
415-
entries: List[IndexEntry], odb: "GitCmdObjectDB", sl: slice, si: int = 0
415+
entries: List[IndexEntry], odb: "ObjectDBW", sl: slice, si: int = 0
416416
) -> Tuple[bytes, List["TreeCacheTup"]]:
417417
R"""Create a tree from the given sorted list of entries and put the respective
418418
trees into the given object database.
@@ -484,7 +484,7 @@ def _tree_entry_to_baseindexentry(tree_entry: "TreeCacheTup", stage: int) -> Bas
484484
return BaseIndexEntry((tree_entry[1], tree_entry[0], stage << CE_STAGESHIFT, tree_entry[2]))
485485

486486

487-
def aggressive_tree_merge(odb: "GitCmdObjectDB", tree_shas: Sequence[bytes]) -> List[BaseIndexEntry]:
487+
def aggressive_tree_merge(odb: "ObjectDBR", tree_shas: Sequence[bytes]) -> List[BaseIndexEntry]:
488488
R"""
489489
:return:
490490
List of :class:`~git.index.typ.BaseIndexEntry`\s representing the aggressive

git/index/typ.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,21 @@
99
from pathlib import Path
1010

1111
from git.objects import Blob
12+
from git.objects.base import IndexObject
1213

1314
from .util import pack, unpack
1415

1516
# typing ----------------------------------------------------------------------
1617

17-
from typing import NamedTuple, Sequence, TYPE_CHECKING, Tuple, Union, cast
18+
from typing import NamedTuple, Sequence, TYPE_CHECKING, Tuple, Type, TypeVar, Union, cast
1819

1920
from git.types import PathLike
2021

2122
if TYPE_CHECKING:
2223
from git.repo import Repo
2324

2425
StageType = int
26+
_T_IndexEntry = TypeVar("_T_IndexEntry", bound="BaseIndexEntry")
2527

2628
# ---------------------------------------------------------------------------------
2729

@@ -104,15 +106,20 @@ class BaseIndexEntry(BaseIndexEntryHelper):
104106
"""
105107

106108
def __new__(
107-
cls,
109+
cls: Type[_T_IndexEntry],
108110
inp_tuple: Union[
109111
Tuple[int, bytes, int, PathLike],
112+
Tuple[int, bytes, int, PathLike, bytes, bytes, int, int, int, int, int],
110113
Tuple[int, bytes, int, PathLike, bytes, bytes, int, int, int, int, int, int],
111114
],
112-
) -> "BaseIndexEntry":
115+
) -> _T_IndexEntry:
113116
"""Override ``__new__`` to allow construction from a tuple for backwards
114117
compatibility."""
115-
return super().__new__(cls, *inp_tuple)
118+
if len(inp_tuple) == 4:
119+
return BaseIndexEntryHelper.__new__(cls, *inp_tuple)
120+
if len(inp_tuple) == 11:
121+
return BaseIndexEntryHelper.__new__(cls, *inp_tuple)
122+
return BaseIndexEntryHelper.__new__(cls, *inp_tuple)
116123

117124
def __str__(self) -> str:
118125
return "%o %s %i\t%s" % (self.mode, self.hexsha, self.stage, self.path)
@@ -148,7 +155,7 @@ def intent_to_add(self) -> bool:
148155
return (self.extended_flags & CE_EXT_INTENT_TO_ADD) > 0
149156

150157
@classmethod
151-
def from_blob(cls, blob: Blob, stage: int = 0) -> "BaseIndexEntry":
158+
def from_blob(cls, blob: IndexObject, stage: int = 0) -> "BaseIndexEntry":
152159
""":return: Fully equipped BaseIndexEntry at the given stage"""
153160
return cls((blob.mode, blob.binsha, stage << CE_STAGESHIFT, blob.path))
154161

@@ -192,10 +199,10 @@ def from_base(cls, base: "BaseIndexEntry") -> "IndexEntry":
192199
Instance of type :class:`BaseIndexEntry`.
193200
"""
194201
time = pack(">LL", 0, 0)
195-
return IndexEntry((base.mode, base.binsha, base.flags, base.path, time, time, 0, 0, 0, 0, 0)) # type: ignore[arg-type]
202+
return IndexEntry((base.mode, base.binsha, base.flags, base.path, time, time, 0, 0, 0, 0, 0))
196203

197204
@classmethod
198-
def from_blob(cls, blob: Blob, stage: int = 0) -> "IndexEntry":
205+
def from_blob(cls, blob: IndexObject, stage: int = 0) -> "IndexEntry":
199206
""":return: Minimal entry resembling the given blob object"""
200207
time = pack(">LL", 0, 0)
201208
return IndexEntry(
@@ -211,5 +218,5 @@ def from_blob(cls, blob: Blob, stage: int = 0) -> "IndexEntry":
211218
0,
212219
0,
213220
blob.size,
214-
) # type: ignore[arg-type]
221+
)
215222
)

git/objects/base.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
from typing import Any, TYPE_CHECKING, Union
2020

21-
from git.types import AnyGitObject, GitObjectTypeString, PathLike
21+
from git.types import AnyGitObject, GitObjectTypeString, PathLike, SupportsWrite
2222

2323
if TYPE_CHECKING:
2424
from gitdb.base import OStream
@@ -200,7 +200,7 @@ def data_stream(self) -> "OStream":
200200
"""
201201
return self.repo.odb.stream(self.binsha)
202202

203-
def stream_data(self, ostream: "OStream") -> "Object":
203+
def stream_data(self, ostream: SupportsWrite[bytes]) -> "Object":
204204
"""Write our data directly to the given output stream.
205205
206206
:param ostream:

git/objects/commit.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ def _interpret_trailers(
502502
) -> str:
503503
message_bytes = message if isinstance(message, bytes) else message.encode(encoding, errors="strict")
504504
cmd = [repo.git.GIT_PYTHON_GIT_EXECUTABLE, "interpret-trailers", *trailer_args]
505-
proc: Git.AutoInterrupt = repo.git.execute( # type: ignore[call-overload]
505+
proc: Git.AutoInterrupt = repo.git.execute(
506506
cmd,
507507
as_process=True,
508508
istream=PIPE,

0 commit comments

Comments
 (0)