Skip to content

More compact and more correct property description. #173

@dvarrazzo

Description

@dvarrazzo

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions