Skip to content

Commit d8755fb

Browse files
committed
fix typing for utils
1 parent 58b88c2 commit d8755fb

File tree

1 file changed

+27
-8
lines changed

1 file changed

+27
-8
lines changed

pygit2/utils.py

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,20 @@
2828
import contextlib
2929
import os
3030
from types import TracebackType
31-
from typing import TYPE_CHECKING, Any, Generic, TypeVar, cast
31+
from typing import TYPE_CHECKING, Any, Generic, TypeAlias, TypeVar, cast, overload
3232

3333
# Import from pygit2
3434
from .ffi import C, ffi
3535

3636
if TYPE_CHECKING:
37+
from _cffi_backend import _CDataBase as CData
3738
from _typeshed import SupportsLenAndGetItem
3839

3940
_T = TypeVar('_T')
41+
StrOrBytesOrPathLike: TypeAlias = str | bytes | os.PathLike[str] | os.PathLike[bytes]
4042

4143

42-
def maybe_string(ptr: Any) -> str | None:
44+
def maybe_string(ptr: CData | Any) -> str | None:
4345
if not ptr:
4446
return None
4547

@@ -49,20 +51,33 @@ def maybe_string(ptr: Any) -> str | None:
4951
return out
5052

5153

52-
def to_bytes(s: Any, encoding: str = 'utf-8', errors: str = 'strict') -> bytes | Any:
54+
# Cannot describe ffi.NULL, so using CData
55+
56+
57+
@overload
58+
def to_bytes(s: CData | None) -> CData: ...
59+
@overload
60+
def to_bytes(s: StrOrBytesOrPathLike) -> bytes: ...
61+
62+
63+
def to_bytes(
64+
s: StrOrBytesOrPathLike | CData | None,
65+
encoding: str = 'utf-8',
66+
errors: str = 'strict',
67+
) -> bytes | CData:
5368
if s == ffi.NULL or s is None:
5469
return ffi.NULL
5570

56-
if hasattr(s, '__fspath__'):
71+
if isinstance(s, os.PathLike):
5772
s = os.fspath(s)
5873

5974
if isinstance(s, bytes):
6075
return s
6176

62-
return s.encode(encoding, errors)
77+
return cast(str, s).encode(encoding, errors)
6378

6479

65-
def to_str(s: Any) -> str:
80+
def to_str(s: StrOrBytesOrPathLike) -> str:
6681
if hasattr(s, '__fspath__'):
6782
s = os.fspath(s)
6883

@@ -75,14 +90,18 @@ def to_str(s: Any) -> str:
7590
raise TypeError(f'unexpected type "{repr(s)}"')
7691

7792

93+
def buffer_to_bytes(cdata: CData) -> bytes:
94+
buf = ffi.buffer(cdata)
95+
return cast(bytes, buf[:])
96+
97+
7898
def ptr_to_bytes(ptr_cdata: Any) -> bytes:
7999
"""
80100
Convert a pointer coming from C code (<cdata 'some_type *'>)
81101
to a byte buffer containing the address that the pointer refers to.
82102
"""
83103

84-
pp = ffi.new('void **', ptr_cdata)
85-
return bytes(ffi.buffer(pp)[:]) # type: ignore
104+
return buffer_to_bytes(ffi.new('void **', ptr_cdata))
86105

87106

88107
@contextlib.contextmanager

0 commit comments

Comments
 (0)