Skip to content

Idea: adding a capabilities fuction? #772

@dvarrazzo

Description

@dvarrazzo

Several psycopg features depend on the libpq version and require precise knowledge of when a certain feature was added. For instance, skimming the ifs in the libpq: prepared statements, prepared statements compatibility with pgbouncer, PQhostAddr, async cancelling, set trace flag.

For pipelines the ad-hoc solution of Pipeline.is_supported(), but new needs are emerging for newer features.

Proposal: adding a psycopg.capability() function to check if a certain capability is supported or not. For instance:

def capability(name: str, *, check: bool = False) -> bool | None:
    """
    Verify if a capability is supported by the current libpq library or database function.

    :param name: the name of the capability to check
    :param check: if True, raise `NotSupportedError` if the capability is unsupported or unknown.
    :return: `True` if the capability is supported, `False` if not, `None` if unknown
    """
    ...

If check = True we may raise an error with a descriptive message for what is required to gain the capability, such as these. This could be add at import level to detect early if a capability required by a program is not supported. Otherwise, the result can be checked in an if.

import psycopg
psycopg.capability("pipeline", check=True)

...

if python.capability("pipeline"):
    with conn.pipeline():
       ...

The capabilities might be just strings or we might provide a string enum too to represent them. I would reserve ourselves the possibility to add a new capability check in bugfix releases.

class Capability(str, Enum):
    pipeline = "pipeline"
    close_prepared = "close_prepared"
    pgbouncer_prepared = "pgbouncer_prepared"  # maybe? Just a friendly alias for the above.
    hostaddr = "hostaddr"
    async_cancel = "async_cancel"
    trace_flags = "trace_flags"

I would like to add this feature in 3.2, because several feature conditional to the libpq version are being introduced.

What do you think? @dlax? @asqui?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions