Skip to content

Commit 60c5355

Browse files
committed
fixup! Use set instead of list for block level elements
1 parent fcc2494 commit 60c5355

File tree

2 files changed

+25
-26
lines changed

2 files changed

+25
-26
lines changed

markdown/extensions/md_in_html.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class HTMLExtractorExtra(HTMLExtractor):
4242

4343
def __init__(self, md: Markdown, *args, **kwargs):
4444
# All block-level tags.
45+
# TODO: Use `md.block_level_elements.copy()` when it becomes a regular set.
4546
self.block_level_tags = set(md.block_level_elements)
4647
# Block-level tags in which the content only gets span level parsing
4748
self.span_tags = set(

markdown/util.py

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,13 @@ def __and__(self, other: set[str], /) -> set[str]:
7272
def __contains__(self, item: str, /) -> bool:
7373
return item in self._set
7474

75-
def __delitem__(self, key: int, /) -> None:
75+
def __delitem__(self, index: int, /) -> None:
7676
warnings.warn(
7777
"Using block level elements as a list is deprecated, use it as a set instead.",
7878
DeprecationWarning,
7979
)
80-
element = self._list[key]
81-
del self._list[key]
80+
element = self._list[index]
81+
del self._list[index]
8282
self._set.remove(element)
8383

8484
def __getitem__(self, index: int, /) -> str:
@@ -100,16 +100,16 @@ def __iadd__(self, other: list[str], /) -> set[str]:
100100

101101
def __iand__(self, other: set[str], /) -> set[str]:
102102
# In-place intersection should update both list and set.
103-
self._list = [element for element in self._list if element in other]
104103
self._set &= other
104+
# Elements were only removed.
105+
self._list[:] = [element for element in self._list if element in self._set]
105106
return self # type: ignore[return-value]
106107

107108
def __ior__(self, other: set[str], /) -> set[str]:
108109
# In-place union should update both list and set.
109-
for element in other:
110-
if element not in self._set:
111-
self._list.append(element)
112110
self._set |= other
111+
# Elements were only added.
112+
self._list.extend(element for element in sorted(self._set - set(self._list)))
113113
return self # type: ignore[return-value]
114114

115115
def __iter__(self) -> Iterator[str]:
@@ -155,14 +155,14 @@ def __reversed__(self) -> Iterator[str]:
155155
)
156156
return reversed(self._list)
157157

158-
def __setitem__(self, key: int, value: str, /) -> None:
158+
def __setitem__(self, index: int, value: str, /) -> None:
159159
warnings.warn(
160160
"Using block level elements as a list is deprecated, use it as a set instead.",
161161
DeprecationWarning,
162162
)
163163
# In-place item-setting should update both list and set.
164-
old = self._list[key]
165-
self._list[key] = value
164+
old = self._list[index]
165+
self._list[index] = value
166166
self._set.discard(old)
167167
self._set.add(value)
168168

@@ -207,27 +207,24 @@ def difference(self, *others: set[str]) -> set[str]:
207207
def difference_update(self, *others: set[str]) -> None:
208208
# In-place difference should update both list and set.
209209
self._set.difference_update(*others)
210-
self._list.clear()
211-
self._list.extend(sorted(self._set))
210+
# Elements were only removed.
211+
self._list[:] = [element for element in self._list if element in self._set]
212212

213213
def discard(self, element: str, /) -> None:
214214
# In-place discard should update both list and set.
215215
self._set.discard(element)
216-
while True:
217-
try:
218-
self._list.remove(element)
219-
except ValueError:
220-
break
216+
try:
217+
self._list.remove(element)
218+
except ValueError:
219+
pass
221220

222221
def extend(self, elements: list[str], /) -> None:
223222
warnings.warn(
224223
"Using block level elements as a list is deprecated, use it as a set instead.",
225224
DeprecationWarning,
226225
)
227226
# In-place extension should update both list and set.
228-
for element in elements:
229-
if element not in self._list:
230-
self._list.append(element)
227+
self._list.extend(elements)
231228
self._set.update(elements)
232229

233230
def index(self, value, start: int = 0, stop: int = sys.maxsize, /):
@@ -253,8 +250,8 @@ def intersection(self, *others: set[str]) -> set[str]:
253250
def intersection_update(self, *others: set[str]) -> None:
254251
# In-place intersection should update both list and set.
255252
self._set.intersection_update(*others)
256-
self._list.clear()
257-
self._list.extend(sorted(self._set))
253+
# Elements were only removed.
254+
self._list[:] = [element for element in self._list if element in self._set]
258255

259256
def isdisjoint(self, other: set[str], /) -> bool:
260257
return self._set.isdisjoint(other)
@@ -297,8 +294,9 @@ def symmetric_difference(self, other: set[str], /) -> set[str]:
297294
def symmetric_difference_update(self, other: set[str], /) -> None:
298295
# In-place symmetric difference should update both list and set.
299296
self._set.symmetric_difference_update(other)
300-
self._list.clear()
301-
self._list.extend(sorted(self._set))
297+
# Elements were both removed and added.
298+
self._list[:] = [element for element in self._list if element in self._set]
299+
self._list.extend(element for element in sorted(self._set - set(self._list)))
302300

303301
def union(self, *others: set[str]) -> set[str]:
304302
# User expects a set back.
@@ -307,8 +305,8 @@ def union(self, *others: set[str]) -> set[str]:
307305
def update(self, *others: set[str]) -> None:
308306
# In-place union should update both list and set.
309307
self._set.update(*others)
310-
self._list.clear()
311-
self._list.extend(sorted(self._set))
308+
# Elements were only added.
309+
self._list.extend(element for element in sorted(self._set - set(self._list)))
312310

313311

314312
# Type it as `set[str]` to express our intent for it to be used as such.

0 commit comments

Comments
 (0)