1import warnings
2import functools
3
4
5class AltairDeprecationWarning(UserWarning):
6    pass
7
8
9def deprecated(message=None):
10    """Decorator to deprecate a function or class.
11
12    Parameters
13    ----------
14    message : string (optional)
15        The deprecation message
16    """
17
18    def wrapper(obj):
19        return _deprecate(obj, message=message)
20
21    return wrapper
22
23
24def _deprecate(obj, name=None, message=None):
25    """Return a version of a class or function that raises a deprecation warning.
26
27    Parameters
28    ----------
29    obj : class or function
30        The object to create a deprecated version of.
31    name : string (optional)
32        The name of the deprecated object
33    message : string (optional)
34        The deprecation message
35
36    Returns
37    -------
38    deprecated_obj :
39        The deprecated version of obj
40
41    Examples
42    --------
43    >>> class Foo(object): pass
44    >>> OldFoo = _deprecate(Foo, "OldFoo")
45    >>> f = OldFoo()  # doctest: +SKIP
46    AltairDeprecationWarning: alt.OldFoo is deprecated. Use alt.Foo instead.
47    """
48    if message is None:
49        message = "alt.{} is deprecated. Use alt.{} instead." "".format(
50            name, obj.__name__
51        )
52    if isinstance(obj, type):
53        return type(
54            name,
55            (obj,),
56            {
57                "__doc__": obj.__doc__,
58                "__init__": _deprecate(obj.__init__, "__init__", message),
59            },
60        )
61    elif callable(obj):
62
63        @functools.wraps(obj)
64        def new_obj(*args, **kwargs):
65            warnings.warn(message, AltairDeprecationWarning)
66            return obj(*args, **kwargs)
67
68        return new_obj
69    else:
70        raise ValueError("Cannot deprecate object of type {}".format(type(obj)))
71