def _parse_arglist(arglist: str) -> addnodes.desc_parameterlist: """Parse a list of arguments using AST parser""" params = addnodes.desc_parameterlist(arglist) sig = signature_from_str('(%s)' % arglist) last_kind = None for param in sig.parameters.values(): if param.kind != param.POSITIONAL_ONLY and last_kind == param.POSITIONAL_ONLY: # PEP-570: Separator for Positional Only Parameter: / params += addnodes.desc_parameter( '', '', addnodes.desc_sig_operator('', '/')) if param.kind == param.KEYWORD_ONLY and last_kind in ( param.POSITIONAL_OR_KEYWORD, param.POSITIONAL_ONLY, None): # PEP-3102: Separator for Keyword Only Parameter: * params += addnodes.desc_parameter( '', '', addnodes.desc_sig_operator('', '*')) node = addnodes.desc_parameter() if param.kind == param.VAR_POSITIONAL: node += addnodes.desc_sig_operator('', '*') node += addnodes.desc_sig_name('', param.name) elif param.kind == param.VAR_KEYWORD: node += addnodes.desc_sig_operator('', '**') node += addnodes.desc_sig_name('', param.name) else: node += addnodes.desc_sig_name('', param.name) if param.annotation is not param.empty: children = _parse_annotation(param.annotation) node += addnodes.desc_sig_punctuation('', ':') node += nodes.Text(' ') node += addnodes.desc_sig_name('', '', *children) # type: ignore if param.default is not param.empty: if param.annotation is not param.empty: node += nodes.Text(' ') node += addnodes.desc_sig_operator('', '=') node += nodes.Text(' ') else: node += addnodes.desc_sig_operator('', '=') node += nodes.inline('', param.default, classes=['default_value'], support_smartquotes=False) params += node last_kind = param.kind if last_kind == Parameter.POSITIONAL_ONLY: # PEP-570: Separator for Positional Only Parameter: / params += addnodes.desc_parameter('', '', addnodes.desc_sig_operator('', '/')) return params
def handle_signature(self, sig: str, signode: desc_signature) -> str: params = addnodes.desc_parameterlist() returns = addnodes.desc_parameterlist() contentnode = addnodes.desc_content() self.state.nested_parse(self.content, self.content_offset, contentnode) for child in contentnode: if isinstance(child, nodes.field_list): for field in child: ty, sg, name = field[0].astext().split(None, 2) param = addnodes.desc_parameter() param += addnodes.desc_sig_keyword_type(sg, sg) param += addnodes.desc_sig_space() param += addnodes.desc_sig_name(name, name) if ty == "arg": params += param elif ty == "ret": returns += param anno = "signal " if self.signal else "method " signode += addnodes.desc_annotation(anno, anno) signode += addnodes.desc_name(sig, sig) signode += params if not self.signal and "noreply" not in self.options: ret = addnodes.desc_returns() ret += returns signode += ret return sig
def handle_subp_sig(self, sig, signode): assert USE_LAL, "LAL is not available" import timeit start_time = timeit.default_timer() try: subp_spec_unit = self.lal_context().get_from_buffer( "<input>", sig, rule=lal.GrammarRule.subp_spec_rule ) except Exception: raise elapsed = timeit.default_timer() - start_time print(elapsed) subp_spec: lal.SubpSpec = subp_spec_unit.root.cast(lal.SubpSpec) if subp_spec is None: logger.warning("Couldn't parse the subp spec") raise ValueError is_func = subp_spec.f_subp_returns is not None modname, name, returntype = ( "", subp_spec.f_subp_name.text, subp_spec.f_subp_returns.text if is_func else "", ) kind = "function " if is_func else "procedure " signode += addnodes.desc_annotation(kind, kind) fullname = self._resolve_module_name(signode, modname, name) signode += nodes.Text(" ") param_list = addnodes.desc_parameterlist() param_list.child_text_separator = "; " signode += param_list if subp_spec.f_subp_params: for p in subp_spec.f_subp_params.f_params: param = addnodes.desc_parameter() param_list += param for i, name in enumerate(p.f_ids): param += addnodes.desc_sig_name("", name.text) if i + 1 < len(p.f_ids): param += addnodes.desc_sig_punctuation("", ", ") param += addnodes.desc_sig_punctuation("", " : ") refnode = self.make_refnode( p.f_type_expr.text, addnodes.desc_sig_name ) param += refnode if returntype: signode += self.make_refnode(returntype, addnodes.desc_returns) return fullname
def handle_signature(self, sig: str, signode: addnodes.desc_signature) -> Tuple[str, str]: """Transform a signature/object into RST nodes.""" try: self.obj = BlarkSphinxCache.instance().find_by_name(sig) except KeyError: self.obj = MissingDeclaration(sig) logger.error("Could not find object: %r (signatures unsupported)", sig) raise ValueError(f"Code object not found: {sig!r}") self.env.ref_context["bk:function"] = self.obj signode["ids"] = [sig] signode["docname"] = self.env.docname signode["qualified_name"] = sig domain_data = self.env.domaindata["bk"][self.signature_prefix.lower()] domain_data.setdefault(sig, []).append(signode) sig_prefix = self.get_signature_prefix(sig) signode += addnodes.desc_annotation(str(sig_prefix), '', *sig_prefix) signode += addnodes.desc_name(self.obj.name, self.obj.name) paramlist = addnodes.desc_parameterlist("paramlist") for block in ("VAR_INPUT", "VAR_IN_OUT", "VAR_OUTPUT", "STRUCT"): decls = self.obj.declarations_by_block.get(block, {}) for variable, decl in decls.items(): node = addnodes.desc_parameter() # node += addnodes.desc_sig_operator('', '*') node += addnodes.desc_type("", decl.type) node += addnodes.desc_sig_space() node += addnodes.desc_sig_name("", variable) if block == "VAR_OUTPUT": node += addnodes.desc_sig_punctuation(text="=>") paramlist += node signode += paramlist if getattr(self.obj, "return_type", None) is not None: signode += addnodes.desc_returns() signode += addnodes.desc_type(text=self.obj.return_type) prefix = "" return sig, prefix
def handle_signature(self, sig, signode): """Monkey patch handle signature to add type annotations to parameters. These type annotations were calculated in autodoc_process_signature. Bugs in autodoc prevented more direct sensible-seeming approaches. In particular, if we set signature to any nonzero value for a property, the property name gets doubled. """ result = old_handle_signature(self, sig, signode) if "property" in self.options: if sig in property_signatures: retann = property_signatures[sig] # _parse_annotation puts links and stuff into the type annotation. # It calls type_to_xref which we monkey patched too. children = sphinx.domains.python._parse_annotation( retann, self.env) signode += addnodes.desc_sig_punctuation( "", " : ") # "property_name : type" signode += addnodes.desc_sig_name(retann, "", *children) return result
def declaration_to_signature( signode: addnodes.desc_signature, obj: summary.DeclarationSummary, *, env: Optional[sphinx.environment.BuildEnvironment] = None, ): if env is not None: signode["ids"] = [obj.qualified_name] signode["docname"] = env.docname signode["qualified_name"] = obj.qualified_name env.domaindata["bk"]["declaration"].setdefault(obj.qualified_name, []).append(signode) yield addnodes.desc_sig_name(obj.name, obj.name) yield addnodes.desc_sig_punctuation(text=" : ") yield addnodes.pending_xref(obj.base_type, nodes.Text(obj.type), refdomain="bk", reftype="type", reftarget=obj.base_type)
def _parse_params(self) -> addnodes.desc_parameterlist: """ Convert the function's parameter list to a tree. """ params = addnodes.desc_parameterlist() last_kind = None for param in self.__inspect_sig.parameters.values(): if (param.kind in (Parameter.KEYWORD_ONLY, Parameter.VAR_KEYWORD) or param.default is Parameter.empty): if self.call_style == JsonRpcMethodCallStyle.ARRAY: raise Exception( "A JSON-RPC method cannot contain both positional-only and " "keyword-only arguments.") else: self.call_style = JsonRpcMethodCallStyle.OBJECT if param.kind in (Parameter.POSITIONAL_ONLY, Parameter.VAR_POSITIONAL): if self.call_style == JsonRpcMethodCallStyle.OBJECT: raise Exception( "A JSON-RPC method cannot contain both positional-only and " "keyword-only arguments.") else: self.call_style = JsonRpcMethodCallStyle.ARRAY node = addnodes.desc_parameter() node += addnodes.desc_sig_name("", param.name) if param.annotation is not param.empty: ann = self._annotation(self.__type_hints[param.name]) node += nodes.Text(f": {ann}") if param.default is not param.empty: node += nodes.Text(f" [default={param.default}]") params += node return params
def handle_signature(self, sig: str, signode: desc_signature) -> Tuple[str, str]: """Breaks down construct signatures Parses out prefix and argument list from construct definition. The namespace and class will be determined by the nesting of domain directives. """ sig = sig.strip() if '(' in sig and sig[-1:] == ')': member, arglist = sig.split('(', 1) member = member.strip() arglist = arglist[:-1].strip() else: member = sig arglist = None # If construct is nested, prefix the current prefix prefix = self.env.ref_context.get('js:object', None) mod_name = self.env.ref_context.get('js:module') name = member try: member_prefix, member_name = member.rsplit('.', 1) except ValueError: member_name = name member_prefix = '' finally: name = member_name if prefix and member_prefix: prefix = '.'.join([prefix, member_prefix]) elif prefix is None and member_prefix: prefix = member_prefix fullname = name if prefix: fullname = '.'.join([prefix, name]) signode['module'] = mod_name signode['object'] = prefix signode['fullname'] = fullname display_prefix = self.get_display_prefix() if display_prefix: signode += addnodes.desc_annotation('', '', *display_prefix) actual_prefix = None if prefix: actual_prefix = prefix elif mod_name: actual_prefix = mod_name if actual_prefix: addName = addnodes.desc_addname('', '') for p in actual_prefix.split('.'): addName += addnodes.desc_sig_name(p, p) addName += addnodes.desc_sig_punctuation('.', '.') signode += addName signode += addnodes.desc_name('', '', addnodes.desc_sig_name(name, name)) if self.has_arguments: if not arglist: signode += addnodes.desc_parameterlist() else: _pseudo_parse_arglist(signode, arglist) return fullname, prefix