def reqrep(wrapped: t.Callable, meth: t.Callable, channel: str = "shell") -> t.Callable: wrapped = wrapped(meth, channel) if not meth.__doc__: # python -OO removes docstrings, # so don't bother building the wrapped docstring return wrapped basedoc, _ = meth.__doc__.split("Returns\n", 1) parts = [basedoc.strip()] if "Parameters" not in basedoc: parts.append(""" Parameters ---------- """) parts.append(""" reply: bool (default: False) Whether to wait for and return reply timeout: float or None (default: None) Timeout to use when waiting for a reply Returns ------- msg_id: str The msg_id of the request sent, if reply=False (default) reply: dict The reply message for this request, if reply=True """) wrapped.__doc__ = "\n".join(parts) return wrapped
def __call__(self, func:typing.Callable): string = func.__doc__ pos = string.index(cn.EXPAND) if pos < 0: return func # Find the indentation for the line indent = pos for idx in range(1, pos): if string[pos - idx] != " ": indent = idx - 1 break indent_str = self._getIndentStr(indent) # Construct the expansion if len(self.header) > 0: expansion = self._indentText(self.header, indent_str) else: expansion = "" keywords = list(self.keywords) keywords.sort() for idx, keyword in enumerate(keywords): self.kwarg_dct[keyword].setIndent(self._indent) expansion += str(self.kwarg_dct[keyword]) expansion += self._indentText(self.trailer, indent_str) # Replace the docstring replace_str = "%s%s" % (indent_str, cn.EXPAND) func.__doc__ = string.replace(replace_str, expansion) return func
def func(f: t.Callable): name = f.__name__ #args = f.__arguments__ annotations = f.__annotations__ module = f.__module__ doc = f.__doc__ qname = f.__qualname__ for opt in sorted(option.options): f = cmd_option(opt, name_prefix)(f) f.__name__ = name[0:-2] if name.endswith("_") else name f.__qualname__ = qname[0:-2] if qname.endswith("_") else qname #f.__args__ = args f.__annotations__ = annotations f.__module__ = module f.__doc__ = doc return f
def func(f: t.Callable): name = f.__name__ #args = f.__arguments__ annotations = f.__annotations__ module = f.__module__ doc = f.__doc__ qname = f.__qualname__ for i, opt in enumerate(sorted(option.options)): validate = None if isinstance(opt, CmdOption) and i == 0: validate = True f = cmd_option(opt, name_prefix, validate=validate)(f) f.__name__ = name[0:-2] if name.endswith("_") else name f.__qualname__ = qname[0:-2] if qname.endswith("_") else qname #f.__args__ = args f.__annotations__ = annotations f.__module__ = module f.__doc__ = doc return f
def update_wrapper( wrapper: T.Callable, wrapped: T.Callable, signature: T.Union[_FullerSig, None, bool] = True, # not in functools docstring: T.Union[str, bool] = True, # not in functools assigned: T.Sequence[str] = WRAPPER_ASSIGNMENTS, updated: T.Sequence[str] = WRAPPER_UPDATES, # docstring options _doc_fmt: T.Optional[dict] = None, # not in functools _doc_style: T.Union[str, T.Callable, None] = None, ): """Update a wrapper function to look like the wrapped function. Parameters ---------- wrapper : Callable the function to be updated wrapped : Callable the original function signature : Signature or None or bool, optional signature to impose on `wrapper`. None and False default to `wrapped`'s signature. True merges `wrapper` and `wrapped` kwdefaults & annotations docstring : str or bool, optional docstring to impose on `wrapper`. False ignores `wrapper`'s docstring, using only `wrapped`'s docstring. None (defualt) merges the `wrapper` and `wrapped` docstring assigned : tuple, optional tuple naming the attributes assigned directly from the wrapped function to the wrapper function (defaults to ``functools.WRAPPER_ASSIGNMENTS``) updated : tuple, optional is a tuple naming the attributes of the wrapper that are updated with the corresponding attribute from the wrapped function (defaults to ``functools.WRAPPER_UPDATES``) _doc_fmt : dict, optional dictionary to format wrapper docstring _doc_style: str or Callable, optional the style of the docstring if None (default), appends `wrapper` docstring if str or Callable, merges the docstring Returns ------- wrapper : Callable `wrapper` function updated by the `wrapped` function's attributes and also the provided `signature` and `docstring`. Raises ------ ValueError if docstring is True """ # --------------------------------------- # preamble signature, _update_sig = __parse_sig_for_update_wrapper(signature, wrapped) # need to get wrapper properties now wrapper_sig = _FullerSig.from_callable(wrapper) wrapper_doc = _nspct.getdoc(wrapper) or "" wrapper_doc = "\n".join(wrapper_doc.split("\n")[1:]) # drop title if _doc_fmt is None: _doc_fmt = {} # --------------------------------------- # update wrapper (same as functools.update_wrapper) for attr in assigned: try: value = getattr(wrapped, attr) except AttributeError: pass else: setattr(wrapper, attr, value) for attr in updated: # update whole dictionary getattr(wrapper, attr).update(getattr(wrapped, attr, {})) # --------------------------------------- # deal with signature if signature in (None, False): pass elif _update_sig: # merge wrapped and wrapper signature signature = __update_wrapper_update_sig( signature, wrapper_sig, _doc_fmt ) for attr in SIGNATURE_ASSIGNMENTS: value = getattr(signature, attr) setattr(wrapper, attr, value) wrapper.__signature__ = signature.signature else: # a signature object for attr in SIGNATURE_ASSIGNMENTS: _value = getattr(signature, attr) setattr(wrapper, attr, _value) # for docstring for param in wrapper_sig.parameters.values(): # can only merge keyword-only if param.kind == _nspct.KEYWORD_ONLY: _doc_fmt[param.name] = param.default wrapper.__signature__ = signature.signature # --------------------------------------- # docstring if _doc_fmt: # (not empty dict) wrapper_doc = _FormatTemplate(wrapper_doc).safe_substitute(**_doc_fmt) wrapper.__doc__ = __update_wrapper_docstring( wrapped, docstring=docstring, wrapper_doc=wrapper_doc, _doc_style=_doc_style, ) # Issue #17482: set __wrapped__ last so we don't inadvertently copy it # from the wrapped function when updating __dict__ wrapper.__wrapped__ = wrapped # Return the wrapper so this can be used as a decorator via partial() return wrapper