Skip to content

Commit bb73b1c

Browse files
committed
Improve typing.
Or make it worse?
1 parent a4a521d commit bb73b1c

File tree

1 file changed

+33
-29
lines changed

1 file changed

+33
-29
lines changed

sdl3/__init__.py

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -223,11 +223,13 @@ def SDL_CHECK_BINARY_NAME(name: str) -> bool:
223223
if (name.split(".")[0] if "." in name else name).endswith(_name):
224224
binaryMap[module] = ctypes.CDLL(os.path.abspath(path))
225225

226-
def SDL_ARRAY(*values, type: typing.Any | None = None) -> tuple[typing.Any, int]:
226+
_CT = typing.TypeVar("_CT", bound = ctypes._SimpleCData)
227+
228+
def SDL_ARRAY(*values: _CT, _type: type[_CT] | None = None) -> tuple[ctypes.Array[_CT], int]:
227229
"""Create a ctypes array from the given arguments."""
228-
return ((type or values[0].__class__) * len(values))(*values), len(values)
230+
return ((_type or type(values[0])) * len(values))(*values), len(values)
229231

230-
def SDL_DEREFERENCE(value: typing.Any) -> typing.Any:
232+
def SDL_DEREFERENCE(value: ctypes._Pointer) -> ctypes._SimpleCData:
231233
"""Dereference a ctypes pointer or object."""
232234
if isinstance(value, ctypes._Pointer): return value.contents
233235
elif hasattr(value, "_obj"): return value._obj
@@ -237,7 +239,7 @@ def SDL_CACHE_FUNC(func: abc.Callable[..., typing.Any]) -> abc.Callable[..., typ
237239
"""Simple function cache decorator."""
238240
cache = {}
239241

240-
def __inner__(*args: typing.Any, **kwargs: typing.Any) -> typing.Any:
242+
def __inner__(*args, **kwargs) -> typing.Any:
241243
_hash = hash((args, tuple(frozenset(sorted(kwargs.items())))))
242244
if _hash not in cache: cache.update({_hash: func(*args, **kwargs)})
243245
return cache.get(_hash, None)
@@ -258,7 +260,7 @@ def SDL_NOT_IMPLEMENTED(name: str) -> abc.Callable[..., None]:
258260
SDL_LOGGER.Log(SDL_LOGGER.Error, f"Invoked an unimplemented function: '{name}'.")
259261

260262
class SDL_FUNC:
261-
def __class_getitem__(cls, key: tuple[str, type, list[type], str]) -> typing.Any:
263+
def __class_getitem__(cls, key: tuple[str, type[ctypes._SimpleCData], list[type[ctypes._SimpleCData]], str]) -> ctypes._CFuncPtr | abc.Callable[..., None]:
262264
"""Create a new ctypes function definition."""
263265

264266
if not (__frozen__ or __release__):
@@ -278,33 +280,33 @@ def __class_getitem__(cls, key: tuple[str, type, list[type], str]) -> typing.Any
278280
if not func and not int(os.environ.get("SDL_IGNORE_MISSING_FUNCTIONS", "1" if __frozen__ or __release__ else "0")) > 0:
279281
SDL_LOGGER.Log(SDL_LOGGER.Warning, f"Function '{key[0]}' not found in binary: '{SDL_BINARY_PATTERNS[SDL_SYSTEM][0].format(key[3])}'.")
280282

281-
if not binary or not func: func = SDL_NOT_IMPLEMENTED(key[0])
282-
func.restype, func.binary = key[1], binary
283+
if not binary or not func: func = SDL_NOT_IMPLEMENTED(key[0]) # type: ignore
284+
func.restype, func.binary = key[1], binary # type: ignore
283285

284286
if ... in key[2]:
285-
def __inner__(*args: typing.Any, **kwargs: typing.Any) -> typing.Any:
286-
for arg in args[len(__inner__.func.argtypes):]:
287-
if isinstance(arg, int): __inner__.func.argtypes += [ctypes.c_int]
288-
elif isinstance(arg, float): __inner__.func.argtypes += [ctypes.c_float]
289-
elif isinstance(arg, bytes): __inner__.func.argtypes += [ctypes.c_char_p]
290-
elif isinstance(arg, bool): __inner__.func.argtypes += [ctypes.c_bool]
291-
else: __inner__.func.argtypes += [arg.__class__]
292-
293-
value = __inner__.func(*args, **kwargs)
294-
__inner__.func.argtypes = key[2][:-1]
287+
def __inner__(*args, **kwargs) -> typing.Any:
288+
for arg in args[len(__inner__.func.argtypes):]: # type: ignore
289+
if isinstance(arg, int): __inner__.func.argtypes += [ctypes.c_int] # type: ignore
290+
elif isinstance(arg, float): __inner__.func.argtypes += [ctypes.c_float] # type: ignore
291+
elif isinstance(arg, bytes): __inner__.func.argtypes += [ctypes.c_char_p] # type: ignore
292+
elif isinstance(arg, bool): __inner__.func.argtypes += [ctypes.c_bool] # type: ignore
293+
else: __inner__.func.argtypes += [arg.__class__] # type: ignore
294+
295+
value = __inner__.func(*args, **kwargs) # type: ignore
296+
__inner__.func.argtypes = key[2][:-1] # type: ignore
295297
return value
296298

297-
func.argtypes, func.vararg = key[2][:-1], True
298-
func, __inner__.func = __inner__, func
299+
func.argtypes, func.vararg = key[2][:-1], True # type: ignore
300+
func, __inner__.func = __inner__, func # type: ignore
299301

300302
else:
301-
func.argtypes, func.vararg = key[2], False
303+
func.argtypes, func.vararg = key[2], False # type: ignore
302304

303305
__module__.functions[key[3]][key[0]] = func
304306
return func
305307

306308
class SDL_POINTER:
307-
def __class_getitem__(cls, key: type) -> type:
309+
def __class_getitem__(cls, key: type[ctypes._SimpleCData]) -> type[ctypes._Pointer]:
308310
"""Create a ctypes pointer type from a ctypes type."""
309311

310312
if not (__frozen__ or __release__):
@@ -313,8 +315,10 @@ def __class_getitem__(cls, key: type) -> type:
313315

314316
return ctypes.POINTER(key)
315317

318+
_T = typing.TypeVar("_T")
319+
316320
class SDL_CAST:
317-
def __class_getitem__(cls, key: tuple[typing.Any, type]) -> typing.Any:
321+
def __class_getitem__(cls, key: tuple[typing.Any, type[_T]]) -> _T:
318322
"""Cast a ctypes pointer to an another type."""
319323

320324
if not (__frozen__ or __release__):
@@ -323,10 +327,10 @@ def __class_getitem__(cls, key: tuple[typing.Any, type]) -> typing.Any:
323327
assert isinstance(key[0], ctypes._Pointer), "Expected a pointer as the first argument."
324328
assert isinstance(key[1], type), "Expected a type as the second argument."
325329

326-
return ctypes.cast(key[0], key[1])
330+
return ctypes.cast(key[0], key[1]) # type: ignore
327331

328332
class SDL_TYPE:
329-
def __class_getitem__(cls, key: tuple[str, type]) -> type:
333+
def __class_getitem__(cls, key: tuple[str, type[_T]]) -> type[_T]:
330334
"""Create a new type from a ctypes type."""
331335

332336
if not (__frozen__ or __release__):
@@ -336,16 +340,16 @@ def __class_getitem__(cls, key: tuple[str, type]) -> type:
336340
assert isinstance(key[1], type), "Expected a type as the second argument."
337341

338342
if hasattr(key[1], "contents"):
339-
return type(key[0], (ctypes._Pointer, ), {"_type_": key[1]._type_, "contents": key[1].contents})
343+
return type(key[0], (ctypes._Pointer, ), {"_type_": key[1]._type_, "contents": key[1].contents}) # type: ignore
340344

341345
elif hasattr(key[1], "_fields_"):
342-
return type(key[0], (ctypes.Structure, ), {"_fields_": key[1]._fields_})
346+
return type(key[0], (ctypes.Structure, ), {"_fields_": key[1]._fields_}) # type: ignore
343347

344348
else:
345-
return type(key[0], (ctypes._SimpleCData, ), {"_type_": key[1]._type_})
349+
return type(key[0], (ctypes._SimpleCData, ), {"_type_": key[1]._type_}) # type: ignore
346350

347351
class SDL_FUNC_TYPE:
348-
def __class_getitem__(cls, key: tuple[str, type, list[type]]) -> type:
352+
def __class_getitem__(cls, key: tuple[str, type[ctypes._SimpleCData], list[type[ctypes._SimpleCData]]]) -> type[ctypes._CFuncPtr]:
349353
"""Create a new ctypes function type."""
350354

351355
if not (__frozen__ or __release__):
@@ -653,7 +657,7 @@ def SDL_GET_FULL_NAME(type: type | None) -> str:
653657

654658
return f"{result}\n{definitions}"
655659

656-
def SDL_GET_OR_GENERATE_DOCS(*args: typing.Any, **kwargs: typing.Any) -> bytes:
660+
def SDL_GET_OR_GENERATE_DOCS(*args, **kwargs) -> bytes:
657661
"""Get type hints and docstrings for SDL3 functions/structures from github or by generating them."""
658662

659663
try:

0 commit comments

Comments
 (0)