o
    k)h/                     @   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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mZ ddlmZ ddlmZ d/dd	Zd
ZdZG dd dZesge Ze  dd Zdd Zdd Z dd Z!da"da#ej$dkree%j&j&j&Z'e(e'dZ)dd Z*dd Z+dd Z,dd  Z-e-g g g dfd!d"Z.e-g g g ddfd#d$Z/G d%d& d&eZ0d/d'd(Z1G d)d* d*Z2d+d, Z3e	j4d-d. Z5dS )0z
Utility functions for

- building and importing modules on test time, using a temporary location
- detecting if compilers are present
- determining paths to tests

    N)Path)	asunicode)temppathIS_WASM)import_module)MesonBackendc                 C   s*  t jdkrtjddd t }z~tj|d}t	|d@}|
d |
d|  d	 |rV|
|  d
|  d	 |
|  d| d |
d|  d|  d|  d|  d	 W d    n1 s`w   Y  ztjg dd|dd}W n tjy   tjddd Y nw |jdkW t| S t| w )Nwin32z*No Fortran tests on Windows (Issue #25134)T)Zallow_module_levelzmeson.buildwzproject('check_compilers')
zadd_languages('z')
z _compiler = meson.get_compiler('z_code = '''z'''
Z_have_z
_feature =z_compiler.compiles(z_code, name: 'z feature check')
)mesonZsetupZbtmpF)checkcwdZcapture_outputz3meson not present, skipping compiler dependent testr   )sysplatformpytestskiptempfilemkdtempospathjoinopenwrite
subprocessrunZCalledProcessError
returncodeshutilrmtree)langZcode_snippetZtmpdirZ
meson_filefZrunmeson r   5lib/python3.10/site-packages/numpy/f2py/tests/util.pycheck_language   sD   



r!   z]
C Example Fortran 77 code
      PROGRAM HELLO
      PRINT *, 'Hello, Fortran 77!'
      END
z
! Example Fortran 90 code
program hello90
  type :: greeting
    character(len=20) :: text
  end type greeting

  type(greeting) :: greet
  greet%text = 'hello, fortran 90!'
  print *, greet%text
end program hello90
c                   @   s   e Zd Zdd Zdd ZdS )CompilerCheckerc                 C   s   d| _ d| _d| _d| _d S )NF)compilers_checkedhas_chas_f77has_f90selfr   r   r    __init__T   s   
zCompilerChecker.__init__c                 C   s   | j sJtjdksLtj 0}|td|tdt|tdt	g}|d 
 | _|d 
 | _|d 
 | _W d    n1 s@w   Y  d| _ d S d S d S )NcygwincZfortranr         T)r#   r   r   
concurrentfuturesZThreadPoolExecutorZsubmitr!   fortran77_codefortran90_coderesultr$   r%   r&   )r(   Zexecutorr/   r   r   r    check_compilersZ   s   

zCompilerChecker.check_compilersN)__name__
__module____qualname__r)   r3   r   r   r   r    r"   S   s    r"   c                   C      t jS N)checkerr$   r   r   r   r    has_c_compilerm      r:   c                   C   r7   r8   )r9   r%   r   r   r   r    has_f77_compilerp   r;   r<   c                   C   r7   r8   )r9   r&   r   r   r   r    has_f90_compilers   r;   r=   c                   C   s   t jot jS r8   )r9   r&   r%   r   r   r   r    has_fortran_compilerv   s   r>   i  r*   z**/*.dllc                   C   sZ   t d ur+ztjt  W n	 ty   Y nw ztt  W n	 ty&   Y nw d a d S d S r8   )_module_dirr   r   remove
ValueErrorr   r   OSErrorr   r   r   r    _cleanup   s   rC   c                   C   s6   t d u rt a tt t tjvrtjdt  t S )Nr   )	r?   r   r   atexitregisterrC   r   r   insertr   r   r   r    get_module_dir   s   

rG   c                  C   s,   t   dt } td7 a| tjv rtd| S )Nz_test_ext_module_%dr,   z%Temporary module name already in use.)rG   _module_numr   modulesRuntimeError)namer   r   r    get_temp_module_name   s   
rL   c                    s   i  fdd} j |_ |S )Nc               
      sh   t | |f}|vr'z | i ||< W n ty& } z||<  d }~ww | }t|tr2||S r8   )repr	Exception
isinstance)akwkeyeretfuncZmemor   r    wrapper   s   
z_memoize.<locals>.wrapper)r4   )rV   rW   r   rU   r    _memoize   s   rX   c              
   C   s  dt jd}t }t std g }g }| D ]5}	tj|	s&td|	 tj	|tj
|	}
t|	|
 ||
 tj|
\}}|dv rM||
 q|sRJ |du rYt }g }d|vrfd|vrfdg}d	d
|g| | | }|ddg7 }|r|dg| 7 }|r|dg| 7 }t }zAt| t jd	|g| }tj|tjtjd}| \}}|jdkrtd|dd t|f W t| |D ]}	t|	 qnt| |D ]}	t|	 qw t jdkrtttj	|d| t g dt  t!|S )zH
    Compile and import a f2py module, built from the given files.

    zimport sys; sys.path = z&; import numpy.f2py; numpy.f2py.main()No Fortran compiler availablez%s is not a file).f90z.f95.fz.c.pyfNz--freethreading-compatiblez--no-freethreading-compatiblez-cz-mz	--backendr
   zskip:zonly:)stdoutstderrr   zRunning f2py failed: %s
%s   r*   z{:s}*)z/usr/bin/rebasez
--databasez--obliviousz	--verbose)"r   r   rG   r>   r   r   r   isfilerJ   r   basenamer   copyfileappendsplitextrL   getcwdchdir
executabler   PopenPIPEZSTDOUTZcommunicater   r   unlinkr   _module_listextendglobformatZ
check_callr   )source_filesoptionsr   onlymodule_namecodedZdst_sourcesZf2py_sourcesfndstbaseextZgil_optionsZ	f2py_optsr   cmdpouterrr   r   r    build_module   sx   







r}   c              	   C   s   |du rd}t |d,}t|d}||  W d   n1 s!w   Y  t|g||||dW  d   S 1 s:w   Y  dS )z6
    Compile and import Fortran code using f2py.

    Nr[   )suffixr	   rp   r   rq   rr   )r   r   r   r}   )Zsource_coderp   r   rq   r~   rr   r   r   r   r   r    
build_code  s   $r   c                       s$   e Zd Z fddZdd Z  ZS )SimplifiedMesonBackendc                    s   t  j|i | d S r8   )superr)   )r(   argskwargs	__class__r   r    r)   0  s   zSimplifiedMesonBackend.__init__c                 C   s   |  | j | | j d S r8   )Zwrite_meson_build	build_dirZ	run_mesonr'   r   r   r    compile3  s   zSimplifiedMesonBackend.compile)r4   r5   r6   r)   r   __classcell__r   r   r   r    r   /  s    r   c                 K   s   t  std t }|du rt }tdi d|d| d|dg d|d|dg d|dg d	|d	g d
|d
g d|dg d|dg d|dg d|dg d|dg d|dg d|ddd|di }|  tj	
d| d|j  t|S )z1
    Build a module via Meson and import it.
    rY   NZ
modulenamesourcesZextra_objectsr   Zinclude_dirsZlibrary_dirsZ	librariesZdefine_macrosZundef_macrosZ
f2py_flagsZsysinfo_flagsZfc_flagsZ
flib_flagsZsetup_flagsZremove_build_dirFZ	extra_datr   /r   )r>   r   r   rG   rL   r   getr   r   r   rF   Zmeson_build_dirr   )ro   rr   r   r   Zbackendr   r   r    build_meson8  sR   
	
r   c                   @   sT   e Zd ZdZdZg Zg Zg ZdZdZ	dZ
dZdZedd Zedd Zdd ZdS )	F2PyTestNr[   c                 C   s*   t | }d|jddd  d|j dS )N_.r,   Z_ext_module)typer5   rsplitr4   )r(   clsr   r   r    rr   q  s   "zF2PyTest.module_namec                 C   s8   t jdkr
td t t_t t_t	 t_
t t_d S )Nr   z)Fails with MinGW64 Gfortran (Issue #9673))r   r   r   r   r:   r   _has_c_compilerr<   _has_f77_compilerr=   _has_f90_compilerr>   _has_fortran_compiler)r   r   r   r    setup_classv  s   

zF2PyTest.setup_classc                 C   s   | j d urd S | jr| jng }| jr|| j tdd |D }tdd |D }tdd |D }|r=| js=td |rG| j	sGtd |rQ| j
sQtd | jd urgt| j| j| j| j| j| jd| _ | jd ur}t| j| j| j| j| jd	| _ d S d S )
Nc                 s       | ]
}t |d V  qdS )r[   Nstrendswith.0ru   r   r   r    	<genexpr>      z(F2PyTest.setup_method.<locals>.<genexpr>c                 s   r   )rZ   Nr   r   r   r   r    r     r   c                 s   r   )r\   Nr   r   r   r   r    r     r   z No Fortran 77 compiler availablez No Fortran 90 compiler availablerY   )rp   r   rq   r~   rr   r   )moduler   rs   rc   r~   anyr   r   r   r   r   r   rp   rq   rr   r}   )r(   ZcodesZ	needs_f77Z	needs_f90Z	needs_pyfr   r   r    setup_method  s@   








	zF2PyTest.setup_method)r4   r5   r6   rs   r   rp   r   rq   r~   r   r   r   r   propertyrr   classmethodr   r   r   r   r   r    r   e  s     

r   c                  G   s   t tjjj }|j|  S r8   )r   numpyZf2py__file__parentZresolveZjoinpath)rP   rt   r   r   r    getpath  s   
r   c              	   c   s8    t  }t|  zd V  W t| d S t| w r8   )r   r   r   rf   )r   Zcurpathr   r   r    	switchdir  s   
r   r8   )6__doc__rm   r   r   r   r   r   rD   r   
contextlibr   Zconcurrent.futuresr.   Zpathlibr   Znumpy._utilsr   Znumpy.testingr   r   	importlibr   Znumpy.f2py._backends._mesonr   r!   r0   r1   r"   r9   r3   r:   r<   r=   r>   r?   rH   r   r   r   ZNUMPY_INSTALL_ROOTlistrk   rC   rG   rL   rX   r}   r   r   r   r   r   contextmanagerr   r   r   r   r    <module>   sh    


O
	-G