Skip to content

Commit 0aa7c39

Browse files
DanielNoordcdce8p
andauthored
Deprecate passing the doc argument (#1453)
Co-authored-by: Marc Mueller <[email protected]>
1 parent b34a63a commit 0aa7c39

File tree

4 files changed

+65
-0
lines changed

4 files changed

+65
-0
lines changed

ChangeLog

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ Release date: TBA
1313
``nodes.FunctionDef`` has been deprecated in favour of the ``doc_node`` attribute.
1414
Note: ``doc_node`` is an (optional) ``nodes.Const`` whereas ``doc`` was an (optional) ``str``.
1515

16+
* Passing the ``doc`` argument to the ``__init__`` of ``nodes.Module``, ``nodes.ClassDef``,
17+
and ``nodes.FunctionDef`` has been deprecated in favour of the ``postinit`` ``doc_node`` attribute.
18+
Note: ``doc_node`` is an (optional) ``nodes.Const`` whereas ``doc`` was an (optional) ``str``.
19+
1620
* Replace custom ``cachedproperty`` with ``functools.cached_property`` and deprecate it
1721
for Python 3.8+.
1822

astroid/decorators.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,44 @@ def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
224224

225225
return deco
226226

227+
def deprecate_arguments(
228+
astroid_version: str = "3.0", **arguments: str
229+
) -> Callable[[Callable[P, R]], Callable[P, R]]:
230+
"""Decorator which emits a DeprecationWarning if any arguments specified
231+
are passed.
232+
233+
Arguments should be a key-value mapping, with the key being the argument to check
234+
and the value being a string that explains what to do instead of passing the argument.
235+
236+
To improve performance, only used when DeprecationWarnings other than
237+
the default one are enabled.
238+
"""
239+
240+
def deco(func: Callable[P, R]) -> Callable[P, R]:
241+
@functools.wraps(func)
242+
def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
243+
244+
keys = list(inspect.signature(func).parameters.keys())
245+
for arg, note in arguments.items():
246+
try:
247+
index = keys.index(arg)
248+
except ValueError:
249+
raise Exception(
250+
f"Can't find argument '{arg}' for '{args[0].__class__.__qualname__}'"
251+
) from None
252+
if arg in kwargs or len(args) > index:
253+
warnings.warn(
254+
f"The argument '{arg}' for "
255+
f"'{args[0].__class__.__qualname__}.{func.__name__}' is deprecated "
256+
f"and will be removed in astroid {astroid_version} ({note})",
257+
DeprecationWarning,
258+
)
259+
return func(*args, **kwargs)
260+
261+
return wrapper
262+
263+
return deco
264+
227265
else:
228266

229267
def deprecate_default_argument_values(
@@ -236,3 +274,14 @@ def deco(func: Callable[P, R]) -> Callable[P, R]:
236274
return func
237275

238276
return deco
277+
278+
def deprecate_arguments(
279+
astroid_version: str = "3.0", **arguments: str
280+
) -> Callable[[Callable[P, R]], Callable[P, R]]:
281+
"""Passthrough decorator to improve performance if DeprecationWarnings are disabled."""
282+
283+
def deco(func: Callable[P, R]) -> Callable[P, R]:
284+
"""Decorator function."""
285+
return func
286+
287+
return deco

astroid/nodes/scoped_nodes/scoped_nodes.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ class Module(LocalsDictNodeNG):
269269
end_col_offset: None
270270
parent: None
271271

272+
@decorators_mod.deprecate_arguments(doc="Use the postinit arg 'doc_node' instead")
272273
def __init__(
273274
self,
274275
name: str,
@@ -1352,6 +1353,7 @@ class FunctionDef(mixins.MultiLineBlockMixin, node_classes.Statement, Lambda):
13521353
)
13531354
_type = None
13541355

1356+
@decorators_mod.deprecate_arguments(doc="Use the postinit arg 'doc_node' instead")
13551357
def __init__(
13561358
self,
13571359
name=None,
@@ -2018,6 +2020,7 @@ def my_meth(self, arg):
20182020
_other_other_fields = ("locals", "_newstyle")
20192021
_newstyle = None
20202022

2023+
@decorators_mod.deprecate_arguments(doc="Use the postinit arg 'doc_node' instead")
20212024
def __init__(
20222025
self,
20232026
name=None,

tests/unittest_scoped_nodes.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2717,6 +2717,15 @@ class MyClass():
27172717
assert node_func.doc == "Docstring"
27182718
assert len(records) == 1
27192719

2720+
# If 'doc' is passed to Module, ClassDef, FunctionDef,
2721+
# a DeprecationWarning should be raised
2722+
doc_node = nodes.Const("Docstring")
2723+
with pytest.warns(DeprecationWarning) as records:
2724+
node_module = nodes.Module(name="MyModule", doc="Docstring")
2725+
node_class = nodes.ClassDef(name="MyClass", doc="Docstring")
2726+
node_func = nodes.FunctionDef(name="MyFunction", doc="Docstring")
2727+
assert len(records) == 3
2728+
27202729

27212730
if __name__ == "__main__":
27222731
unittest.main()

0 commit comments

Comments
 (0)