o
    re1V                     @   s^  d dl mZmZm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mZmZmZmZmZ ddlmZ ddlmZmZ ddlmZmZmZmZ ed	ZG d
d dZG dd deZ										d)ddZ dd Z!dd Z"						d*ddZ#d+ddZ$dd Z%dd Z&dd  Z'd!d" Z(						d,d#d$Z)d%d& Z*G d'd( d(ej+Z,dS )-    )absolute_importdivisionprint_functionN)	has_magic   )	BaseCache
BlockCache
BytesCache	MMapCacheReadAheadCachecaches)compr)
filesystemget_filesystem_class)_unstrip_protocolbuild_name_functioninfer_compressionstringify_pathZfsspecc                   @   s`   e Zd ZdZ					dddZdd Zdd	 Zd
d Zdd Ze	dd Z
dd Zdd ZdS )OpenFileaF  
    File-like object to be used in a context

    Can layer (buffered) text-mode and compression over any file-system, which
    are typically binary-only.

    These instances are safe to serialize, as the low-level file object
    is not created until invoked using ``with``.

    Parameters
    ----------
    fs: FileSystem
        The file system to use for opening the file. Should be a subclass or duck-type
        with ``fsspec.spec.AbstractFileSystem``
    path: str
        Location to open
    mode: str like 'rb', optional
        Mode of the opened file
    compression: str or None, optional
        Compression to apply
    encoding: str or None, optional
        The encoding to use if opened in text mode.
    errors: str or None, optional
        How to handle encoding errors if opened in text mode.
    newline: None or str
        Passed to TextIOWrapper in text mode, how to handle line endings.
    autoopen: bool
        If True, calls open() immediately. Mostly used by pickle
    pos: int
        If given and autoopen is True, seek to this location immediately
    rbNc                 C   s:   || _ || _|| _t||| _|| _|| _|| _g | _d S N)	fspathmodeget_compressioncompressionencodingerrorsnewlinefobjects)selfr   r   r   r   r   r   r    r!   ;D:\Projects\ConvertPro\env\Lib\site-packages\fsspec/core.py__init__?   s   

zOpenFile.__init__c                 C   s$   t | j| j| j| j| j| j| jffS r   )r   r   r   r   r   r   r   r   r    r!   r!   r"   
__reduce__R   s   zOpenFile.__reduce__c                 C   s   d | jS )Nz<OpenFile '{}'>)formatr   r$   r!   r!   r"   __repr__`      zOpenFile.__repr__c                 C   s   | j ddddd }| jj| j|d}|g| _| jd ur2t| j }|||d d}| j| d| j vrHt	|| j
| j| jd}| j| | jd S )Nt b)r   r   )r   r   r   )r   replacer   openr   r   r   r   appendPickleableTextIOWrapperr   r   r   )r    r   fcompressr!   r!   r"   	__enter__c   s   



zOpenFile.__enter__c                 G   s   |    d S r   )close)r    argsr!   r!   r"   __exit__x   r(   zOpenFile.__exit__c                 C   s   t | j| jS r   )r   r   r   r$   r!   r!   r"   	full_name{   s   zOpenFile.full_namec                 C   s   |   S )a  Materialise this as a real open file without context

        The OpenFile object should be explicitly closed to avoid enclosed file
        instances persisting. You must, therefore, keep a reference to the OpenFile
        during the life of the file-like it generates.
        r3   r$   r!   r!   r"   r.      s   zOpenFile.openc                 C   s>   t | jD ]}d| jvr|js|  |  q| j  dS )z#Close all encapsulated file objectsrN)reversedr   r   closedflushr4   clear)r    r1   r!   r!   r"   r4      s
   
zOpenFile.close)r   NNNN)__name__
__module____qualname____doc__r#   r%   r'   r3   r6   propertyr7   r.   r4   r!   r!   r!   r"   r      s     $

	r   c                       sL   e Zd ZdZddd fdd
Zdd Zd	d
 Z fddZdd Z  Z	S )	OpenFilesa  List of OpenFile instances

    Can be used in a single context, which opens and closes all of the
    contained files. Normal list access to get the elements works as
    normal.

    A special case is made for caching filesystems - the files will
    be down/uploaded together at the start or end of the context, and
    this may happen concurrently, if the target filesystem supports it.
    r   Nr   r   c                   s"   || _ || _g | _t j|  d S r   )r   r   filessuperr#   )r    r   r   r5   	__class__r!   r"   r#      s   zOpenFiles.__init__c                 C   sd   | j d u r	td| j }	 t|dr|| | _| jS t|dr)|j d ur)|j }nnqdd | D S )NzContext has already been usedT	open_manyr   c                 S   s   g | ]}|  qS r!   r8   .0sr!   r!   r"   
<listcomp>       z'OpenFiles.__enter__.<locals>.<listcomp>)r   
ValueErrorhasattrrI   rE   )r    r   r!   r!   r"   r3      s   

	zOpenFiles.__enter__c                    sd   | j } fdd| D  d| jvr0	 t|dr|| j d S t|dr-|j d ur-|j }nd S qd S )Nc                    s   g | ]}|j   qS r!   )r6   rJ   r5   r!   r"   rM          z&OpenFiles.__exit__.<locals>.<listcomp>r9   TrI   r   )r   r   rP   Zcommit_manyrE   )r    r5   r   r!   rQ   r"   r6      s   

zOpenFiles.__exit__c                    s,   t  |}t|trt|| j| jdS |S )NrD   )rF   __getitem__
isinstanceslicerC   r   r   )r    itemoutrG   r!   r"   rS      s   
zOpenFiles.__getitem__c                 C   s   dt |  S )Nz<List of %s OpenFile instances>)lenr$   r!   r!   r"   r'      r(   zOpenFiles.__repr__)
r>   r?   r@   rA   r#   r3   r6   rS   r'   __classcell__r!   r!   rG   r"   rC      s    rC   r   utf8Tc              	      sr   t | |||||
d\}}dvr&|	r&fdd|D }fdd|D  t fdd|D dS )	av
  Given a path or paths, return a list of ``OpenFile`` objects.

    For writing, a str path must contain the "*" character, which will be filled
    in by increasing numbers, e.g., "part*" ->  "part1", "part2" if num=2.

    For either reading or writing, can instead provide explicit list of paths.

    Parameters
    ----------
    urlpath: string or list
        Absolute or relative filepath(s). Prefix with a protocol like ``s3://``
        to read from alternative filesystems. To read from multiple files you
        can pass a globstring or a list of paths, with the caveat that they
        must all have the same protocol.
    mode: 'rb', 'wt', etc.
    compression: string or None
        If given, open file using compression codec. Can either be a compression
        name (a key in ``fsspec.compression.compr``) or "infer" to guess the
        compression from the filename suffix.
    encoding: str
        For text mode only
    errors: None or str
        Passed to TextIOWrapper in text mode
    name_function: function or None
        if opening a set of files for writing, those files do not yet exist,
        so we need to generate their names by formatting the urlpath for
        each sequence number
    num: int [1]
        if writing mode, number of files we expect to create (passed to
        name+function)
    protocol: str or None
        If given, overrides the protocol found in the URL.
    newline: bytes or None
        Used for line terminator in text mode. If None, uses system default;
        if blank, uses no translation.
    auto_mkdir: bool (True)
        If in write mode, this will ensure the target directory exists before
        writing, by calling ``fs.mkdirs(exist_ok=True)``.
    expand: bool
    **kwargs: dict
        Extra options that make sense to a particular storage connection, e.g.
        host, port, username, password, etc.

    Examples
    --------
    >>> files = open_files('2015-*-*.csv')  # doctest: +SKIP
    >>> files = open_files(
    ...     's3://bucket/2015-*-*.csv.gz', compression='gzip'
    ... )  # doctest: +SKIP

    Returns
    -------
    An ``OpenFiles`` instance, which is a list of ``OpenFile`` objects that can
    be used as a single context

    Notes
    -----
    For a full list of the available protocols and the implementations that
    they map across to see the latest online documentation:

    - For implementations built into ``fsspec`` see
      https://filesystem-spec.readthedocs.io/en/latest/api.html#built-in-implementations
    - For implementations in separate packages see
      https://filesystem-spec.readthedocs.io/en/latest/api.html#other-known-implementations
    )numname_functionstorage_optionsprotocolexpandr9   c                    s   h | ]}  |qS r!   )_parentrK   r   r   r!   r"   	<setcomp>$  rR   zopen_files.<locals>.<setcomp>c                    s   g | ]	} j |d dqS )T)exist_ok)makedirs)rK   parentrb   r!   r"   rM   %      zopen_files.<locals>.<listcomp>c                    s"   g | ]}t | d qS ))r   r   r   r   r   )r   ra   r   r   r   r   r   r   r!   r"   rM   '  s    
rD   )get_fs_token_pathsrC   )urlpathr   r   r   r   r\   r[   r^   r   
auto_mkdirr_   kwargsZfs_tokenpathsparentsr!   rh   r"   
open_files   s&   O	
ro   c                    s   t d d| v r fdd| dD n| g}g }d }| }t|D ]L}|dd p3t|d p3d}t|}||}||i }	||d u rN|		| t
d
i ||	}
||}|dv rfd	|
vrf|}||||
f |}q$tt|}|S )Nz.*[^a-z]+.*z::c                    s*   g | ]}d |v s  |r|n|d  qS )://)matchrK   pxr!   r"   rM   ;  s   * z_un_chain.<locals>.<listcomp>r^   r   file>   	filecacheZ
blockcacheZsimplecachetarget_protocolr!   )recompilesplitcopyr:   popsplit_protocolr   Z_get_kwargs_from_urlsupdatedict_strip_protocolr/   list)r   rl   bitsrW   Zprevious_bitbitr^   clsextra_kwargskwskwr!   rt   r"   	_un_chain8  s0   



r   c                    s   h d  fdd|  D }t| |}i }tt|D ].\}}|\}}}|t|d kr7td
i ||}qtd
i |||d< ||d< ||d< q|d \}	}}
t|fi |}||	fS )a  
    Turn fully-qualified and potentially chained URL into filesystem instance

    Parameters
    ----------
    url : str
        The fsspec-compatible URL
    **kwargs: dict
        Extra options that make sense to a particular storage connection, e.g.
        host, port, username, password, etc.

    Returns
    -------
    filesystem : FileSystem
        The new filesystem discovered from ``url`` and created with
        ``**kwargs``.
    urlpath : str
        The file-systems-specific URL for ``url``.
    >	   r_   r   r   r   r\   r   r[   rk   r   c                    s   i | ]\}}| vr||qS r!   r!   )rK   kvZknown_kwargsr!   r"   
<dictcomp>x  s    zurl_to_fs.<locals>.<dictcomp>r   target_optionsrx   for   Nr!   )itemsr   	enumerater:   rX   r   r   )urlrl   chaininkwargsichurlsr^   r   rj   _r   r!   r   r"   	url_to_fsW  s   


r   c           	      K   s6   t d| g||||||dd|}|st| |d S )a  Given a path or paths, return one ``OpenFile`` object.

    Parameters
    ----------
    urlpath: string or list
        Absolute or relative filepath. Prefix with a protocol like ``s3://``
        to read from alternative filesystems. Should not include glob
        character(s).
    mode: 'rb', 'wt', etc.
    compression: string or None
        If given, open file using compression codec. Can either be a compression
        name (a key in ``fsspec.compression.compr``) or "infer" to guess the
        compression from the filename suffix.
    encoding: str
        For text mode only
    errors: None or str
        Passed to TextIOWrapper in text mode
    protocol: str or None
        If given, overrides the protocol found in the URL.
    newline: bytes or None
        Used for line terminator in text mode. If None, uses system default;
        if blank, uses no translation.
    **kwargs: dict
        Extra options that make sense to a particular storage connection, e.g.
        host, port, username, password, etc.

    Examples
    --------
    >>> openfile = open('2015-01-01.csv')  # doctest: +SKIP
    >>> openfile = open(
    ...     's3://bucket/2015-01-01.csv.gz', compression='gzip'
    ... )  # doctest: +SKIP
    >>> with openfile as f:
    ...     df = pd.read_csv(f)  # doctest: +SKIP
    ...

    Returns
    -------
    ``OpenFile`` object.

    Notes
    -----
    For a full list of the available protocols and the implementations that
    they map across to see the latest online documentation:

    - For implementations built into ``fsspec`` see
      https://filesystem-spec.readthedocs.io/en/latest/api.html#built-in-implementations
    - For implementations in separate packages see
      https://filesystem-spec.readthedocs.io/en/latest/api.html#other-known-implementations
    F)rj   r   r   r   r   r^   r   r_   r   Nr!   )ro   FileNotFoundError)	rj   r   r   r   r   r^   r   rl   rW   r!   r!   r"   r.     s   <	r.   c                 K   s   d|vrt dt| fd|i|}t|d jddst d|}dd	 |D }W d
   n1 s3w   Y  t| trEt| sE|d S |S )aK  Open file(s) which can be resolved to local

    For files which either are local, or get downloaded upon open
    (e.g., by file caching)

    Parameters
    ----------
    url: str or list(str)
    mode: str
        Must be read mode
    storage_options:
        passed on to FS for or used by open_files (e.g., compression)
    r9   z(Can only ensure local files when readingr   r   
local_fileFzOopen_local can only be used on a filesystem which has attribute local_file=Truec                 S   s   g | ]}|j qS r!   )namerK   r1   r!   r!   r"   rM     s    zopen_local.<locals>.<listcomp>N)rO   ro   getattrr   rT   strr   )r   r   r]   ZofrE   rm   r!   r!   r"   
open_local  s   r   c                 C   s0   |dkrt | }|d ur|tvrtd| |S )NZinferz!Compression type %s not supported)r   r   rO   )rj   r   r!   r!   r"   r     s
   r   c                 C   s<   t | } d| v r| dd\}}t|dkr||fS d| fS )zReturn protocol, path pairrp   r   N)r   r{   rX   )rj   r^   r   r!   r!   r"   r~     s   r~   c                 C   s   t | \}}t|}|| S )zCReturn only path part of full URL, according to appropriate backend)r~   r   r   )rj   r^   r   r   r!   r!   r"   strip_protocol  s   
r   c                 C   s   g }t | } d|v rFtdd | D dkrtdt|t| }| D ]}d|v r2|t||| q"|| q"t||krD|d| }|S | D ]}t|rW||	| qH|| qH|S )a(  Expand paths if they have a ``*`` in them (write mode) or any of ``*?[]``
    in them (read mode).

    :param paths: list of paths
    mode: str
        Mode in which to open files.
    num: int
        If opening in writing mode, number of files we expect to create.
    fs: filesystem object
    name_function: callable
        If opening in writing mode, this callable is used to generate path
        names. Names are generated for each partition by
        ``urlpath.replace('*', name_function(partition_index))``.
    :return: list of paths
    wc                 S   s   g | ]}d |v rdqS )*r   r!   rr   r!   r!   r"   rM      s    z*expand_paths_if_needed.<locals>.<listcomp>r   z;When writing data, only one filename mask can be specified.r   N)
r   sumrO   maxrX   extend_expand_pathsr/   r   glob)rm   r   r[   r   r\   Zexpanded_pathsZ	curr_pathr!   r!   r"   expand_paths_if_needed  s(   
r   c                    s  t | tttfr| stdtt| d }nt| }pi |r%|d< t|p*i }i }	tt|D ].\}
}|\}}}|
t	|d krOt
di ||	}	q4t
di ||	|	d< ||	d< ||	d< q4|d \}}}t|fi |	 t | tttfrfdd	| D }t	td
d |D dkrtd| dd	 |D }n |}t |tttfrt||| |}n0d|v r|rt|||}n#d|v r|rt|||}nd|v r fdd	t |D }n|g}  j|fS )a  Filesystem, deterministic token, and paths from a urlpath and options.

    Parameters
    ----------
    urlpath: string or iterable
        Absolute or relative filepath, URL (may include protocols like
        ``s3://``), or globstring pointing to data.
    mode: str, optional
        Mode in which to open files.
    num: int, optional
        If opening in writing mode, number of files we expect to create.
    name_function: callable, optional
        If opening in writing mode, this callable is used to generate path
        names. Names are generated for each partition by
        ``urlpath.replace('*', name_function(partition_index))``.
    storage_options: dict, optional
        Additional keywords to pass to the filesystem class.
    protocol: str or None
        To override the protocol specifier in the URL
    expand: bool
        Expand string paths for writing, assuming the path is a directory
    zempty urlpath sequencer   r^   r   r   rx   r   c                    s"   g | ]}t t| pi d  qS r   )r   r   )rK   u)r]   r!   r"   rM   q  s    z&get_fs_token_paths.<locals>.<listcomp>c                 s   s    | ]}|d  V  qdS )r   Nr!   rK   Zpcr!   r!   r"   	<genexpr>t  s    z%get_fs_token_paths.<locals>.<genexpr>z$Protocol mismatch getting fs from %sc                 S   s   g | ]}|d  qS r   r!   r   r!   r!   r"   rM   v  rN   r   ru   r   c                    s   g | ]	}  |s|qS r!   )isdirr   rb   r!   r"   rM     rg   Nr!   )rT   r   tuplesetrO   r   r   r   r:   rX   r   r   r   r   r   sortedr   Z	_fs_token)rj   r   r[   r\   r]   r^   r_   Zurlpath0r   r   r   r   r   Znested_protocolr   rm   r   Zpchainsr!   )r   r]   r"   ri   ;  sL   




ri   c                    s   t tr>ddkrtddvrtjd d u r%t|d   fddt|D }|t	|kr<t
d |S t ttfrSt|ksMJ t}|S td)	Nr   r   z.Output path spec must contain exactly one '*'.z*.partc                    s   g | ]
} d  |qS )r   )r-   )rK   r   r\   r   r!   r"   rM     s    z!_expand_paths.<locals>.<listcomp>zqIn order to preserve order between partitions paths created with ``name_function`` should sort to partition orderzPath should be either
1. A list of paths: ['foo.json', 'bar.json', ...]
2. A directory: 'foo/
3. A path with a '*' in it: 'foo.*.json')rT   r   countrO   osr   joinr   ranger   loggerwarningr   r   rX   )r   r\   r[   rm   r!   r   r"   r     s(   
r   c                       s4   e Zd ZdZ					d fdd	Zdd Z  ZS )	r0   zTextIOWrapper cannot be pickled. This solves it.

    Requires that ``buffer`` be pickleable, which all instances of
    AbstractBufferedFile are.
    NFc                    s$   ||||||f| _ t j| j   d S r   )r5   rF   r#   )r    bufferr   r   r   line_bufferingwrite_throughrG   r!   r"   r#     s   	z PickleableTextIOWrapper.__init__c                 C   s
   t | jfS r   )r0   r5   r$   r!   r!   r"   r%     s   
z"PickleableTextIOWrapper.__reduce__)NNNFF)r>   r?   r@   rA   r#   r%   rY   r!   r!   rG   r"   r0     s    	r0   )
r   NrZ   NNr   NNTT)r   NrZ   NNN)r   )r   r   NNNT)-
__future__r   r   r   iologgingr   ry   r   r   Zcachingr   r   r	   r
   r   r   r   r   registryr   r   utilsr   r   r   r   	getLoggerr   r   r   rC   ro   r   r   r.   r   r   r~   r   r   ri   r   TextIOWrapperr0   r!   r!   r!   r"   <module>   s^     
s<
m4

L1
M