a
    ߙfb6                     @   s   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mZ ddl	m
Z
 ddlmZ edd ZG dd	 d	eZG d
d de
edZdS )zImplements the wrapper for the Astropy test runner.

This is for backward-compatibility for other downstream packages and can be removed
once astropy-helpers has reached end-of-life.

    N)contextmanager)Command)logc               	   c   sV   t tjd6} tj}| t_zdV  W |t_n|t_0 W d   n1 sH0    Y  dS )z
    A context manager to temporarily disable stdout.

    Used later when installing a temporary copy of astropy to avoid a
    very verbose output.
    wN)openosdevnullsysstdout)r   Z
old_stdout r   4lib/python3.9/site-packages/astropy/tests/command.py_suppress_stdout   s    r   c                       s    e Zd ZdZ fddZ  ZS )FixRemoteDataOptionau  
    This metaclass is used to catch cases where the user is running the tests
    with --remote-data. We've now changed the --remote-data option so that it
    takes arguments, but we still want --remote-data to work as before and to
    enable all remote tests. With this metaclass, we can modify sys.argv
    before setuptools try to parse the command-line options.
    c                    sl   zt jd}W n ty"   Y n0 dt j|< zt jd}W n tyP   Y n0 dt j|< t |||S )Nz--remote-dataz--remote-data=anyz-Rz-R=any)r	   argvindex
ValueErrorsuper__init__)clsnamebasesZdctidx	__class__r   r   r   ,   s    

zFixRemoteDataOption.__init__)__name__
__module____qualname____doc__r   __classcell__r   r   r   r   r   $   s   r   c                   @   sV   e Zd ZdZg dZdZdd Zdd Zdd	 Zd
d Z	dd Z
dddZdd ZdS )AstropyTestzRun the tests for this package))zpackage=PzThe name of a specific package to test, e.g. 'io.fits' or 'utils'. Accepts comma separated string to specify multiple packages. If nothing is specified, all default tests are run.)z
test-path=taH  Specify a test location by path.  If a relative path to a  .py file, it is relative to the built package, so e.g., a  leading "astropy/" is necessary.  If a relative  path to a .rst file, it is relative to the directory *below* the --docs-path directory, so a leading "docs/" is usually necessary.  May also be an absolute path.)zverbose-resultsVz#Turn on verbose output from pytest.)zplugins=pz&Plugins to enable when running pytest.)z	pastebin=bz8Enable pytest pastebin output. Either 'all' or 'failed'.)zargs=az,Additional arguments to be passed to pytest.)zremote-data=RzZRun tests that download remote data. Should be one of none/astropy/any (defaults to none).)pep88zPEnable PEP8 checking and disable regular tests. Requires the pytest-pep8 plugin.)pdbdz0Start the interactive Python debugger on errors.)coveragecz8Create a coverage report. Requires the coverage package.)z
open-filesozAFail if any tests leave files open.  Requires the psutil package.)z	parallel=jzRun the tests in parallel on the specified number of CPUs.  If "auto", all the cores on the machine will be used.  Requires the pytest-xdist plugin.)z
docs-path=NzThe path to the documentation .rst files.  If not provided, and the current directory contains a directory called "docs", that will be used.)z	skip-docsNz(Don't test the documentation .rst files.)zrepeat=NzPHow many times to repeat each test (can be used to check for sporadic failures).)z
temp-root=NzThe root directory in which to create the temporary testing files. If unspecified the system default is used (e.g. /tmp) as explained in the documentation for tempfile.mkstemp.)zverbose-installNzOTurn on terminal output from the installation of astropy in a temporary folder.)readonlyNz7Make the temporary installation being tested read-only. c                 C   sp   d | _ d | _d| _d | _d | _d | _d| _d| _d| _d| _	d| _
d| _d | _d| _d | _d | _d| _d| _d S )NFZnoner   )packageZ	test_pathZverbose_resultsZpluginsZpastebinargsZremote_datar'   r)   r+   Z
open_filesparallel	docs_pathZ	skip_docsrepeat	temp_rootverbose_installr/   selfr   r   r   initialize_optionsz   s$    zAstropyTest.initialize_optionsc                 C   s   d S Nr   r8   r   r   r   finalize_options   s    zAstropyTest.finalize_optionsc                 C   sD   d}d}| j r*|  \}}||7 }||7 }d}d}|j|| ||dS )z9
        Build a Python script to run the tests.
        r0   z/import builtins; builtins._ASTROPY_TEST_ = Truea  {cmd_pre}{0}; import {1.package_name}, sys; result = ({1.package_name}.test(package={1.package!r}, test_path={1.test_path!r}, args={1.args!r}, plugins={1.plugins!r}, verbose={1.verbose_results!r}, pastebin={1.pastebin!r}, remote_data={1.remote_data!r}, pep8={1.pep8!r}, pdb={1.pdb!r}, open_files={1.open_files!r}, parallel={1.parallel!r}, docs_path={1.docs_path!r}, skip_docs={1.skip_docs!r}, add_local_eggs_to_path=True, repeat={1.repeat!r})); {cmd_post}sys.exit(result))cmd_precmd_post)r+   _generate_coverage_commandsformat)r9   r=   r>   ZpreZpostZset_flagcmdr   r   r   generate_testing_command   s    z$AstropyTest.generate_testing_commandc              	   C   s  | j jr| j | j j | jdu r|| j ddd}|durbtj|d rbtj	|d | _ntjdr|tj	d| _| 
  | j jr| j | j j tjdrtdtj| jd | jrtd | jdd	 zz.|  }tjtjd
|g| jdd}| }W n0 ty<   ddl}||j | }Y n0 W | jrT| jdd	 t| j n"| jrv| jdd	 t| j 0 t |dS )z 
        Run the tests!
        NZ
build_docsZ
source_dir   Zdocsz.eggsz;changing permissions of temporary installation to read-onlyF)writablez-c)cwdZ	close_fdsr   T)!distributionZinstall_requiresZfetch_build_eggsr4   Zget_option_dictgetr   pathexistsabspath_build_temp_installZtests_requireshutilcopytreejointesting_pathr/   r   info _change_permissions_testing_pathrB   
subprocessPopenr	   
executablewaitKeyboardInterruptsignalZsend_signalSIGINTZrmtreetmp_dir
SystemExit)r9   Zcfg_docs_dirrA   ZtestprocZretcoderW   r   r   r   run   sD    


zAstropyTest.runc                 C   s   t j| jd | jd}tj|| _t	d| j  | 
d | jd}| j|_| jrf| d n0t  | d W d   n1 s0    Y  | d}|j| _| jdurtj| jtj| j}t| j| || _td| j dS )a  
        Install the package and to a temporary directory for the purposes of
        testing. This allows us to test the install command, include the
        entry points, and also avoids creating pyc and __pycache__ directories
        inside the build directory
        z-test-)prefixdirz#installing to temporary directory: ZinstallNz	setup.cfg)tempfileZmkdtemppackage_namer6   r   rH   realpathrY   r   rP   Zreinitialize_commandrF   Zget_command_objr\   r7   Zrun_commandr   Zget_finalized_commandZinstall_librO   r4   rN   basenamerL   rM   copy)r9   rY   Zinstall_cmdZnew_docs_pathr   r   r   rK      s*    
(


zAstropyTest._build_temp_installFc                 C   sz   |rt jt jB }nt j}t| jD ]P\}}}|D ] }ttj|||t j	B  q2|D ]}ttj||| qXq$d S r;   )
statS_IRUSRS_IWUSRr   walkrO   chmodrH   rN   S_IXUSR)r9   rD   Zbasic_flagsrootdirsfilesdirnamefilenamer   r   r   rQ   .  s    z,AstropyTest._change_permissions_testing_pathc           	      C   s,  | j dkrtdzddl}W n ty8   tdY n0 tj| j| j	dddd}t
|d	}| }W d   n1 s0    Y  |	d
| j	dd}tj| jd}t
|d }||d W d   n1 s0    Y  dtjdtj|}dtjdtj| j}||fS )zf
        This method creates the post and pre commands if coverage is to be
        generated
        r   z*--coverage can not be used with --parallelNz;--coverage requires that the coverage package is installed../Ztests
coveragercrz{packagename}wbzutf-8zZimport coverage; cov = coverage.coverage(data_file=r"{}", config_file=r"{}"); cov.start();z	.coveragezgcov.stop(); from astropy.tests.helper import _save_coverage; _save_coverage(cov, result, r"{}", r"{}");)r3   r   r+   ImportErrorr   rH   rN   rO   r_   replacer   readrY   writeencoder@   rJ   )	r9   r+   rp   fdZcoveragerc_contentZtmp_coveragerctmpr=   r>   r   r   r   r?   9  s>    

&.z'AstropyTest._generate_coverage_commandsN)F)r   r   r   ZdescriptionZuser_optionsr_   r:   r<   rB   r[   rK   rQ   r?   r   r   r   r   r   ?   s   6$H/
r   )	metaclass)r   r   rc   rL   rR   r	   r^   
contextlibr   Z
setuptoolsr   Zastropy.loggerr   r   typer   r   r   r   r   r   <module>   s   
