DeinAlptraum wrote:

@Endilll this is an attempt at implementing what we've discussed previously: 
defining the library function signatures only in a single place in a way that 
serves both as type annotations for the library functions and registering the 
correct library function types on the lib object. This PR seems to work as is 
(at least all unit tests pass, except for a single one that I was too lazy to 
adapt for the PoC) but it has several issues, namely

1. the biggest one: it seems that, once a function has been registered 
(=argument and return types defined on the lib object) they are automatically 
converted as far as possible. To quote from 
https://docs.python.org/3/library/ctypes.html
> Specifying a format protects against incompatible argument types (just as a 
> prototype for a C function), and tries to convert the arguments to valid types

> When a foreign function is called, each actual argument is passed to the 
> [from_param()](https://docs.python.org/3/library/ctypes.html#ctypes._CData.from_param)
>  class method of the items in the 
> [argtypes](https://docs.python.org/3/library/ctypes.html#ctypes._CFuncPtr.argtypes)
>  tuple, this method allows adapting the actual argument to an object that the 
> foreign function accepts. For example, **a 
> [c_char_p](https://docs.python.org/3/library/ctypes.html#ctypes.c_char_p) 
> item in the 
> [argtypes](https://docs.python.org/3/library/ctypes.html#ctypes._CFuncPtr.argtypes)
>  tuple will convert a string passed as argument into a bytes object using 
> ctypes conversion rules**.

> Fundamental data types, when returned as foreign function call results, [...] 
> are transparently converted to native Python types. In other words, **if a 
> foreign function has a 
> [restype](https://docs.python.org/3/library/ctypes.html#ctypes._CFuncPtr.restype)
>  of 
> [c_char_p](https://docs.python.org/3/library/ctypes.html#ctypes.c_char_p), 
> you will always receive a Python bytes object, not a 
> [c_char_p](https://docs.python.org/3/library/ctypes.html#ctypes.c_char_p) 
> instance**.

 That explains why we don't have to do any conversion between C types and 
Python types at the boundary between the lib object and the Python interface. 
Unfortunately, it also means that, while we need to annotate the library 
functions with C Types such as `c_int` so that these can be read out and 
properly registered on the library object, after these are registered at 
runtime these types become wrong so the type checker complains at almost every 
function call that we don't actually pass in or return e.g. a `c_int` but a 
normal Python `int`. 

2. `ctypes` uses function calls to generate certain types used when registering 
functions at runtime. E.g. pointer types are generated by calling 
`POINTER(sometype)`. The type checker doesn't call functions so it cannot use 
these for annotations. These specific function calls just wrap the type in the 
`_Pointer` generic, which makes for a valid type annotation as 
`_Pointer[sometype]` - the ugly thing is, I need to convert between these via 
string manipulation to convert `_Pointer` type annotations to a `POINTER()` 
call when registering the function. The way this makes the types used for 
function registration less transparent makes me uncomfortable.
3. Adding on to 2., there is also the `CFUNCTYPE()` used for generating the 
types for the callback functions, similar to `POINTER()`, but it goes beyond 
simple wrapping so there is no way to annotate these correctly. I had to 
annotate these as *the actual generated function objects* so the functions can 
be registered properly, but the type checker complains correctly that these are 
not valid types.

Sorry, I hope this was comprehensible, the issues are a bit involved... Would 
love to hear your opinion on this, but imo this seems like it adds too many 
workarounds and intransparencies, and there's so many unsolvable issues that we 
end up with almost no benefit.

https://github.com/llvm/llvm-project/pull/142120
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to