o
    5hs'                     @  s   d dl mZ d dlZd dlZd dlmZ d dl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lmZ d	d
lmZ d	dlmZ d dlm  mZ d dlmZ dejv ZG dd dZG dd dZdd Z dS )    )annotationsN)cache_from_source)path)	build_extget_abi3_suffix)Distribution)CompileError)	Extension   )environment)DALS)get_config_varZ__pypy__c                   @  s<   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd ZdS )TestBuildExtc                 C  s@   t  }t|}d|jd< |d}tj|d}||ksJ dS )z
        Setuptools needs to give back the same
        result as distutils, even if the fullname
        is not in ext_map.
         zfoo/barZfooN)r   r   ext_mapget_ext_filenameorig)selfdistcmdresZwanted r   ?lib/python3.10/site-packages/setuptools/tests/test_build_ext.pytest_get_ext_filename   s   

z"TestBuildExt.test_get_ext_filenamec                 C  s   t t  tddgdd}tt|gd}t|}|  d|jv s$J |d}t s7|	t
ds5J d
S tjdkrE|	dsCJ d
S d	|v sKJ d
S )z}
        Filename needs to be loadable by several versions
        of Python 3 if 'is_abi3' is truthy on Extension()
        	spam.eggseggs.cTZpy_limited_apiext_modulesZ
EXT_SUFFIXwin32zeggs.pydZabi3N)printr   r	   r   dictr   Zfinalize_optionsr   r   endswithr   sysplatform)r   	extensionr   r   r   r   r   r   test_abi3_filename&   s   


zTestBuildExt.test_abi3_filenamec                 C  s   t  }t|}tddgdd |jd< }d|_ts|d}nd}z"dtjd< |d	}d
|ks2J |d}||ks=J W tjd= dS tjd= w )zd
        SETUPTOOLS_EXT_SUFFIX variable always overrides
        default extension options.
        Zfor_abi3zs.cTr   Fzfor_abi3.test-suffixz.test-suffixSETUPTOOLS_EXT_SUFFIXZnormalznormal.test-suffixN)	r   r   r	   r   Z_links_to_dynamicIS_PYPYr   osenviron)r   r   r   extexpectr   r   r   r   test_ext_suffix_override;   s$   


z%TestBuildExt.test_ext_suffix_overridec                 C  sf   ddddiiidddiid}t dd	g}t d
dg}t ddg}t| td|||gddidS )NZmypkgZsubpkgzext2.cr   ext1zmain.c)srczc-extensionsz
mypkg.ext1zc-extensions/ext1/main.czmypkg.subpkg.ext2zsrc/mypkg/subpkg/ext2.cext3zc-extension/ext3.cz%test%r/   )script_namer   Zpackage_dir)r	   r   buildr   )r   filesr.   Zext2r0   r   r   r   dist_with_example[   s   

zTestBuildExt.dist_with_examplec                 C  s   | dd |dd |  }|d}d|_|  |jtj	d}dd |
 D }|| d	| d
| dgks?J | i ksGJ |d d|_|  dd |  D }|| d	d| d
d| ddikssJ d S )Nr'   .mp3&setuptools.command.build_ext.use_stubsFr   /c                 S  s   g | ]	}| tjd qS r7   replacer)   sep).0xr   r   r   
<listcomp>v   s    z1TestBuildExt.test_get_outputs.<locals>.<listcomp>	/ext3.mp3/mypkg/ext1.mp3/mypkg/subpkg/ext2.mp3Tc                 S  *   i | ]\}}| tjd | tjd qS r8   r9   r<   kvr   r   r   
<dictcomp>       z1TestBuildExt.test_get_outputs.<locals>.<dictcomp>src/ext3.mp3src/mypkg/ext1.mp3src/mypkg/subpkg/ext2.mp3)setenvsetattrr4   get_command_objeditable_modeensure_finalized	build_libr:   r)   r;   Zget_outputsget_output_mappingZreinitialize_commanditems)r   
tmpdir_cwdmonkeypatchr   r   rP   Zoutputsmappingr   r   r   test_get_outputsl   s2   






zTestBuildExt.test_get_outputsc           
      C  sD  | dd |dd |  }|d}d|_|  |jD ]	}||dd q|jt	j
d}dd	 |  D }d
d }||| d|d| dd|| d|d| dd|| d|d| ddikspJ | d|vsyJ | d|vsJ || d}	|	|v sJ |	| dsJ |	dsJ d S )Nr'   r5   r6   Tr   Z_needs_stubr7   c                 S  rB   r8   r9   rC   r   r   r   rF      rG   zBTestBuildExt.test_get_output_mapping_with_stub.<locals>.<dictcomp>c                 S  s   t | tjdS )zDMake it possible to do comparisons and tests in a OS-independent wayr7   )_compiled_file_namer:   r)   r;   )filer   r   r   C   s   z9TestBuildExt.test_get_output_mapping_with_stub.<locals>.Cz/ext3.pyzsrc/ext3.pyr?   rH   z/mypkg/ext1.pyzsrc/mypkg/ext1.pyr@   rI   z/mypkg/subpkg/ext2.pyzsrc/mypkg/subpkg/ext2.pyrA   rJ   z/mypkg/__pycache__/ext1z.pyc)rK   rL   r4   rM   rN   rO   
extensionsrP   r:   r)   r;   rQ   rR   
startswithr"   )
r   rS   rT   r   r   r+   rP   rU   rY   Zexample_stubr   r   r   !test_get_output_mapping_with_stub   s6   







z.TestBuildExt.test_get_output_mapping_with_stubN)	__name__
__module____qualname__r   r&   r-   r4   rV   r\   r   r   r   r   r      s      r   c                   @  s.   e Zd ZdddZdd Zd	d
 Zdd ZdS )TestBuildExtInplaceoptionalboolreturnr   c                 K  sn   di i dd}t | tddg|d}tt|gd}d|_t|}t|jdd	d
d| |	  |S )Nz#include missingheader.h
)libtmp)r   z.buildr   r   )ra   r   setup.pyz
.build/libz
.build/tmp)rP   Z
build_tempr   )
r   r2   r	   r   r!   r1   r   varsupdaterO   )r   ra   Zoptsr3   r%   r   r   r   r   r   get_build_ext_cmd   s   
z%TestBuildExtInplace.get_build_ext_cmdc                 C  s"   |  }|j |j  |j S )z
        Historically, distutils "logged" by printing to sys.std*.
        Later versions adopted the logging framework. Grab
        messages regardless of how they were captured.
        )Z
readouterrout
splitlineserrmessages)r   caplogcapsysZstdr   r   r   get_log_messages   s   z$TestBuildExtInplace.get_log_messagesc                 C  s8   | j ddd}|  tdd | ||D sJ dS )z
        If optional extensions fail to build, setuptools should show the error
        in the logs but not fail to build
        Tra   Zinplacec                 s  s    | ]}d V  qdS )z0build_ext: building extension "spam.eggs" failedNr   )r<   msgr   r   r   	<genexpr>   s
    
z4TestBuildExtInplace.test_optional.<locals>.<genexpr>N)ri   runanyrp   )r   rS   rn   ro   r   r   r   r   test_optional   s
   
z!TestBuildExtInplace.test_optionalc                 C  sF   | j ddd}tt |  W d    d S 1 sw   Y  d S )NFTrq   )ri   pytestZraisesr   rt   )r   rS   r   r   r   r   test_non_optional   s   
"z%TestBuildExtInplace.test_non_optionalN)ra   rb   rc   r   )r]   r^   r_   ri   rp   rv   rx   r   r   r   r   r`      s
    
	r`   c                 C  sZ   t dt dt dd}t| tjdgdd\}\}}|dks+J d	| d
| d S )Nz
            from setuptools import Extension, setup
            setup(
                name='foo',
                version='0.0.0',
                ext_modules=[Extension('foo', ['foo.c'])],
            )
            a  
            #include "Python.h"

            #if PY_MAJOR_VERSION >= 3

            static struct PyModuleDef moduledef = {
                    PyModuleDef_HEAD_INIT,
                    "foo",
                    NULL,
                    0,
                    NULL,
                    NULL,
                    NULL,
                    NULL,
                    NULL
            };

            #define INITERROR return NULL

            PyMODINIT_FUNC PyInit_foo(void)

            #else

            #define INITERROR return

            void initfoo(void)

            #endif
            {
            #if PY_MAJOR_VERSION >= 3
                PyObject *module = PyModule_Create(&moduledef);
            #else
                PyObject *module = Py_InitModule("extension", NULL);
            #endif
                if (module == NULL)
                    INITERROR;
            #if PY_MAJOR_VERSION >= 3
                return module;
            #endif
            }
            zD
            [build]
            build_base = foo_build
            )rf   zfoo.cz	setup.cfgr2   )r      )r   Zdata_streamr   z	
STDOUT:
z	
STDERR:
)r   r   r2   r   Zrun_setup_py)rS   r3   codestdoutstderrr   r   r   test_build_ext_config_handling   s    
+
= r}   )!Z
__future__r   r)   r#   importlib.utilr   rW   rw   Zjaracor   Zsetuptools.command.build_extr   r   Zsetuptools.distr   Zsetuptools.errorsr   Zsetuptools.extensionr	   r   r   textwrapr   Zdistutils.command.build_extZcommandr   Zdistutils.sysconfigr   builtin_module_namesr(   r   r`   r}   r   r   r   r   <module>   s&    
 ,