14
14
from setuptools .dist import Distribution
15
15
from setuptools .config import setupcfg , pyprojecttoml
16
16
from setuptools .config import expand
17
- from setuptools .config ._apply_pyprojecttoml import _WouldIgnoreField
17
+ from setuptools .config ._apply_pyprojecttoml import _WouldIgnoreField , _some_attrgetter
18
+ from setuptools .command .egg_info import write_requirements
18
19
19
20
20
21
EXAMPLES = (Path (__file__ ).parent / "setupcfg_examples.txt" ).read_text ()
@@ -207,12 +208,12 @@ def test_license_and_license_files(tmp_path):
207
208
208
209
209
210
class TestPresetField :
210
- def pyproject (self , tmp_path , dynamic ):
211
+ def pyproject (self , tmp_path , dynamic , extra_content = "" ):
211
212
content = f"[project]\n name = 'proj'\n dynamic = { dynamic !r} \n "
212
213
if "version" not in dynamic :
213
214
content += "version = '42'\n "
214
215
file = tmp_path / "pyproject.toml"
215
- file .write_text (content , encoding = "utf-8" )
216
+ file .write_text (content + extra_content , encoding = "utf-8" )
216
217
return file
217
218
218
219
@pytest .mark .parametrize (
@@ -233,12 +234,14 @@ def test_not_listed_in_dynamic(self, tmp_path, attr, field, value):
233
234
dist = pyprojecttoml .apply_configuration (dist , pyproject )
234
235
235
236
# TODO: Once support for pyproject.toml config stabilizes attr should be None
236
- dist_value = getattr ( dist , attr , None ) or getattr (dist . metadata , attr , object () )
237
+ dist_value = _some_attrgetter ( f"metadata. { attr } " , attr ) (dist )
237
238
assert dist_value == value
238
239
239
240
@pytest .mark .parametrize (
240
241
"attr, field, value" ,
241
242
[
243
+ ("install_requires" , "dependencies" , []),
244
+ ("extras_require" , "optional-dependencies" , {}),
242
245
("install_requires" , "dependencies" , ["six" ]),
243
246
("classifiers" , "classifiers" , ["Private :: Classifier" ]),
244
247
]
@@ -247,9 +250,31 @@ def test_listed_in_dynamic(self, tmp_path, attr, field, value):
247
250
pyproject = self .pyproject (tmp_path , [field ])
248
251
dist = makedist (tmp_path , ** {attr : value })
249
252
dist = pyprojecttoml .apply_configuration (dist , pyproject )
250
- dist_value = getattr ( dist , attr , None ) or getattr (dist . metadata , attr , object () )
253
+ dist_value = _some_attrgetter ( f"metadata. { attr } " , attr ) (dist )
251
254
assert dist_value == value
252
255
256
+ def test_optional_dependencies_dont_remove_env_markers (self , tmp_path ):
257
+ """
258
+ Internally setuptools converts dependencies with markers to "extras".
259
+ If ``install_requires`` is given by ``setup.py``, we have to ensure that
260
+ applying ``optional-dependencies`` does not overwrite the mandatory
261
+ dependencies with markers (see #3204).
262
+ """
263
+ # If setuptools replace its internal mechanism that uses `requires.txt`
264
+ # this test has to be rewritten to adapt accordingly
265
+ extra = "\n [project.optional-dependencies]\n foo = ['bar>1']\n "
266
+ pyproject = self .pyproject (tmp_path , ["dependencies" ], extra )
267
+ install_req = ['importlib-resources (>=3.0.0) ; python_version < "3.7"' ]
268
+ dist = makedist (tmp_path , install_requires = install_req )
269
+ dist = pyprojecttoml .apply_configuration (dist , pyproject )
270
+ assert "foo" in dist .extras_require
271
+ assert ':python_version < "3.7"' in dist .extras_require
272
+ egg_info = dist .get_command_obj ("egg_info" )
273
+ write_requirements (egg_info , tmp_path , tmp_path / "requires.txt" )
274
+ reqs = (tmp_path / "requires.txt" ).read_text (encoding = "utf-8" )
275
+ assert "importlib-resources" in reqs
276
+ assert "bar" in reqs
277
+
253
278
254
279
# --- Auxiliary Functions ---
255
280
0 commit comments