@@ -658,6 +658,36 @@ def build_editable(self, directory: Path, verbose: bool = False) -> pathlib.Path
658658 return wheel_file
659659
660660
661+ def _table (scheme : Dict [str , Callable [[Any , str ], Any ]]) -> Callable [[Any , str ], Dict [str , Any ]]:
662+ def func (value : Any , name : str ) -> Dict [str , Any ]:
663+ if not isinstance (value , dict ):
664+ raise ConfigError (f'configuration entry "{ name } " must be a table' )
665+ table = {}
666+ for key , val in value .items ():
667+ check = scheme .get (key )
668+ if check is None :
669+ raise ConfigError (f'unknown configuration entry "{ name } .{ key } "' )
670+ table [key ] = check (val , f'{ name } .{ key } ' )
671+ return table
672+ return func
673+
674+
675+ def _strings (value : Any , name : str ) -> List [str ]:
676+ if not isinstance (value , list ) or not all (isinstance (x , str ) for x in value ):
677+ raise ConfigError (f'configuration entry "{ name } " must be a list of strings' )
678+ return value
679+
680+
681+ def _validate_pyproject_config (pyproject : Dict [str , Any ]) -> Dict [str , Any ]:
682+ scheme = _table ({
683+ 'args' : _table ({
684+ name : _strings for name in _MESON_ARGS_KEYS
685+ })
686+ })
687+ table = pyproject .get ('tool' , {}).get ('meson-python' , {})
688+ return scheme (table , 'tool.meson-python' )
689+
690+
661691class Project ():
662692 """Meson project wrapper to generate Python artifacts."""
663693
@@ -730,14 +760,10 @@ def __init__( # noqa: C901
730760 if self ._metadata :
731761 self ._validate_metadata ()
732762
733- # load meson args
734- for key in self ._get_config_key ('args' ):
735- self ._meson_args [key ].extend (self ._get_config_key (f'args.{ key } ' ))
736- # XXX: We should validate the user args to make sure they don't conflict with ours.
737-
738- self ._check_for_unknown_config_keys ({
739- 'args' : _MESON_ARGS_KEYS ,
740- })
763+ # load meson args from pyproject.toml
764+ pyproject_config = _validate_pyproject_config (self ._config )
765+ for key , value in pyproject_config ['args' ].items ():
766+ self ._meson_args [key ].extend (value )
741767
742768 # meson arguments from the command line take precedence over
743769 # arguments from the configuration file thus are added later
@@ -778,14 +804,6 @@ def __init__( # noqa: C901
778804 if self ._metadata and 'version' in self ._metadata .dynamic :
779805 self ._metadata .version = self .version
780806
781- def _get_config_key (self , key : str ) -> Any :
782- value : Any = self ._config
783- for part in f'tool.meson-python.{ key } ' .split ('.' ):
784- if not isinstance (value , Mapping ):
785- raise ConfigError (f'Configuration entry "tool.meson-python.{ key } " should be a TOML table not { type (value )} ' )
786- value = value .get (part , {})
787- return value
788-
789807 def _proc (self , * args : str ) -> None :
790808 """Invoke a subprocess."""
791809 print ('{cyan}{bold}+ {}{reset}' .format (' ' .join (args ), ** _STYLES ))
@@ -858,17 +876,6 @@ def _validate_metadata(self) -> None:
858876 f'expected { self ._metadata .requires_python } '
859877 )
860878
861- def _check_for_unknown_config_keys (self , valid_args : Mapping [str , Collection [str ]]) -> None :
862- config = self ._config .get ('tool' , {}).get ('meson-python' , {})
863-
864- for key , valid_subkeys in config .items ():
865- if key not in valid_args :
866- raise ConfigError (f'Unknown configuration key "tool.meson-python.{ key } "' )
867-
868- for subkey in valid_args [key ]:
869- if subkey not in valid_subkeys :
870- raise ConfigError (f'Unknown configuration key "tool.meson-python.{ key } .{ subkey } "' )
871-
872879 @cached_property
873880 def _wheel_builder (self ) -> _WheelBuilder :
874881 return _WheelBuilder (
0 commit comments