3838_T = TypeVar ('_T' )
3939
4040
41- """
42- Constants you might want to modify
43- -----------------------------------------------------------------------------
44- """
41+ def deprecated (message : str , stacklevel : int = 2 ):
42+ """
43+ Raise a [`DeprecationWarning`][] when wrapped function/method is called.
44+
45+ Usage:
46+
47+ ```python
48+ @deprecated("This method will be removed in version X; use Y instead.")
49+ def some_method():
50+ pass
51+ ```
52+ """
53+ def wrapper (func ):
54+ @wraps (func )
55+ def deprecated_func (* args , ** kwargs ):
56+ warnings .warn (
57+ f"'{ func .__name__ } ' is deprecated. { message } " ,
58+ category = DeprecationWarning ,
59+ stacklevel = stacklevel
60+ )
61+ return func (* args , ** kwargs )
62+ return deprecated_func
63+ return wrapper
4564
4665
4766# TODO: Raise errors from list methods in the future.
4867# Later, remove this class entirely and use a regular set.
49- class _BlockLevelElements :
68+ class _BlockLevelElements ( list ) :
5069 # This hybrid list/set container exists for backwards compatibility reasons,
5170 # to support using both the `BLOCK_LEVEL_ELEMENTS` global variable (soft-deprecated)
5271 # and the `Markdown.block_level_elements` instance attribute (preferred) as a list or a set.
@@ -57,11 +76,8 @@ def __init__(self, elements: list[str], /) -> None:
5776 self ._list = elements .copy ()
5877 self ._set = set (self ._list )
5978
79+ @deprecated ("Using block level elements as a list is deprecated, use it as a set instead." )
6080 def __add__ (self , other : list [str ], / ) -> list [str ]:
61- warnings .warn (
62- "Using block level elements as a list is deprecated, use it as a set instead." ,
63- DeprecationWarning ,
64- )
6581 # Using `+` means user expects a list back.
6682 return self ._list + other
6783
@@ -72,29 +88,20 @@ def __and__(self, other: set[str], /) -> set[str]:
7288 def __contains__ (self , item : str , / ) -> bool :
7389 return item in self ._set
7490
91+ @deprecated ("Using block level elements as a list is deprecated, use it as a set instead." )
7592 def __delitem__ (self , index : int , / ) -> None :
76- warnings .warn (
77- "Using block level elements as a list is deprecated, use it as a set instead." ,
78- DeprecationWarning ,
79- )
8093 element = self ._list [index ]
8194 del self ._list [index ]
8295 # Only remove from set if absent from list.
8396 if element not in self ._list :
8497 self ._set .remove (element )
8598
99+ @deprecated ("Using block level elements as a list is deprecated, use it as a set instead." )
86100 def __getitem__ (self , index : int , / ) -> str :
87- warnings .warn (
88- "Using block level elements as a list is deprecated, use it as a set instead." ,
89- DeprecationWarning ,
90- )
91101 return self ._list [index ]
92102
103+ @deprecated ("Using block level elements as a list is deprecated, use it as a set instead." )
93104 def __iadd__ (self , other : list [str ], / ) -> set [str ]:
94- warnings .warn (
95- "Using block level elements as a list is deprecated, use it as a set instead." ,
96- DeprecationWarning ,
97- )
98105 # In-place addition should update both list and set.
99106 self ._list += other
100107 self ._set .update (set (other ))
@@ -150,18 +157,12 @@ def __xor__(self, value: set[str], /) -> set[str]:
150157 # Using `^` means user expects a set back.
151158 return self ._set ^ value
152159
160+ @deprecated ("Using block level elements as a list is deprecated, use it as a set instead." )
153161 def __reversed__ (self ) -> Iterator [str ]:
154- warnings .warn (
155- "Using block level elements as a list is deprecated, use it as a set instead." ,
156- DeprecationWarning ,
157- )
158162 return reversed (self ._list )
159163
164+ @deprecated ("Using block level elements as a list is deprecated, use it as a set instead." )
160165 def __setitem__ (self , index : int , value : str , / ) -> None :
161- warnings .warn (
162- "Using block level elements as a list is deprecated, use it as a set instead." ,
163- DeprecationWarning ,
164- )
165166 # In-place item-setting should update both list and set.
166167 old = self ._list [index ]
167168 self ._list [index ] = value
@@ -178,11 +179,8 @@ def add(self, element: str, /) -> None:
178179 self ._set .add (element )
179180 self ._list .append (element )
180181
182+ @deprecated ("Using block level elements as a list is deprecated, use it as a set instead." )
181183 def append (self , element : str , / ) -> None :
182- warnings .warn (
183- "Using block level elements as a list is deprecated, use it as a set instead." ,
184- DeprecationWarning ,
185- )
186184 # In-place addition should update both list and set.
187185 self ._list .append (element )
188186 self ._set .add (element )
@@ -195,11 +193,8 @@ def copy(self) -> _BlockLevelElements:
195193 # We're not sure yet whether the user wants to use it as a set or list.
196194 return _BlockLevelElements (self ._list )
197195
196+ @deprecated ("Using block level elements as a list is deprecated, use it as a set instead." )
198197 def count (self , value : str , / ) -> int :
199- warnings .warn (
200- "Using block level elements as a list is deprecated, use it as a set instead." ,
201- DeprecationWarning ,
202- )
203198 # Count in list, for backwards compatibility.
204199 # If used as a set, both counts will be the same (1).
205200 return self ._list .count (value )
@@ -222,27 +217,18 @@ def discard(self, element: str, /) -> None:
222217 except ValueError :
223218 pass
224219
220+ @deprecated ("Using block level elements as a list is deprecated, use it as a set instead." )
225221 def extend (self , elements : list [str ], / ) -> None :
226- warnings .warn (
227- "Using block level elements as a list is deprecated, use it as a set instead." ,
228- DeprecationWarning ,
229- )
230222 # In-place extension should update both list and set.
231223 self ._list .extend (elements )
232224 self ._set .update (elements )
233225
226+ @deprecated ("Using block level elements as a list is deprecated, use it as a set instead." )
234227 def index (self , value , start : int = 0 , stop : int = sys .maxsize , / ):
235- warnings .warn (
236- "Using block level elements as a list is deprecated, use it as a set instead." ,
237- DeprecationWarning ,
238- )
239228 return self ._list .index (value , start , stop )
240229
230+ @deprecated ("Using block level elements as a list is deprecated, use it as a set instead." )
241231 def insert (self , index : int , element : str , / ) -> None :
242- warnings .warn (
243- "Using block level elements as a list is deprecated, use it as a set instead." ,
244- DeprecationWarning ,
245- )
246232 # In-place insertion should update both list and set.
247233 self ._list .insert (index , element )
248234 self ._set .add (element )
@@ -289,24 +275,14 @@ def remove(self, element: str, /) -> None:
289275 self ._list .remove (element )
290276 except ValueError :
291277 break
292- # We raise `ValueError` for backwards compatibility.
293- try :
294- self ._set .remove (element )
295- except KeyError :
296- raise ValueError (f"{ element !r} not in list" ) from None
278+ self ._set .remove (element )
297279
280+ @deprecated ("Using block level elements as a list is deprecated, use it as a set instead." )
298281 def reverse (self ) -> None :
299- warnings .warn (
300- "Using block level elements as a list is deprecated, use it as a set instead." ,
301- DeprecationWarning ,
302- )
303282 self ._list .reverse ()
304283
284+ @deprecated ("Using block level elements as a list is deprecated, use it as a set instead." )
305285 def sort (self , / , * , key : Callable | None = None , reverse : bool = False ) -> None :
306- warnings .warn (
307- "Using block level elements as a list is deprecated, use it as a set instead." ,
308- DeprecationWarning ,
309- )
310286 self ._list .sort (key = key , reverse = reverse )
311287
312288 def symmetric_difference (self , other : set [str ], / ) -> set [str ]:
@@ -331,6 +307,9 @@ def update(self, *others: set[str]) -> None:
331307 self ._list .extend (element for element in sorted (self ._set - set (self ._list )))
332308
333309
310+ # Constants you might want to modify
311+ # -----------------------------------------------------------------------------
312+
334313# Type it as `set[str]` to express our intent for it to be used as such.
335314# We explicitly lie here, so that users running type checkers will get
336315# warnings when they use the container as a list. This is a very effective
@@ -402,31 +381,6 @@ def get_installed_extensions():
402381 return metadata .entry_points (group = 'markdown.extensions' )
403382
404383
405- def deprecated (message : str , stacklevel : int = 2 ):
406- """
407- Raise a [`DeprecationWarning`][] when wrapped function/method is called.
408-
409- Usage:
410-
411- ```python
412- @deprecated("This method will be removed in version X; use Y instead.")
413- def some_method():
414- pass
415- ```
416- """
417- def wrapper (func ):
418- @wraps (func )
419- def deprecated_func (* args , ** kwargs ):
420- warnings .warn (
421- f"'{ func .__name__ } ' is deprecated. { message } " ,
422- category = DeprecationWarning ,
423- stacklevel = stacklevel
424- )
425- return func (* args , ** kwargs )
426- return deprecated_func
427- return wrapper
428-
429-
430384def parseBoolValue (value : str | None , fail_on_errors : bool = True , preserve_none : bool = False ) -> bool | None :
431385 """Parses a string representing a boolean value. If parsing was successful,
432386 returns `True` or `False`. If `preserve_none=True`, returns `True`, `False`,
0 commit comments