@@ -132,6 +132,17 @@ def check_nsp(dist, attr, value):
132
132
)
133
133
134
134
135
+ def check_default_extras_require (dist , attr , value ):
136
+ """Verify that extras_require mapping is valid"""
137
+ try :
138
+ assert isinstance (value , (list , tuple ))
139
+ assert all (isinstance (val , str ) for val in value )
140
+ except AssertionError as e :
141
+ raise DistutilsSetupError (
142
+ "'default_extras_require' must be a a list whose values are strings."
143
+ ) from e
144
+
145
+
135
146
def check_extras (dist , attr , value ):
136
147
"""Verify that extras_require mapping is valid"""
137
148
try :
@@ -292,6 +303,7 @@ class Distribution(_Distribution):
292
303
'license_files' : lambda : None ,
293
304
'install_requires' : list ,
294
305
'extras_require' : dict ,
306
+ 'default_extras_require' : list ,
295
307
}
296
308
297
309
# Used by build_py, editable_wheel and install_lib commands for legacy namespaces
@@ -314,7 +326,11 @@ def __init__(self, attrs: MutableMapping[str, Any] | None = None) -> None:
314
326
vars (self ).setdefault (ep .name , None )
315
327
316
328
metadata_only = set (self ._DISTUTILS_UNSUPPORTED_METADATA )
317
- metadata_only -= {"install_requires" , "extras_require" }
329
+ metadata_only -= {
330
+ "install_requires" ,
331
+ "extras_require" ,
332
+ "default_extras_require" ,
333
+ }
318
334
dist_attrs = {k : v for k , v in attrs .items () if k not in metadata_only }
319
335
_Distribution .__init__ (self , dist_attrs )
320
336
@@ -380,6 +396,7 @@ def _finalize_requires(self):
380
396
self ._normalize_requires ()
381
397
self .metadata .install_requires = self .install_requires
382
398
self .metadata .extras_require = self .extras_require
399
+ self .metadata .default_extras_require = self .default_extras_require
383
400
384
401
if self .extras_require :
385
402
for extra in self .extras_require .keys ():
@@ -392,6 +409,7 @@ def _normalize_requires(self):
392
409
"""Make sure requirement-related attributes exist and are normalized"""
393
410
install_requires = getattr (self , "install_requires" , None ) or []
394
411
extras_require = getattr (self , "extras_require" , None ) or {}
412
+ default_extras_require = getattr (self , "default_extras_require" , None ) or []
395
413
396
414
# Preserve the "static"-ness of values parsed from config files
397
415
list_ = _static .List if _static .is_static (install_requires ) else list
@@ -402,6 +420,17 @@ def _normalize_requires(self):
402
420
(k , list (map (str , _reqs .parse (v or [])))) for k , v in extras_require .items ()
403
421
)
404
422
423
+ self .default_extras_require = []
424
+ for extra in default_extras_require :
425
+ if extra not in self .extras_require :
426
+ raise ValueError (
427
+ f"The default-extra `{ extra } ` does not exists in `extras_require`."
428
+ )
429
+ self .default_extras_require .append (extra )
430
+
431
+ list_ = _static .List if _static .is_static (default_extras_require ) else list
432
+ self .default_extras_require = list_ (self .default_extras_require )
433
+
405
434
def _finalize_license_files (self ) -> None :
406
435
"""Compute names of all license files which should be included."""
407
436
license_files : list [str ] | None = self .metadata .license_files
0 commit comments