a
    Lfc                     @   s  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	Z	d dl
Z
ddlmZ d dlmZ eddZdd
dZe
jdddd Ze
jdddd Ze
jdddd Ze
jdddd Ze
jdddd Ze
jdddd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Ze
jj e	! d&kp@ej"d'kd(d)d*d+ Z#e
jj e	! d&kplej"d'kd(d)d,d- Z$e
jj%d.d/ Z&d0d1 Z'd2d3 Z(d4d5 Z)d6d7 Z*d8d9 Z+d:d; Z,d<d= Z-d>d? Z.d@dA Z/dBdC Z0dDdE Z1dFdG Z2dHdI Z3dJdK Z4e
jj5dLd)dMdN Z6dOdP Z7dQdR Z8dSdT Z9dUdV Z:dWdX Z;dYdZ Z<d[d\ Z=d]d^ Z>d_d` Z?e
jj5dLd)dadb Z@dcdd ZAdedf ZBdgdh ZCdidj ZDdkdl ZEdmdn ZFdodp ZGdqdr ZHdsdt ZIdudv ZJdwdx ZKdydz ZLd{d| ZMd}d~ ZNdd ZOdd ZPdd ZQdd ZRdS )    N)Path)
namedtuple   )util)mainPPathsz(finp, f90inp, pyf, wrap77, wrap90, cmodfuntitledc              
   C   sR   t | }t|d|d|d|| d|| d|| ddS )ax  Takes in a temporary file for testing and returns the expected output and input paths

    Here expected output is essentially one of any of the possible generated
    files.

    ..note::

         Since this does not actually run f2py, none of these are guaranteed to
         exist, and module names are typically incorrect

    Parameters
    ----------
    fname_inp : str
                The input filename
    mname : str, optional
                The name of the module, untitled by default

    Returns
    -------
    genp : NamedTuple PPaths
            The possible paths which are generated, not all of which exist
    z.fz.f90.pyfz-f2pywrappers.fz-f2pywrappers2.f90module.c)finpf90inppyfwrap77wrap90cmodf)r   r   with_suffix	with_name)Z	fname_inpmnamebpath r   U/var/www/ai-form-bot/venv/lib/python3.9/site-packages/numpy/f2py/tests/test_f2py2e.pyget_io_paths   s    r   session)scopec                 C   s2   t dddd }|  d }|j|dd |S )'Generates a single f90 file for testingtestssrcclizhiworld.f90z	hello.f90asciiencodingr   Zgetpath	read_textZgetbasetemp
write_texttmpdir_factoryfdatfnr   r   r   hello_world_f909   s    r(   c                 C   s2   t dddd }|  d }|j|dd |S )z(F90 file for testing warnings in gh23598r   r   Zcrackfortranzgh23598Warn.f90r   r   r!   r$   r   r   r   gh23598_warnB   s    r)   c                 C   s2   t dddd }|  d }|j|dd |S )z8F90 file for testing disallowed CLI arguments in ghff819r   r   r   zgh_22819.pyfr   r   r!   r$   r   r   r   gh22819_cliK   s    r*   c                 C   s2   t dddd }|  d }|j|dd |S )'Generates a single f77 file for testingr   r   r   zhi77.fzhello.fr   r   r!   r$   r   r   r   hello_world_f77T   s    r,   c                 C   s2   t dddd }|  d }|j|dd |S )r+   r   r   Zreturn_realzfoo77.fzfoo.fr   r   r!   r$   r   r   r   retreal_f77]   s    r-   c                 C   s`   t dddd }t dddd }|  d }|  d }|j|dd	 |j|dd	 |S )
r   r   r   f2cmapzisoFortranEnvMap.f90z.f2py_f2cmapz
f2cmap.f90Zmapfiler   r   r!   )r%   r&   r.   r'   Zfmapr   r   r   
f2cmap_f90e   s    r/   c                 C   s   t |}|tdd|   t|jd t  dd |jdD }d|vsVJ d|vsbJ d|v snJ d	|v szJ d
sJ W d   n1 s0    Y  dS )zCheck that module names are handled correctly
    gh-22819
    Essentially, the -m name cannot be used to import the module, so the module
    named in the .pyf needs to be used instead

    CLI :: -m and a .pyf file
    argvf2py -m blah c                 S   s   g | ]}|  r|jqS r   )is_filename).0itemr   r   r   
<listcomp>}       z$test_gh22819_cli.<locals>.<listcomp>*zblahmodule.czblah-f2pywrappers.fztest_22819-f2pywrappers.fztest_22819module.czIgnoring blahN)	r   setattrsyssplitr   	switchdirparentf2pyclirglob)capfdr*   monkeypatchipathZ	gen_pathsr   r   r   test_gh22819_cliq   s    rC   c              	   C   s   t |}|tdd| d  t|jD tjt	dd t
  W d   n1 sZ0    Y  W d   n1 sx0    Y  dS )zBOnly one .pyf file allowed
    gh-22819
    CLI :: .pyf files
    r0   r1   z
 hello.pyfzOnly one .pyf file per call)matchN)r   r9   r:   r;   r   r<   r=   pytestraises
ValueErrorr>   )r@   r*   rA   rB   r   r   r   test_gh22819_many_pyf   s
    rH   c                 C   sx   t |dd}|j}|tdd| d  t|j, t  |j	
 }d|vsVJ W d    n1 sj0    Y  d S )Ntestr   r0   f2py z -m testzintproductf2pywrap, intpr)r   r   r9   r:   r;   r   r<   r=   r>   r   r"   )r@   r)   rA   foutlrB   wrapperr   r   r   test_gh23598_warn   s    
rN   c                 C   s   t |}t |jd }|tdd| d|   t|j@ t  | 	 \}}d|v s`J t | 
 srJ W d   n1 s0    Y  dS )zIEnsures that a signature file is generated via the CLI
    CLI :: -h
    r	   r0   zf2py -h  Saving signatures to fileN)r   stemr9   r:   r;   r   r<   r=   r>   
readouterrexists)r@   r(   rA   rB   Zopathout_r   r   r   test_gen_pyf   s    rV   c                 C   sz   t |}|tdd|   t|j: t  |  \}}d|v sLJ d|v sXJ W d   n1 sl0    Y  dS )zHEnsures that a signature file can be dumped to stdout
    CLI :: -h
    r0   zf2py -h stdout rP   zfunction hi() ! in N	r   r9   r:   r;   r   r<   r=   r>   rR   r@   r(   rA   rB   rT   rU   r   r   r   test_gen_pyf_stdout   s    rY   c              	   C   s   t |}|tdd|   t|jj t djddd t	t
. t  |  \}}d|v sjJ W d   n1 s~0    Y  W d   n1 s0    Y  dS )	zjEnsures that the CLI refuses to overwrite signature files
    CLI :: -h without --overwrite-signature
    r0   f2py -h faker.pyf 	faker.pyf	Fake newsr   r   z&Use --overwrite-signature to overwriteN)r   r9   r:   r;   r   r<   r=   r#   rE   rF   
SystemExitr>   rR   )r@   r(   rA   rB   rU   errr   r   r   test_gen_pyf_no_overwrite   s    r_   Linux)      zCompiler and 3.12 required)reasonc                 C   sn   t |}|tdd|   t|j. t  |  \}}d|v sLJ W d   n1 s`0    Y  dS )z@Check that modules are named correctly

    CLI :: defaults
    r0   zf2py --backend meson -c zuntitledmodule.cNrW   rX   r   r   r   test_untitled_cli   s    rd   c              	   C   sP  d}t ||d}|j}|tdd| d|   t|j. t  | 	 \}}d|v s`J W d   n1 st0    Y  |tdd  t|j. t  | 	 \}}d	|v sJ W d   n1 s0    Y  d
}|tdd| d| d  t|j0 t  | 	 \}}d|v s,J W d   n1 sB0    Y  dS )zqCheck that no distutils imports are performed on 3.12
    CLI :: --fcompiler --help-link --backend distutils
    hirJ   r0   rK   z -c --fcompiler=gfortran -m z%--fcompiler cannot be used with mesonNzf2py --help-linkzUse --dep for meson buildsZhi2z -c -m z --backend distutilsz.Cannot use distutils backend with Python>=3.12)
r   r   r9   r:   r;   r   r<   r=   r>   rR   )r@   r(   rA   MNAMErL   rB   rT   rU   r   r   r   !test_no_py312_distutils_fcompiler   s2    *
*rg   c                 C   s   t |dd}|j}d}d}|tdd| d|   t|jf t  | 	 \}}| D ]}	d|	 d	|v s`J q`| D ]}
d
|
 d|v sJ qW d   n1 s0    Y  dS )z9Tests that functions can be skipped
    CLI :: skip:
    rI   rJ   t0 t4 t8 sd s8 s4td s0r0   rK   z -m test skip: z=buildmodule: Could not found the body of interfaced routine "". Skipping.Constructing wrapper function ""N
r   r   r9   r:   r;   r   r<   r=   r>   rR   )r@   r-   rA   rL   rB   toskip	remainingrT   r^   skeyrkeyr   r   r   test_f2py_skip   s$    
rr   c                 C   s   t |dd}|j}d}d}|tdd| d|   t|jf t  | 	 \}}| D ]}	d|	 d	|v s`J q`| D ]}
d
|
 d|v sJ qW d   n1 s0    Y  dS )z>Test that functions can be kept by only:
    CLI :: only:
    rI   rJ   rh   ri   r0   rK   z -m test only: <buildmodule: Could not find the body of interfaced routine "rj   rk   rl   Nrm   )r@   r-   rA   rL   rB   rn   tokeeprT   r^   rp   rq   r   r   r   test_f2py_only  s$    
ru   c                 C   s   t |dd}|j}d}t|}d}d}	|tdd| d|	 d	| d
|   t|jf t	  | 
 \}
}| D ]}d| d|v sxJ qx| D ]}d| d|
v sJ qW d   n1 s0    Y  dS )zfTests that it is possible to return to file processing mode
    CLI :: :
    BUG: numpy-gh #20520
    rI   rJ   rh   ztd s0 hiblahr0   rK    -m z only: z : rs   rj   rk   rl   N)r   r   r   r9   r:   r;   r   r<   r=   r>   rR   )r@   r(   r-   rA   rL   rB   rn   Zipath2rt   r   rT   r^   rp   rq   r   r   r   test_file_processing_switch'  s*    
rx   c                 C   s   d}t ||d}|j}|tdd| d|   t|j t  W d   n1 s\0    Y  t	
|jsvJ t	
|jsJ dS )zHChecks the generation of files based on a module name
    CLI :: -m
    re   rJ   r0   rK   rw   N)r   r   r9   r:   r;   r   r<   r=   r>   r   rS   r   r   )r@   r(   rA   rf   rL   rB   r   r   r   test_mod_gen_f77E  s    $ry   c              	   C   s   d}t ||d}|j}|tdd| d| d  t|jV t  t	d
 $}| }d|v slJ W d	   n1 s0    Y  W d	   n1 s0    Y  d	S )
zCheck that pyf files are correctly generated with module structure
    CLI :: -m <name> -h pyf_file
    BUG: numpy-gh #20520
    re   rJ   r0   rK   rw   z
 -h hi.pyfzhi.pyfzpython module hiN)r   r   r9   r:   r;   r   r<   r=   r>   r   openread)r@   r,   rA   rf   rL   rB   ZhipyfZpyfdatr   r   r   test_mod_gen_gh25263V  s     r|   c           	      C   s&  t |dd}|j}td}td}|tdd| d  t|j	F t
  |  \}}||dusrJ ||du sJ W d   n1 s0    Y  |tdd| d	  t|j	H t
  |  \}}||du sJ ||dusJ W d   n1 s0    Y  dS )
zHLowers cases by flag or when -h is present

    CLI :: --[no-]lower
    rI   rJ   zHI\(\)zhi\(\)r0   rK   z -m test --lowerNz -m test --no-lower)r   r   recompiler9   r:   r;   r   r<   r=   r>   rR   search	r@   r,   rA   rL   rB   ZcapshiZcapslorT   rU   r   r   r   test_lower_cmodf  s$    

0r   c           	   	   C   s6  t |dd}|j}td}td}|tdd| d|j d  t	|j
F t  |  \}}||d	uszJ ||d	u sJ W d	   n1 s0    Y  |tdd| d|j d
  t	|j
H t  |  \}}||d	u sJ ||d	usJ W d	   n1 s(0    Y  d	S )z^Lowers cases in signature files by flag or when -h is present

    CLI :: --[no-]lower -h
    rI   rJ   z	Block: HIz	Block: hir0   rK   z -h z -m test --overwrite-signatureNz) -m test --overwrite-signature --no-lower)r   r   r}   r~   r9   r:   r   r;   r   r<   r=   r>   rR   r   r   r   r   r   test_lower_sig  s0    

0r   c              
   C   s   t |}d}d}|tdd| d| d|   t|j6 t  |  \}}d| d|v shJ W d	   n1 s|0    Y  d	S )
zNEnsures that the build directory can be specified

    CLI :: --build-dir
    rv   Ztttmpr0   f2py -m rO   z --build-dir zWrote C/API module "rl   NrW   )r@   r(   rA   rB   r   ZodirrT   rU   r   r   r   test_build_dir  s    r   c                 C   s   t |}|tdd| d  t|j@ t djddd t  | 	 \}}d|v s`J W d	   n1 st0    Y  d	S )
zXEnsures that the build directory can be specified

    CLI :: --overwrite-signature
    r0   rZ   z --overwrite-signaturer[   r\   r   r   rP   N)
r   r9   r:   r;   r   r<   r=   r#   r>   rR   rX   r   r   r   test_overwrite  s    r   c              	   C   s   t |}d}|tdd| d| d  t|jp t  |  \}}d|v sXJ t | d	  }d|
 v s|J W d	   n1 s0    Y  W d	   n1 s0    Y  d	S )
zJEnsures that TeX documentation is written out

    CLI :: --latex-doc
    rv   r0   r   rO   z --latex-docDocumentation is saved to file
module.tex\documentclassNr   r9   r:   r;   r   r<   r=   r>   rR   rz   r{   r@   r(   rA   rB   r   rT   rU   Zotexr   r   r   test_latexdoc  s    r   c              	   C   sz   t |}d}|tdd| d| d  t|j. t  |  \}}d|vsXJ W d   n1 sl0    Y  dS )zMEnsures that TeX documentation is written out

    CLI :: --no-latex-doc
    rv   r0   r   rO   z --no-latex-docr   NrW   r@   r(   rA   rB   r   rT   rU   r   r   r   test_nolatexdoc  s    r   c              	   C   s   t |}d}|tdd| d| d  t|jr t  |  \}}d|v sXJ t d| d	  }d	|
 vs~J W d
   n1 s0    Y  W d
   n1 s0    Y  d
S )zEnsures that truncated documentation is written out

    TODO: Test to ensure this has no effect without --latex-doc
    CLI :: --latex-doc --short-latex
    rv   r0   r   rO   z --latex-doc --short-latexr   ./r   r   Nr   r   r   r   r   test_shortlatex  s    r   c              	   C   s   t |}d}|tdd| d| d  t|jr t  |  \}}d|v sXJ t d| d	  }d	|
 v s~J W d
   n1 s0    Y  W d
   n1 s0    Y  d
S )zIEnsures that RsT documentation is written out

    CLI :: --rest-doc
    rv   r0   r   rO   z --rest-doc#ReST Documentation is saved to filer   zmodule.restz.. -*- rest -*-Nr   )r@   r(   rA   rB   r   rT   rU   Zorstr   r   r   test_restdoc  s    r   c              	   C   sz   t |}d}|tdd| d| d  t|j. t  |  \}}d|vsXJ W d   n1 sl0    Y  dS )zLEnsures that TeX documentation is written out

    CLI :: --no-rest-doc
    rv   r0   r   rO   z --no-rest-docr   NrW   r   r   r   r   test_norestexdoc  s    r   c              	   C   s   t |}d}|tdd| d| d  t|jZ t  t d| d  }d|	 v sfJ W d	   n1 sz0    Y  W d	   n1 s0    Y  d	S )
zIEnsures that debugging wrappers are written

    CLI :: --debug-capi
    rv   r0   r   rO   z --debug-capir   r
   z#define DEBUGCFUNCSN
r   r9   r:   r;   r   r<   r=   r>   rz   r{   )r@   r(   rA   rB   r   ocmodr   r   r   test_debugcapi#  s    r   z2Consistently fails on CI; noisy so skip not xfail.c              	   C   s   t | }d}|tdd| d| d  t|jZ t  td}t	j
|ddd	}d
}td}|j|ksvJ |j|ksJ W d   n1 s0    Y  dS )zEEnsures that debugging wrappers work

    CLI :: --debug-capi -c
    rv   r0   r   rO   z -c --debug-capiz#python3 -c "import blah; blah.hi()"TUTF-8capture_outputr     Hello World
a   debug-capi:Python C/API function blah.hi()
debug-capi:float hi=:output,hidden,scalar
debug-capi:hi=0
debug-capi:Fortran subroutine `f2pywraphi(&hi)'
debug-capi:hi=0
debug-capi:Building return value.
debug-capi:Python C/API function blah.hi: successful.
debug-capi:Freeing memory.
        N)r   r9   r:   r;   r   r<   r=   r>   shlex
subprocessruntextwrapdedentstdoutstderr)r(   rA   rB   r   cmd_runrouteoutZeerrr   r   r   test_debugcapi_bld3  s    


r   c              	   C   s   t |}d}|tdd| d|   t|j t  W d   n1 sR0    Y  |  \}}d|v stJ |tdd| d| d  t|j. t  |  \}}d|v sJ W d   n1 s0    Y  dS )zoEnsures that fortran subroutine wrappers for F77 are included by default

    CLI :: --[no]-wrap-functions
    rv   r0   r   rO   N Fortran 77 wrappers are saved toz --wrap-functionsrW   r   r   r   r   test_wrapfunc_defQ  s    $r   c              	   C   sz   t |}d}|tdd| d| d  t|j. t  |  \}}d|vsXJ W d   n1 sl0    Y  dS )zeEnsures that fortran subroutine wrappers for F77 can be disabled

    CLI :: --no-wrap-functions
    rv   r0   r   rO   z --no-wrap-functionsr   NrW   r   r   r   r   test_nowrapfuncj  s    r   c              	   C   s   t |}d}|tdd| d| d  t|jj t  t d| d 0}|	 }d|v sjJ d	|v svJ W d
   n1 s0    Y  W d
   n1 s0    Y  d
S )zcAdd to the include directories

    CLI :: -include
    TODO: Document this in the help string
    rv   r0   r   rO   z' -include<stdbool.h> -include<stdio.h> r   r
   z#include <stdbool.h>z#include <stdio.h>Nr   )r@   r(   rA   rB   r   r   Zocmrr   r   r   test_inclheaderz  s    r   c                   C   s   dS )z?Add to the include directories

    CLI :: --include-paths
    Nr   r   r   r   r   test_inclpath  s    r   c                   C   s   dS )z;Add to the include directories

    CLI :: --help-link
    Nr   r   r   r   r   
test_hlink  s    r   c                 C   s   t |}|tdd| d  t|j^ t  |  \}}d|v sNJ d|v sZJ d|v sfJ d|v srJ d|v s~J W d	   n1 s0    Y  d	S )
zOCheck that Fortran-to-Python KIND specs can be passed

    CLI :: --f2cmap
    r0   r1   z --f2cmap mapfilez!Reading f2cmap from 'mapfile' ...z&Mapping "real(kind=real32)" to "float"z'Mapping "real(kind=real64)" to "double"z,Mapping "integer(kind=int64)" to "long_long"z0Successfully applied user defined f2cmap changesNrW   )r@   r/   rA   rB   rT   rU   r   r   r   test_f2cmap  s    r   c                 C   st   t |}|tdd| d  t|j2 t  |  \}}t	|dksRJ W d   n1 sf0    Y  dS )z)Reduce verbosity

    CLI :: --quiet
    r0   r1   z --quietr   N)
r   r9   r:   r;   r   r<   r=   r>   rR   lenrX   r   r   r   
test_quiet  s    r   c                 C   sp   t |}|tdd| d  t|j. t  |  \}}d|v sNJ W d   n1 sb0    Y  dS )z-Increase verbosity

    CLI :: --verbose
    r0   r1   z
 --verboseZanalyzelineNrW   rX   r   r   r   test_verbose  s    r   c                 C   sl   | tdd  tt< t  |  \}}ddl}|j	|
 ksJJ W d   n1 s^0    Y  dS )z"Ensure version

    CLI :: -v
    r0   zf2py -vr   N)r9   r:   r;   rE   rF   r]   r>   rR   numpy__version__strip)r@   rA   rT   rU   npr   r   r   test_version  s    r   c                 C   s   t | }|tdd| d  t|jB t  td}t	j
|ddd}d}|j|ksbJ W d	   n1 sv0    Y  d	S )
z
    CLI :: -c
    r0   r1   z -cz"python -c "import blah; blah.hi()"Tr   r   r   N)r   r9   r:   r;   r   r<   r=   r>   r   r   r   r   )r(   rA   rB   r   r   r   r   r   r   test_npdistop  s    
r   c                   C   s   dS )z
    CLI :: -c --fcompiler
    Nr   r   r   r   r   test_npd_fcompiler  s    r   c                   C   s   dS )z
    CLI :: -c --compiler
    Nr   r   r   r   r   test_npd_compiler  s    r   c                   C   s   dS )z$
    CLI :: -c --help-fcompiler
    Nr   r   r   r   r   test_npd_help_fcompiler  s    r   c                   C   s   dS )z
    CLI :: -c --f77exec
    Nr   r   r   r   r   test_npd_f77exec  s    r   c                   C   s   dS )z
    CLI :: -c --f90exec
    Nr   r   r   r   r   test_npd_f90exec  s    r   c                   C   s   dS )z
    CLI :: -c --f77flags
    Nr   r   r   r   r   test_npd_f77flags  s    r   c                   C   s   dS )z
    CLI :: -c --f90flags
    Nr   r   r   r   r   test_npd_f90flags#  s    r   c                   C   s   dS )z
    CLI :: -c --opt
    Nr   r   r   r   r   test_npd_opt+  s    r   c                   C   s   dS )z
    CLI :: -c --arch
    Nr   r   r   r   r   test_npd_arch3  s    r   c                   C   s   dS )z
    CLI :: -c --noopt
    Nr   r   r   r   r   test_npd_noopt;  s    r   c                   C   s   dS )z
    CLI :: -c --noarch
    Nr   r   r   r   r   test_npd_noarchC  s    r   c                   C   s   dS )z
    CLI :: -c --debug
    Nr   r   r   r   r   test_npd_debugK  s    r   c                   C   s   dS )z%
    CLI :: -c --link-<resource>
    Nr   r   r   r   r   test_npd_link_autoS  s    r   c                   C   s   dS )z/
    CLI :: -c -L/path/to/lib/ -l<libname>
    Nr   r   r   r   r   test_npd_lib[  s    r   c                   C   s   dS )z
    CLI :: -D<define>
    Nr   r   r   r   r   test_npd_definec  s    r   c                   C   s   dS )z
    CLI :: -U<name>
    Nr   r   r   r   r   test_npd_undefinek  s    r   c                   C   s   dS )z$
    CLI :: -I/path/to/include/
    Nr   r   r   r   r   test_npd_incls  s    r   c                   C   s   dS )z8
    CLI :: <filename>.o <filename>.so <filename>.a
    Nr   r   r   r   r   test_npd_linker{  s    r   )r   )Sr   r}   r:   r   r   pathlibr   collectionsr   platformrE    r   Znumpy.f2py.f2py2er   r>   r   r   Zfixturer(   r)   r*   r,   r-   r/   rC   rH   rN   rV   rY   r_   markZskipifsystemversion_inford   rg   Zxfailrr   ru   rx   ry   r|   r   r   r   r   r   r   r   r   r   r   skipr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   s   (

'












"

'
		
