2026-02-01 09:31:38 +01:00

51 lines
1.8 KiB
Python

"""Positional argument deprecation decorator."""
from __future__ import annotations
import inspect
from functools import wraps
from typing import Any, Callable
from warnings import warn
def _deprecate_args(*old_args: str) -> Callable:
def _generate_arg_string(used_args: tuple[str, ...]) -> str:
used_args = list(map(repr, used_args))
arg_count = len(used_args)
arg_string = (
" and ".join(used_args)
if arg_count < 3
else f"{', '.join(used_args[:-1])}, and {used_args[-1]}"
)
arg_string += f" as {'' if arg_count > 1 else 'a '}"
arg_string += "keyword argument"
return arg_string + ("s" if arg_count > 1 else "")
def wrapper(func: Callable):
@wraps(func)
def wrapped(*args: Any, **kwargs: Any):
signature = inspect.signature(func)
positional_args = [
name
for name, parameter in signature.parameters.items()
if parameter.kind is inspect.Parameter.POSITIONAL_OR_KEYWORD
]
_old_args = tuple(filter(lambda arg: arg not in positional_args, old_args))
if positional_args:
# remove the acceptable positional arguments like self or id for helpers
kwargs.update(zip(positional_args, args))
args = tuple(args[len(positional_args) :])
if args:
arg_string = _generate_arg_string(_old_args[: len(args)])
warn(
f"Positional arguments for {func.__qualname__!r} will no longer be"
f" supported in PRAW 8.\nCall this function with {arg_string}.",
DeprecationWarning,
stacklevel=2,
)
return func(**dict(zip(_old_args, args)), **kwargs)
return wrapped
return wrapper