Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More compact and more correct property description. #173

Closed
dvarrazzo opened this issue Apr 22, 2021 · 3 comments
Closed

More compact and more correct property description. #173

dvarrazzo opened this issue Apr 22, 2021 · 3 comments

Comments

@dvarrazzo
Copy link

Properties introspected by typehints are decorated with a "return type" clause. This can take up a lot of space and talking about "return type" for a property/attribute is not even that correct.

In psycopg3 documentation I have monkeypatched AttributeDocumenter.add_content() so that if an attribute has a :rtype: it is converted into a :type:, which is placed right after the directive. The difference can be seen in:

image

The code involved is something like what shown below, for reference. Of course the implementation in the module itself would be different.

    orig_attr_add_content = AttributeDocumenter.add_content

    def fixed_attr_add_content(self, more_content, no_docstring=False):
        """
        Replace a docstring such as::

            .. py:attribute:: ConnectionInfo.dbname
               :module: psycopg3

               The database name of the connection.

               :rtype: :py:class:`str`

        into:

            .. py:attribute:: ConnectionInfo.dbname
               :type: str
               :module: psycopg3

               The database name of the connection.

        which creates a more compact representation of a property.

        """
        orig_attr_add_content(self, more_content, no_docstring)
        if not isinstance(self.object, property):
            return
        iret, mret = match_in_lines(r"\s*:rtype: (.*)", self.directive.result)
        iatt, matt = match_in_lines(r"\.\.", self.directive.result)
        if not (mret and matt):
            return
        self.directive.result.pop(iret)
        self.directive.result.insert(
            iatt + 1,
            f"{self.indent}:type: {unrest(mret.group(1))}",
            source=self.get_sourcename(),
        )

    AttributeDocumenter.add_content = fixed_attr_add_content

def match_in_lines(pattern, lines):
    """Match a regular expression against a list of strings.

    Return the index of the first matched line and the match object.
    None, None if nothing matched.
    """
    for i, line in enumerate(lines):
        m = re.match(pattern, line)
        if m:
            return i, m
    else:
        return None, None

def unrest(s):
    r"""remove the reST markup from a string

    e.g. :py:data:`~typing.Optional`\[:py:class:`int`] -> Optional[int]

    required because :type: does the types lookup itself apparently.
    """
    s = re.sub(r":[^`]*:`~?([^`]*)`", r"\1", s)  # drop role
    s = re.sub(r"\\(.)", r"\1", s)  # drop escape

    # note that ~psycopg3.pq.ConnStatus is converted to pq.ConnStatus
    # which should be interpreted well if currentmodule is set ok.
    s = re.sub(r"(?:typing|psycopg3)\.", "", s)  # drop unneeded modules
    s = re.sub(r"~", "", s)  # drop the tilde

    return s
@gaborbernat
Copy link
Member

A PR for this would be welcome.

@bryanforbes
Copy link
Contributor

Setting :type: for properties based on the return type of the property function is addressed in Sphinx 4.0 via sphinx-doc/sphinx#7383. It seems that the :rtype: annotation for properties can be removed now. However, the types added by sphinx don't get run through typehints_formatter(), so it might be a good idea to include that functionality (if possible).

@hoodmane
Copy link
Collaborator

hoodmane commented Jan 20, 2023

I think this is resolved, partially by #287 and partially by the change to sphinx 4.0 mentioned above (probably some other changes were also involved, not sure).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants