@@ -111,13 +111,16 @@ def quoted_for_c_string(s):
111111def is_legal_py_identifier (s ):
112112 return all (is_legal_c_identifier (field ) for field in s .split ('.' ))
113113
114- # added "module", "self", "cls", and "null" just to be safe
115- # (clinic will generate variables with these names)
114+ # though it's called c_keywords, really it's a list of parameter names
115+ # that are okay in Python but aren't a good idea in C. so if they're used
116+ # Argument Clinic will add "_value" to the end of the name in C.
117+ # (We added "args", "type", "module", "self", "cls", and "null"
118+ # just to be safe, even though they're not C keywords.)
116119c_keywords = set ("""
117- asm auto break case char cls const continue default do double
120+ args asm auto break case char cls const continue default do double
118121else enum extern float for goto if inline int long module null
119122register return self short signed sizeof static struct switch
120- typedef typeof union unsigned void volatile while
123+ type typedef typeof union unsigned void volatile while
121124""" .strip ().split ())
122125
123126def ensure_legal_c_identifier (s ):
@@ -392,11 +395,17 @@ def docstring_for_c_string(self, f):
392395
393396 @staticmethod
394397 def template_base (* args ):
395- flags = '|' . join ( f for f in args if f )
396- return """
398+ # HACK suppress methoddef define for METHOD_NEW and METHOD_INIT
399+ base = """
397400PyDoc_STRVAR({c_basename}__doc__,
398401{docstring});
402+ """
403+
404+ if args [- 1 ] == None :
405+ return base
399406
407+ flags = '|' .join (f for f in args if f )
408+ return base + """
400409#define {methoddef_name} \\
401410 {{"{name}", (PyCFunction){c_basename}, {methoddef_flags}, {c_basename}__doc__}},
402411""" .replace ('{methoddef_flags}' , flags )
@@ -650,7 +659,13 @@ def render_function(self, f):
650659 name = full_name .rpartition ('.' )[2 ]
651660 template_dict ['name' ] = name
652661
653- c_basename = f .c_basename or full_name .replace ("." , "_" )
662+ if f .c_basename :
663+ c_basename = f .c_basename
664+ else :
665+ fields = full_name .split ("." )
666+ if fields [- 1 ] == '__new__' :
667+ fields .pop ()
668+ c_basename = "_" .join (fields )
654669 template_dict ['c_basename' ] = c_basename
655670
656671 methoddef_name = "{}_METHODDEF" .format (c_basename .upper ())
@@ -1171,8 +1186,81 @@ def __init__(self, name, module=None, cls=None):
11711186 def __repr__ (self ):
11721187 return "<clinic.Class " + repr (self .name ) + " at " + str (id (self )) + ">"
11731188
1189+ unsupported_special_methods = set ("""
1190+
1191+ __abs__
1192+ __add__
1193+ __and__
1194+ __bytes__
1195+ __call__
1196+ __complex__
1197+ __delitem__
1198+ __divmod__
1199+ __eq__
1200+ __float__
1201+ __floordiv__
1202+ __ge__
1203+ __getattr__
1204+ __getattribute__
1205+ __getitem__
1206+ __gt__
1207+ __hash__
1208+ __iadd__
1209+ __iand__
1210+ __idivmod__
1211+ __ifloordiv__
1212+ __ilshift__
1213+ __imod__
1214+ __imul__
1215+ __index__
1216+ __int__
1217+ __invert__
1218+ __ior__
1219+ __ipow__
1220+ __irshift__
1221+ __isub__
1222+ __iter__
1223+ __itruediv__
1224+ __ixor__
1225+ __le__
1226+ __len__
1227+ __lshift__
1228+ __lt__
1229+ __mod__
1230+ __mul__
1231+ __neg__
1232+ __new__
1233+ __next__
1234+ __or__
1235+ __pos__
1236+ __pow__
1237+ __radd__
1238+ __rand__
1239+ __rdivmod__
1240+ __repr__
1241+ __rfloordiv__
1242+ __rlshift__
1243+ __rmod__
1244+ __rmul__
1245+ __ror__
1246+ __round__
1247+ __rpow__
1248+ __rrshift__
1249+ __rshift__
1250+ __rsub__
1251+ __rtruediv__
1252+ __rxor__
1253+ __setattr__
1254+ __setitem__
1255+ __str__
1256+ __sub__
1257+ __truediv__
1258+ __xor__
11741259
1175- DATA , CALLABLE , METHOD , STATIC_METHOD , CLASS_METHOD = range (5 )
1260+ """ .strip ().split ())
1261+
1262+
1263+ INVALID , CALLABLE , STATIC_METHOD , CLASS_METHOD , METHOD_INIT , METHOD_NEW = range (6 )
11761264
11771265class Function :
11781266 """
@@ -1207,6 +1295,8 @@ def __init__(self, parameters=None, *, name,
12071295
12081296 @property
12091297 def methoddef_flags (self ):
1298+ if self .kind in (METHOD_INIT , METHOD_NEW ):
1299+ return None
12101300 flags = []
12111301 if self .kind == CLASS_METHOD :
12121302 flags .append ('METH_CLASS' )
@@ -1846,7 +1936,7 @@ class self_converter(CConverter):
18461936 type = "PyObject *"
18471937 def converter_init (self , * , type = None ):
18481938 f = self .function
1849- if f .kind == CALLABLE :
1939+ if f .kind in ( CALLABLE , METHOD_INIT ) :
18501940 if f .cls :
18511941 self .name = "self"
18521942 else :
@@ -1858,6 +1948,9 @@ def converter_init(self, *, type=None):
18581948 elif f .kind == CLASS_METHOD :
18591949 self .name = "cls"
18601950 self .type = "PyTypeObject *"
1951+ elif f .kind == METHOD_NEW :
1952+ self .name = "type"
1953+ self .type = "PyTypeObject *"
18611954
18621955 if type :
18631956 self .type = type
@@ -2258,6 +2351,18 @@ def state_modulename_name(self, line):
22582351 function_name = fields .pop ()
22592352 module , cls = self .clinic ._module_and_class (fields )
22602353
2354+ fields = full_name .split ('.' )
2355+ if fields [- 1 ] == '__new__' :
2356+ if (self .kind != CLASS_METHOD ) or (not cls ):
2357+ fail ("__new__ must be a class method!" )
2358+ self .kind = METHOD_NEW
2359+ elif fields [- 1 ] == '__init__' :
2360+ if (self .kind != CALLABLE ) or (not cls ):
2361+ fail ("__init__ must be a normal method, not a class or static method!" )
2362+ self .kind = METHOD_INIT
2363+ elif fields [- 1 ] in unsupported_special_methods :
2364+ fail (fields [- 1 ] + " should not be converted to Argument Clinic! (Yet.)" )
2365+
22612366 if not module :
22622367 fail ("Undefined module used in declaration of " + repr (full_name .strip ()) + "." )
22632368 self .function = Function (name = function_name , full_name = full_name , module = module , cls = cls , c_basename = c_basename ,
0 commit comments