Exemple #1
0
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
Exemple #2
0
    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
Exemple #4
0
    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
Exemple #5
0
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
Exemple #6
0
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)
Exemple #7
0
    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
Exemple #8
0
    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