Issue
Given the code for a class definition, I am trying to extract all attributes and their comments (""
empty string if no comments).
class Player(Schema):
score = fields.Float()
"""
Total points from killing zombies and finding treasures
"""
name = fields.String()
age = fields.Int()
backpack = fields.Nested(
PlayerBackpackInventoryItem,
missing=[PlayerBackpackInventoryItem.from_name("knife")],
)
"""
Collection of items that a player can store in their backpack
"""
In the above example, we expected the parsed result to be:
[
("score", "Total points from killing zombies and finding treasures"),
("name", ""),
("age", ""),
("backpack", "Collection of items that a player can store in their backpack")
]
In my attempt below, it is failing to extract the comments properly, giving an output:
[
('score', 'Total points from killing zombies and finding treasures'),
('name', ''),
('age', ''),
('backpack', '')
]
How can the regex expression (or even the entire parsing logic) be fixed to handle the situations present in the example class code?
Thanks
import re
code_block = '''class Player(Schema):
score = fields.Float()
"""
Total points from killing zombies and finding treasures
"""
name = fields.String()
age = fields.Int()
backpack = fields.Nested(
PlayerBackpackInventoryItem,
missing=[PlayerBackpackInventoryItem.from_name("knife")],
)
"""
Collection of items that a player can store in their backpack
"""
'''
def parse_schema_comments(code):
# Regular expression pattern to match field names and multiline comments
pattern = r'(\w+)\s*=\s*fields\.\w+\([^\)]*\)(?:\n\s*"""\n(.*?)\n\s*""")?'
# Find all matches using the pattern
matches = re.findall(pattern, code, re.DOTALL)
# Process the matches to format them as required
result = []
for match in matches:
field_name, comment = match
comment = comment.strip() if comment else ""
result.append((field_name, comment))
return result
parsed_comments = parse_schema_comments(code_block)
print(parsed_comments)
Solution
I might use ast, e.g.:
import ast
code_block = '''class Player(Schema):
score = fields.Float()
"""
Total points from killing zombies and finding treasures
"""
name = fields.String()
age = fields.Int()
backpack = fields.Nested(
PlayerBackpackInventoryItem,
missing=[PlayerBackpackInventoryItem.from_name("knife")],
)
"""
Collection of items that a player can store in their backpack
"""
'''
doc = {}
for x in ast.parse(code_block).body[0].body:
if isinstance(x, ast.Assign):
name = x.targets[0].id
doc[name] = ''
else:
doc[name] = x.value.value.strip()
print(list(doc.items()))
Result (Attempt This Online!):
[('score', 'Total points from killing zombies and finding treasures'),
('name', ''),
('age', ''),
('backpack', 'Collection of items that a player can store in their backpack')]
Answered By - Kelly Bundy
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.