o
    d.0                     @  sF  d dl mZ d dlZ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
mZmZ d dlZd dlmZmZ d dlmZ d dlmZ d dlZd dlmZ d d	lmZ d d
lmZ e
rbd dlmZmZ dZdZ dd Z!dd Z"e"dddde efd1ddZ#d2d3ddZ$	d2d4d#d$Z%d2d5d&d'Z&d2d5d(d)Z'd6d7d,d-Z(d2d8d/d0Z)dS )9    )annotationsNwraps)TYPE_CHECKINGAnyCallable)FilePathReadPickleBuffer)get_lzma_file)import_optional_dependency)rands)ensure_clean)urlopen)	DataFrameSeries)z	timed outzServer Hangupz#HTTP Error 503: Service Unavailablez502: Proxy ErrorzHTTP Error 502: internal errorzHTTP Error 502zHTTP Error 503zHTTP Error 403zHTTP Error 400z$Temporary failure in name resolutionzName or service not knownzConnection refusedzcertificate verify)e   o   n   h   6   <   c                  C  s(   dd l } dd l}t| jjt|jjtj	fS )Nr   )
http.clienturllib.errorOSErrorclientHTTPExceptionTimeoutErrorerrorURLErrorsockettimeout)httpurllib r#   G/app/.heroku/python/lib/python3.10/site-packages/pandas/_testing/_io.py_get_default_network_errorsI   s   r%   c                   s   t   fdd}|S )aB  
    allows a decorator to take optional positional and keyword arguments.
    Assumes that taking a single, callable, positional argument means that
    it is decorating a function, i.e. something like this::

        @my_decorator
        def function(): pass

    Calls decorator with decorator(f, *args, **kwargs)
    c                    sJ    fdd} ot  dkot d }|r# d }d ||S |S )Nc                   s   | g R i S Nr#   )f)args	decoratorkwargsr#   r$   decf   s   z+optional_args.<locals>.wrapper.<locals>.dec   r   r#   )lencallable)r(   r*   r+   Zis_decoratingr'   r)   )r(   r*   r$   wrapperd   s   zoptional_args.<locals>.wrapperr   )r)   r0   r#   r/   r$   optional_argsX   s   r1   zhttps://www.google.comFurlstrraise_on_errorboolcheck_before_testc              	     sB   ddl du rt d_t fdd}|S )a  
    Label a test as requiring network connection and, if an error is
    encountered, only raise if it does not find a network connection.

    In comparison to ``network``, this assumes an added contract to your test:
    you must assert that, under normal conditions, your test will ONLY fail if
    it does not have network connectivity.

    You can call this in 3 ways: as a standard decorator, with keyword
    arguments, or with a positional argument that is the url to check.

    Parameters
    ----------
    t : callable
        The test requiring network connectivity.
    url : path
        The url to test via ``pandas.io.common.urlopen`` to check
        for connectivity. Defaults to 'https://www.google.com'.
    raise_on_error : bool
        If True, never catches errors.
    check_before_test : bool
        If True, checks connectivity before running the test case.
    error_classes : tuple or Exception
        error classes to ignore. If not in ``error_classes``, raises the error.
        defaults to OSError. Be careful about changing the error classes here.
    skip_errnos : iterable of int
        Any exception that has .errno or .reason.erno set to one
        of these values will be skipped with an appropriate
        message.
    _skip_on_messages: iterable of string
        any exception e for which one of the strings is
        a substring of str(e) will be skipped with an appropriate
        message. Intended to suppress errors where an errno isn't available.

    Notes
    -----
    * ``raise_on_error`` supersedes ``check_before_test``

    Returns
    -------
    t : callable
        The decorated test ``t``, with checks for connectivity errors.

    Example
    -------

    Tests decorated with @network will fail if it's possible to make a network
    connection to another URL (defaults to google.com)::

      >>> from pandas import _testing as tm
      >>> @tm.network
      ... def test_network():
      ...     with pd.io.common.urlopen("rabbit://bonanza.com"):
      ...         pass
      >>> test_network()  # doctest: +SKIP
      Traceback
         ...
      URLError: <urlopen error unknown url type: rabbit>

      You can specify alternative URLs::

        >>> @tm.network("https://www.yahoo.com")
        ... def test_something_with_yahoo():
        ...    raise OSError("Failure Message")
        >>> test_something_with_yahoo()  # doctest: +SKIP
        Traceback (most recent call last):
            ...
        OSError: Failure Message

    If you set check_before_test, it will check the url first and not run the
    test on failure::

        >>> @tm.network("failing://url.blaher", check_before_test=True)
        ... def test_something():
        ...     print("I ran!")
        ...     raise ValueError("Failure")
        >>> test_something()  # doctest: +SKIP
        Traceback (most recent call last):
            ...

    Errors not related to networking will always be raised.
    r   NTc               
     s   rst sd  z| i |W S  tys } zNt|dd }|s5t|dr5t|jdd }|v rAd|  t| t fddD rXd|  t|r_r` d|  W Y d }~d S d }~ww )	Nz<May not have network connectivity because cannot connect to errnoreasonz+Skipping test due to known errno and error c                 3  s     | ]}|     v V  qd S r&   )lower).0mZe_strr#   r$   	<genexpr>   s    z+network.<locals>.wrapper.<locals>.<genexpr>z;Skipping test because exception message is known and error z4Skipping test due to lack of connectivity and error )	can_connectskip	Exceptiongetattrhasattrr8   r3   any
isinstance)r(   r*   errr7   _skip_on_messagesr6   error_classespytestr4   skip_errnostr2   r<   r$   r0      s6   znetwork.<locals>.wrapper)rI   r%   networkr   )rK   r2   r4   r6   rH   rJ   rG   r0   r#   rF   r$   rL   u   s   \rL   returnc                 C  sx   |du rt  }z*t| dd}|jdkr	 W d   W dS W d   W dS 1 s*w   Y  W dS  |y;   Y dS w )a@  
    Try to connect to the given url. True if succeeds, False if OSError
    raised

    Parameters
    ----------
    url : basestring
        The URL to try to connect to

    Returns
    -------
    connectable : bool
        Return True if no OSError (unable to connect) or URLError (bad url) was
        raised
    N   )r       FT)r%   r   status)r2   rH   responser#   r#   r$   r>      s   
r>   objr   path"FilePath | ReadPickleBuffer | NoneDataFrame | Seriesc                 C  s^   |}|du rdt d d}t|}t| | t|W  d   S 1 s(w   Y  dS )a  
    Pickle an object and then read it again.

    Parameters
    ----------
    obj : any object
        The object to pickle and then re-read.
    path : str, path object or file-like object, default None
        The path where the pickled object is written and then read.

    Returns
    -------
    pandas object
        The original object that was pickled and then re-read.
    N__
   z	__.pickle)r   r   pdZ	to_pickleZread_pickle)rR   rS   _pathZ	temp_pathr#   r#   r$   round_trip_pickle  s   
$rZ   
str | Nonec                 C  f   ddl }|dj}|du rd}t|}| || |||}W d   |S 1 s,w   Y  |S )a  
    Write an object to file specified by a pathlib.Path and read it back

    Parameters
    ----------
    writer : callable bound to pandas object
        IO writing function (e.g. DataFrame.to_csv )
    reader : callable
        IO reading function (e.g. pd.read_csv )
    path : str, default None
        The path where the object is written and then read.

    Returns
    -------
    pandas object
        The original object that was serialized and then re-read.
    r   NpathlibZ___pathlib___)rI   importorskipPathr   )writerreaderrS   rI   r_   rR   r#   r#   r$   round_trip_pathlib7     

rb   c                 C  r\   )a  
    Write an object to file specified by a py.path LocalPath and read it back.

    Parameters
    ----------
    writer : callable bound to pandas object
        IO writing function (e.g. DataFrame.to_csv )
    reader : callable
        IO reading function (e.g. pd.read_csv )
    path : str, default None
        The path where the object is written and then read.

    Returns
    -------
    pandas object
        The original object that was serialized and then re-read.
    r   Nzpy.pathZ___localpath___)rI   r^   localr   )r`   ra   rS   rI   Z	LocalPathrR   r#   r#   r$   round_trip_localpathT  rc   re   testdestc                 C  s   |f}d}d}| dkrt j}d}||f}d}nI| dkr7tj}d}tj|d}t|}	t||_||	f}d}n)| d	kr?t	j
}n!| d
krGtj}n| dkrQtdj}n| dkrYt }ntd|  |||d}
t|
||  W d   dS 1 syw   Y  dS )a  
    Write data to a compressed file.

    Parameters
    ----------
    compression : {'gzip', 'bz2', 'zip', 'xz', 'zstd'}
        The compression type to use.
    path : str
        The file path to write the data.
    data : str
        The data to write.
    dest : str, default "test"
        The destination file (for ZIP only)

    Raises
    ------
    ValueError : An invalid compression value was passed in.
    wbwritezipwwritestrtar)nameaddfilegzipbz2ZzstdZ	zstandardxzzUnrecognized compression type: )modeN)zipfileZipFiletarfileTarFileTarInfoioBytesIOr-   sizerp   GzipFilerq   BZ2Filer   openr
   
ValueErrorrA   )compressionrS   datarg   r(   rs   methodZcompress_methodfilebytesr'   r#   r#   r$   write_to_compressedq  s8   

"r   Nonec                 C  s<   ddl m}m} | d u r| D ]} ||  qd S ||  d S )Nr   )closeget_fignums)Zmatplotlib.pyplotr   r   )Zfignum_closer   r#   r#   r$   r     s   

r   )r2   r3   r4   r5   r6   r5   r&   )rM   r5   )rR   r   rS   rT   rM   rU   )rS   r[   )rf   )rg   r3   )rM   r   )*
__future__r   rq   	functoolsr   rp   ry   r   rv   typingr   r   r   rt   Zpandas._typingr   r	   Zpandas.compatr
   Zpandas.compat._optionalr   ZpandasrX   Zpandas._testing._randomr   Zpandas._testing.contextsr   Zpandas.io.commonr   r   r   Z_network_error_messagesZ_network_errno_valsr%   r1   rL   r>   rZ   rb   re   r   r   r#   r#   r#   r$   <module>   sL     #8