o
    h3                     @   sd  d 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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ZddlZddlZdd Zejdd Zdd Zd	d
 Zdd Z		d1ddZdd Zdd Zejdd Zejdd Zejdd Zdd ZG dd  d ZG d!d" d"ej j!Z"ejd#d$d%d&Z#d'd( Z$d)d* Z%d+d, Z&d-d. Z'd/d0 Z(dS )2z
Utility functions for testing
    Nc                   C   s
   t dS )zLRandomly choose either 1 or -1.

    Returns
    -------
    sign : int
    )   randomchoice r   r   F/var/www/vscode/kcb/lib/python3.10/site-packages/pyarrow/tests/util.pyrandsign*   s   
r	   c              	   c   s8    t  }t |  zdV  W t | dS t | w )a  Set the random seed inside of a context manager.

    Parameters
    ----------
    seed : int
        The seed to set

    Notes
    -----
    This function is useful when you want to set a random seed but not affect
    the random state of other functions using the random module.
    N)r   getstateseedsetstate)r   original_stater   r   r   random_seed4   s   
r   c              	   C   s   d|   krdksJ d J d|dk rt dd| |  d }t| |}|s0t|S d| d }td|}td|t||dS )	a  Generate a random decimal value with specified precision and scale.

    Parameters
    ----------
    precision : int
        The maximum number of digits to generate. Must be an integer between 1
        and 38 inclusive.
    scale : int
        The maximum number of digits following the decimal point.  Must be an
        integer greater than or equal to 0.

    Returns
    -------
    decimal_value : decimal.Decimal
        A random decimal.Decimal object with the specified precision and scale.
    r   &   z,precision must be between 1 and 38 inclusiver   zHranddecimal does not yet support generating decimals with negative scale
   z{}.{}0)
ValueErrorr   randintdecimalDecimalformatstrrjust)	precisionscalemax_whole_valuewholemax_fractional_value
fractionalr   r   r   randdecimalJ   s   $
r   c                 C   s   t dd t| D S )Nc                 S   s   g | ]}t d dqS )A   z   )r   r   .0ir   r   r   
<listcomp>p   s    z random_ascii.<locals>.<listcomp>)bytesrange)lengthr   r   r   random_asciio   s   r)   c                    s,   t tjtj  d fddt| D S )z%
    Generate one random string.
     c                 3   s    | ]}t  V  qd S Nr   r"   RANDS_CHARSr   r   	<genexpr>x   s    zrands.<locals>.<genexpr>)liststringascii_lettersdigitsjoinr'   )ncharsr   r,   r   randss   s   r5   rss   r   r   c                    s`   ddl }| fdd    fdd}t|D ]|   | dkr-|  qdS )a  
    Execute the function and try to detect a clear memory leak either internal
    to Arrow or caused by a reference counting problem in the Python binding
    implementation. Raises exception if a leak detected

    Parameters
    ----------
    f : callable
        Function to invoke on each iteration
    metric : {'rss', 'vms', 'shared'}, default 'rss'
        Attribute of psutil.Process.memory_info to use for determining current
        memory use
    threshold : int, default 128K
        Threshold in number of bytes to consider a leak
    iterations : int, default 10
        Total number of invocations of f
    check_interval : int, default 1
        Number of invocations of f in between each memory use check
    r   Nc                      s   t   t  S r+   )gccollectgetattrmemory_infor   )metricprocr   r   _get_use   s   z#memory_leak_check.<locals>._get_usec                     s*     } |  krt d|  d S )NzDMemory leak detected. Departure from baseline {} after {} iterations)	Exceptionr   )current_use)r>   baseline_user$   	thresholdr   r   _leak_check   s   z&memory_leak_check.<locals>._leak_check)psutilProcessr'   )fr<   rB   
iterationscheck_intervalrD   rC   r   )r>   rA   r$   r<   r=   rB   r   memory_leak_check{   s   rI   c                  C   sZ   t j } | dd}t jt jt jtj}|r%t j	
||f}n|}|| d< | S )N
PYTHONPATHr*   )osenvironcopygetpathabspathdirnamepa__file__pathsepr3   )envexisting_pythonpathmodule_pathnew_pythonpathr   r   r    get_modified_env_with_pythonpath   s   
rY   c                 G   sN   t  }tjtjt}tj|| }tj|g}|	| t
j||d d S )N)rU   )rY   rK   rO   rQ   realpathrS   r3   sys
executableextend
subprocess
check_call)script_nameargssubprocess_envdir_pathpython_filecmdr   r   r   invoke_script   s   

rf   c              	   c   sb    t j| }|t j| < zdV  W |du rt j| = dS |t j| < dS |du r+t j| = w |t j| < w )zA
    Temporarily set environment variable *name* to *value*.
    N)rK   rL   rN   )namevalue
orig_valuer   r   r   changed_environ   s   
rj   c              	   c   s<    t  }t t|  zd V  W t | d S t | w r+   )rK   getcwdchdirr   )rO   curdirr   r   r   
change_cwd   s   rn   c                   c   s*    t   z
d V  W t   d S t   w r+   )r8   disableenabler   r   r   r   disabled_gc   s
   rq   c                 C   s&   t jdkrd| }|S d| }|S )Nntz
file:///{}z	file://{})rK   rg   r   )rO   urir   r   r   _filesystem_uri   s
   


rt   c                   @   s   e Zd Zdd Zdd ZdS )FSProtocolClassc                 C   
   || _ d S r+   )_pathselfrO   r   r   r   __init__      
zFSProtocolClass.__init__c                 C   s
   t | jS r+   )r   rw   ry   r   r   r   
__fspath__   r{   zFSProtocolClass.__fspath__N)__name__
__module____qualname__rz   r}   r   r   r   r   ru      s    ru   c                   @   s   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&S )'ProxyHandlerz
    A dataset handler that proxies to an underlying filesystem.  Useful
    to partially wrap an existing filesystem with partial changes.
    c                 C   rv   r+   )_fs)ry   fsr   r   r   rz      r{   zProxyHandler.__init__c                 C   s   t |tr| j|jkS tS r+   
isinstancer   r   NotImplementedry   otherr   r   r   __eq__      
zProxyHandler.__eq__c                 C   s   t |tr| j|jkS tS r+   r   r   r   r   r   __ne__  r   zProxyHandler.__ne__c                 C   s   d| j j S )Nzproxy::)r   	type_namer|   r   r   r   get_type_name	     zProxyHandler.get_type_namec                 C      | j |S r+   )r   normalize_pathrx   r   r   r   r     r   zProxyHandler.normalize_pathc                 C   r   r+   r   get_file_info)ry   pathsr   r   r   r     r   zProxyHandler.get_file_infoc                 C   r   r+   r   )ry   selectorr   r   r   get_file_info_selector  r   z#ProxyHandler.get_file_info_selectorc                 C      | j j||dS )N)	recursive)r   
create_dir)ry   rO   r   r   r   r   r        zProxyHandler.create_dirc                 C   r   r+   )r   
delete_dirrx   r   r   r   r     r   zProxyHandler.delete_dirc                 C   r   )N)missing_dir_okr   delete_dir_contents)ry   rO   r   r   r   r   r     s   z ProxyHandler.delete_dir_contentsc                 C   s   | j jdddS )Nr*   T)accept_root_dirr   r|   r   r   r   delete_root_dir_contents  r   z%ProxyHandler.delete_root_dir_contentsc                 C   r   r+   )r   delete_filerx   r   r   r   r   "  r   zProxyHandler.delete_filec                 C      | j ||S r+   )r   movery   srcdestr   r   r   r   %     zProxyHandler.movec                 C   r   r+   )r   	copy_filer   r   r   r   r   (  r   zProxyHandler.copy_filec                 C   r   r+   )r   open_input_streamrx   r   r   r   r   +  r   zProxyHandler.open_input_streamc                 C   r   r+   )r   open_input_filerx   r   r   r   r   .  r   zProxyHandler.open_input_filec                 C   r   N)metadata)r   open_output_streamry   rO   r   r   r   r   r   1  r   zProxyHandler.open_output_streamc                 C   r   r   )r   open_append_streamr   r   r   r   r   4  r   zProxyHandler.open_append_streamN)r~   r   r   __doc__rz   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r      s(    r   Fwarn_on_full_bufferc              	   c   s    t  \}}d }z*|d |d tj| | d}|V  W |d ur*t| |  |  d S |d ur=t| |  |  w )NFr   )socket
socketpairsetblockingsignalset_wakeup_fdfilenoclose)r   rwold_fdr   r   r   signal_wakeup_fd8  s$   




r   c                 C   s   | dg}t j|t jt jdd8}|ddkr 	 W d    dS |j }| d }t||}|rC|d}t	||kW  d    S t
d	1 sJw   Y  d S )
Nz	--versionutf-8stdoutstderrencodingr   r   Fz version RELEASE\.(\d+)-.*r   z+minio component older than the minimum year)r^   PopenPIPEwaitr   readresearchgroupintFileNotFoundError)	componentminimum_year	full_argsr=   r   patternversion_matchversion_yearr   r   r   _ensure_minio_component_versionK  s&   



r   c                 C   sn   t   }t   | dk r3zt| dddd| || W d S  ty*   t d Y nw t   | dk std)Nr   aliassetmyminiozhttp://r   z+mc command could not connect to local minio)time_run_mc_commandChildProcessErrorsleepr?   )mcdiraddress
access_key
secret_keystartr   r   r   _wait_for_minio_startup\  s   
r   c                 G   s   dd| gt | }tj|tjtjdd=}|d}d|}td|  td|  td	|j   td
|j	   |dkrIt
dW d    d S 1 sTw   Y  d S )Nmcz-Cr   r   r    zCmd: z
  Return: z
  Stdout: z
  Stderr: r   zCould not run mc)r/   r^   r   r   r   r3   printr   r   r   r   )r   ra   r   r=   retvalcmd_strr   r   r   r   h  s   


"r   c              	   C   s>  t jdkr
td ztdd tdd | d }| d \}}}}d||}	tj|d}
tj	|
r9t
|
 t|
 tj|d	}t|d
d}|| W d   n1 s[w   Y  t|
|	|| t|
dddd|| t|
ddddd| t|
dddddd| t|
ddd W dS  ty   td Y dS w )ab  
    Attempts to use the mc command to configure the minio server
    with a special user limited:limited123 which does not have
    permission to create buckets.  This mirrors some real life S3
    configurations where users are given strict permissions.

    Arrow S3 operations should still work in such a configuration
    (e.g. see ARROW-13685)
    win32z*The mc command is not installed on Windowsr   i  miniotempdir
connectionz{}:{}zlimited-buckets-policy.jsonr   )modeNadminuseraddzmyminio/policycreatezno-create-bucketsattachz--usermbzmyminio/existing-bucketz--ignore-existingz"Configuring limited s3 user failed)r[   platformpytestskipr   r   rK   rO   r3   existsshutilrmtreemkdiropenwriter   r   r   )	s3_serverr   usernamepasswordr   hostportr   r   r   r   policy_pathpolicy_filer   r   r   _configure_s3_limited_userv  s@   









r   c                  C   s@   d} dt jv rt jt jd } | st jd}t j|} | S )zs
    This is the default location where tz.cpp will look for (until we make
    this configurable at run-time)
    FPYARROW_TZDATA_PATHz%USERPROFILE%\Downloads\tzdata)rK   rL   rO   r   
expandvars)tzdata_booltzdata_pathr   r   r   windows_has_tzdata  s   
r  )r6   r7   r   r   ))r   
contextlibr   r8   rK   r   r   r   r   r   r0   r^   r[   r   r   pyarrowrR   
pyarrow.fsr	   contextmanagerr   r   r)   r5   rI   rY   rf   rj   rn   rq   rt   ru   r   FileSystemHandlerr   r   r   r   r   r   r  r   r   r   r   <module>   sX   

%
+

	
	B3