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