38
38
_T = TypeVar ('_T' )
39
39
40
40
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
45
64
46
65
47
66
# TODO: Raise errors from list methods in the future.
48
67
# Later, remove this class entirely and use a regular set.
49
- class _BlockLevelElements :
68
+ class _BlockLevelElements ( list ) :
50
69
# This hybrid list/set container exists for backwards compatibility reasons,
51
70
# to support using both the `BLOCK_LEVEL_ELEMENTS` global variable (soft-deprecated)
52
71
# 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:
57
76
self ._list = elements .copy ()
58
77
self ._set = set (self ._list )
59
78
79
+ @deprecated ("Using block level elements as a list is deprecated, use it as a set instead." )
60
80
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
- )
65
81
# Using `+` means user expects a list back.
66
82
return self ._list + other
67
83
@@ -72,29 +88,20 @@ def __and__(self, other: set[str], /) -> set[str]:
72
88
def __contains__ (self , item : str , / ) -> bool :
73
89
return item in self ._set
74
90
91
+ @deprecated ("Using block level elements as a list is deprecated, use it as a set instead." )
75
92
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
- )
80
93
element = self ._list [index ]
81
94
del self ._list [index ]
82
95
# Only remove from set if absent from list.
83
96
if element not in self ._list :
84
97
self ._set .remove (element )
85
98
99
+ @deprecated ("Using block level elements as a list is deprecated, use it as a set instead." )
86
100
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
- )
91
101
return self ._list [index ]
92
102
103
+ @deprecated ("Using block level elements as a list is deprecated, use it as a set instead." )
93
104
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
- )
98
105
# In-place addition should update both list and set.
99
106
self ._list += other
100
107
self ._set .update (set (other ))
@@ -150,18 +157,12 @@ def __xor__(self, value: set[str], /) -> set[str]:
150
157
# Using `^` means user expects a set back.
151
158
return self ._set ^ value
152
159
160
+ @deprecated ("Using block level elements as a list is deprecated, use it as a set instead." )
153
161
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
- )
158
162
return reversed (self ._list )
159
163
164
+ @deprecated ("Using block level elements as a list is deprecated, use it as a set instead." )
160
165
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
- )
165
166
# In-place item-setting should update both list and set.
166
167
old = self ._list [index ]
167
168
self ._list [index ] = value
@@ -178,11 +179,8 @@ def add(self, element: str, /) -> None:
178
179
self ._set .add (element )
179
180
self ._list .append (element )
180
181
182
+ @deprecated ("Using block level elements as a list is deprecated, use it as a set instead." )
181
183
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
- )
186
184
# In-place addition should update both list and set.
187
185
self ._list .append (element )
188
186
self ._set .add (element )
@@ -195,11 +193,8 @@ def copy(self) -> _BlockLevelElements:
195
193
# We're not sure yet whether the user wants to use it as a set or list.
196
194
return _BlockLevelElements (self ._list )
197
195
196
+ @deprecated ("Using block level elements as a list is deprecated, use it as a set instead." )
198
197
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
- )
203
198
# Count in list, for backwards compatibility.
204
199
# If used as a set, both counts will be the same (1).
205
200
return self ._list .count (value )
@@ -222,27 +217,18 @@ def discard(self, element: str, /) -> None:
222
217
except ValueError :
223
218
pass
224
219
220
+ @deprecated ("Using block level elements as a list is deprecated, use it as a set instead." )
225
221
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
- )
230
222
# In-place extension should update both list and set.
231
223
self ._list .extend (elements )
232
224
self ._set .update (elements )
233
225
226
+ @deprecated ("Using block level elements as a list is deprecated, use it as a set instead." )
234
227
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
- )
239
228
return self ._list .index (value , start , stop )
240
229
230
+ @deprecated ("Using block level elements as a list is deprecated, use it as a set instead." )
241
231
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
- )
246
232
# In-place insertion should update both list and set.
247
233
self ._list .insert (index , element )
248
234
self ._set .add (element )
@@ -289,24 +275,14 @@ def remove(self, element: str, /) -> None:
289
275
self ._list .remove (element )
290
276
except ValueError :
291
277
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 )
297
279
280
+ @deprecated ("Using block level elements as a list is deprecated, use it as a set instead." )
298
281
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
- )
303
282
self ._list .reverse ()
304
283
284
+ @deprecated ("Using block level elements as a list is deprecated, use it as a set instead." )
305
285
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
- )
310
286
self ._list .sort (key = key , reverse = reverse )
311
287
312
288
def symmetric_difference (self , other : set [str ], / ) -> set [str ]:
@@ -331,6 +307,9 @@ def update(self, *others: set[str]) -> None:
331
307
self ._list .extend (element for element in sorted (self ._set - set (self ._list )))
332
308
333
309
310
+ # Constants you might want to modify
311
+ # -----------------------------------------------------------------------------
312
+
334
313
# Type it as `set[str]` to express our intent for it to be used as such.
335
314
# We explicitly lie here, so that users running type checkers will get
336
315
# warnings when they use the container as a list. This is a very effective
@@ -402,31 +381,6 @@ def get_installed_extensions():
402
381
return metadata .entry_points (group = 'markdown.extensions' )
403
382
404
383
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
-
430
384
def parseBoolValue (value : str | None , fail_on_errors : bool = True , preserve_none : bool = False ) -> bool | None :
431
385
"""Parses a string representing a boolean value. If parsing was successful,
432
386
returns `True` or `False`. If `preserve_none=True`, returns `True`, `False`,
0 commit comments