@@ -79,6 +79,9 @@ class InvalidLicenseExpression(Exception): # type: ignore[no-redef]
7979 MesonArgs = Mapping [MesonArgsKeys , List [str ]]
8080
8181
82+ _PYPROJECT_METADATA_VERSION = tuple (map (int , pyproject_metadata .__version__ .split ('.' )[:2 ]))
83+ _SUPPORTED_DYNAMIC_FIELDS = {'version' , } if _PYPROJECT_METADATA_VERSION < (0 , 9 ) else {'version' , 'license' , 'license-files' }
84+
8285_NINJA_REQUIRED_VERSION = '1.8.2'
8386_MESON_REQUIRED_VERSION = '0.63.3' # keep in sync with the version requirement in pyproject.toml
8487
@@ -260,7 +263,7 @@ def from_pyproject( # type: ignore[override]
260263 metadata = super ().from_pyproject (data , project_dir , metadata_version )
261264
262265 # Check for unsupported dynamic fields.
263- unsupported_dynamic = set (metadata .dynamic ) - { 'version' , }
266+ unsupported_dynamic = set (metadata .dynamic ) - _SUPPORTED_DYNAMIC_FIELDS # type: ignore[operator]
264267 if unsupported_dynamic :
265268 fields = ', ' .join (f'"{ x } "' for x in unsupported_dynamic )
266269 raise pyproject_metadata .ConfigurationError (f'Unsupported dynamic fields: { fields } ' )
@@ -731,13 +734,30 @@ def __init__(
731734 raise pyproject_metadata .ConfigurationError (
732735 'Field "version" declared as dynamic but version is not defined in meson.build' )
733736 self ._metadata .version = packaging .version .Version (version )
737+ if 'license' in self ._metadata .dynamic :
738+ license = self ._meson_license
739+ if license is None :
740+ raise pyproject_metadata .ConfigurationError (
741+ 'Field "license" declared as dynamic but license is not specified in meson.build' )
742+ # mypy is not happy when analyzing typing based on
743+ # pyproject-metadata < 0.9 where license needs to be of
744+ # License type. However, this code is not executed if
745+ # pyproject-metadata is older than 0.9 because then dynamic
746+ # license is not allowed.
747+ self ._metadata .license = license # type: ignore[assignment, unused-ignore]
748+ if 'license-files' in self ._metadata .dynamic :
749+ self ._metadata .license_files = self ._meson_license_files
734750 else :
735751 # if project section is missing, use minimal metdata from meson.build
736752 name , version = self ._meson_name , self ._meson_version
737753 if not version :
738754 raise pyproject_metadata .ConfigurationError (
739755 'Section "project" missing in pyproject.toml and version is not defined in meson.build' )
740- self ._metadata = Metadata (name = name , version = packaging .version .Version (version ))
756+ kwargs = {
757+ 'license' : self ._meson_license ,
758+ 'license_files' : self ._meson_license_files
759+ } if _PYPROJECT_METADATA_VERSION >= (0 , 9 ) else {}
760+ self ._metadata = Metadata (name = name , version = packaging .version .Version (version ), ** kwargs )
741761
742762 # verify that we are running on a supported interpreter
743763 if self ._metadata .requires_python :
@@ -862,6 +882,31 @@ def _meson_version(self) -> Optional[str]:
862882 return None
863883 return value
864884
885+ @property
886+ def _meson_license (self ) -> Optional [str ]:
887+ """The license specified with the ``license`` argument to ``project()`` in meson.build."""
888+ value = self ._info ('intro-projectinfo' ).get ('license' , None )
889+ if value is None :
890+ return None
891+ assert isinstance (value , list )
892+ if len (value ) > 1 :
893+ raise pyproject_metadata .ConfigurationError (
894+ 'using a list of strings for the license declared in meson.build is ambiguous: use a SPDX license expression' )
895+ value = value [0 ]
896+ assert isinstance (value , str )
897+ if value == 'unknown' :
898+ return None
899+ return str (canonicalize_license_expression (value )) # str() is to make mypy happy
900+
901+ @property
902+ def _meson_license_files (self ) -> Optional [List [pathlib .Path ]]:
903+ """The license files specified with the ``license_files`` argument to ``project()`` in meson.build."""
904+ value = self ._info ('intro-projectinfo' ).get ('license_files' , None )
905+ if not value :
906+ return None
907+ assert isinstance (value , list )
908+ return [pathlib .Path (x ) for x in value ]
909+
865910 def sdist (self , directory : Path ) -> pathlib .Path :
866911 """Generates a sdist (source distribution) in the specified directory."""
867912 # Generate meson dist file.
0 commit comments