U
    kuf                     @   s   d dl Z d dlZd dlZd dlZd dlZd dlZd dlZddlmZ ddl	m
Z
 ddlmZ dd ZG dd	 d	ejZG d
d dejZG dd dejZG dd dejZdd ZdS )    N   )abc)only)ZipPathc                 C   s   t tj| S N)itercollectionsOrderedDictfromkeys)items r   ?/tmp/pip-unpacked-wheel-jirmq66v/importlib_resources/readers.pyremove_duplicates   s    r   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )
FileReaderc                 C   s   t |jj| _d S r   )pathlibPathpathparent)selfloaderr   r   r   __init__   s    zFileReader.__init__c                 C   s   t | j|S z{
        Return the file system path to prevent
        `resources.path()` from creating a temporary
        copy.
        strr   joinpathr   resourcer   r   r   resource_path   s    zFileReader.resource_pathc                 C   s   | j S r   r   r   r   r   r   files   s    zFileReader.filesN)__name__
__module____qualname__r   r   r    r   r   r   r   r      s   r   c                       s4   e Zd Zdd Z fddZdd Zdd Z  ZS )		ZipReaderc                 C   s4   | d\}}}|jdd| d | _|j| _d S )N.\/)
rpartitionprefixreplacearchive)r   r   module_namer   r   r   r   $   s    zZipReader.__init__c              
      sD   zt  |W S  tk
r> } zt|jd W 5 d }~X Y nX d S Nr   )superopen_resourceKeyErrorFileNotFoundErrorargs)r   r   exc	__class__r   r   r1   )   s    zZipReader.open_resourcec                 C   s   |   |}| o| S )zf
        Workaround for `zipfile.Path.is_file` returning true
        for non-existent paths.
        )r    r   is_fileexists)r   r   targetr   r   r   is_resource/   s    zZipReader.is_resourcec                 C   s   t | j| jS r   )r   r+   r)   r   r   r   r   r    7   s    zZipReader.files)r!   r"   r#   r   r1   r;   r    __classcell__r   r   r6   r   r$   #   s   r$   c                       sx   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	 fddZ
edd Zdd Zedd Zdd Z  ZS )MultiplexedPathz
    Given a series of Traversable objects, implement a merged
    version of the interface across all objects. Useful for
    namespace packages which may be multihomed at a single
    name.
    c                 G   sF   t ttt|| _| js&d}t|tdd | jD sBtdd S )Nz.MultiplexedPath must contain at least one pathc                 s   s   | ]}|  V  qd S r   is_dir.0r   r   r   r   	<genexpr>H   s     z+MultiplexedPath.__init__.<locals>.<genexpr>z)MultiplexedPath only supports directories)listmap_ensure_traversabler   _pathsr3   allNotADirectoryError)r   pathsmessager   r   r   r   C   s    zMultiplexedPath.__init__c                 C   sF   dd | j D }td}tjt||d|d}t| jdd |D S )Nc                 s   s    | ]}|  D ]
}|V  qqd S r   )iterdir)rA   r   childr   r   r   rB   L   s     
  z*MultiplexedPath.iterdir.<locals>.<genexpr>r.   )keyc                 s   s   | ]\}}|V  qd S r   r   )rA   r.   Zlocsr   r   r   rB   O   s     )rF   operator
attrgetter	itertoolsgroupbysortedrD   _follow)r   childrenZby_namegroupsr   r   r   rK   K   s    
zMultiplexedPath.iterdirc                 C   s   t |  dd S Nz is not a filer3   r   r   r   r   
read_bytesQ   s    zMultiplexedPath.read_bytesc                 O   s   t |  dd S rV   rW   r   r4   kwargsr   r   r   	read_textT   s    zMultiplexedPath.read_textc                 C   s   dS )NTr   r   r   r   r   r?   W   s    zMultiplexedPath.is_dirc                 C   s   dS )NFr   r   r   r   r   r8   Z   s    zMultiplexedPath.is_filec                    s:   zt  j| W S  tjk
r4   | jd j|  Y S X d S r/   )r0   r   r   ZTraversalErrorrF   )r   Zdescendantsr6   r   r   r   ]   s    zMultiplexedPath.joinpathc                 C   sf   t |d\}}}z
t|W S  tk
r`   z| | W  Y S  tk
rZ   t| Y  Y S X Y nX dS )z
        Construct a MultiplexedPath if needed.

        If children contains a sole element, return it.
        Otherwise, return a MultiplexedPath of the items.
        Unless one of the items is not a Directory, then return the first.
           N)rP   teer   
ValueErrorrH   next)clsrT   subdirsZone_dirZone_filer   r   r   rS   e   s    	
zMultiplexedPath._followc                 O   s   t |  dd S rV   rW   rY   r   r   r   openx   s    zMultiplexedPath.openc                 C   s   | j d jS r/   )rF   r.   r   r   r   r   r.   {   s    zMultiplexedPath.namec                 C   s"   d dd | jD }d| dS )Nz, c                 s   s   | ]}d | d V  qdS )'Nr   r@   r   r   r   rB      s     z+MultiplexedPath.__repr__.<locals>.<genexpr>zMultiplexedPath())joinrF   )r   rI   r   r   r   __repr__   s    zMultiplexedPath.__repr__)r!   r"   r#   __doc__r   rK   rX   r[   r?   r8   r   classmethodrS   rb   propertyr.   rf   r<   r   r   r6   r   r=   ;   s   

r=   c                   @   sP   e Zd Zdd ZeejdddZedd Ze	dd	 Z
d
d Zdd ZdS )NamespaceReaderc                 C   s*   dt |krtdtt| j| | _d S )NZNamespacePathzInvalid path)r   r^   r=   rD   _resolver   )r   namespace_pathr   r   r   r      s    zNamespaceReader.__init__)returnc                 C   s   dd |  |D \}|S )a'  
        Given an item from a namespace path, resolve it to a Traversable.

        path_str might be a directory on the filesystem or a path to a
        zipfile plus the path within the zipfile, e.g. ``/foo/bar`` or
        ``/foo/baz.zip/inner_dir`` or ``foo\baz.zip\inner_dir\sub``.
        c                 s   s   | ]}|  r|V  qd S r   r>   )rA   Zcandr   r   r   rB      s      z+NamespaceReader._resolve.<locals>.<genexpr>)_candidate_paths)r`   path_strdirr   r   r   rk      s    	zNamespaceReader._resolvec                 c   s    t |V  | |E d H  d S r   )r   r   _resolve_zip_path)r`   ro   r   r   r   rn      s    z NamespaceReader._candidate_pathsc              
   c   st   t ttd| D ]Z}ttttt	@ | |
 d  ddd }t| d |  |dV  W 5 Q R X qd S )Nz[\\/]r&   r'   )reversedrC   refinditer
contextlibsuppressr3   IsADirectoryErrorrH   PermissionErrorendr*   r   startlstrip)ro   matchinnerr   r   r   rq      s    z!NamespaceReader._resolve_zip_pathc                 C   s   t | j|S r   r   r   r   r   r   r      s    zNamespaceReader.resource_pathc                 C   s   | j S r   r   r   r   r   r   r       s    zNamespaceReader.filesN)r!   r"   r#   r   rh   r   Traversablerk   rn   staticmethodrq   r   r    r   r   r   r   rj      s   

rj   c                 C   s(   t | ts| S tjdtdd t| S )zk
    Convert deprecated string arguments to traversables (pathlib.Path).

    Remove with Python 3.15.
    z<String arguments are deprecated. Pass a Traversable instead.r\   )
stacklevel)
isinstancer   warningswarnDeprecationWarningr   r   r   r   r   r   rE      s    
rE   )r   ru   rP   r   rN   rs   r    r   
_itertoolsr   Zcompat.py39r   r   ZTraversableResourcesr   r$   r~   r=   rj   rE   r   r   r   r   <module>   s   I/