U
    ui"X                     @   sX  d dl Z d dlZd dlm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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mZmZ d
dlmZ d dlZ G dd dZ!G dd dZ"G dd dZ#G dd dZ$G dd dZ%G dd dZ&dd Z'dd Z(dd Z)d d! Z*d"d# Z+d$d% Z,d&d' Z-d(d) Z.dS )*    N)ConfigParser)product)cast)Path)sdist)find_package_pathfind_parent_package)Distribution)PackageDiscoveryError   )quiet)get_sdist_membersget_wheel_membersrun)DALSc                   @   s   e Zd Zdd Zdd ZdS )TestFindParentPackagec                 C   sP   |d j ddd |d   |d   dddg}t|d	d
i|dksLtd S )Nzsrc/namespace/pkg/nestedTexist_okparentsz$src/namespace/pkg/nested/__init__.pyzsrc/namespace/pkg/__init__.py	namespaceznamespace.pkgznamespace.pkg.nested srcmkdirtouchr   AssertionError)selftmp_pathpackages r   J/tmp/pip-unpacked-wheel-9osl9suo/setuptools/tests/test_config_discovery.pytest_single_package   s
    
z)TestFindParentPackage.test_single_packagec                 C   s\   dddg}|D ]0}|d|  j ddd |d| d   qt|dd	i|d ksXtd S )
Npkgpkg1pkg2src/Tr   z/__init__.pyr   r   r   )r   r   multiplenamer   r   r    test_multiple_toplevel!   s
    
z,TestFindParentPackage.test_multiple_toplevelN)__name__
__module____qualname__r!   r(   r   r   r   r    r      s   r   c                   @   s  e Zd ZdZddidgddddiiddgid	dgidd
dgii i i i d	ZddgddgddgdgdgdZdd Zej	de
 dd Zej	de
 dd Zedededed d!Zej	d"ed#d$d%gdd	ge
 d&d' Zej	d(d)gdhfd*gdd+hfd,gdd-hfd.gdd/d0hfd1gdd/hfd2gdhfd3gdhfgd4d5 Zej	d6d7gd8ggd9d: Zd;d< Zd=d> Zd?d@ ZdAS )B TestDiscoverPackagesAndPyModuleszMake sure discovered values for ``packages`` and ``py_modules`` work
    similarly to explicit configuration for the simple scenarios.
    r   r   r"   )package_dirr   r-   libr   
py_modulesnszns.pkg)	zexplicit-srczvariation-libzexplicit-flatzexplicit-single_modulezexplicit-namespacezautomatic-srczautomatic-flatzautomatic-single_modulezautomatic-namespacesrc/pkg/__init__.pyzsrc/pkg/main.pyzlib/pkg/__init__.pyzlib/pkg/main.pyzpkg/__init__.pyzpkg/main.pypkg.pyzns/pkg/__init__.py)r   r.   flatsingle_moduler   c                 C   s,   | d\}}}| j| }| j| }||fS )N-)	partitionFILESOPTIONS)r   circumstance_Zlayoutfilesoptionsr   r   r    	_get_infoF   s    

z*TestDiscoverPackagesAndPyModules._get_infor9   c                    sb   |  |\}}t||| t||\}}dd |jjD }|D ] t fdd|D s>tq>d S )Nc                 S   s   g | ]}| tjd qS )/)replaceossep.0fr   r   r    
<listcomp>S   s     zHTestDiscoverPackagesAndPyModules.test_sdist_filelist.<locals>.<listcomp>c                 3   s   | ]}|  V  qd S N)endswithrB   filer   r    	<genexpr>U   s     zGTestDiscoverPackagesAndPyModules.test_sdist_filelist.<locals>.<genexpr>)r=   _populate_project_dir_run_sdist_programaticallyfilelistr;   anyr   )r   r   r9   r;   r<   r:   cmdmanifestr   rH   r    test_sdist_filelistL   s    z4TestDiscoverPackagesAndPyModules.test_sdist_filelistc           	      C   s(  |  |\}}t||| |d   |d   |d   |d   |d   |d   |d   |d   t| tt|d	}td
 td	| |t
|ksttt|d}td td	| dd |D }||kst|D ]"}d|kstd|ks tq d S )Nbuildz	build/libzbuild/bdist.linux-x86_64z build/bdist.linux-x86_64/file.pyzbuild/lib/__init__.pyzbuild/lib/file.pydistzdist/file.pydist/*.tar.gz~~~~~ sdist_members ~~~~~

dist/*.whl~~~~~ wheel_members ~~~~~c                 S   s    h | ]}| d d ddqS r%   r   zlib/r?   rB   r   r   r    	<setcomp>p   s     z@TestDiscoverPackagesAndPyModules.test_project.<locals>.<setcomp>)r=   rK   r   r   
_run_buildr   nextglobprintjoinsetr   r   )	r   r   r9   r;   r<   sdist_fileswheel_files
orig_filesrI   r   r   r    test_projectW   s.    z-TestDiscoverPackagesAndPyModules.test_projectz
            [metadata]
            name = myproj
            version = 0.0.0

            [options]
            {param} =
            z
            __import__('setuptools').setup(
                name="myproj",
                version="0.0.0",
                {param}=[]
            )
            z
            [build-system]
            requires = []
            build-backend = 'setuptools.build_meta'

            [project]
            name = "myproj"
            version = "0.0.0"

            [tool.setuptools]
            {param} = []
            zv
            [build-system]
            requires = []
            build-backend = 'setuptools.build_meta'
            )	setup.cfgsetup.pypyproject.tomltemplate-pyproject.tomlz config_file, param, circumstancerf   rg   rh   c                 C   s   | j | dddg }t||i  |dkr6|dd}n | jd }|d j|dd	 |}| j| j|d
}|| j|dd	 t|i }	t|	|g kstddd| }
t|	|
d kstd S )Nzmod.pyzother.pyr1   rh   r:   r5   ri   utf-8encoding)paramr   r/   )r/   r   )	r7   rK   r?   PURPOSEFULLY_EMPY
write_textformat	_get_distgetattrr   )r   r   config_filerm   r9   r;   Ztemplate_param	pyprojectconfigrS   otherr   r   r    test_purposefully_empty   s    	

z8TestDiscoverPackagesAndPyModules.test_purposefully_emptyzextra_files, pkgszvenv/bin/simulate_venvzpkg-stubs/__init__.pyiz	pkg-stubszother-stubs/__init__.pyizother-stubsz namespace-stubs/pkg/__init__.pyiznamespace-stubsznamespace-stubs.pkgz&namespace-stubs/pkg-stubs/__init__.pyiz_hidden/file.pyznews/finalize.pyc                 C   s:   | j d | }t||i  t|i }t|j|ks6td S )Nr3   )r7   rK   rq   ra   r   r   )r   r   extra_filespkgsr;   rS   r   r   r    !test_flat_layout_with_extra_files   s    
zBTestDiscoverPackagesAndPyModules.test_flat_layout_with_extra_filesrx   zother/__init__.pyzother/finalize.pyc              	   C   sB   | j d | }t||i  tjtdd t|i  W 5 Q R X d S )Nr3   multiple (packages|modules)matchr7   rK   pytestraisesr
   rq   )r   r   rx   r;   r   r   r    +test_flat_layout_with_dangerous_extra_files   s    zLTestDiscoverPackagesAndPyModules.test_flat_layout_with_dangerous_extra_filesc                 C   s>   | j d dg }t||i  t|i }t|jdhks:td S )Nr4   zinvalid-module-name.pyr"   )r7   rK   rq   ra   r/   r   )r   r   r;   rS   r   r   r    #test_flat_layout_with_single_module   s    
zDTestDiscoverPackagesAndPyModules.test_flat_layout_with_single_modulec              	   C   sD   | j d dg }t||i  tjtdd t|i  W 5 Q R X d S )Nr4   zvalid_module_name.pyr{   r|   r~   )r   r   r;   r   r   r    &test_flat_layout_with_multiple_modules   s    zGTestDiscoverPackagesAndPyModules.test_flat_layout_with_multiple_modulesc              	   C   sz   ddl m} d}|d jt|dd |d   tj | |	d W 5 Q R X t
t|d	}d|ksvtd
S )zRegression for issue 3692r   )
build_metaz%[project]
name = "test"
version = "1"rh   rj   rk   zfoo.py.z*.whlN)
setuptoolsr   ro   r   r   jaracopathZDirectoryStackcontextbuild_wheelr   r]   r^   r   )r   r   r   rt   rc   r   r   r    %test_py_modules_when_wheel_dir_is_cwd   s    zFTestDiscoverPackagesAndPyModules.test_py_modules_when_wheel_dir_is_cwdN)r)   r*   r+   __doc__r8   r7   r=   r   markparametrizekeysrQ   re   r   rn   r   rw   rz   r   r   r   r   r   r   r   r    r,   +   s    



!
	+





r,   c                   @   sT   e Zd ZdZdgdgddgddgdgd	gd
Zejde dd Z	dd Z
dS )TestNoConfigz0.0.0zsrc/pkg1.pyzsrc/pkg2/__init__.pyzsrc/pkg3/__init__.pyzsrc/pkg3-stubs/__init__.pyzpkg4/__init__.pyzpkg4-stubs/__init__.pyzsrc/ns/nested/pkg1/__init__.pyzns/nested/pkg2/__init__.py)r#   r$   Zpkg3Zpkg4zns.nested.pkg1zns.nested.pkg2examplec                 C   s0   t || j| i  t|i }| |ks,td S rF   )rK   EXAMPLESrq   get_namer   )r   r   r   rS   r   r   r    test_discover_name  s    
zTestNoConfig.test_discover_namec                 C   s>   dg}t ||i  t|d |d| j d }| s:td S )Nzsrc/ns/nested/pkg/__init__.py--sdistzdist/ns_nested_pkg-z.tar.gz)rK   r\   DEFAULT_VERSIONis_filer   )r   r   r;   	dist_filer   r   r    test_build_with_discovered_name  s
    
z,TestNoConfig.test_build_with_discovered_nameN)r)   r*   r+   r   r   r   r   r   r   r   r   r   r   r   r    r     s   	
r   c                   @   s@   e Zd Zejddi fddddidfgdd Zd	d
 ZdS )TestWithAttrDirectivezfolder, optsr   r.   zfind:where)r   packages.findc           
      C   s   | ddg}t ||| |d jdd}|dddiidd| i}tjj||d	 t|i }| dkslt| d
ks|t|j	stt
d|j	|}tj|st|t| kstt|d |d }	|	 std S )Nz/pkg/__init__.pyrf   rj   rk   r"   __init__.pyversion = 42z'[metadata]
version = attr: pkg.version
prefix42r   zdist/pkg-42.tar.gz)rK   	read_textr   r   rR   rq   r   r   get_versionr-   r   r@   existsr   partsr\   r   )
r   r   folderoptsr;   ru   	overwriterS   package_pathr   r   r   r    test_setupcfg_metadata  s&     
 


z,TestWithAttrDirective.test_setupcfg_metadatac                 C   s`   t |dgi  dddiidd}tjj||d t|i }| dksJt|jd	d
iks\td S )Nr1   r"   r   r   zh[project]
name = 'pkg'
dynamic = ['version']
[tool.setuptools.dynamic]
version = {attr = 'pkg.version'}
r   rh   r   r   r   r   )rK   r   r   rR   rq   r   r   r-   )r   r   r   rS   r   r   r    test_pyproject_metadata<  s    

z-TestWithAttrDirective.test_pyproject_metadataN)r)   r*   r+   r   r   r   r   r   r   r   r   r    r     s   
r   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )TestWithCExtensionc                 C   sF   ddddddddd	d
ddg}t ||i  d}|d jt|dd d S )Nzbenchmarks/file.pyzdocs/Makefilezdocs/requirements.txtzdocs/source/conf.pyzproj/header.hzproj/file.pyzpy/proj.cppzpy/other.cppz
py/file.pyzpy/py.typedzpy/tests/test_proj.pyz
README.rsta^  
            from setuptools import Extension, setup

            ext_modules = [
                Extension(
                    "proj",
                    ["py/proj.cpp", "py/other.cpp"],
                    include_dirs=["."],
                    language="c++",
                ),
            ]
            setup(ext_modules=ext_modules)
        rg   rj   rk   rK   ro   r   )r   r   r;   Zsetup_scriptr   r   r     _simulate_package_with_extensionN  s     z3TestWithCExtension._simulate_package_with_extensionc                 C   s   |  | d}|d jt|dd d}|d jt|dd t|i }| dksXt| dksht|jd	ksvt|jd	kstt	|j
d
kst|j
d jdkstd	S )zEnsure that auto-discovery is not triggered when the project is based on
        C-extensions only, for backward compatibility.
        zr
            [build-system]
            requires = []
            build-backend = 'setuptools.build_meta'
        rh   rj   rk   zQ
            [metadata]
            name = proj
            version = 42
        rf   Zprojr   Nr   r   )r   ro   r   rq   r   r   r   r/   r   lenext_modulesr'   )r   r   rt   setupcfgrS   r   r   r    *test_skip_discovery_with_setupcfg_metadatao  s    

z=TestWithCExtension.test_skip_discovery_with_setupcfg_metadatac              	   C   sL   |  | d}|d jt|dd tjtdd t|i  W 5 Q R X dS )a  When opting-in to pyproject.toml metadata, auto-discovery will be active if
        the package lists C-extensions, but does not configure py-modules or packages.

        This way we ensure users with complex package layouts that would lead to the
        discovery of multiple top-level modules/packages see errors and are forced to
        explicitly set ``packages`` or ``py-modules``.
        zT
            [project]
            name = 'proj'
            version = '42'
        rh   rj   rk   r{   r|   N)r   ro   r   r   r   r
   rq   )r   r   rt   r   r   r    0test_dont_skip_discovery_with_pyproject_metadata  s
    
zCTestWithCExtension.test_dont_skip_discovery_with_pyproject_metadataN)r)   r*   r+   r   r   r   r   r   r   r    r   M  s   !r   c                   @   s   e Zd Zdd ZdZdZdZej	ddde
eifdd	e
eifd
de
eifd
d	e
eifd
de
ee
d ifd
d	e
ee
d ifgdd ZdS )TestWithPackageDatac                 C   sF   | d| d| dg}t ||i  d}|d jt|dd d S )Nz/proj/__init__.py/proj/file1.txt/proj/nested/file2.txtz/
            global-include *.py *.txt
        zMANIFEST.inrj   rk   r   )r   r   src_rootr;   rP   r   r   r    !_simulate_package_with_data_files  s    z5TestWithPackageData._simulate_package_with_data_fileszd
    [metadata]
    name = proj
    version = 42

    [options]
    include_package_data = True
    z8
    [project]
    name = "proj"
    version = "42"
    z:
    [tool.setuptools]
    package-dir = {"" = "src"}
    zsrc_root, filesr   rf   rh   r   z
                        packages = find:
                        package_dir =
                            =src

                        [options.packages.find]
                        where = src
                        zv
                        [tool.setuptools]
                        package-dir = {"" = "src"}
                        c                 C   s   t jj|t|d | || tj| dtjdtj| dtjdh}t	| t
t|d}td td| ||ksttt|d}td	 td| d
d |D }||kstdS )zq
        Make sure auto-discovery does not affect package include_package_data.
        See issue #3196.
        r   r   r>   r   rT   rU   rV   rW   rX   c                 S   s    h | ]}| d d ddqS rY   rZ   rB   r   r   r    r[     s     z@TestWithPackageData.test_include_package_data.<locals>.<setcomp>N)r   r   rR   strr   r@   normpathr?   rA   r\   r   r]   r^   r_   r`   r   r   )r   r   r   r;   expectedrb   rc   rd   r   r   r    test_include_package_data  s    *z-TestWithPackageData.test_include_package_dataN)r)   r*   r+   r   ZEXAMPLE_SETUPCFGZEXAMPLE_PYPROJECTZPYPROJECT_PACKAGE_DIRr   r   r   r   r   r   r   r   r    r     s>     %r   c                 C   sN   dddg}t | |i  ti }t |_|  |jd ks<t|jd ksJtd S )Nzdir1/__init__.pyzdir2/__init__.pyzfile.py)rK   r	   objectconfigurationset_defaultsr/   r   r   )r   r;   rS   r   r   r    (test_compatible_with_numpy_configuration   s    r   c                 C   sD   t jddi ti }dg|_|  |  | dks@td S )Nr2   r   z--namer"   )	r   r   rR   r	   script_argsr   parse_command_liner   r   )
tmpdir_cwdrS   r   r   r    $test_name_discovery_doesnt_break_cli  s    r   c                    s   dddiit dd}tj| ti   jj fdd}| jd|     	 d	ksht
t jdhks|t
d
S )a
  According to #3545 it seems that ``name`` discovery is running,
    even when the project already explicitly sets it.
    This seems to be related to parsing of dynamic versions (via ``attr`` directive),
    which requires the auto-discovery of ``package_dir``.
    r"   r   z__version__ = 42
z
            [project]
            name = "myproj"  # purposefully different from package name
            dynamic = ["version"]
            [tool.setuptools.dynamic]
            version = {"attr" = "pkg.__version__"}
            r   c                      s        dkstd S )NZmyproj)r   r   r   rS   Zorig_analyse_namer   r    spy_analyse_name/  s    zJtest_preserve_explicit_name_with_dynamic_version.<locals>.spy_analyse_nameanalyse_namer   N)r   r   r   rR   r	   r   r   setattrparse_config_filesr   r   ra   r   )r   Zmonkeypatchr;   r   r   r   r    0test_preserve_explicit_name_with_dynamic_version  s     r   c                    s^   dddd}t jj| d t |  fdd|D }|D ]}|jjddd	 |  q<d S )
Nz$import setuptools
setuptools.setup()z# Example PackagezCopyright (c) 2018)rg   z	README.mdLICENSEr   c                 3   s   | ]} | V  qd S rF   r   rB   rootr   r    rJ   F  s     z(_populate_project_dir.<locals>.<genexpr>Tr   )r   r   rR   _write_setupcfgparentr   r   )r   r;   r<   basicpathsr   r   r   r    rK   ;  s    
rK   c              	   C   s
  |st d d S t }|d | D ]\}}|dkr^|d|  |d|  | q(t|tr|d||d |< q(t|trddd | D }d| |d |< q(t	||d |< q(t
| d	 d
dd}|| W 5 Q R X t d t | d	 jdd d S )Nz~~~~~ **NO** setup.cfg ~~~~~r<   r   zoptions.z, rV   c                 s   s"   | ]\}}d | d| V  qdS )	z = Nr   )rC   kvr   r   r    rJ   Y  s     z"_write_setupcfg.<locals>.<genexpr>rf   wrj   rk   z~~~~~ setup.cfg ~~~~~)r_   r   add_sectionitemsupdate
isinstancelistr`   dictr   openwriter   )r   r<   r   keyvalueZ	str_valuerD   r   r   r    r   L  s&    


r   c                 G   s*   t jdddf|t| f}t|ddidS )Nz-mrR   z--no-isolationZDISTUTILS_DEBUGr   )env)sys
executabler   r   )r   flagsrO   r   r   r    r\   c  s    r\   c              	   C   s   d tj| }| d }| rPt|  tttj	j
di dd}W 5 Q R X nt|}||_d|_t|  |  W 5 Q R X |  |S )Nr>   rg   init)
stop_after)r`   r@   r   splitr   r   r   r	   	distutilscore	run_setupr   script_namer   r   )	dist_pathattrsr   scriptrS   r   r   r    rq   h  s    

rq   c              
   C   sd   t | |}t|}|  |jjs.|jjs.tt " t|  |	  W 5 Q R X W 5 Q R X ||fS rF   )
rq   r   ensure_finalizeddistributionr   r/   r   r   r   r   )r   r   rS   rO   r   r   r    rL   ~  s    
rL   )/r@   r   configparserr   	itertoolsr   typingr   Zjaraco.pathr   r   r   r   r   Zsetuptools.command.sdistr   Zsetuptools.discoveryr   r   Zsetuptools.distr	   Zsetuptools.errorsr
   Zcontextsr   Zintegration.helpersr   r   r   textwrapr   distutils.corer   r   r,   r   r   r   r   r   r   r   rK   r   r\   rq   rL   r   r   r   r    <module>   s>    X0Ra	$