DeinAlptraum wrote:

@Endilll I think I might not have been clear, the issue I am the most concerned 
about is the following.
As an example, consider `clang_PrintingPolicy_getProperty`. Previously, it was 
defined in `FUNCTION_LIST` as

```python
("clang_PrintingPolicy_getProperty", [PrintingPolicy, c_int], c_uint),
```
and correspondingly, its signature in the `ClangLib` protocol in this PR is
```python
def clang_PrintingPolicy_getProperty(self, arg1: PrintingPolicy, arg2: c_int) 
-> c_uint: ...
```
Then the `_get_annotations` function can extract the argument and return types 
to correctly register the C function on the library object, with these `c_int`, 
`c_uint` types. The problem is, `ctypes` adds automatic conversion here _once 
the function is registered_. So after the registration, the second argument 
expects a Python `int`, and it also returns a Python `int`. So our interface 
would have to be correctly annotated as
```python
    def get_property(self, property: PrintingPolicyProperty) -> int:
        """Get a property value for the given printing policy."""
        return conf.lib.clang_PrintingPolicy_getProperty(self, property.value)
```
but that leads to the following type errors:
```
clang/cindex.py:3980: error: Incompatible return value type (got "c_uint", 
expected "int")  [return-value]
clang/cindex.py:3980: error: Argument 2 to "clang_PrintingPolicy_getProperty" 
of "ClangLib" has incompatible type "int"; expected "c_int"  [arg-type]
```
I.e. the library function automatically converts Python `int` to `c_int` when 
they are passed, and the `c_uint` to a Python `int` on return. This is why our 
interface implementation also passes a Python `int` (`property.value`) into the 
function and can return a Python `int` without having to call any conversion 
functions. The above annotation of the interface is thus correct, but due to 
the automatic conversion, the previous annotation on the `ClangLib` protocol 
are now incorrect, leading to the type-checker errors (the code itself runs 
perfectly fine). 

Unfortunately, I don't see a way around this: we need to register the functions 
on the library object by explicitly giving it the corresponding `ctypes` types, 
and we need to annotate the `ClangLib` protocol with the Python types in order 
for type-checking to get reasonable results. As we want to derive the library 
function types from the annotations, we need a map from Python types to 
`ctypes` types, but this is not possible due to the ambiguity e.g. Python `int` 
maps to both `c_int` and `c_uint`.

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