@@ -85,6 +85,10 @@ def call_assign_regex(name):
8585 return re .compile (regex )
8686
8787
88+ def optional_ptr_cast (to_type ):
89+ return fr'(?:\({ to_type } \s*\*\){ SPACE_REGEX } *)?'
90+
91+
8892def is_c_filename (filename ):
8993 return filename .endswith (C_FILE_EXT )
9094
@@ -249,28 +253,48 @@ class Py_INCREF_return(Operation):
249253 (re .compile (fr'({ INDENTATION_REGEX } )'
250254 + fr'Py_(X?)INCREF\(({ EXPR_REGEX } )\)\s*;'
251255 + same_indentation (r'\1' )
252- + r'return \3;' ,
256+ + r'return ' + optional_ptr_cast ( 'PyObject' ) + r' \3;' ,
253257 re .MULTILINE ),
254258 r'\1return Py_\2NewRef(\3);' ),
255259
256260 # Same regex than the previous one,
257261 # but the two statements are on the same line.
258262 (re .compile (fr'Py_(X?)INCREF\(({ EXPR_REGEX } )\)\s*;'
259263 + fr'{ SPACE_REGEX } *'
260- + r'return \2;' ,
264+ + r'return ' + optional_ptr_cast ( 'PyObject' ) + r' \2;' ,
261265 re .MULTILINE ),
262266 r'return Py_\1NewRef(\2);' ),
263267 )
264268 # Need Py_NewRef(): new in Python 3.10
265269 NEED_PYTHONCAPI_COMPAT = True
266270
267271
268- def optional_ptr_cast (to_type ):
269- return fr'(?:\({ to_type } \s*\*\))?'
270-
271272class Py_INCREF_assign (Operation ):
272273 NAME = "Py_INCREF_assign"
274+ # "Py_INCREF(x); y = x;" must be replaced before "y = x; Py_INCREF(y);",
275+ # to not miss consecutive "Py_INCREF; assign; Py_INCREF; assign; ..."
276+ # (see unit tests)
273277 REPLACE = (
278+ # "Py_INCREF(x); y = x;" => "y = Py_NewRef(x)"
279+ # "Py_XINCREF(x); y = x;" => "y = Py_XNewRef(x)"
280+ # The two statements must have the same indentation, otherwise the
281+ # regex does not match.
282+ (re .compile (fr'({ INDENTATION_REGEX } )'
283+ + fr'Py_(X?)INCREF\(({ EXPR_REGEX } )\);'
284+ + same_indentation (r'\1' )
285+ + assign_regex_str (fr'({ EXPR_REGEX } )' ,
286+ optional_ptr_cast ('PyObject' ) + r'\3' ),
287+ re .MULTILINE ),
288+ r'\1\4 = Py_\2NewRef(\3);' ),
289+
290+ # Same regex than the previous one,
291+ # but the two statements are on the same line.
292+ (re .compile (fr'Py_(X?)INCREF\(({ EXPR_REGEX } )\);'
293+ + fr'{ SPACE_REGEX } *'
294+ + assign_regex_str (fr'({ EXPR_REGEX } )' ,
295+ optional_ptr_cast ('PyObject' ) + r'\2' )),
296+ r'\3 = Py_\1NewRef(\2);' ),
297+
274298 # "y = x; Py_INCREF(x);" => "y = Py_NewRef(x);"
275299 # "y = x; Py_INCREF(y);" => "y = Py_NewRef(x);"
276300 # "y = x; Py_XINCREF(x);" => "y = Py_XNewRef(x);"
@@ -293,26 +317,6 @@ class Py_INCREF_assign(Operation):
293317 + fr'{ SPACE_REGEX } *'
294318 + r'Py_(X?)INCREF\((?:\1|\2)\);' ),
295319 r'\1 = Py_\3NewRef(\2);' ),
296-
297- # "Py_INCREF(x); y = x;" => "y = Py_NewRef(x)"
298- # "Py_XINCREF(x); y = x;" => "y = Py_XNewRef(x)"
299- # The two statements must have the same indentation, otherwise the
300- # regex does not match.
301- (re .compile (fr'({ INDENTATION_REGEX } )'
302- + fr'Py_(X?)INCREF\(({ EXPR_REGEX } )\);'
303- + same_indentation (r'\1' )
304- + assign_regex_str (fr'({ EXPR_REGEX } )' ,
305- optional_ptr_cast ('PyObject' ) + r'\3' ),
306- re .MULTILINE ),
307- r'\1\4 = Py_\2NewRef(\3);' ),
308-
309- # Same regex than the previous one,
310- # but the two statements are on the same line.
311- (re .compile (fr'Py_(X?)INCREF\(({ EXPR_REGEX } )\);'
312- + fr'{ SPACE_REGEX } *'
313- + assign_regex_str (fr'({ EXPR_REGEX } )' ,
314- optional_ptr_cast ('PyObject' ) + r'\2' )),
315- r'\3 = Py_\1NewRef(\2);' ),
316320 )
317321 # Need Py_NewRef(): new in Python 3.10
318322 NEED_PYTHONCAPI_COMPAT = True
0 commit comments