15
15
16
16
from pyproject_api ._util import ensure_empty_dir
17
17
18
+ if sys .version_info >= (3 , 8 ): # pragma: no cover (py38+)
19
+ from typing import TypedDict
20
+ else : # pragma: no cover (py38+)
21
+ from typing_extensions import TypedDict
22
+
18
23
if sys .version_info >= (3 , 11 ): # pragma: no cover (py311+)
19
24
import tomllib
20
25
else : # pragma: no cover (py311+)
24
29
ConfigSettings = Optional [Dict [str , Any ]]
25
30
26
31
32
+ class OptionalHooks (TypedDict , total = True ):
33
+ """A flag indicating if the backend supports the optional hook or not"""
34
+
35
+ get_requires_for_build_sdist : bool
36
+ prepare_metadata_for_build_wheel : bool
37
+ get_requires_for_build_wheel : bool
38
+ build_editable : bool
39
+ get_requires_for_build_editable : bool
40
+ prepare_metadata_for_build_editable : bool
41
+
42
+
27
43
class CmdStatus (ABC ):
28
44
@property
29
45
@abstractmethod
@@ -190,6 +206,7 @@ def __init__(
190
206
self ._backend_obj = backend_obj
191
207
self .requires : tuple [Requirement , ...] = requires
192
208
self ._reuse_backend = reuse_backend
209
+ self ._optional_hooks : OptionalHooks | None = None
193
210
194
211
@classmethod
195
212
def create_args_from_folder (
@@ -243,17 +260,25 @@ def backend_args(self) -> list[str]:
243
260
result .append (self ._backend_obj )
244
261
return result
245
262
263
+ @property
264
+ def optional_hooks (self ) -> OptionalHooks :
265
+ """:return: a dictionary indicating if the optional hook is supported or not"""
266
+ if self ._optional_hooks is None :
267
+ result , _ , __ = self ._send ("_optional_hooks" )
268
+ self ._optional_hooks = result
269
+ return self ._optional_hooks
270
+
246
271
def get_requires_for_build_sdist (self , config_settings : ConfigSettings | None = None ) -> RequiresBuildSdistResult :
247
272
"""
248
273
Get build requirements for a source distribution (per PEP-517).
249
274
250
275
:param config_settings: run arguments
251
276
:return: outcome
252
277
"""
253
- try :
278
+ if self . optional_hooks [ "get_requires_for_build_sdist" ] :
254
279
result , out , err = self ._send (cmd = "get_requires_for_build_sdist" , config_settings = config_settings )
255
- except BackendFailed as exc :
256
- result , out , err = [], exc . out , exc . err
280
+ else :
281
+ result , out , err = [], "" , ""
257
282
if not isinstance (result , list ) or not all (isinstance (i , str ) for i in result ):
258
283
self ._unexpected_response ("get_requires_for_build_sdist" , result , "list of string" , out , err )
259
284
return RequiresBuildSdistResult (tuple (Requirement (r ) for r in cast (List [str ], result )), out , err )
@@ -265,10 +290,10 @@ def get_requires_for_build_wheel(self, config_settings: ConfigSettings | None =
265
290
:param config_settings: run arguments
266
291
:return: outcome
267
292
"""
268
- try :
293
+ if self . optional_hooks [ "get_requires_for_build_wheel" ] :
269
294
result , out , err = self ._send (cmd = "get_requires_for_build_wheel" , config_settings = config_settings )
270
- except BackendFailed as exc :
271
- result , out , err = [], exc . out , exc . err
295
+ else :
296
+ result , out , err = [], "" , ""
272
297
if not isinstance (result , list ) or not all (isinstance (i , str ) for i in result ):
273
298
self ._unexpected_response ("get_requires_for_build_wheel" , result , "list of string" , out , err )
274
299
return RequiresBuildWheelResult (tuple (Requirement (r ) for r in cast (List [str ], result )), out , err )
@@ -282,10 +307,10 @@ def get_requires_for_build_editable(
282
307
:param config_settings: run arguments
283
308
:return: outcome
284
309
"""
285
- try :
310
+ if self . optional_hooks [ "get_requires_for_build_editable" ] :
286
311
result , out , err = self ._send (cmd = "get_requires_for_build_editable" , config_settings = config_settings )
287
- except BackendFailed as exc :
288
- result , out , err = [], exc . out , exc . err
312
+ else :
313
+ result , out , err = [], "" , ""
289
314
if not isinstance (result , list ) or not all (isinstance (i , str ) for i in result ):
290
315
self ._unexpected_response ("get_requires_for_build_editable" , result , "list of string" , out , err )
291
316
return RequiresBuildEditableResult (tuple (Requirement (r ) for r in cast (List [str ], result )), out , err )
@@ -301,13 +326,13 @@ def prepare_metadata_for_build_wheel(
301
326
:return: metadata generation result
302
327
"""
303
328
self ._check_metadata_dir (metadata_directory )
304
- try :
329
+ if self . optional_hooks [ "prepare_metadata_for_build_wheel" ] :
305
330
basename , out , err = self ._send (
306
331
cmd = "prepare_metadata_for_build_wheel" ,
307
332
metadata_directory = metadata_directory ,
308
333
config_settings = config_settings ,
309
334
)
310
- except BackendFailed :
335
+ else :
311
336
# if backend does not provide it acquire it from the wheel
312
337
basename , err , out = self ._metadata_from_built_wheel (config_settings , metadata_directory , "build_wheel" )
313
338
if not isinstance (basename , str ):
@@ -333,13 +358,13 @@ def prepare_metadata_for_build_editable(
333
358
:return: metadata generation result
334
359
"""
335
360
self ._check_metadata_dir (metadata_directory )
336
- try :
361
+ if self . optional_hooks [ "prepare_metadata_for_build_editable" ] :
337
362
basename , out , err = self ._send (
338
363
cmd = "prepare_metadata_for_build_editable" ,
339
364
metadata_directory = metadata_directory ,
340
365
config_settings = config_settings ,
341
366
)
342
- except BackendFailed :
367
+ else :
343
368
# if backend does not provide it acquire it from the wheel
344
369
basename , err , out = self ._metadata_from_built_wheel (config_settings , metadata_directory , "build_editable" )
345
370
if not isinstance (basename , str ):
@@ -481,5 +506,5 @@ def _send(self, cmd: str, **kwargs: Any) -> tuple[Any, str, str]:
481
506
482
507
@abstractmethod
483
508
@contextmanager
484
- def _send_msg (self , cmd : str , result_file : Path , msg : str ) -> Iterator [CmdStatus ]: # noqa: U100
509
+ def _send_msg (self , cmd : str , result_file : Path , msg : str ) -> Iterator [CmdStatus ]:
485
510
raise NotImplementedError
0 commit comments