• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

domdfcoding / domdf_python_tools / 3732685666

pending completion
3732685666

push

github

Dominic Davis-Foster
Bump version v3.5.0 -> v3.5.1

2143 of 2200 relevant lines covered (97.41%)

0.97 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.78
/domdf_python_tools/delegators.py
1
#!/usr/bin/env python
2
# cython: language_level=3
3
#
4
#  delegators.py
5
"""
1✔
6
Decorators for functions that delegate parts of their functionality to other functions.
7

8
.. versionadded:: 0.10.0
9
"""
10
#
11
#  Copyright © 2020 Dominic Davis-Foster <dominic@davis-foster.co.uk>
12
#
13
#  Permission is hereby granted, free of charge, to any person obtaining a copy
14
#  of this software and associated documentation files (the "Software"), to deal
15
#  in the Software without restriction, including without limitation the rights
16
#  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
#  copies of the Software, and to permit persons to whom the Software is
18
#  furnished to do so, subject to the following conditions:
19
#
20
#  The above copyright notice and this permission notice shall be included in all
21
#  copies or substantial portions of the Software.
22
#
23
#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24
#  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25
#  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26
#  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
27
#  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
28
#  OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
29
#  OR OTHER DEALINGS IN THE SOFTWARE.
30
#
31
#  delegate_kwargs based on https://github.com/fastai/fastcore
32
#  |  Licensed under the Apache License, Version 2.0 (the "License"); you may
33
#  |  not use this file except in compliance with the License. You may obtain
34
#  |  a copy of the License at
35
#  |
36
#  |      http://www.apache.org/licenses/LICENSE-2.0
37
#  |
38
#  |  Unless required by applicable law or agreed to in writing, software
39
#  |  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
40
#  |  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
41
#  |  License for the specific language governing permissions and limitations
42
#  |  under the License.
43
#
44

45
# stdlib
46
import inspect
1✔
47
from typing import Callable, TypeVar, get_type_hints
1✔
48

49
__all__ = ["delegate_kwargs", "delegates"]
1✔
50

51
_C = TypeVar("_C", bound="Callable")
1✔
52

53

54
def delegate_kwargs(to: Callable, *except_: str) -> Callable[[_C], _C]:
1✔
55
        r"""
56
        Decorator to replace ``**kwargs`` in function signatures with the
57
        parameter names from the delegated function.
58

59
        :param to: The function \*\*kwargs is passed on to.
60
        :param \*except\_: Parameter names not to delegate.
61

62
        :raises ValueError: if a non-default argument follows a default argument.
63
        """  # noqa: D400
64

65
        # TODO: return annotation
66

67
        def _f(f: _C) -> _C:
1✔
68
                to_f, from_f = to, f
1✔
69

70
                to_sig = inspect.signature(to_f)
1✔
71
                from_sig = inspect.signature(from_f)
1✔
72
                to_annotations = get_type_hints(to_f)
1✔
73
                from_annotations = get_type_hints(from_f)
1✔
74
                to_params = {k: v for k, v in to_sig.parameters.items() if k not in except_}
1✔
75
                from_params = dict(from_sig.parameters)
1✔
76

77
                if from_params.pop("kwargs", False):
1✔
78
                        if "kwargs" in from_annotations:
1✔
79
                                del from_annotations["kwargs"]
1✔
80

81
                        for param in from_params:
1✔
82
                                if param in to_params:
1✔
83
                                        del to_params[param]
1✔
84

85
                        f.__signature__ = from_sig.replace(  # type: ignore
1✔
86
                                parameters=[*from_params.values(), *to_params.values()]
87
                                )
88
                        f.__annotations__ = {**to_annotations, **from_annotations}
1✔
89

90
                return f
1✔
91

92
        return _f
1✔
93

94

95
def delegates(to: Callable) -> Callable[[_C], _C]:
1✔
96
        r"""
97
        Decorator to replace ``*args, **kwargs``  function signatures
98
        with the signature of the delegated function.
99

100
        :param to: The function the arguments are passed on to.
101
        """  # noqa: D400
102

103
        def copy_annotations(f):
1✔
104
                if hasattr(to, "__annotations__"):
1✔
105
                        if hasattr(f, "__annotations__"):
1✔
106
                                return_annotation = f.__annotations__.get("return", inspect.Parameter.empty)
1✔
107
                                f.__annotations__.update(to.__annotations__)
1✔
108
                                if return_annotation is not inspect.Parameter.empty:
1✔
109
                                        f.__annotations__["return"] = return_annotation
1✔
110
                        else:
111
                                f.__annotations__ = to.__annotations__
×
112

113
        def _f(f: _C) -> _C:
1✔
114
                to_sig = inspect.signature(to)
1✔
115
                from_sig = inspect.signature(f)
1✔
116
                from_params = dict(from_sig.parameters)
1✔
117

118
                if tuple(from_params.keys()) == ("args", "kwargs"):
1✔
119
                        f.__signature__ = to_sig  # type: ignore
1✔
120
                        copy_annotations(f)
1✔
121

122
                elif tuple(from_params.keys()) == ("self", "args", "kwargs"):
1✔
123
                        f.__signature__ = from_sig.replace(  # type: ignore
1✔
124
                                parameters=[from_params["self"], *to_sig.parameters.values()]
125
                                )
126

127
                        copy_annotations(f)
1✔
128

129
                return f
1✔
130

131
        return _f
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc