Description
Consider the following (after the corrected handling of ISO_C
in #25226):
Ignoring map {'integer':{'c_short':'short int'}}: 'short int' must be in ['double', 'float', 'long_double', 'char', 'signed_char', 'unsigned_char', 'short', 'unsigned_short', 'int', 'long', 'long_long', 'unsigned', 'complex_float', 'complex_double', 'complex_long_double', 'string', 'character']
Ignoring map {'integer':{'c_long':'long int'}}: 'long int' must be in ['double', 'float', 'long_double', 'char', 'signed_char', 'unsigned_char', 'short', 'unsigned_short', 'int', 'long', 'long_long', 'unsigned', 'complex_float', 'complex_double', 'complex_long_double', 'string', 'character']
Ignoring map {'integer':{'c_long_long':'long long int'}}: 'long long int' must be in ['double', 'float', 'long_double', 'char', 'signed_char', 'unsigned_char', 'short', 'unsigned_short', 'int', 'long', 'long_long', 'unsigned', 'complex_float', 'complex_double', 'complex_long_double', 'string', 'character']
Ignoring map {'integer':{'c_signed_char':'signed char'}}: 'signed char' must be in ['double', 'float', 'long_double', 'char', 'signed_char', 'unsigned_char', 'short', 'unsigned_short', 'int', 'long', 'long_long', 'unsigned', 'complex_float', 'complex_double', 'complex_long_double', 'string', 'character']
Ignoring map {'integer':{'c_size_t':'size_t'}}: 'size_t' must be in ['double', 'float', 'long_double', 'char', 'signed_char', 'unsigned_char', 'short', 'unsigned_short', 'int', 'long', 'long_long', 'unsigned', 'complex_float', 'complex_double', 'complex_long_double', 'string', 'character']
Ignoring map {'integer':{'c_int8_t':'int8_t'}}: 'int8_t' must be in ['double', 'float', 'long_double', 'char', 'signed_char', 'unsigned_char', 'short', 'unsigned_short', 'int', 'long', 'long_long', 'unsigned', 'complex_float', 'complex_double', 'complex_long_double', 'string', 'character']
Ignoring map {'integer':{'c_int16_t':'int16_t'}}: 'int16_t' must be in ['double', 'float', 'long_double', 'char', 'signed_char', 'unsigned_char', 'short', 'unsigned_short', 'int', 'long', 'long_long', 'unsigned', 'complex_float', 'complex_double', 'complex_long_double', 'string', 'character']
Ignoring map {'integer':{'c_int32_t':'int32_t'}}: 'int32_t' must be in ['double', 'float', 'long_double', 'char', 'signed_char', 'unsigned_char', 'short', 'unsigned_short', 'int', 'long', 'long_long', 'unsigned', 'complex_float', 'complex_double', 'complex_long_double', 'string', 'character']
Ignoring map {'integer':{'c_int64_t':'int64_t'}}: 'int64_t' must be in ['double', 'float', 'long_double', 'char', 'signed_char', 'unsigned_char', 'short', 'unsigned_short', 'int', 'long', 'long_long', 'unsigned', 'complex_float', 'complex_double', 'complex_long_double', 'string', 'character']
Ignoring map {'integer':{'c_int_least8_t':'int_least8_t'}}: 'int_least8_t' must be in ['double', 'float', 'long_double', 'char', 'signed_char', 'unsigned_char', 'short', 'unsigned_short', 'int', 'long', 'long_long', 'unsigned', 'complex_float', 'complex_double', 'complex_long_double', 'string', 'character']
Ignoring map {'integer':{'c_int_least16_t':'int_least16_t'}}: 'int_least16_t' must be in ['double', 'float', 'long_double', 'char', 'signed_char', 'unsigned_char', 'short', 'unsigned_short', 'int', 'long', 'long_long', 'unsigned', 'complex_float', 'complex_double', 'complex_long_double', 'string', 'character']
Ignoring map {'integer':{'c_int_least32_t':'int_least32_t'}}: 'int_least32_t' must be in ['double', 'float', 'long_double', 'char', 'signed_char', 'unsigned_char', 'short', 'unsigned_short', 'int', 'long', 'long_long', 'unsigned', 'complex_float', 'complex_double', 'complex_long_double', 'string', 'character']
Ignoring map {'integer':{'c_int_least64_t':'int_least64_t'}}: 'int_least64_t' must be in ['double', 'float', 'long_double', 'char', 'signed_char', 'unsigned_char', 'short', 'unsigned_short', 'int', 'long', 'long_long', 'unsigned', 'complex_float', 'complex_double', 'complex_long_double', 'string', 'character']
Ignoring map {'integer':{'c_int_fast8_t':'int_fast8_t'}}: 'int_fast8_t' must be in ['double', 'float', 'long_double', 'char', 'signed_char', 'unsigned_char', 'short', 'unsigned_short', 'int', 'long', 'long_long', 'unsigned', 'complex_float', 'complex_double', 'complex_long_double', 'string', 'character']
Ignoring map {'integer':{'c_int_fast16_t':'int_fast16_t'}}: 'int_fast16_t' must be in ['double', 'float', 'long_double', 'char', 'signed_char', 'unsigned_char', 'short', 'unsigned_short', 'int', 'long', 'long_long', 'unsigned', 'complex_float', 'complex_double', 'complex_long_double', 'string', 'character']
Ignoring map {'integer':{'c_int_fast32_t':'int_fast32_t'}}: 'int_fast32_t' must be in ['double', 'float', 'long_double', 'char', 'signed_char', 'unsigned_char', 'short', 'unsigned_short', 'int', 'long', 'long_long', 'unsigned', 'complex_float', 'complex_double', 'complex_long_double', 'string', 'character']
Ignoring map {'integer':{'c_int_fast64_t':'int_fast64_t'}}: 'int_fast64_t' must be in ['double', 'float', 'long_double', 'char', 'signed_char', 'unsigned_char', 'short', 'unsigned_short', 'int', 'long', 'long_long', 'unsigned', 'complex_float', 'complex_double', 'complex_long_double', 'string', 'character']
Ignoring map {'integer':{'c_intmax_t':'intmax_t'}}: 'intmax_t' must be in ['double', 'float', 'long_double', 'char', 'signed_char', 'unsigned_char', 'short', 'unsigned_short', 'int', 'long', 'long_long', 'unsigned', 'complex_float', 'complex_double', 'complex_long_double', 'string', 'character']
Ignoring map {'integer':{'c_intptr_t':'intptr_t'}}: 'intptr_t' must be in ['double', 'float', 'long_double', 'char', 'signed_char', 'unsigned_char', 'short', 'unsigned_short', 'int', 'long', 'long_long', 'unsigned', 'complex_float', 'complex_double', 'complex_long_double', 'string', 'character']
Ignoring map {'integer':{'c_ptrdiff_t':'intptr_t'}}: 'intptr_t' must be in ['double', 'float', 'long_double', 'char', 'signed_char', 'unsigned_char', 'short', 'unsigned_short', 'int', 'long', 'long_long', 'unsigned', 'complex_float', 'complex_double', 'complex_long_double', 'string', 'character']
Mapping "real(kind=c_float)" to "float"
Mapping "real(kind=c_double)" to "double"
Ignoring map {'real':{'c_long_double':'long double'}}: 'long double' must be in ['double', 'float', 'long_double', 'char', 'signed_char', 'unsigned_char', 'short', 'unsigned_short', 'int', 'long', 'long_long', 'unsigned', 'complex_float', 'complex_double', 'complex_long_double', 'string', 'character']
Ignoring map {'complex':{'c_float_complex':'float _Complex'}}: 'float _Complex' must be in ['double', 'float', 'long_double', 'char', 'signed_char', 'unsigned_char', 'short', 'unsigned_short', 'int', 'long', 'long_long', 'unsigned', 'complex_float', 'complex_double', 'complex_long_double', 'string', 'character']
Ignoring map {'complex':{'c_double_complex':'double _Complex'}}: 'double _Complex' must be in ['double', 'float', 'long_double', 'char', 'signed_char', 'unsigned_char', 'short', 'unsigned_short', 'int', 'long', 'long_long', 'unsigned', 'complex_float', 'complex_double', 'complex_long_double', 'string', 'character']
Ignoring map {'complex':{'c_long_double_complex':'long double _Complex'}}: 'long double _Complex' must be in ['double', 'float', 'long_double', 'char', 'signed_char', 'unsigned_char', 'short', 'unsigned_short', 'int', 'long', 'long_long', 'unsigned', 'complex_float', 'complex_double', 'complex_long_double', 'string', 'character']
Ignoring map {'logical':{'c_bool':'_Bool'}}: '_Bool' must be in ['double', 'float', 'long_double', 'char', 'signed_char', 'unsigned_char', 'short', 'unsigned_short', 'int', 'long', 'long_long', 'unsigned', 'complex_float', 'complex_double', 'complex_long_double', 'string', 'character']
Mapping "character(kind=c_char)" to "char"
Which can be seen by passing verbose = True
to process_f2cmap_dict
while mapping the iso_c
values in capi_maps.py
. To silence these, there are the (commented out) entries in iso_c2py_map
in _isocbind.py
.
The reason they are commented out is, otherwise, F2PY will internally construct and try to use "construction" functions like these:
needs['short_from_pyobj'] = ['int_from_pyobj']
cfuncs['short_from_pyobj'] = """
static int
short_from_pyobj(short* v, PyObject *obj, const char *errmess) {
int i = 0;
if (int_from_pyobj(&i, obj, errmess)) {
*v = (short)i;
return 1;
}
return 0;
}
Which are defined in cfuncs.py
. Now most of these (almost all) follow a pattern, they just cast and call int_from_pyobj
or similar. However, for the iso_c
(and really in general for the remaining C types) there should be similar functions.
Solution
This could be copy pasted, but really they should be generated on the fly out of templates like the meson
backend and its meson.build
backend. That would also finally allow for syntax highlighting, currently modifying the cfuncs.py
C code is rather painful.
Addenum
For #25226 the mapping of types isn't really required. Here are the changes needed to _isocbind.py
to reproduce the issue:
iso_c_binding_map = {
'integer': {
'c_int': 'int',
'c_short': 'short int',
'c_long': 'long int',
'c_long_long': 'long long int',
'c_signed_char': 'signed char',
'c_size_t': 'size_t',
'c_int8_t': 'int8_t',
'c_int16_t': 'int16_t',
'c_int32_t': 'int32_t',
'c_int64_t': 'int64_t',
'c_int_least8_t': 'int_least8_t',
'c_int_least16_t': 'int_least16_t',
'c_int_least32_t': 'int_least32_t',
'c_int_least64_t': 'int_least64_t',
'c_int_fast8_t': 'int_fast8_t',
'c_int_fast16_t': 'int_fast16_t',
'c_int_fast32_t': 'int_fast32_t',
'c_int_fast64_t': 'int_fast64_t',
'c_intmax_t': 'intmax_t',
'c_intptr_t': 'intptr_t',
'c_ptrdiff_t': 'intptr_t',
},
'real': {
'c_float': 'float',
'c_double': 'double',
'c_long_double': 'long double'
},
'complex': {
'c_float_complex': 'float _Complex',
'c_double_complex': 'double _Complex',
'c_long_double_complex': 'long double _Complex'
},
'logical': {
'c_bool': '_Bool'
},
'character': {
'c_char': 'char'
}
}
# TODO: At some point these should be included, but then they'd need special
# handling in cfuncs.py e.g. needs[int64_t_from_pyobj] These are not very hard
# to add, since they all derive from the base `int_from_pyobj`, e.g. the way
# `short_from_pyobj` and others do
isoc_c2pycode_map = {
'int': 'i', # int
'short int': 'h', # short int
'long': 'l', # long int
'long long': 'q', # long long int
'signed char': 'b', # signed char
'size_t': 'I', # size_t (approx unsigned int)
'int8_t': 'b', # int8_t
'int16_t': 'h', # int16_t
'int32_t': 'i', # int32_t
'int64_t': 'q', # int64_t
'int_least8_t': 'b', # int_least8_t
'int_least16_t': 'h', # int_least16_t
'int_least32_t': 'i', # int_least32_t
'int_least64_t': 'q', # int_least64_t
'int_fast8_t': 'b', # int_fast8_t
'int_fast16_t': 'h', # int_fast16_t
'int_fast32_t': 'i', # int_fast32_t
'int_fast64_t': 'q', # int_fast64_t
'intmax_t': 'q', # intmax_t (approx long long)
'intptr_t': 'q', # intptr_t (approx long long)
'ptrdiff_t': 'q', # intptr_t (approx long long)
'float': 'f', # float
'double': 'd', # double
'long double': 'g', # long double
'float _Complex': 'F', # float _Complex
'double _Complex': 'D', # double _Complex
'long double _Complex': 'D', # very approximate complex
'_Bool': 'i', # Bool but not really
'char': 'c', # char
}
iso_c2py_map = {
'int': 'int',
'short int': 'int', # forced casting
'long': 'int',
'long long': 'long',
'signed char': 'int', # forced casting
'size_t': 'int', # approx Python int
'int8_t': 'int', # forced casting
'int16_t': 'int', # forced casting
'int32_t': 'int',
'int64_t': 'long',
'int_least8_t': 'int', # forced casting
'int_least16_t': 'int', # forced casting
'int_least32_t': 'int',
'int_least64_t': 'long',
'int_fast8_t': 'int', # forced casting
'int_fast16_t': 'int', # forced casting
'int_fast32_t': 'int',
'int_fast64_t': 'long',
'intmax_t': 'long',
'intptr_t': 'long',
'ptrdiff_t': 'long',
'float': 'float',
'double': 'float', # forced casting
'long double': 'float', # forced casting
'float _Complex': 'complex', # forced casting
'double _Complex': 'complex',
'long double _Complex': 'complex', # forced casting
'_Bool': 'bool',
'char': 'bytes', # approx Python bytes
}