o
    d&.                     @   s  d Z ddl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ZddlmZ ddlm  mZ ddlZddlmZ ejje ddZG dd dejjZG d	d
 d
eZG dd deZG dd deZG dd deZ G dd deZ!G dd deZ"G dd deZ#G dd deZ$G dd dejjZ%dd Z&dd Z'ej(dd  Z)ejj*d!eej+dfeej,dfe!ej-d"fej.e"ej-d#ej/gd$e#ej0dfe$ej1dfeej+dfe ej,dfgd gd%d&d' Z2ejj*d!eej+dfeej,dfe!ej-d"fej.e"ej-d#ej/gd$e#ej0dfe$ej1dfeej+dfe ej,dfgd gd%d(d) Z3ejj*d*e%ej+fgd gd%d+d, Z4ej*d-d"d#gd.d/ Z5dS )0z9
Tests for the pandas custom headers in http(s) requests
    N)BytesIO)is_ci_environmentzThis test can hang in our CI min_versions build and leads to '##[error]The runner has received a shutdown signal...' in GHA. GH 45651)reasonc                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	BaseUserAgentResponderz
    Base class for setting up a server that can be set up to respond
    with a particular file format with accompanying content-type headers.
    The interfaces on the different io methods are different enough
    that this seemed logical to do.
    c                 C   s,   |  d | jd | _td| jgi}|S )z<
        shared logic at the start of a GET request
           
User-Agentheader)send_responseheadersZrequested_from_user_agentpd	DataFrame)selfresponse_df r   S/app/.heroku/python/lib/python3.10/site-packages/pandas/tests/io/test_user_agent.pystart_processing_headers$   s   
z/BaseUserAgentResponder.start_processing_headersc              	   C   sl   t  )}tj|dd}|| W d   n1 sw   Y  | }W d   |S 1 s/w   Y  |S )zQ
        some web servers will send back gzipped files to save bandwidth
        w)fileobjmodeN)r   gzipGzipFilewritegetvalue)r   response_bytesbioZzipperr   r   r   
gzip_bytes1   s   

z!BaseUserAgentResponder.gzip_bytesc                 C   s   | j | dS )z:
        shared logic at the end of a GET request
        N)wfiler   )r   r   r   r   r   write_back_bytes;   s   z'BaseUserAgentResponder.write_back_bytesN)__name__
__module____qualname____doc__r   r   r   r   r   r   r   r      s
    
r   c                   @      e Zd Zdd ZdS )CSVUserAgentResponderc                 C   s<   |   }| dd |   |jddd}| | d S )NContent-Typetext/csvFindexutf-8)r   send_headerend_headersto_csvencoder   r   r   r   r   r   r   do_GETC   s
   zCSVUserAgentResponder.do_GETNr   r   r    r.   r   r   r   r   r#   B       r#   c                   @   r"   )GzippedCSVUserAgentResponderc                 C   sR   |   }| dd | dd |   |jddd}| |}| | d S )Nr$   r%   Content-Encodingr   Fr&   r(   )r   r)   r*   r+   r,   r   r   r-   r   r   r   r.   N   s   
z#GzippedCSVUserAgentResponder.do_GETNr/   r   r   r   r   r1   M   r0   r1   c                   @   r"   )JSONUserAgentResponderc                 C   s8   |   }| dd |   | d}| | d S )Nr$   application/jsonr(   )r   r)   r*   to_jsonr,   r   r-   r   r   r   r.   [   
   zJSONUserAgentResponder.do_GETNr/   r   r   r   r   r3   Z   r0   r3   c                   @   r"   )GzippedJSONUserAgentResponderc                 C   sN   |   }| dd | dd |   | d}| |}| | d S )Nr$   r4   r2   r   r(   )r   r)   r*   r5   r,   r   r   r-   r   r   r   r.   f   s   
z$GzippedJSONUserAgentResponder.do_GETNr/   r   r   r   r   r7   e   r0   r7   c                   @   r"   ) ParquetPyArrowUserAgentResponderc                 C   s8   |   }| dd |   |jddd}| | d S )Nr$   application/octet-streamFpyarrow)r'   engine)r   r)   r*   
to_parquetr   r-   r   r   r   r.   s   r6   z'ParquetPyArrowUserAgentResponder.do_GETNr/   r   r   r   r   r8   r   r0   r8   c                   @   r"   )$ParquetFastParquetUserAgentResponderc                 C   sx   |   }| dd |   dd l}|jdddd d |dd}| }W d    n1 s0w   Y  | | d S )	Nr$   r9   r   z'memory://fastparquet_user_agent.parquetFfastparquet)r'   r;   compressionrb)r   r)   r*   fsspecr<   openreadr   )r   r   rA   fr   r   r   r   r.   ~   s   
z+ParquetFastParquetUserAgentResponder.do_GETNr/   r   r   r   r   r=   }   r0   r=   c                   @   r"   )PickleUserAgentResponderc                 C   sB   |   }| dd |   t }|| | }| | d S )Nr$   r9   )r   r)   r*   r   Z	to_pickler   r   r   r   r   r   r   r   r   r.      s   
zPickleUserAgentResponder.do_GETNr/   r   r   r   r   rE      r0   rE   c                   @   r"   )StataUserAgentResponderc                 C   sF   |   }| dd |   t }|j|dd | }| | d S )Nr$   r9   F)Zwrite_index)r   r)   r*   r   Zto_statar   r   rF   r   r   r   r.      s   zStataUserAgentResponder.do_GETNr/   r   r   r   r   rG      r0   rG   c                   @   s   e Zd ZdZdd ZdS )AllHeaderCSVResponderz?
    Send all request headers back for checking round trip
    c                 C   sP   t | j }| d | dd |   |jddd}| j	
| d S )Nr   r$   r%   Fr&   r(   )r   r   r
   itemsr	   r)   r*   r+   r,   r   r   r-   r   r   r   r.      s   
zAllHeaderCSVResponder.do_GETN)r   r   r    r!   r.   r   r   r   r   rH      s    rH   c                    s    fdd}|S )Nc                     s6   	 z | i |W S  t jjy   td Y nw q)NT皙?)urlliberrorURLErrortimesleep)argskwargsfuncr   r   inner   s   zwait_until_ready.<locals>.innerr   )rS   rP   rQ   rT   r   rR   r   wait_until_ready   s   rU   c                 C   sF   t jd|f| }|  W d    n1 sw   Y  |  d S )N	localhost)httpserverZ
HTTPServerhandle_requestserver_close)	responderportrX   r   r   r   process_server   s   
r]   c                 c   s    t   }|d | d }W d   n1 sw   Y  tjt| j|fd}|  |V  |d |	  d}d}|
 rX||krK|  n|d7 }td |
 sB|  dS )	z
    Fixture that starts a local http server in a separate process on localhost
    and returns the port.

    Running in a separate process instead of a thread to allow termination/killing
    of http server upon cleanup.
    )rV   r      N)targetrP   
      r   rJ   )socketbindgetsocknamemultiprocessingProcessr]   paramstartjoin	terminateis_alivekillrN   rO   close)requestsockr\   Zserver_processZ	kill_timeZ	wait_timer   r   r   r[      s,   





r[   z&responder, read_method, parquet_enginer:   r>   )Zmarks)Zindirectc                 C   sd   |d urt | |dkrt d t|}|d u r"|d|  }n	|d|  |d}|jr0J d S )Nr>   rA   http://localhost:)r;   )pytestimportorskiprU   empty)r[   read_methodparquet_enginedf_httpr   r   r   test_server_and_default_headers   s   

rw   c                 C   s   |d urt | |dkrt d d}td|gi}t|}|d u r0|d|  d|id}n|d|  d|i|d}t|| d S )	Nr>   rA   Super Cool Oner   rp   r   storage_optionsrz   r;   )rq   rr   r   r   rU   tmassert_frame_equal)r[   rt   ru   custom_user_agentdf_truerv   r   r   r   test_server_and_custom_headers  s$   

r   zresponder, read_methodc                    s   d}d}||d t |}|d|   d}||d    }|dg }|ddg }t  }t| fdd	|D d
}|dg}| jdgdd}t	
|| d S )Nrx   zSuper Secret Oner   ZAuthrp   ry   01c                    s   g | ]} | qS r   r   ).0kry   r   r   
<listcomp>^  s    z6test_server_and_all_custom_headers.<locals>.<listcomp>)r   r   r'   r^   )Zaxis)rU   isinkeysZsort_valuesZreset_indexlistr   r   Zdropr|   r}   )r[   rt   r~   Zcustom_auth_tokenrv   r   r   r   ry   r   "test_server_and_all_custom_headersE  s$   r   r;   c                 C   sl   ddd}t |  tddgi}d}t jt|d |jd|| d	 W d    d S 1 s/w   Y  d S )
NZcustomZother_customr   Zcolumn_nameZcolumn_valuezxstorage_options passed with file object or non-fsspec file path|storage_options passed with buffer, or non-supported URL)matchz/tmp/junk.parquetr{   )rq   rr   r   r   Zraises
ValueErrorr<   )r;   r
   Ztrue_dfmsgr   r   r   ,test_to_parquet_to_disk_with_storage_optionse  s   	
"r   )6r!   r   Zhttp.serverrW   ior   re   rb   rN   urllib.errorrK   rq   Zpandas.compatr   Zpandas.util._test_decoratorsutilZ_test_decoratorstdZpandasr   Zpandas._testingZ_testingr|   markZskipifZ
pytestmarkrX   ZBaseHTTPRequestHandlerr   r#   r1   r3   r7   r8   r=   rE   rG   rH   rU   r]   Zfixturer[   ZparametrizeZread_csv	read_jsonZread_parquetrg   Z&skip_array_manager_not_yet_implementedZread_pickleZ
read_statarw   r   r   r   r   r   r   r   <module>   s    &




	







	




