| 1 |  |  | from collections import OrderedDict | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  | from copy import copy | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | from inspect import getfullargspec, ismethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | from coala_utils.decorators import enforce_signature | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | from coalib.settings.DocstringMetadata import DocstringMetadata | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  | class FunctionMetadata: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  |     str_nodesc = "No description given." | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  |     str_optional = "Optional, defaults to '{}'." | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  |     @enforce_signature | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  |     def __init__(self, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  |                  name: str, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  |                  desc: str="", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  |                  retval_desc: str="", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  |                  non_optional_params: (dict, None)=None, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  |                  optional_params: (dict, None)=None, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  |                  omit: (set, tuple, list, frozenset)=frozenset()): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  |         Creates the FunctionMetadata object. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  |         :param name:                The name of the function. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  |         :param desc:                The description of the function. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  |         :param retval_desc:         The retval description of the function. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  |         :param non_optional_params: A dict containing the name of non optional | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  |                                     parameters as the key and a tuple of a | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  |                                     description and the python annotation. To | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  |                                     preserve the order, use OrderedDict. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  |         :param optional_params:     A dict containing the name of optional | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  |                                     parameters as the key and a tuple | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  |                                     of a description, the python annotation and | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  |                                     the default value. To preserve the order, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  |                                     use OrderedDict. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  |         :param omit:                A set of parameters to omit. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |         if non_optional_params is None: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  |             non_optional_params = OrderedDict() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  |         if optional_params is None: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  |             optional_params = OrderedDict() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |         self.name = name | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |         self._desc = desc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |         self.retval_desc = retval_desc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |         self._non_optional_params = non_optional_params | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |         self._optional_params = optional_params | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |         self.omit = set(omit) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |     @property | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |     def desc(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  |         Returns description of the function. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |         return self._desc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |     @desc.setter | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |     @enforce_signature | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |     def desc(self, new_desc: str): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |         Set's the description to the new_desc. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |         self._desc = new_desc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |     def _filter_out_omitted(self, params): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |         Filters out parameters that are to omit. This is a helper method for | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |         the param related properties. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |         :param params: The parameter dictionary to filter. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  |         :return:       The filtered dictionary. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |         return OrderedDict(filter(lambda p: p[0] not in self.omit, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  |                                   tuple(params.items()))) | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 75 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 76 |  |  |     @property | 
            
                                                                        
                            
            
                                    
            
            
                | 77 |  |  |     def non_optional_params(self): | 
            
                                                                        
                            
            
                                    
            
            
                | 78 |  |  |         """ | 
            
                                                                        
                            
            
                                    
            
            
                | 79 |  |  |         Retrieves a dict containing the name of non optional parameters as the | 
            
                                                                        
                            
            
                                    
            
            
                | 80 |  |  |         key and a tuple of a description and the python annotation. Values that | 
            
                                                                        
                            
            
                                    
            
            
                | 81 |  |  |         are present in self.omit will be omitted. | 
            
                                                                        
                            
            
                                    
            
            
                | 82 |  |  |         """ | 
            
                                                                        
                            
            
                                    
            
            
                | 83 |  |  |         return self._filter_out_omitted(self._non_optional_params) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |     @property | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |     def optional_params(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |         Retrieves a dict containing the name of optional parameters as the key | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |         and a tuple of a description, the python annotation and the default | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |         value. Values that are present in self.omit will be omitted. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  |         return self._filter_out_omitted(self._optional_params) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |     def add_alias(self, original, alias): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  |         Adds an alias for the original setting. The alias setting will have | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  |         the same metadata as the original one. If the original setting is not | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  |         optional, the alias will default to ``None``. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  |         :param original:  The name of the original setting. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  |         :param alias:     The name of the alias for the original. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |         :raises KeyError: If the new setting doesn't exist in the metadata. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  |         self._optional_params[alias] = ( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |             self._optional_params[original] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |             if original in self._optional_params | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |             else self._non_optional_params[original] + (None, )) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  |     def create_params_from_section(self, section): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 |  |  |         Create a params dictionary for this function that holds all values the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  |         function needs plus optional ones that are available. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 |  |  |         :param section:    The section to retrieve the values from. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 |  |  |         :return:           The params dictionary. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 |  |  |         params = {} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 |  |  |         for param in self.non_optional_params: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 |  |  |             _, annotation = self.non_optional_params[param] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 |  |  |             params[param] = self._get_param(param, section, annotation) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 123 |  |  |         for param in self.optional_params: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 124 |  |  |             if param in section: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 125 |  |  |                 _, annotation, _ = self.optional_params[param] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 126 |  |  |                 params[param] = self._get_param(param, section, annotation) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 127 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 128 |  |  |         return params | 
            
                                                                                                            
                            
            
                                    
            
            
                | 129 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 130 |  |  |     @staticmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 131 |  |  |     def _get_param(param, section, annotation): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 132 |  |  |         if annotation is None: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 133 |  |  |             annotation = lambda x: x | 
            
                                                                                                            
                            
            
                                    
            
            
                | 134 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 135 |  |  |         try: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 136 |  |  |             return annotation(section[param]) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 137 |  |  |         except (TypeError, ValueError): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 138 |  |  |             raise ValueError("Unable to convert parameter {!r} into type " | 
            
                                                                                                            
                            
            
                                    
            
            
                | 139 |  |  |                              "{}.".format(param, annotation)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 140 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 141 |  |  |     @classmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 142 |  |  |     def from_function(cls, func, omit=frozenset()): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 143 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 144 |  |  |         Creates a FunctionMetadata object from a function. Please note that any | 
            
                                                                                                            
                            
            
                                    
            
            
                | 145 |  |  |         variable argument lists are not supported. If you do not want the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 146 |  |  |         first (usual named 'self') argument to appear please pass the method of | 
            
                                                                                                            
                            
            
                                    
            
            
                | 147 |  |  |         an actual INSTANCE of a class; passing the method of the class isn't | 
            
                                                                                                            
                            
            
                                    
            
            
                | 148 |  |  |         enough. Alternatively you can add "self" to the omit set. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 149 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 150 |  |  |         :param func: The function. If __metadata__ of the unbound function is | 
            
                                                                                                            
                            
            
                                    
            
            
                | 151 |  |  |                      present it will be copied and used, otherwise it will be | 
            
                                                                                                            
                            
            
                                    
            
            
                | 152 |  |  |                      generated. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 153 |  |  |         :param omit: A set of parameter names that are to be ignored. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 154 |  |  |         :return:     The FunctionMetadata object corresponding to the given | 
            
                                                                                                            
                            
            
                                    
            
            
                | 155 |  |  |                      function. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 156 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 157 |  |  |         if hasattr(func, "__metadata__"): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 158 |  |  |             metadata = copy(func.__metadata__) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 159 |  |  |             metadata.omit = omit | 
            
                                                                                                            
                            
            
                                    
            
            
                | 160 |  |  |             return metadata | 
            
                                                                                                            
                            
            
                                    
            
            
                | 161 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 162 |  |  |         doc = func.__doc__ or "" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 163 |  |  |         doc_comment = DocstringMetadata.from_docstring(doc) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 164 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 165 |  |  |         non_optional_params = OrderedDict() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 166 |  |  |         optional_params = OrderedDict() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 167 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 168 |  |  |         argspec = getfullargspec(func) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 169 |  |  |         args = () if argspec.args is None else argspec.args | 
            
                                                                                                            
                            
            
                                    
            
            
                | 170 |  |  |         defaults = () if argspec.defaults is None else argspec.defaults | 
            
                                                                                                            
                            
            
                                    
            
            
                | 171 |  |  |         num_non_defaults = len(args) - len(defaults) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 172 |  |  |         for i, arg in enumerate(args): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 173 |  |  |             # Implicit self argument or omitted explicitly | 
            
                                                                                                            
                            
            
                                    
            
            
                | 174 |  |  |             if i < 1 and ismethod(func): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 175 |  |  |                 continue | 
            
                                                                                                            
                            
            
                                    
            
            
                | 176 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 177 |  |  |             if i < num_non_defaults: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 178 |  |  |                 non_optional_params[arg] = ( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 179 |  |  |                     doc_comment.param_dict.get(arg, cls.str_nodesc), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 180 |  |  |                     argspec.annotations.get(arg, None)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 181 |  |  |             else: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 182 |  |  |                 optional_params[arg] = ( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 183 |  |  |                     doc_comment.param_dict.get(arg, cls.str_nodesc) + " (" + | 
            
                                                                                                            
                            
            
                                    
            
            
                | 184 |  |  |                     cls.str_optional.format( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 185 |  |  |                         defaults[i-num_non_defaults]) + ")", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 186 |  |  |                     argspec.annotations.get(arg, None), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 187 |  |  |                     defaults[i-num_non_defaults]) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 188 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 189 |  |  |         return cls(name=func.__name__, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 190 |  |  |                    desc=doc_comment.desc, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 191 |  |  |                    retval_desc=doc_comment.retval_desc, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 192 |  |  |                    non_optional_params=non_optional_params, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 193 |  |  |                    optional_params=optional_params, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 194 |  |  |                    omit=omit) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 195 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 196 |  |  |     def filter_parameters(self, dct): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 197 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 198 |  |  |         Filters the given dict for keys that are declared as parameters inside | 
            
                                                                                                            
                            
            
                                    
            
            
                | 199 |  |  |         this metadata (either optional or non-optional). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 200 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 201 |  |  |         You can use this function to safely pass parameters from a given | 
            
                                                                                                            
                            
            
                                    
            
            
                | 202 |  |  |         dictionary: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 203 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 204 |  |  |         >>> def multiply(a, b=2, c=0): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 205 |  |  |         ...     return a * b + c | 
            
                                                                                                            
                            
            
                                    
            
            
                | 206 |  |  |         >>> metadata = FunctionMetadata.from_function(multiply) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 207 |  |  |         >>> args = metadata.filter_parameters({'a': 10, 'b': 20, 'd': 30}) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 208 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 209 |  |  |         You can safely pass the arguments to the function now: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 210 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 211 |  |  |         >>> multiply(**args)  # 10 * 20 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 212 |  |  |         200 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 213 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 214 |  |  |         :param dct: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 215 |  |  |             The dict to filter. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 216 |  |  |         :return: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 217 |  |  |             A new dict containing the filtered items. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 218 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 219 |  |  |         return {key: dct[key] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 220 |  |  |                 for key in (self.non_optional_params.keys() | | 
            
                                                                                                            
                            
            
                                    
            
            
                | 221 |  |  |                             self.optional_params.keys()) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 222 |  |  |                 if key in dct} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 223 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 224 |  |  |     @classmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 225 |  |  |     def merge(cls, *metadatas): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 226 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 227 |  |  |         Merges signatures of ``FunctionMetadata`` objects. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 228 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 229 |  |  |         Parameter (either optional or non-optional) and non-parameter | 
            
                                                                                                            
                            
            
                                    
            
            
                | 230 |  |  |         descriptions are merged from left to right, meaning the right hand | 
            
                                                                                                            
                            
            
                                    
            
            
                | 231 |  |  |         metadata overrides the left hand one. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 232 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 233 |  |  |         >>> def a(x, y): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 234 |  |  |         ...     ''' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 235 |  |  |         ...     desc of *a* | 
            
                                                                                                            
                            
            
                                    
            
            
                | 236 |  |  |         ...     :param x: x of a | 
            
                                                                                                            
                            
            
                                    
            
            
                | 237 |  |  |         ...     :param y: y of a | 
            
                                                                                                            
                            
            
                                    
            
            
                | 238 |  |  |         ...     :return:  5*x*y | 
            
                                                                                                            
                            
            
                                    
            
            
                | 239 |  |  |         ...     ''' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 240 |  |  |         ...     return 5 * x * y | 
            
                                                                                                            
                            
            
                                    
            
            
                | 241 |  |  |         >>> def b(x): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 242 |  |  |         ...     ''' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 243 |  |  |         ...     desc of *b* | 
            
                                                                                                            
                            
            
                                    
            
            
                | 244 |  |  |         ...     :param x: x of b | 
            
                                                                                                            
                            
            
                                    
            
            
                | 245 |  |  |         ...     :return:  100*x | 
            
                                                                                                            
                            
            
                                    
            
            
                | 246 |  |  |         ...     ''' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 247 |  |  |         ...     return 100 * x | 
            
                                                                                                            
                            
            
                                    
            
            
                | 248 |  |  |         >>> metadata1 = FunctionMetadata.from_function(a) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 249 |  |  |         >>> metadata2 = FunctionMetadata.from_function(b) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 250 |  |  |         >>> merged = FunctionMetadata.merge(metadata1, metadata2) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 251 |  |  |         >>> merged.name | 
            
                                                                                                            
                            
            
                                    
            
            
                | 252 |  |  |         "<Merged signature of 'a', 'b'>" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 253 |  |  |         >>> merged.desc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 254 |  |  |         'desc of *b*' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 255 |  |  |         >>> merged.retval_desc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 256 |  |  |         '100*x' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 257 |  |  |         >>> merged.non_optional_params['x'][0] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 258 |  |  |         'x of b' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 259 |  |  |         >>> merged.non_optional_params['y'][0] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 260 |  |  |         'y of a' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 261 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 262 |  |  |         :param metadatas: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 263 |  |  |             The sequence of metadatas to merge. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 264 |  |  |         :return: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 265 |  |  |             A ``FunctionMetadata`` object containing the merged signature of | 
            
                                                                                                            
                            
            
                                    
            
            
                | 266 |  |  |             all given metadatas. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 267 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 268 |  |  |         # Collect the metadatas, as we operate on them more often and we want | 
            
                                                                                                            
                            
            
                                    
            
            
                | 269 |  |  |         # to support arbitrary sequences. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 270 |  |  |         metadatas = tuple(metadatas) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 271 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 272 |  |  |         merged_name = ("<Merged signature of " + | 
            
                                                                                                            
                            
            
                                    
            
            
                | 273 |  |  |                        ", ".join(repr(metadata.name) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 274 |  |  |                                  for metadata in metadatas) + | 
            
                                                                                                            
                            
            
                                    
            
            
                | 275 |  |  |                        ">") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 276 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 277 |  |  |         merged_desc = next((m.desc for m in reversed(metadatas) if m.desc), "") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 278 |  |  |         merged_retval_desc = next( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 279 |  |  |             (m.retval_desc for m in reversed(metadatas) if m.retval_desc), "") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 280 |  |  |         merged_non_optional_params = {} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 281 |  |  |         merged_optional_params = {} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 282 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 283 |  |  |         for metadata in metadatas: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 284 |  |  |             # Use the fields and not the properties to get also omitted | 
            
                                                                                                            
                            
            
                                    
            
            
                | 285 |  |  |             # parameters. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 286 |  |  |             merged_non_optional_params.update(metadata._non_optional_params) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 287 |  |  |             merged_optional_params.update(metadata._optional_params) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 288 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 289 |  |  |         merged_omit = set.union(*(metadata.omit for metadata in metadatas)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 290 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 291 |  |  |         return cls(merged_name, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 292 |  |  |                    merged_desc, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 293 |  |  |                    merged_retval_desc, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 294 |  |  |                    merged_non_optional_params, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 295 |  |  |                    merged_optional_params, | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 296 |  |  |                    merged_omit) | 
            
                                                        
            
                                    
            
            
                | 297 |  |  |  |