6060 # {ID => reason}
6161}
6262
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+
63103KINDS = frozenset ((* KIND .TYPES , KIND .VARIABLE ))
64104
65105
@@ -202,6 +242,8 @@ def _check_typedep(decl, typedecl, types, knowntypes):
202242 # XXX Fail?
203243 return 'typespec (missing)'
204244 elif typedecl is _info .UNKNOWN :
245+ if _has_other_supported_type (decl ):
246+ return None
205247 # XXX Is this right?
206248 return 'typespec (unknown)'
207249 elif not isinstance (typedecl , TypeDeclaration ):
@@ -216,12 +258,42 @@ def _check_typedep(decl, typedecl, types, knowntypes):
216258 elif decl .kind is KIND .VARIABLE :
217259 if not is_process_global (decl ):
218260 return None
261+ if _is_kwlist (decl ):
262+ return None
263+ if _has_other_supported_type (decl ):
264+ return None
219265 checked = _check_vartype (decl , typedecl , types , knowntypes )
220266 return 'mutable' if checked is FIXED_TYPE else checked
221267 else :
222268 raise NotImplementedError (decl )
223269
224270
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+
225297def _check_vartype (decl , typedecl , types , knowntypes ):
226298 """Return failure reason."""
227299 checked = _check_typespec (decl , typedecl , types , knowntypes )
0 commit comments