@@ -222,8 +222,12 @@ def source_line_to_tokens(tokens: Iterable[tokenize.TokenInfo]) -> Dict[int, Lis
222
222
return line_to_tokens
223
223
224
224
225
- def get_subsequent_assign_lines (source_cls : str ) -> Set [int ]:
226
- """For all multiline assign statements, get the line numbers after the first line in the assignment."""
225
+ def get_subsequent_assign_lines (source_cls : str ) -> Tuple [Set [int ], Set [int ]]:
226
+ """For all multiline assign statements, get the line numbers after the first line in the assignment.
227
+
228
+ :param source_cls: The source code of the class.
229
+ :return: A set of intermediate line numbers for multiline assign statements and a set of final line numbers.
230
+ """
227
231
# Parse source code using ast (with an if statement to avoid indentation errors)
228
232
source = f"if True:\n { textwrap .indent (source_cls , ' ' )} "
229
233
body = ast .parse (source ).body [0 ]
@@ -236,37 +240,43 @@ def get_subsequent_assign_lines(source_cls: str) -> Set[int]:
236
240
# Check for correct parsing
237
241
if not isinstance (body , ast .If ):
238
242
warnings .warn (parse_warning )
239
- return set ()
243
+ return set (), set ()
240
244
241
245
# Extract if body
242
246
if_body = body .body
243
247
244
248
# Check for a single body
245
249
if len (if_body ) != 1 :
246
250
warnings .warn (parse_warning )
247
- return set ()
251
+ return set (), set ()
248
252
249
253
# Extract class body
250
254
cls_body = if_body [0 ]
251
255
252
256
# Check for a single class definition
253
257
if not isinstance (cls_body , ast .ClassDef ):
254
258
warnings .warn (parse_warning )
255
- return set ()
259
+ return set (), set ()
256
260
257
261
# Get line numbers of assign statements
258
- assign_lines = set ()
262
+ intermediate_assign_lines = set ()
263
+ final_assign_lines = set ()
259
264
for node in cls_body .body :
260
265
if isinstance (node , (ast .Assign , ast .AnnAssign )):
261
266
# Check if the end line number is found
262
267
if node .end_lineno is None :
263
268
warnings .warn (parse_warning )
264
269
continue
265
270
266
- # Get line number of assign statement excluding the first line (and minus 1 for the if statement)
267
- assign_lines |= set (range (node .lineno , node .end_lineno ))
271
+ # Only consider multiline assign statements
272
+ if node .end_lineno > node .lineno :
273
+ # Get intermediate line number of assign statement excluding the first line (and minus 1 for the if statement)
274
+ intermediate_assign_lines |= set (range (node .lineno , node .end_lineno - 1 ))
275
+
276
+ # If multiline assign statement, get the line number of the last line (and minus 1 for the if statement)
277
+ final_assign_lines .add (node .end_lineno - 1 )
268
278
269
- return assign_lines
279
+ return intermediate_assign_lines , final_assign_lines
270
280
271
281
272
282
def get_class_variables (cls : type ) -> Dict [str , Dict [str , str ]]:
@@ -283,14 +293,25 @@ def get_class_variables(cls: type) -> Dict[str, Dict[str, str]]:
283
293
284
294
# For all multiline assign statements, get the line numbers after the first line of the assignment
285
295
# This is used to avoid identifying comments in multiline assign statements
286
- subsequent_assign_lines = get_subsequent_assign_lines (source_cls )
296
+ intermediate_assign_lines , final_assign_lines = get_subsequent_assign_lines (source_cls )
287
297
288
298
# Extract class variables
289
299
class_variable = None
290
300
variable_to_comment = {}
291
301
for line , tokens in line_to_tokens .items ():
302
+ # If this is the final line of a multiline assign, extract any potential comments
303
+ if line in final_assign_lines :
304
+ # Find the comment (if it exists)
305
+ for token in tokens :
306
+ print (token )
307
+ if token ["token_type" ] == tokenize .COMMENT :
308
+ # Leave out "#" and whitespace from comment
309
+ variable_to_comment [class_variable ]["comment" ] = token ["token" ][1 :].strip ()
310
+ break
311
+ continue
312
+
292
313
# Skip assign lines after the first line of multiline assign statements
293
- if line in subsequent_assign_lines :
314
+ if line in intermediate_assign_lines :
294
315
continue
295
316
296
317
for i , token in enumerate (tokens ):
0 commit comments