Skip to content

Commit d5a958b

Browse files
committed
Add second comment to _ArrayItemGroup
1 parent 1a3085c commit d5a958b

File tree

2 files changed

+59
-7
lines changed

2 files changed

+59
-7
lines changed

tests/test_items.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,3 +1019,27 @@ def test_removal_of_arrayitem_with_extra_whitespace():
10191019
docstr = doc.as_string()
10201020
parse(docstr)
10211021
assert docstr == expected
1022+
1023+
1024+
def test_removal_of_items_from_badly_formatted_arrays():
1025+
for i in range(10):
1026+
doc = parse(
1027+
"""
1028+
x = [
1029+
'0'#a
1030+
,#b
1031+
'1' #c
1032+
, #d
1033+
'2' # e
1034+
,'3', # f
1035+
'4'#g
1036+
,'5' #h
1037+
,'6',#i
1038+
'7' ,#j
1039+
'8' , #k
1040+
'9' , # l
1041+
]
1042+
"""
1043+
)
1044+
doc["x"].remove(str(i))
1045+
parse(doc.as_string())

tomlkit/items.py

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,30 +1083,33 @@ def _getstate(self, protocol: int = 3) -> tuple:
10831083

10841084

10851085
class _ArrayItemGroup:
1086-
__slots__ = ("comma", "comment", "indent", "value")
1086+
__slots__ = ("comma", "comment", "comment2", "indent", "value")
10871087

10881088
def __init__(
10891089
self,
10901090
value: Item | None = None,
10911091
indent: Whitespace | None = None,
10921092
comma: Whitespace | None = None,
10931093
comment: Comment | None = None,
1094+
comment2: Comment | None = None,
10941095
) -> None:
10951096
self.value = value
10961097
self.indent = indent
10971098
self.comma = comma
10981099
self.comment = comment
1100+
self.comment2 = comment2
10991101

11001102
def __iter__(self) -> Iterator[Item]:
11011103
return filter(
1102-
lambda x: x is not None, (self.indent, self.value, self.comma, self.comment)
1104+
lambda x: x is not None,
1105+
(self.indent, self.value, self.comment, self.comma, self.comment2),
11031106
)
11041107

11051108
def __repr__(self) -> str:
11061109
return repr(tuple(self))
11071110

11081111
def is_whitespace(self) -> bool:
1109-
return self.value is None and self.comment is None
1112+
return self.value is None and self.comment is None and self.comment2 is None
11101113

11111114
def __bool__(self) -> bool:
11121115
try:
@@ -1135,12 +1138,25 @@ def __init__(
11351138
self._reindex()
11361139

11371140
def _group_values(self, value: list[Item]) -> list[_ArrayItemGroup]:
1138-
"""Group the values into (indent, value, comma, comment) tuples"""
1141+
"""Group the values into (indent, value, comment, comma, comment2) tuples"""
11391142
groups = []
11401143
this_group = _ArrayItemGroup()
1141-
for item in value:
1144+
for i, item in enumerate(value):
11421145
if isinstance(item, Whitespace):
11431146
if "," not in item.s:
1147+
# Whitespace without a comma doesn't necessarily mean end of group
1148+
# Check the next item to see if it has a comma, which does mean end of group.
1149+
if (
1150+
len(value) > i + 1
1151+
and isinstance(value[i + 1], Whitespace)
1152+
and "," in value[i + 1].s
1153+
):
1154+
# Prepend this whitespace to that item
1155+
value[i + 1] = Whitespace(item.s + value[i + 1].s)
1156+
# Set an indent if this group does not have one.
1157+
if not this_group.indent:
1158+
this_group.indent = Whitespace("\n")
1159+
continue
11441160
groups.append(this_group)
11451161
this_group = _ArrayItemGroup(indent=item)
11461162
else:
@@ -1151,7 +1167,13 @@ def _group_values(self, value: list[Item]) -> list[_ArrayItemGroup]:
11511167
elif isinstance(item, Comment):
11521168
if this_group.value is None:
11531169
this_group.value = Null()
1154-
this_group.comment = item
1170+
# It's possible to have two comments per group.
1171+
if isinstance(value[i - 1], Whitespace) and "," in value[i - 1].s:
1172+
# If the previous item is Whitespace and contains a comma,
1173+
# this must be comment two.
1174+
this_group.comment2 = item
1175+
else:
1176+
this_group.comment = item
11551177
elif this_group.value is None:
11561178
this_group.value = item
11571179
else:
@@ -1209,8 +1231,9 @@ def as_string(self) -> str:
12091231
self.trivia.indent
12101232
+ " " * 4
12111233
+ v.value.as_string()
1212-
+ ("," if not isinstance(v.value, Null) else "")
12131234
+ (v.comment.as_string() if v.comment is not None else "")
1235+
+ ("," if not isinstance(v.value, Null) else "")
1236+
+ (v.comment2.as_string() if v.comment2 is not None else "")
12141237
+ "\n"
12151238
for v in self._value
12161239
if v.value is not None
@@ -1372,6 +1395,11 @@ def insert(self, pos: int, value: Any) -> None:
13721395
# Copy the comma from the last item if 1) it contains a value and
13731396
# 2) the array is multiline
13741397
comma = last_item.comma
1398+
if last_item.comment and not last_item.comma:
1399+
# Arrays with a single value might not have a comma after the value, but may have a comment.
1400+
# Move comment one to comment two if so.
1401+
last_item.comment2 = last_item.comment
1402+
last_item.comment = None
13751403
if last_item.comma is None and not isinstance(last_item.value, Null):
13761404
# Add comma to the last item to separate it from the following items.
13771405
last_item.comma = Whitespace(",")

0 commit comments

Comments
 (0)