|
1 | | -# Adapted from scikit-learn https://github.com/scikit-learn/scikit-learn/pull/13311 |
2 | | -# For reference, here is a copy of their copyright notice: |
3 | | - |
4 | | -# BSD 3-Clause License |
5 | | - |
6 | | -# Copyright (c) 2007-2021 The scikit-learn developers. |
7 | | -# All rights reserved. |
8 | | - |
9 | | -# Redistribution and use in source and binary forms, with or without |
10 | | -# modification, are permitted provided that the following conditions are met: |
11 | | - |
12 | | -# * Redistributions of source code must retain the above copyright notice, this |
13 | | -# list of conditions and the following disclaimer. |
14 | | - |
15 | | -# * Redistributions in binary form must reproduce the above copyright notice, |
16 | | -# this list of conditions and the following disclaimer in the documentation |
17 | | -# and/or other materials provided with the distribution. |
18 | | - |
19 | | -# * Neither the name of the copyright holder nor the names of its |
20 | | -# contributors may be used to endorse or promote products derived from |
21 | | -# this software without specific prior written permission. |
22 | | - |
23 | | -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
24 | | -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
25 | | -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
26 | | -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
27 | | -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
28 | | -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
29 | | -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
30 | | -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
31 | | -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
32 | | -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
33 | | - |
34 | | -import inspect |
35 | 1 | import warnings |
36 | | -from functools import wraps |
37 | | - |
38 | | -POSITIONAL_OR_KEYWORD = inspect.Parameter.POSITIONAL_OR_KEYWORD |
39 | | -KEYWORD_ONLY = inspect.Parameter.KEYWORD_ONLY |
40 | | -POSITIONAL_ONLY = inspect.Parameter.POSITIONAL_ONLY |
41 | | -EMPTY = inspect.Parameter.empty |
42 | | - |
43 | | - |
44 | | -def _deprecate_positional_args(version): |
45 | | - """Decorator for methods that issues warnings for positional arguments |
46 | | - Using the keyword-only argument syntax in pep 3102, arguments after the |
47 | | - ``*`` will issue a warning when passed as a positional argument. |
48 | | -
|
49 | | - Parameters |
50 | | - ---------- |
51 | | - version : str |
52 | | - version of the library when the positional arguments were deprecated |
53 | | -
|
54 | | - Examples |
55 | | - -------- |
56 | | - Deprecate passing `b` as positional argument: |
57 | | - >>> def func(a, b=1): |
58 | | - ... pass |
59 | | - >>> @_deprecate_positional_args("v0.1.0") |
60 | | - ... def func(a, *, b=2): |
61 | | - ... pass |
62 | | - >>> func(1, 2) |
63 | | -
|
64 | | - Notes |
65 | | - ----- |
66 | | - This function is adapted from scikit-learn under the terms of its license. See |
67 | | - """ |
68 | | - |
69 | | - def _decorator(func): |
70 | | - signature = inspect.signature(func) |
71 | | - |
72 | | - pos_or_kw_args = [] |
73 | | - kwonly_args = [] |
74 | | - for name, param in signature.parameters.items(): |
75 | | - if param.kind in (POSITIONAL_OR_KEYWORD, POSITIONAL_ONLY): |
76 | | - pos_or_kw_args.append(name) |
77 | | - elif param.kind == KEYWORD_ONLY: |
78 | | - kwonly_args.append(name) |
79 | | - if param.default is EMPTY: |
80 | | - # IMHO `def f(a, *, b):` does not make sense -> disallow it |
81 | | - # if removing this constraint -> need to add these to kwargs as well |
82 | | - raise TypeError("Keyword-only param without default disallowed.") |
83 | | - |
84 | | - @wraps(func) |
85 | | - def inner(*args, **kwargs): |
86 | | - name = func.__name__ |
87 | | - n_extra_args = len(args) - len(pos_or_kw_args) |
88 | | - if n_extra_args > 0: |
89 | | - extra_args = ", ".join(kwonly_args[:n_extra_args]) |
90 | | - |
91 | | - warnings.warn( |
92 | | - f"Passing '{extra_args}' as positional argument(s) to {name} " |
93 | | - f"was deprecated in version {version} and will raise an error two " |
94 | | - "releases later. Please pass them as keyword arguments." |
95 | | - "", |
96 | | - FutureWarning, |
97 | | - stacklevel=2, |
98 | | - ) |
99 | | - |
100 | | - zip_args = zip(kwonly_args[:n_extra_args], args[-n_extra_args:]) |
101 | | - kwargs.update({name: arg for name, arg in zip_args}) |
102 | | - |
103 | | - return func(*args[:-n_extra_args], **kwargs) |
104 | | - |
105 | | - return func(*args, **kwargs) |
106 | | - |
107 | | - return inner |
108 | | - |
109 | | - return _decorator |
110 | 2 |
|
111 | 3 |
|
112 | 4 | def _module_renamed_warning_init(attr): |
|
0 commit comments