o
    Uh                     @   s   d Z ddlZddlZddlZddlZddlmZmZmZm	Z	m
Z
 g dZG dd deZG dd dZG d	d
 d
Zdee dee	eeef  fddZdS )zGProvides an object-oriented model for handling :pep:`376` RECORD files.    N)IterableIteratorOptionalTuplecast)HashRecordEntryInvalidRecordEntryparse_record_filec                       s(   e Zd ZdZ fddZdd Z  ZS )r	   zPRaised when a RecordEntry is not valid, due to improper element values or count.c                    s"   t  d| || _|| _d S )Nz, )super__init__joinissueselements)selfr   r   	__class__ e/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/installer/records.pyr      s   
zInvalidRecordEntry.__init__c                 C   s   d | j| jS )Nz.InvalidRecordEntry(elements={!r}, issues={!r}))formatr   r   r   r   r   r   __repr__   s   zInvalidRecordEntry.__repr__)__name__
__module____qualname____doc__r   r   __classcell__r   r   r   r   r	      s    r	   c                   @   sr   e Zd ZdZdededdfddZdefdd	Zdefd
dZdd Zde	de
fddZededd fddZdS )r   z/Represents the "hash" element of a RecordEntry.namevaluereturnNc                 C   s   || _ || _dS )a  Construct a ``Hash`` object.

        Most consumers should use :py:meth:`Hash.parse` instead, since no
        validation or parsing is performed by this constructor.

        :param name: name of the hash function
        :param value: hashed value
        Nr   r   )r   r   r   r   r   r   r   "   s   	
zHash.__init__c                 C   s   | j  d| j S )N=r    r   r   r   r   __str__.   s   zHash.__str__c                 C   s   d| j d| jdS )Nz
Hash(name=z, value=)r    r   r   r   r   r   1   s   zHash.__repr__c                 C   s&   t |tstS | j|jko| j|jkS N)
isinstancer   NotImplementedr   r   r   otherr   r   r   __eq__4   s   
zHash.__eq__datac                 C   s2   t | j| }t|dd}| j|kS )zValidate that ``data`` matches this instance.

        :param data: Contents of the file.
        :return: Whether ``data`` matches the hashed value.
        asciir!   )	hashlibnewr   digestbase64urlsafe_b64encodedecoderstripr   )r   r*   r.   r   r   r   r   validate9   s   
zHash.validatehc                 C   s   | dd\}}| ||S )a<  Build a Hash object, from a "name=value" string.

        This accepts a string of the format for the second element in a record,
        as described in :pep:`376`.

        Typical usage::

            Hash.parse("sha256=Y0sCextp4SQtQNU-MSs7SsdxD1W-gfKJtUlEbvZ3i-4")

        :param h: a name=value string
        r!      )split)clsr4   r   r   r   r   r   parseC   s   
z
Hash.parse)r   r   r   r   strr   r"   r   r)   bytesboolr3   classmethodr8   r   r   r   r   r      s    
r   c                	       s   e Zd ZdZdedee dee ddf fddZdd	ee de	eeef fd
dZ
defddZdd ZdedefddZededededd fddZ  ZS )r   zRepresents a single record in a RECORD file.

    A list of :py:class:`RecordEntry` objects fully represents a RECORD file.
    pathhash_sizer   Nc                    s    t    || _|| _|| _dS )a=  Construct a ``RecordEntry`` object.

        Most consumers should use :py:meth:`RecordEntry.from_elements`, since no
        validation or parsing is performed by this constructor.

        :param path: file's path
        :param hash\_: hash of the file's contents
        :param size: file's size in bytes
        N)r   r   r=   r>   r?   )r   r=   r>   r?   r   r   r   r   Z   s   


zRecordEntry.__init__path_prefixc                 C   sh   |dur| dsJ || j }n| j}tjdkr|dd}|t| jp%d| jdur1t| jfS dfS )zConvert this into a 3-element tuple that can be written in a RECORD file.

        :param path_prefix: A prefix to attach to the path -- must end in `/`
        :return: a (path, hash, size) row
        N/\ )endswithr=   ossepreplacer9   r>   r?   )r   r@   r=   r   r   r   to_rowj   s   
zRecordEntry.to_rowc                 C   s   d | j| j| jS )Nz-RecordEntry(path={!r}, hash_={!r}, size={!r}))r   r=   r>   r?   r   r   r   r   r      s   zRecordEntry.__repr__c                 C   s2   t |tstS | j|jko| j|jko| j|jkS r$   )r%   r   r&   r=   r>   r?   r'   r   r   r   r)      s   


zRecordEntry.__eq__r*   c                 C   s2   | j durt|| j krdS | jr| j|S dS )zValidate that ``data`` matches this instance.

        :param data: Contents of the file corresponding to this instance.
        :return: whether ``data`` matches hash and size.
        NFT)r?   lenr>   r3   )r   r*   r   r   r   r3      s
   zRecordEntry.validatec                 C   s   g }|s	| d |r!zt|}W n ty    | d Y nw d}|r:zt|}W n ty9   | d Y nw d}|rGt|||f|d| |||dS )a  Build a RecordEntry object, from values of the elements.

        Typical usage::

            for row in parse_record_file(f):
                record = RecordEntry.from_elements(row[0], row[1], row[2])

        Meaning of each element is specified in :pep:`376`.

        :param path: first element (file's path)
        :param hash\_: second element (hash of the file's contents)
        :param size: third element (file's size in bytes)
        :raises InvalidRecordEntry: if any element is invalid
        z`path` cannot be emptyz*`hash` does not follow the required formatNz`size` cannot be non-integerr   r   )r=   r>   r?   )appendr   r8   
ValueErrorintr	   )r7   r=   r>   r?   r   
hash_value
size_valuer   r   r   from_elements   s(   
zRecordEntry.from_elementsr$   )r   r   r   r   r9   r   r   rM   r   r   rH   r   r)   r:   r;   r3   r<   rP   r   r   r   r   r   r   T   s    &"	$r   rowsr   c                 c   s    t j| dddd}t|D ]2\}}t|dkr'd|t|}t||gd|d d	d
|d< ttt	t	t	f t
|}|V  qdS )zParse a :pep:`376` RECORD.

    Returns an iterable of 3-value tuples, that can be passed to
    :any:`RecordEntry.from_elements`.

    :param rows: iterator providing lines of a RECORD (no trailing newlines).
    ,"
)	delimiter	quotecharlineterminator   z)Row Index {}: expected 3 elements, got {}rJ   r   rB   rA   N)csvreader	enumeraterI   r   r	   rG   r   r   r9   tuple)rQ   rZ   	row_indexr   messager   r   r   r   r
      s   r
   )r   r/   rY   r,   rE   typingr   r   r   r   r   __all__	Exceptionr	   r   r   r9   r
   r   r   r   r   <module>   s    5(t