60
60
# {ID => reason}
61
61
}
62
62
63
+ # XXX We should be handling these through known.tsv.
64
+ _OTHER_SUPPORTED_TYPES = {
65
+ # Holds tuple of strings, which we statically initialize:
66
+ '_PyArg_Parser' ,
67
+ # Uses of these should be const, but we don't worry about it.
68
+ 'PyModuleDef' ,
69
+ 'PyModuleDef_Slot[]' ,
70
+ 'PyType_Spec' ,
71
+ 'PyType_Slot[]' ,
72
+ 'PyMethodDef' ,
73
+ 'PyMethodDef[]' ,
74
+ 'PyMemberDef[]' ,
75
+ 'PyGetSetDef[]' ,
76
+ 'PyNumberMethods' ,
77
+ 'PySequenceMethods' ,
78
+ 'PyMappingMethods' ,
79
+ 'PyAsyncMethods' ,
80
+ 'PyBufferProcs' ,
81
+ 'PyStructSequence_Field[]' ,
82
+ 'PyStructSequence_Desc' ,
83
+ }
84
+
85
+ # XXX We should normalize all cases to a single name,
86
+ # e.g. "kwlist" (currently the most common).
87
+ _KWLIST_VARIANTS = [
88
+ ('*' , 'kwlist' ),
89
+ ('*' , 'keywords' ),
90
+ ('*' , 'kwargs' ),
91
+ ('Modules/_csv.c' , 'dialect_kws' ),
92
+ ('Modules/_datetimemodule.c' , 'date_kws' ),
93
+ ('Modules/_datetimemodule.c' , 'datetime_kws' ),
94
+ ('Modules/_datetimemodule.c' , 'time_kws' ),
95
+ ('Modules/_datetimemodule.c' , 'timezone_kws' ),
96
+ ('Modules/_lzmamodule.c' , 'optnames' ),
97
+ ('Modules/_lzmamodule.c' , 'arg_names' ),
98
+ ('Modules/cjkcodecs/multibytecodec.c' , 'incnewkwarglist' ),
99
+ ('Modules/cjkcodecs/multibytecodec.c' , 'streamkwarglist' ),
100
+ ('Modules/socketmodule.c' , 'kwnames' ),
101
+ ]
102
+
63
103
KINDS = frozenset ((* KIND .TYPES , KIND .VARIABLE ))
64
104
65
105
@@ -202,6 +242,8 @@ def _check_typedep(decl, typedecl, types, knowntypes):
202
242
# XXX Fail?
203
243
return 'typespec (missing)'
204
244
elif typedecl is _info .UNKNOWN :
245
+ if _has_other_supported_type (decl ):
246
+ return None
205
247
# XXX Is this right?
206
248
return 'typespec (unknown)'
207
249
elif not isinstance (typedecl , TypeDeclaration ):
@@ -216,12 +258,42 @@ def _check_typedep(decl, typedecl, types, knowntypes):
216
258
elif decl .kind is KIND .VARIABLE :
217
259
if not is_process_global (decl ):
218
260
return None
261
+ if _is_kwlist (decl ):
262
+ return None
263
+ if _has_other_supported_type (decl ):
264
+ return None
219
265
checked = _check_vartype (decl , typedecl , types , knowntypes )
220
266
return 'mutable' if checked is FIXED_TYPE else checked
221
267
else :
222
268
raise NotImplementedError (decl )
223
269
224
270
271
+ def _is_kwlist (decl ):
272
+ # keywords for PyArg_ParseTupleAndKeywords()
273
+ # "static char *name[]" -> "static const char * const name[]"
274
+ # XXX These should be made const.
275
+ for relpath , name in _KWLIST_VARIANTS :
276
+ if decl .name == name :
277
+ if relpath == '*' :
278
+ break
279
+ assert os .path .isabs (decl .file .filename )
280
+ relpath = os .path .normpath (relpath )
281
+ if decl .file .filename .endswith (os .path .sep + relpath ):
282
+ break
283
+ else :
284
+ return False
285
+ vartype = '' .join (str (decl .vartype ).split ())
286
+ return vartype == 'char*[]'
287
+
288
+
289
+ def _has_other_supported_type (decl ):
290
+ vartype = str (decl .vartype ).split ()
291
+ if vartype [0 ] == 'struct' :
292
+ vartype = vartype [1 :]
293
+ vartype = '' .join (vartype )
294
+ return vartype in _OTHER_SUPPORTED_TYPES
295
+
296
+
225
297
def _check_vartype (decl , typedecl , types , knowntypes ):
226
298
"""Return failure reason."""
227
299
checked = _check_typespec (decl , typedecl , types , knowntypes )
0 commit comments