From cbf5367aa5f7dc8281aecc8a2c81ca94d640df31 Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Thu, 22 Apr 2021 20:18:32 +0100 Subject: [PATCH] More compact doc rendering of introspected property types --- docs/api/connections.rst | 27 +++++++------- docs/api/cursors.rst | 14 +++---- docs/api/pool.rst | 4 +- docs/api/pq.rst | 4 +- docs/lib/pg3_docs.py | 70 +++++++++++++++++++++++++++++++++++ psycopg3/psycopg3/conninfo.py | 21 ++++++----- 6 files changed, 106 insertions(+), 34 deletions(-) diff --git a/docs/api/connections.rst b/docs/api/connections.rst index 5a9f6dfb0..8b19c410d 100644 --- a/docs/api/connections.rst +++ b/docs/api/connections.rst @@ -110,8 +110,8 @@ The `!Connection` class For details see :ref:`transactions`. - .. automethod:: commit() - .. automethod:: rollback() + .. automethod:: commit + .. automethod:: rollback .. automethod:: transaction .. note:: It must be called as ``with conn.transaction() as tx: ...`` @@ -253,31 +253,30 @@ Connection support objects The object is usually returned by `Connection.info`. - .. autoproperty:: status - .. autoproperty:: transaction_status - .. autoproperty:: server_version + .. autoattribute:: status + .. autoattribute:: transaction_status + .. autoattribute:: server_version .. automethod:: get_parameters - - .. autoproperty:: host - .. autoproperty:: port - .. autoproperty:: dbname - .. autoproperty:: user - .. autoproperty:: password - .. autoproperty:: options + .. autoattribute:: host + .. autoattribute:: port + .. autoattribute:: dbname + .. autoattribute:: user + .. autoattribute:: password + .. autoattribute:: options .. automethod:: parameter_status Example of parameters are ``server_version``, ``standard_conforming_string``... See :pq:`PQparameterStatus()` for all the available parameters. - .. autoproperty:: protocol_version + .. autoattribute:: protocol_version .. rubric:: Objects involved in :ref:`transactions` .. autoclass:: Transaction() - .. autoproperty:: savepoint_name + .. autoattribute:: savepoint_name .. autoattribute:: connection .. autoclass:: AsyncTransaction() diff --git a/docs/api/cursors.rst b/docs/api/cursors.rst index 089e56755..8fd26c8e0 100644 --- a/docs/api/cursors.rst +++ b/docs/api/cursors.rst @@ -126,7 +126,7 @@ The `!Cursor` class .. note:: cursors are iterable objects, so just using ``for record in cursor`` syntax will iterate on the records in the current recordset. - .. autoproperty:: row_factory + .. autoattribute:: row_factory The property affects the objects returned by the `fetchone()`, `fetchmany()`, `fetchall()` methods. The default @@ -338,12 +338,12 @@ The description `Column` object .. __: https://www.python.org/dev/peps/pep-0249/#description - .. autoproperty:: name - .. autoproperty:: type_code - .. autoproperty:: display_size - .. autoproperty:: internal_size - .. autoproperty:: precision - .. autoproperty:: scale + .. autoattribute:: name + .. autoattribute:: type_code + .. autoattribute:: display_size + .. autoattribute:: internal_size + .. autoattribute:: precision + .. autoattribute:: scale COPY-related objects diff --git a/docs/api/pool.rst b/docs/api/pool.rst index 824ebddbc..b4724f156 100644 --- a/docs/api/pool.rst +++ b/docs/api/pool.rst @@ -158,8 +158,8 @@ The `!ConnectionPool` class The name of the pool set on creation, or automatically generated if not set. - .. autoproperty:: min_size - .. autoproperty:: max_size + .. autoattribute:: min_size + .. autoattribute:: max_size The current minimum and maximum size of the pool. Use `resize()` to change them at runtime. diff --git a/docs/api/pq.rst b/docs/api/pq.rst index ebf5ea0b5..f4b5942c0 100644 --- a/docs/api/pq.rst +++ b/docs/api/pq.rst @@ -83,13 +83,13 @@ Objects wrapping libpq structures and functions .. autoclass:: PGconn() - .. autoproperty:: pgconn_ptr + .. autoattribute:: pgconn_ptr .. automethod:: get_cancel .. autoclass:: PGresult() - .. autoproperty:: pgresult_ptr + .. autoattribute:: pgresult_ptr .. autoclass:: Conninfo diff --git a/docs/lib/pg3_docs.py b/docs/lib/pg3_docs.py index cf6e67700..af1fd7097 100644 --- a/docs/lib/pg3_docs.py +++ b/docs/lib/pg3_docs.py @@ -83,6 +83,7 @@ def monkeypatch_autodoc(): orig_doc_get_real_modname = Documenter.get_real_modname orig_attr_get_real_modname = AttributeDocumenter.get_real_modname + orig_attr_add_content = AttributeDocumenter.add_content def fixed_doc_get_real_modname(self): if self.object in recovered_classes: @@ -94,8 +95,77 @@ def monkeypatch_autodoc(): return recovered_classes[self.parent] return orig_attr_get_real_modname(self) + 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(), + ) + Documenter.get_real_modname = fixed_doc_get_real_modname AttributeDocumenter.get_real_modname = fixed_attr_get_real_modname + 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 def walk_modules(d): diff --git a/psycopg3/psycopg3/conninfo.py b/psycopg3/psycopg3/conninfo.py index d6b1a681a..34e402307 100644 --- a/psycopg3/psycopg3/conninfo.py +++ b/psycopg3/psycopg3/conninfo.py @@ -103,37 +103,39 @@ class ConnectionInfo: @property def host(self) -> str: - """The host name of the database.""" + """The host name of the database. See :pq:`PQhost`.""" return self._get_pgconn_attr("host") @property def hostaddr(self) -> str: - """The server ip address of the connection.""" + """The server ip address of the connection. See :pq:`PQhostaddr`.""" return self._get_pgconn_attr("hostaddr") @property def port(self) -> int: - """The port of the database connection.""" + """The port of the database connection. See :pq:`PQport`.""" return int(self._get_pgconn_attr("port")) @property def dbname(self) -> str: - """The name of the connected database.""" + """The database name of the connection. See :pq:`PQdb`.""" return self._get_pgconn_attr("db") @property def user(self) -> str: - """The user of the database connection.""" + """The user of the database connection. See :pq:`PQuser`.""" return self._get_pgconn_attr("user") @property def password(self) -> str: - """The password of the database connection.""" + """The password of the database connection. See :pq:`PQpass`.""" return self._get_pgconn_attr("password") @property def options(self) -> str: - """The options parameter of the database connection.""" + """ + The options parameter of the database connection. See :pq:`PQoptions`. + """ return self._get_pgconn_attr("options") def get_parameters(self) -> Dict[str, str]: @@ -186,13 +188,14 @@ class ConnectionInfo: @property def server_version(self) -> int: - """An integer representing the server version. + """ + An integer representing the server version. See :pq:`PQserverVersion()`. The number is formed by converting the major, minor, and revision numbers into two-decimal-digit numbers and appending them together. After PostgreSQL 10 the minor version was dropped, so the second group of digits is always 00. For example, version 9.3.5 will be returned as - 90305, version 10.2 as 100002. See :pq:`PQserverVersion()`. + 90305, version 10.2 as 100002. """ return self.pgconn.server_version -- 2.47.2