2828import contextlib
2929import os
3030from 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
3434from .ffi import C , ffi
3535
3636if 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+
7898def 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