Skip to content

Commit

Permalink
MAINT: simplify package metadata handling
Browse files Browse the repository at this point in the history
Code can be simplified using pyproject_metadata.StandardMetadata also
when we infer the package metadata from meson.build.
  • Loading branch information
dnicolodi committed Feb 9, 2023
1 parent 11c13d7 commit cf6cf99
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 62 deletions.
77 changes: 20 additions & 57 deletions mesonpy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -748,20 +748,6 @@ def __init__( # noqa: C901
# load pyproject.toml
pyproject = tomllib.loads(self._source_dir.joinpath('pyproject.toml').read_text())

# package metadata
self._pep621 = 'project' in pyproject:
if self.pep621:
self._metadata = pyproject_metadata.StandardMetadata.from_pyproject(pyproject, self._source_dir)
else:
print(
'{yellow}{bold}! Using Meson to generate the project metadata '
'(no `project` section in pyproject.toml){reset}'.format(**_STYLES)
)
self._metadata = None

if self._metadata:
self._validate_metadata()

# load meson args from pyproject.toml
pyproject_config = _validate_pyproject_config(pyproject)
for key, value in pyproject_config.get('args', {}).items():
Expand Down Expand Up @@ -802,9 +788,20 @@ def __init__( # noqa: C901
has_valid_build_dir = self._build_dir.joinpath('meson-private', 'coredata.dat').is_file()
self._configure(reconfigure=has_valid_build_dir and not native_file_mismatch)

# set version if dynamic (this fetches it from Meson)
if self._metadata and 'version' in self._metadata.dynamic:
self._metadata.version = self.version
# package metadata
if 'project' in pyproject:
self._metadata = pyproject_metadata.StandardMetadata.from_pyproject(pyproject, self._source_dir)
else:
self._metadata = pyproject_metadata.StandardMetadata(name=self._meson_name, version=self._meson_version)
print(
'{yellow}{bold}! Using Meson to generate the project metadata '
'(no `project` section in pyproject.toml){reset}'.format(**_STYLES)
)
self._validate_metadata()

# set version from meson.build if dynamic
if 'version' in self._metadata.dynamic:
self._metadata.version = self._meson_version

def _proc(self, *args: str) -> None:
"""Invoke a subprocess."""
Expand Down Expand Up @@ -858,8 +855,6 @@ def _configure(self, reconfigure: bool = False) -> None:
def _validate_metadata(self) -> None:
"""Check the pyproject.toml metadata and see if there are any issues."""

assert self._metadata

# check for unsupported dynamic fields
unsupported_dynamic = {
key for key in self._metadata.dynamic
Expand Down Expand Up @@ -991,45 +986,18 @@ def _meson_version(self) -> str:

@property
def name(self) -> str:
"""Project name. Specified in pyproject.toml."""
name = self._metadata.name if self._metadata else self._meson_name
assert isinstance(name, str)
return name.replace('-', '_')
"""Project name."""
return self._metadata.name.replace('-', '_')

@property
def version(self) -> str:
"""Project version. Either specified in pyproject.toml or meson.build."""
if self._metadata and 'version' not in self._metadata.dynamic:
version = str(self._metadata.version)
else:
version = self._meson_version
assert isinstance(version, str)
return version
"""Project version."""
return str(self._metadata.version)

@cached_property
def metadata(self) -> bytes:
"""Project metadata."""
# the rest of the keys are only available when using PEP 621 metadata
if not self.pep621:
data = textwrap.dedent(f'''
Metadata-Version: 2.1
Name: {self.name}
Version: {self.version}
''').strip()
return data.encode()

# re-import pyproject_metadata to raise ModuleNotFoundError if it is really missing
import pyproject_metadata # noqa: F401
assert self._metadata

core_metadata = self._metadata.as_rfc822()
# use self.version as the version may be dynamic -- fetched from Meson
#
# we need to overwrite this field in the RFC822 field as
# pyproject_metadata removes 'version' from the dynamic fields when
# giving it a value via the dataclass
core_metadata.headers['Version'] = [self.version]
return bytes(core_metadata)
"""Project metadata as an RFC822 message."""
return bytes(self._metadata.as_rfc822())

@property
def license_file(self) -> Optional[pathlib.Path]:
Expand All @@ -1044,11 +1012,6 @@ def is_pure(self) -> bool:
"""Is the wheel "pure" (architecture independent)?"""
return bool(self._wheel_builder.is_pure)

@property
def pep621(self) -> bool:
"""Does the project use PEP 621 metadata?"""
return self._pep621

def sdist(self, directory: Path) -> pathlib.Path:
"""Generates a sdist (source distribution) in the specified directory."""
# generate meson dist file
Expand Down
10 changes: 5 additions & 5 deletions tests/test_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ def test_no_pep621(sdist_library):
with tarfile.open(sdist_library, 'r:gz') as sdist:
sdist_pkg_info = sdist.extractfile('library-1.0.0/PKG-INFO').read().decode()

assert sdist_pkg_info == textwrap.dedent('''
assert sdist_pkg_info == textwrap.dedent('''\
Metadata-Version: 2.1
Name: library
Version: 1.0.0
''').strip()
''')


def test_pep621(sdist_full_metadata):
Expand Down Expand Up @@ -61,10 +61,10 @@ def test_pep621(sdist_full_metadata):

def test_dynamic_version(sdist_dynamic_version):
with tarfile.open(sdist_dynamic_version, 'r:gz') as sdist:
sdist_pkg_info = sdist.extractfile('dynamic_version-1.0.0/PKG-INFO').read().decode().strip()
sdist_pkg_info = sdist.extractfile('dynamic_version-1.0.0/PKG-INFO').read().decode()

assert sdist_pkg_info == textwrap.dedent('''
assert sdist_pkg_info == textwrap.dedent('''\
Metadata-Version: 2.1
Name: dynamic-version
Version: 1.0.0
''').strip()
''')

0 comments on commit cf6cf99

Please sign in to comment.