U
    ui'                     @   s   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kZG dd dZG dd dZdd ZdS )    N)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<t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AssertionError)selfdistcmdreswanted r   C/tmp/pip-unpacked-wheel-9osl9suo/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ksHt|	d}t sl|
tdstn&tjdkr|
dstnd	|kst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_modules
EXT_SUFFIXwin32zeggs.pydabi3N)printr   r   r   dictr   finalize_optionsr   r   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sdt	|d}||kszt	W 5 tjd= X dS )zd
        SETUPTOOLS_EXT_SUFFIX variable always overrides
        default extension options.
        Zfor_abi3zs.cTr   Fzfor_abi3.test-suffixSETUPTOOLS_EXT_SUFFIXz.test-suffixnormalznormal.test-suffixN)
r   r   r   r   Z_links_to_dynamicIS_PYPYr   osenvironr   )r   r   r   extexpectr   r   r   r   test_ext_suffix_override9   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%r4   )script_namer   package_dir)r   r   buildr   )r   filesr3   Zext2r5   r   r   r   dist_with_exampleY   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~t| i kst|d d|_|  dd |  D }|| d	d| d
d| ddikstd S )Nr+   .mp3&setuptools.command.build_ext.use_stubsFr   /c                 S   s   g | ]}| tjd qS r=   replacer.   sep).0xr   r   r   
<listcomp>t   s     z1TestBuildExt.test_get_outputs.<locals>.<listcomp>	/ext3.mp3/mypkg/ext1.mp3/mypkg/subpkg/ext2.mp3Tc                 S   s*   i | ]"\}}| tjd | tjd qS r>   r?   rB   kvr   r   r   
<dictcomp>   s    z1TestBuildExt.test_get_outputs.<locals>.<dictcomp>src/ext3.mp3src/mypkg/ext1.mp3src/mypkg/subpkg/ext2.mp3)setenvsetattrr:   get_command_objeditable_modeensure_finalized	build_libr@   r.   rA   get_outputsr   get_output_mappingreinitialize_commanditems)r   
tmpdir_cwdmonkeypatchr   r   rT   outputsmappingr   r   r   test_get_outputsj   s8    



   zTestBuildExt.test_get_outputsc           
      C   sL  | 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st| d|kst| d|kst|| d}	|	|ks"t|	| ds8t|	dsHtd S )Nr+   r;   r<   Tr   Z_needs_stubr=   c                 S   s*   i | ]"\}}| tjd | tjd qS r>   r?   rH   r   r   r   rK      s    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 wayr=   )_compiled_file_namer@   r.   rA   )filer   r   r   C   s    z9TestBuildExt.test_get_output_mapping_with_stub.<locals>.Cz/ext3.pyzsrc/ext3.pyrE   rL   z/mypkg/ext1.pyzsrc/mypkg/ext1.pyrF   rM   z/mypkg/subpkg/ext2.pyzsrc/mypkg/subpkg/ext2.pyrG   rN   z/mypkg/__pycache__/ext1z.pyc)rO   rP   r:   rQ   rR   rS   
extensionsrT   r@   r.   rA   rV   rX   r   
startswithr&   )
r   rY   rZ   r   r   r0   rT   r\   r`   Zexample_stubr   r   r   !test_get_output_mapping_with_stub   sB    


      

z.TestBuildExt.test_get_output_mapping_with_stubN)	__name__
__module____qualname__r   r*   r2   r:   r]   rc   r   r   r   r   r      s     r   c                   @   s2   e Zd ZedddZdd Zdd Zdd	 Zd
S )TestBuildExtInplaceoptionalc                 K   sn   di i dd}t | tddg|d}tt|gd}d|_t|}t|jf d	d
d| |	  |S )Nz#include missingheader.h
)libtmp)r   z.buildr   r   rh   r   setup.pyz
.build/libz
.build/tmp)rT   
build_temp)
r   r8   r   r   r$   r6   r   varsupdaterS   )r   ri   optsr9   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 s4tdS )z
        If optional extensions fail to build, setuptools should show the error
        in the logs but not fail to build
        Tri   Zinplacec                 s   s   | ]
}d V  qdS )z0build_ext: building extension "spam.eggs" failedNr   )rB   msgr   r   r   	<genexpr>   s   z4TestBuildExtInplace.test_optional.<locals>.<genexpr>N)rq   runanyrx   r   )r   rY   rv   rw   r   r   r   r   test_optional   s
    
z!TestBuildExtInplace.test_optionalc              	   C   s0   | j ddd}tt |  W 5 Q R X d S )NFTry   )rq   pytestZraisesr   r|   )r   rY   r   r   r   r   test_non_optional   s    z%TestBuildExtInplace.test_non_optionalN)rd   re   rf   boolrq   rx   r~   r   r   r   r   r   rg      s   	rg   c                 C   sN   t dt dt dd}t| tjdgdd\}}|dksJt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
            )rl   zfoo.cz	setup.cfgr8   )r      )r   Zdata_streamr   z
STDOUT:
%s
STDERR:
%s)r   r   r8   r
   Zrun_setup_pyr   )rY   r9   codeoutputr   r   r   test_build_ext_config_handling   s     
+=

r   )r.   r'   importlib.utilr   r^   r   Zjaracor   Zsetuptools.command.build_extr   r   Zsetuptools.distr   Zsetuptools.errorsr   Zsetuptools.extensionr   r   r
   textwrapr   Zdistutils.command.build_extcommandr   distutils.sysconfigr   builtin_module_namesr-   r   rg   r   r   r   r   r   <module>   s"   
 ,