o
    NZh[W                     @  sf  d dl 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	 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										d2ddZ dd Z!dd Z"						d3ddZ#	d4d5d"d#Z$d$d% Z%d&d' Z&d(d) Z'd*d+ Z(						d6d,d-Z)d.d/ Z*G d0d1 d1ej+Z,dS )7    )annotationsN)	has_magic)Path   )	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    B/var/www/html/lang_env/lib/python3.10/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__S   s   zOpenFile.__reduce__c                 C  s   d| j  dS )Nz<OpenFile 'z'>)r   r#   r    r    r!   __repr__a   s   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__d   s   



zOpenFile.__enter__c                 G  s   |    d S r   )close)r   argsr    r    r!   __exit__y   s   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.
        r0   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flushr1   clear)r   r.   r    r    r!   r1      s
   
zOpenFile.close)r   NNNN)__name__
__module____qualname____doc__r"   r$   r%   r0   r3   propertyr4   r+   r1   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   r2   	__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    r5   .0sr    r    r!   
<listcomp>       z'OpenFiles.__enter__.<locals>.<listcomp>)r   
ValueErrorhasattrrF   rB   )r   r   r    r    r!   r0      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    )r3   rG   r2   r    r!   rJ          z&OpenFiles.__exit__.<locals>.<listcomp>r6   TrF   r   )r   r   rM   Zcommit_manyrB   )r   r2   r   r    rN   r!   r3      s   

zOpenFiles.__exit__c                   s,   t  |}t|trt|| j| jdS |S )NrA   )rC   __getitem__
isinstanceslicer@   r   r   )r   itemoutrD   r    r!   rP      s   
zOpenFiles.__getitem__c                 C  s   dt |  dS )Nz	<List of z OpenFile instances>)lenr#   r    r    r!   r%      s   zOpenFiles.__repr__)
r;   r<   r=   r>   r"   r0   r3   rP   r%   __classcell__r    r    rD   r!   r@      s    r@   r   utf8Tc              	     s   t | |||||
d\}}jdkr|	_n&dvr=|	r=fdd|D }|D ]}z	j|dd W q( ty<   Y q(w 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expandfiler6   c                   s   h | ]}  |qS r    )_parentrH   r   r   r    r!   	<setcomp>'  rO   zopen_files.<locals>.<setcomp>T)exist_okc                   s"   g | ]}t | d qS ))r   r   r   r   r   )r   r_   r   r   r   r   r   r   r    r!   rJ   .  s    
zopen_files.<locals>.<listcomp>rA   )get_fs_token_pathsr[   
auto_mkdirmakedirsPermissionErrorr@   )urlpathr   r   r   r   rY   rX   r[   r   re   r\   kwargsZfs_tokenpathsparentsparentr    rc   r!   
open_files   s4   O
	
rm   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rH   pxr    r!   rJ   B  s   * z_un_chain.<locals>.<listcomp>r[   r   r]   >   Zsimplecache	filecacheZ
blockcachetarget_protocolr    )recompilesplitcopyr7   popsplit_protocolr   Z_get_kwargs_from_urlsupdatedict_strip_protocolr,   list)r   ri   bitsrT   Zprevious_bitbitr[   clsextra_kwargskwskwr    rr   r!   	_un_chain?  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``.
    >   rY   rX   r   r\   r   r   r   r   c                   s   i | ]\}}| vr||qS r    r    )rH   kvZknown_kwargsr    r!   
<dictcomp>~  s    zurl_to_fs.<locals>.<dictcomp>r   target_optionsru   for   Nr    )itemsr   	enumerater7   rU   r}   r   )urlri   chaininkwargsichurlsr[   r   rh   _r   r    r   r!   	url_to_fs^  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)rh   r   r   r   r   r[   r   r\   r   Nr    )rm   FileNotFoundError)	rh   r   r   r   r   r[   r   ri   rT   r    r    r!   r+     s   <	r+   r   #str | list[str] | Path | list[Path]r   strrZ   r}   returnstr | list[str]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rAt| rFt| trJ|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)
    r6   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rH   r.   r    r    r!   rJ     s    zopen_local.<locals>.<listcomp>N)rL   rm   getattrr   rQ   r   r   r   )r   r   rZ   ZofrB   rj   r    r    r!   
open_local  s   r   c                 C  s4   |dkrt | }|d ur|tvrtd| d|S )NZinferzCompression type z not supported)r   r   rL   )rh   r   r    r    r!   r     s
   r   c                 C  sR   t | } d| v r| dd\}}t|dkr||fS | dr%| ddS d| fS )zReturn protocol, path pairrn   r   zdata::N)r   rx   rU   
startswith)rh   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~   )rh   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    rp   r    r    r!   rJ   ,  s    z*expand_paths_if_needed.<locals>.<listcomp>r   z;When writing data, only one filename mask can be specified.r   N)
r   sumrL   maxrU   extend_expand_pathsr,   r   glob)rj   r   rX   r   rY   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	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   ru   r   c                   s"   g | ]}t t| pi d  qS r   )r   r   )rH   u)rZ   r    r!   rJ   }  s    z&get_fs_token_paths.<locals>.<listcomp>c                 S  s   h | ]}|d  qS )r   r    rH   Zpcr    r    r!   ra     rK   z%get_fs_token_paths.<locals>.<setcomp>z$Protocol mismatch getting fs from %sc                 S  s   g | ]}|d  qS r   r    r   r    r    r!   rJ     rK   r   rs   r   c                   s   g | ]	}  |s|qS r    )isdirr   r`   r    r!   rJ     s    Nr    )rQ   r   tuplesetrL   r   r   r   r7   rU   r}   r   r~   r   r   sortedr   Z	_fs_token)rh   r   rX   rY   rZ   r[   r\   Zurlpath0r   r   r   r   r   Znested_protocolr   rj   r   Zpchainsr    )r   rZ   r!   rd   G  sL   




rd   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*   )rH   r   rY   r   r    r!   rJ     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')rQ   r   countrL   osr   joinr   ranger   loggerwarningr   r   rU   )r   rY   rX   rj   r    r   r!   r     s(   
r   c                      s4   e Zd ZdZ					d fdd	Zdd Z  ZS )	r-   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   )r2   rC   r"   )r   bufferr   r   r   line_bufferingwrite_throughrD   r    r!   r"     s   	z PickleableTextIOWrapper.__init__c                 C  s
   t | jfS r   )r-   r2   r#   r    r    r!   r$     s   
z"PickleableTextIOWrapper.__reduce__)NNNFF)r;   r<   r=   r>   r"   r$   rV   r    r    rD   r!   r-     s    	r-   )
r   NrW   NNr   NNTT)r   NrW   NNN)r   )r   r   r   r   rZ   r}   r   r   )r   r   NNNT)-
__future__r   iologgingr   rv   r   r   pathlibr   Zcachingr   r   r   r	   r
   r   r   r   registryr   r   utilsr   r   r   r   	getLoggerr   r   r   r@   rm   r   r   r+   r   r   r{   r   r   rd   r   TextIOWrapperr-   r    r    r    r!   <module>   sb     
s<
s3
N!1
M