U
    ui:K                     @  s  d Z ddlm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 ddlZddlmZ ddlmZ ddlZdd	lmZ dd
lmZmZmZ ddlmZmZ ddlmZ ddlmZ ddlm Z m!Z! e	e"j#Z$dZ%dd Z&ej'(de!e$e% ej')dej'j*dd Z+dZ,dZ-dZ.de,fddZ/dd Z0ej'(dd d!d"gd#d$ Z1d%d& Z2d'd( Z3ej'(d)ej4e,d*d+d,ej4e-d-ej'j5d.d/d0d1d2fd3d4 Z6G d5d6 d6Z7G d7d8 d8Z8G d9d: d:Z9G d;d< d<Z:G d=d> d>Z;G d?d@ d@Z<G dAdB dBZ=dCdDdEdFZ>dS )GzMake sure that applying the configuration from pyproject.toml is equivalent to
applying a similar configuration from setup.cfg

To run these tests offline, please have a look on ``./downloads/preload.py``
    )annotationsN)cleandoc)Path)Mock)LiteTranslator)Metadata)write_requirements)expandpyprojecttomlsetupcfg)_MissingDynamic_some_attrgetterDistribution)RemovedConfigError   )retrieve_fileurls_from_filezsetupcfg_examples.txtc                 K  s   t d| i|S )NZsrc_rootr   )pathattrs r   T/tmp/pip-unpacked-wheel-9osl9suo/setuptools/tests/config/test_apply_pyprojecttoml.pymakedist!   s    r   urlignorec                 C  s  | tdtdd t| }t|d}|jdd}t |d}|j|dd t	
t||}t
t||}t|}	t|}
|	|
ksttdd	 ||fD rt|jt|jksttd
d	 ||fD rt|j dd |j D }dd |j D }||ksttdd	 ||fD r^dd |j D }dd |j D }||ks^ttdd	 ||fD rdd |jD }dd |jD }||kstt|jt|jksttdd	 ||fD rdd |j D }dd |j D }||kstd S )NZ	read_attrz0.0.1)Zreturn_valuepyproject.tomlutf-8encodingz	setup.cfgc                 s  s   | ]}t |d dV  qdS )license_filesNgetattr.0dr   r   r   	<genexpr>7   s     z>test_apply_pyproject_equivalent_to_setupcfg.<locals>.<genexpr>c                 s  s   | ]}t |d dV  qdS )entry_pointsNr    r"   r   r   r   r%   :   s     c                 S  s(   h | ] \}}|ft d d |D qS )c                 s  s   | ]}| d dV  qdS   Nreplacer#   ir   r   r   r%   =   s     Htest_apply_pyproject_equivalent_to_setupcfg.<locals>.<setcomp>.<genexpr>sortedr#   kvr   r   r   	<setcomp><   s   z>test_apply_pyproject_equivalent_to_setupcfg.<locals>.<setcomp>c                 S  s(   h | ] \}}|ft d d |D qS )c                 s  s   | ]}| d dV  qdS r'   r*   r,   r   r   r   r%   A   s     r.   r/   r1   r   r   r   r4   @   s   c                 s  s   | ]}t |d dV  qdS )package_dataNr    r"   r   r   r   r%   F   s     c                 S  s   h | ]\}}|ft |qS r   r/   r1   r   r   r   r4   G   s     c                 S  s   h | ]\}}|ft |qS r   r/   r1   r   r   r   r4   H   s     c                 s  s   | ]}t |d dV  qdS )
data_filesNr    r"   r   r   r   r%   K   s     c                 S  s   h | ]\}}|ft |qS r   r/   r1   r   r   r   r4   L   s     c                 S  s   h | ]\}}|ft |qS r   r/   r1   r   r   r   r4   M   s     c                 s  s   | ]}t |d dV  qdS )extras_requireNr    r"   r   r   r   r%   Q   s     c                 S  s   h | ]\}}|ft |qS r   r/   r1   r   r   r   r4   R   s     c                 S  s   h | ]\}}|ft |qS r   r/   r1   r   r   r   r4   S   s     )setattrr	   r   r   r   	read_textr   	translate
write_textr
   apply_configurationr   r   core_metadataAssertionErroranysetr   printr&   itemsr5   r6   install_requiresr7   )r   monkeypatchtmp_pathZsetupcfg_exampleZpyproject_exampleZsetupcfg_texttoml_configZ	dist_tomlZdist_cfgZpkg_info_tomlZpkg_info_cfgZep_tomlZep_cfgZpkg_data_tomlZpkg_data_cfgZdata_files_tomlZdata_files_cfgZextra_req_tomlZextra_req_cfgr   r   r   +test_apply_pyproject_equivalent_to_setupcfg%   sF    

rG   u  [project]
name = "spam"
version = "2020.0.0"
description = "Lovely Spam! Wonderful Spam!"
readme = "README.rst"
requires-python = ">=3.8"
license = {file = "LICENSE.txt"}
keywords = ["egg", "bacon", "sausage", "tomatoes", "Lobster Thermidor"]
authors = [
  {email = "hi@pradyunsg.me"},
  {name = "Tzu-Ping Chung"}
]
maintainers = [
  {name = "Brett Cannon", email = "brett@python.org"},
  {name = "John X. Ãørçeč", email = "john@utf8.org"},
  {name = "Γαμα קּ 東", email = "gama@utf8.org"},
]
classifiers = [
  "Development Status :: 4 - Beta",
  "Programming Language :: Python"
]

dependencies = [
  "httpx",
  "gidgethub[httpx]>4.0.0",
  "django>2.1; os_name != 'nt'",
  "django>2.0; os_name == 'nt'"
]

[project.optional-dependencies]
test = [
  "pytest < 5.0.0",
  "pytest-cov[all]"
]

[project.urls]
homepage = "http://example.com"
documentation = "http://readthedocs.org"
repository = "http://github.com"
changelog = "http://github.com/me/spam/blob/master/CHANGELOG.md"

[project.scripts]
spam-cli = "spam:main_cli"

[project.gui-scripts]
spam-gui = "spam:main_gui"

[project.entry-points."spam.magical"]
tomatoes = "spam:main_tomatoes"
u   [project]
name = "spam"
version = "2020.0.0"
authors = [
  {email = "hi@pradyunsg.me"},
  {name = "Tzu-Ping Chung"}
]
maintainers = [
  {name = "Степан Бандера", email = "криївка@оун-упа.укр"},
]
zE
def main_cli(): pass
def main_gui(): pass
def main_tomatoes(): pass
z
README.rstc                 C  s   | d }|}dd| di}|  D ]\}}|||}q$|j|dd | | jddd | d jd	dd | d
 jtdd |S )Nr   zreadme = "README.rst"z
readme = ""r   r   zhello worldLICENSE.txt--- LICENSE stub ---zspam.py)rB   r+   r;   PEP621_EXAMPLE_SCRIPT)rE   readmepyproject_text	pyprojecttextreplacementsorigZsubstr   r   r   _pep621_example_project   s    rR   c                 C  sB   t | }tt| |}|jjdks(tt|jjdhks>tdS )z&Make sure the example in PEP 621 worksrJ   rI   N)	rR   r
   r<   r   metadatalicenser>   r@   r   rE   rN   distr   r   r   test_pep621_example   s    rW   zreadme, ctype)z
Readme.txtz
text/plain)z	readme.mdztext/markdown)ztext.rstz
text/x-rstc                 C  s.   t | |}tt| |}|jj|ks*td S NrR   r
   r<   r   rS   Zlong_description_content_typer>   )rE   rL   ctyperN   rV   r   r   r   test_readme_content_type   s    	
r[   c              	   C  s8   t | d}tjtdd tt| | W 5 Q R X d S )Nz
README.texz%Undefined content type for README.texmatch)rR   pytestraises
ValueErrorr
   r<   r   )rE   rN   r   r   r   test_undefined_content_type   s    
ra   c                 C  s.   t | d}tt| |}|jjd ks*td S )NREADMErY   rU   r   r   r   3test_no_explicit_content_type_for_missing_extension   s    
rc   )rM   expected_maintainers_meta_valueug   Brett Cannon <brett@python.org>, "John X. Ãørçeč" <john@utf8.org>, Γαμα קּ 東 <gama@utf8.org>znon-international-emails)iduA   Степан Бандера <криївка@оун-упа.укр>zlCPython's `email.headerregistry.Address` only supports RFC 5322, as of Nov 10, 2022 and latest Python 3.11.0T)reasonstrictzinternational-email)marksre   c              	   C  s~   t |d|d}tt||}|jj| ks.t|d }t|ddd}|j| W 5 Q R X |j	dd}d|  |ksztd S )Nrb   )rM   zPKG-FILEwr   r   zMaintainer-email: )
rR   r
   r<   r   rS   maintainer_emailr>   openwrite_pkg_filer9   )rd   rM   rE   rN   rV   Zpkg_filefhcontentr   r   r    test_utf8_maintainer_in_metadata   s    ro   c                   @  s$   e Zd Zdd Zdd Zdd ZdS )TestLicenseFilesc                 C  sP   t |d}|jdd}d|ks"td|ks.t| d| d}|j|dd |S )Nrb   r   r   z license = {file = "LICENSE.txt"}z[tool.setuptools]
)rR   r9   r>   r;   )selfrE   Zadditional_textrN   rO   r   r   r   base_pyproject  s    
zTestLicenseFiles.base_pyprojectc                 C  sz   d}|  ||}|d   |d   |d }|jddd tt||}t|jjddhksft	|jj
dksvt	d S )Nz,[tool.setuptools]
license-files = ["_FILE*"]z	_FILE.txtz	_FILE.rstrI   zLicenseRef-Proprietary
r   r   )rs   touchr;   r
   r<   r   r@   rS   r   r>   rT   )rr   rE   setuptools_configrN   rT   rV   r   r   r   +test_both_license_and_license_files_defined  s    z<TestLicenseFiles.test_both_license_and_license_files_definedc                 C  sx   d}|  ||}d }|D ]}|| j| ddd qtt||}|d  sZtt|j	j
|dhksttd S )Nz"[tool.setuptools]
zip-safe = falsez5LICENCE-a.html COPYING-abc.txt AUTHORS-xyz NOTICE,defrq   r   r   rI   )rs   splitr;   r
   r<   r   existsr>   r@   rS   r   )rr   rE   ru   rN   r   fnamerV   r   r   r   test_default_patterns  s    z&TestLicenseFiles.test_default_patternsN)__name__
__module____qualname__rs   rv   rz   r   r   r   r   rp      s   rp   c                   @  sJ   e Zd Zdd Zejdddgdd Zejddd	d
gdd ZdS )TestPyModulesc                 C  s6   d|d}t d}|jt|dd tti |S )Nzr
        [project]
        name = "test"
        version = "42.0"
        [tool.setuptools]
        py-modules = [z
]
        r   r   r   )r   r;   r   r
   r<   r   )rr   namerF   rN   r   r   r   rV   /  s    zTestPyModules.distmodulezpip-runu   abc-d.λ-xyz-ec                 C  s"   | | || |jkstd S rX   )chdirrV   
py_modulesr>   rr   rE   rD   r   r   r   r   test_valid_module_name;  s    
z$TestPyModules.test_valid_module_namezpip runz-pip-runzpip-run-stubsc              	   C  s4   | | tjtdd | |j W 5 Q R X d S )Nz
py-modulesr\   )r   r^   r_   r`   rV   r   r   r   r   r   test_invalid_module_name@  s    
z&TestPyModules.test_invalid_module_nameN)	r{   r|   r}   rV   r^   markparametrizer   r   r   r   r   r   r~   ,  s
   
r~   c                   @  s   e Zd Zdd ZdS )TestExtModulesc              	   C  s   | | td}d}|jt|dd ttj tt	i |}W 5 Q R X t
|jdksbt|jd jdksvtt|jd jdd	hkstd S )
Nr   z
        [project]
        name = "test"
        version = "42.0"
        [tool.setuptools]
        ext-modules = [
          {name = "my.ext", sources = ["hello.c", "world.c"]}
        ]
        r   r   r   r   zmy.extzhello.czworld.c)r   r   r;   r   r^   warnsr
   Z_ExperimentalConfigurationr<   r   lenext_modulesr>   r   r@   sources)rr   rE   rD   rN   rF   rV   r   r   r   test_pyproject_sets_attributeH  s    
	z,TestExtModules.test_pyproject_sets_attributeN)r{   r|   r}   r   r   r   r   r   r   G  s   r   c                   @  s   e Zd Zdd ZdS )TestDeprecatedFieldsc              	   C  sL   |d }d}|j t|dd tjtdd tt|| W 5 Q R X d S )Nr   z
        [project]
        name = "myproj"
        version = "42"
        [tool.setuptools]
        namespace-packages = ["myproj.pkg"]
        r   r   znamespace-packagesr\   )r;   r   r^   r_   r   r
   r<   r   )rr   rE   rN   configr   r   r   test_namespace_packages]  s
    z,TestDeprecatedFields.test_namespace_packagesN)r{   r|   r}   r   r   r   r   r   r   \  s   r   c                   @  s   e Zd Zd$ddZejddddgfddd	d
gifddddgifejdddgfdejdgigdd Z	ejdddg fddi fdddgfdddgfgdd Z
dd Zdd Zejdddgejd d!d" Zd#S )%TestPresetFieldr)   c                 C  s:   d|d}d|kr|d7 }|d }|j || dd |S )Nz"[project]
name = 'proj'
dynamic = rq   versionzversion = '42'
r   r   r   )r;   )rr   rE   ZdynamicZextra_contentrn   filer   r   r   rN   l  s    zTestPresetField.pyprojectzattr, field, valueclassifierszPrivate :: Classifierr&   scriptsconsole_scriptsfoobar=foobar:maingui-scriptsgui_scriptszbazquux=bazquux:mainrC   dependenciessixrh   z&ignore:.*install_requires. overwrittenc           	   	   C  sv   |  |g }t|f||i}td| tj}tjt|d t	||}W 5 Q R X t
d| ||}|rrtdS )z:Setuptools cannot set a field if not listed in ``dynamic``z&defined outside of `pyproject.toml`:.*r\   	metadata.N)rN   r   recompileSr^   r   r   r
   r<   r   r>   )	rr   rE   attrfieldvaluerN   rV   msg
dist_valuer   r   r   test_not_listed_in_dynamict  s    z*TestPresetField.test_not_listed_in_dynamicr7   zoptional-dependenciesc                 C  sN   |  ||g}t|f||i}t||}td| ||}||ksJtd S )Nr   )rN   r   r
   r<   r   r>   )rr   rE   r   r   r   rN   rV   r   r   r   r   test_listed_in_dynamic  s
    
z&TestPresetField.test_listed_in_dynamicc              	   C  s^   d}|d }|j |dd t|dgd}tjdd t||}W 5 Q R X d|jksZtd S )	Nz:[project]
name='pkg'
version='0.1'
dependencies=['click']
r   r   r   wheelrC   z`install_requires` overwrittenr\   )r;   r   r^   r   r
   r<   rC   r>   )rr   rE   srcrN   rV   r   r   r   %test_warning_overwritten_dependencies  s    z5TestPresetField.test_warning_overwritten_dependenciesc                 C  s   d}|  |dg|}dg}t||d}t||}d|jks@t|d}t|||d  |d jdd	}d
|ksvtd|kstd|kstdS )a#  
        Internally setuptools converts dependencies with markers to "extras".
        If ``install_requires`` is given by ``setup.py``, we have to ensure that
        applying ``optional-dependencies`` does not overwrite the mandatory
        dependencies with markers (see #3204).
        z1
[project.optional-dependencies]
foo = ['bar>1']
r   z6importlib-resources (>=3.0.0) ; python_version < "3.7"r   Zfooegg_infozrequires.txtr   r   zimportlib-resourcesbarz:python_version < "3.7"N)	rN   r   r
   r<   r7   r>   get_command_objr   r9   )rr   rE   extrarN   install_reqrV   r   reqsr   r   r   2test_optional_dependencies_dont_remove_env_markers  s    	
zBTestPresetField.test_optional_dependencies_dont_remove_env_markerszfield,group)r   r   )r   r   errorc                 C  s>   |  ||g}t||dgid}t||}||jks:td S )Nr   )r&   )rN   r   r
   r<   r&   r>   )rr   rE   r   grouprN   rV   r   r   r   .test_scripts_dont_require_dynamic_entry_points  s    z>TestPresetField.test_scripts_dont_require_dynamic_entry_pointsN)r)   )r{   r|   r}   rN   r^   r   r   paramfilterwarningsr   r   r   r   r   r   r   r   r   r   k  s@   






	
	 
r   c                   @  s   e Zd Zdd ZdS )TestMetac              	   C  s4   t | }tdd | D s&tW 5 Q R X dS )z,Meta test to ensure tests can run from sdistc                 s  s   | ]}| tV  qd S rX   )endswithEXAMPLES_FILE)r#   r   r   r   r   r%     s     z6TestMeta.test_example_file_in_sdist.<locals>.<genexpr>N)tarfilerk   r?   getnamesr>   )rr   Zsetuptools_sdisttarr   r   r   test_example_file_in_sdist  s    z#TestMeta.test_example_file_in_sdistN)r{   r|   r}   r   r   r   r   r   r     s   r   c                   @  s   e Zd Zdd ZdS )TestInteropCommandLineParsingc           	      C  sf   | | d}t|d}|jt|dd ddgi}tt||}|  | }d|j	ksbt
d S )NzJ
        [project]
        name = "test"
        version = "42.0"
        r   r   r   script_argsz	--versionz42.0)r   r   r;   r   r
   r<   r   parse_command_lineZ
readouterroutr>   )	rr   rE   rD   ZcapsysrF   rN   optsrV   Zcapturedr   r   r   test_version  s    


z*TestInteropCommandLineParsing.test_versionN)r{   r|   r}   r   r   r   r   r   r     s   r   str)returnc              	   C  s   t  }| j| | }W 5 Q R X tj|dd d}t }|d7 }|d7 }|d7 }|d g }|	 D ]&}|
|sn||krqn||d  qnd|S )	NT)validater   )zAuthor:zAuthor-email:zMaintainer:zMaintainer-email:)zProject-URL: Homepage,z
Home-page:)zDescription-Content-Type:r)   rq   )ioStringIOrS   rl   getvaluer   Z
from_emailr@   add
splitlines
startswithappendjoin)rV   bufferZpkg_file_txtZskip_prefixes
skip_linesresultliner   r   r   r=     s     

r=   )?__doc__
__future__r   r   r   r   inspectr   pathlibr   Zunittest.mockr   r^   Zini2toml.apir   Zpackaging.metadatar   
setuptoolsZsetuptools.command.egg_infor   Zsetuptools.configr	   r
   r   Z&setuptools.config._apply_pyprojecttomlr   r   Zsetuptools.distr   Zsetuptools.errorsr   Z	downloadsr   r   __file__parentZHEREr   r   r   r   r   Zuses_networkrG   ZPEP621_EXAMPLEZ"PEP621_INTERNATIONAL_EMAIL_EXAMPLErK   rR   rW   r[   ra   rc   r   Zxfailro   rp   r~   r   r   r   r   r   r=   r   r   r   r   <module>   s   

/4	


/]