o
    Lj                     @  s   d dl mZ d dlmZmZ d dlmZmZ d dlm	Z	 h dZ
d"ddZd#ddZd$ddZd%ddZeG dd dZe	e	e	fd&dd Zd!S )'    )annotations)	dataclassfield)ListOptional)SENTINEL>   {}()[]valuestr
field_namereturnNonec                 C  s<   | D ]}t |dk st |dks|tv rt| dqdS )zEnsure value contains only printable ASCII without spaces or braces.

    This mirrors the constraints enforced by other Redis clients for values that
    will appear in CLIENT LIST / CLIENT INFO output.
    !   ~   zG must not contain spaces, newlines, non-printable characters, or bracesN)ord_BRACES
ValueError)r   r   ch r   O/home/djax/ivt_ai_plugin/venv/lib/python3.10/site-packages/redis/driver_info.py_validate_no_invalid_chars   s    r   namec                 C  s*   ddl }t| d |d| stddS )ao  Validate an upstream driver name.

    The name should look like a typical Python distribution or package name,
    following a simplified form of PEP 503 normalisation rules:

    * start with a lowercase ASCII letter
    * contain only lowercase letters, digits, hyphens and underscores

    Examples of valid names: ``"django-redis"``, ``"celery"``, ``"rq"``.
    r   NzDriver namez^[a-z][a-z0-9_-]*$zUpstream driver name must use a Python package-style name: start with a lowercase letter and contain only lowercase letters, digits, hyphens, and underscores (e.g., 'django-redis').)rer   matchr   )r   r   r   r   r   _validate_driver_name   s   
r   versionc                 C  s   t | d d S )NzDriver version)r   )r    r   r   r   _validate_driver_version1      r!   driver_namedriver_versionc                 C  s   |  d| S )N_vr   )r#   r$   r   r   r   _format_driver_entry5   r"   r&   c                   @  sj   e Zd ZU dZeZded< eZded< ee	dZ
ded< dd	 ZedddZdddZedddZdS )
DriverInfoa  Driver information used to build the CLIENT SETINFO LIB-NAME and LIB-VER values.

    This class consolidates all driver metadata (redis-py version and upstream drivers)
    into a single object that is propagated through connection pools and connections.

    The formatted name follows the pattern::

        name(driver1_vVersion1;driver2_vVersion2)

    Parameters
    ----------
    name : str, optional
        The base library name. If omitted, defaults to "redis-py". If None,
        LIB-NAME will not be sent.
    lib_version : str, optional
        The redis-py library version. If omitted, the version will be determined
        automatically from the installed package. If None, LIB-VER will not be sent.

    Examples
    --------
    >>> info = DriverInfo()
    >>> info.formatted_name
    'redis-py'

    >>> info = DriverInfo().add_upstream_driver("django-redis", "5.4.0")
    >>> info.formatted_name
    'redis-py(django-redis_v5.4.0)'

    >>> info = DriverInfo(lib_version="5.0.0")
    >>> info.lib_version
    '5.0.0'
    Optional[str] | objectr   lib_version)default_factory	List[str]	_upstreamc                 C  s6   | j tu rd| _ | jtu rddlm} | | _dS dS )z7Initialize default metadata if not explicitly provided.zredis-pyr   )get_lib_versionN)r   r   r)   redis.utilsr-   )selfr-   r   r   r   __post_init__`   s   

zDriverInfo.__post_init__r   c                 C  s
   t | jS )zuReturn a copy of the upstream driver entries.

        Each entry is in the form ``"driver-name_vversion"``.
        )listr,   )r/   r   r   r   upstream_driversi   s   
zDriverInfo.upstream_driversr#   r   r$   'DriverInfo'c                 C  sL   |du rt d|du rt dt| t| t||}| jd| | S )zAdd an upstream driver to this instance and return self.

        The most recently added driver appears first in :pyattr:`formatted_name`.
        NzDriver name must not be NonezDriver version must not be Noner   )r   r   r!   r&   r,   insert)r/   r#   r$   entryr   r   r   add_upstream_driverr   s   
zDriverInfo.add_upstream_driverOptional[str]c                 C  s:   | j }t|tr
|sdS | js|S | dd| j dS )zReturn the base name with upstream drivers encoded, if any.

        With no upstream drivers, this is just :pyattr:`name`. Otherwise::

            name(driver1_vX;driver2_vY)
        Nr
   ;r   )r   
isinstancer   r,   join)r/   r   r   r   r   formatted_name   s   	zDriverInfo.formatted_nameN)r   r+   )r#   r   r$   r   r   r3   )r   r7   )__name__
__module____qualname____doc__r   r   __annotations__r)   r   r1   r,   r0   propertyr2   r6   r;   r   r   r   r   r'   9   s   
 !	
r'   driver_infoOptional[DriverInfo] | objectlib_namer(   r)   Optional[DriverInfo]c                 C  sF   | t u r|du r|du rdS t||dS | du st| tr| S td)a%  Resolve driver_info from parameters.

    If driver_info is provided, use it. Otherwise, create DriverInfo from
    lib_name and lib_version (using defaults only for sentinel values).

    Parameters
    ----------
    driver_info : DriverInfo, optional
        The DriverInfo instance to use
    lib_name : str, optional
        The library name (default: "redis-py")
    lib_version : str, optional
        The library version (default: auto-detected)

    Returns
    -------
    DriverInfo, optional
        The resolved DriverInfo instance
    N)r   r)   z1driver_info must be a DriverInfo instance or None)r   r'   r9   	TypeError)rB   rD   r)   r   r   r   resolve_driver_info   s   rG   N)r   r   r   r   r   r   )r   r   r   r   )r    r   r   r   )r#   r   r$   r   r   r   )rB   rC   rD   r(   r)   r(   r   rE   )
__future__r   dataclassesr   r   typingr   r   r.   r   r   r   r   r!   r&   r'   rG   r   r   r   r   <module>   s    



_