Skip to content

Commit

Permalink
prototype implementation of interpreting PEP725 metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
msarahan committed Jan 4, 2024
1 parent c1dba7a commit 35c3a0c
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 10 deletions.
47 changes: 47 additions & 0 deletions grayskull/strategy/py_toml.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,52 @@ def add_flit_metadata(metadata: dict, toml_metadata: dict) -> dict:
return metadata


def is_pep725_present(toml_metadata: dict):
return 'external' in toml_metadata


def get_pep725_mapping(purl: str):
'''This function maps a PURL to the name in the conda ecosystem. It is expected
that this will be provided on a per-ecosystem basis (such as by conda-forge)'''
# taken from

package_mapping = {
'virtual:compiler/c': '${{ compiler("c") }}',
'virtual:compiler/cpp': '${{ compiler("cxx") }}',
'virtual:compiler/fortran': '${{ compiler("fortran") }}',
'virtual:compiler/rust': '${{ compiler("rust") }}',
'virtual:interface/blas': '${{ blas }}',
}
return package_mapping.get(purl) or f'# WARNING: no matching mapping was found for PURL "{purl}". The dependency has been omitted here.'


def add_pep725_metadata(metadata: dict, toml_metadata: dict):
if not is_pep725_present(toml_metadata):
return metadata

externals = toml_metadata['external']
# each of these is a list of PURLs. For each one we find,
# we need to map it to the the conda ecosystem
requirements = metadata.get('requirements', {})
section_map = (
('build', 'build-requires'),
('host', 'host-requires'),
('run', 'dependencies')
)
for (conda_section, pep725_section) in section_map:
requirements[conda_section] = [get_pep725_mapping(purl) for purl in externals.get(pep725_section, [])]
# Conda doesn't really have a notion of optional dependencies. We just insert them all.
optional_features = toml_metadata.get(f'optional-{pep725_section}', {})
for feature_name, feature_deps in optional_features.items():
requirements[conda_section].append(f'# OPTIONAL dependencies from feature "{feature_name}"')
requirements[conda_section].extend(feature_deps)
if not requirements[conda_section]:
del requirements[conda_section]

if requirements:
metadata['requirements'] = requirements
return metadata

def get_all_toml_info(path_toml: Union[Path, str]) -> dict:
with open(path_toml, "rb") as f:
toml_metadata = tomli.load(f)
Expand Down Expand Up @@ -288,5 +334,6 @@ def get_all_toml_info(path_toml: Union[Path, str]) -> dict:

add_poetry_metadata(metadata, toml_metadata)
add_flit_metadata(metadata, toml_metadata)
add_pep725_metadata(metadata, toml_metadata)

return metadata
8 changes: 0 additions & 8 deletions tests/test_flit.py

This file was deleted.

38 changes: 36 additions & 2 deletions tests/test_poetry.py → tests/test_py_toml.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
from grayskull.strategy.py_toml import (
InvalidVersion,
add_poetry_metadata,
add_flit_metadata,
add_pep725_metadata,
encode_poetry_version,
get_all_toml_info,
get_caret_ceiling,
Expand All @@ -18,6 +20,14 @@
)


def test_add_flit_metadata():
metadata = {"build": {"entry_points": []}}
toml_metadata = {"tool": {"flit": {"scripts": {"key": "value"}}}}
result = add_flit_metadata(metadata, toml_metadata)
assert result == {"build": {"entry_points": ["key = value"]}}



@pytest.mark.parametrize(
"version, major, minor, patch",
[
Expand Down Expand Up @@ -160,7 +170,7 @@ def test_poetry_langchain_snapshot(tmpdir):
assert filecmp.cmp(snapshot_path, output_path, shallow=False)


def test_get_constrained_dep_version_not_present():
def test_poetry_get_constrained_dep_version_not_present():
assert (
get_constrained_dep(
{"git": "https://codeberg.org/hjacobs/pytest-kind.git"}, "pytest-kind"
Expand All @@ -169,7 +179,7 @@ def test_get_constrained_dep_version_not_present():
)


def test_entrypoints():
def test_poetry_entrypoints():
poetry = {
"requirements": {"host": ["setuptools"], "run": ["python"]},
"build": {},
Expand Down Expand Up @@ -198,3 +208,27 @@ def test_entrypoints():
},
"test": {},
}

@pytest.mark.parametrize(
"conda_section, pep725_section",
[
('build', 'build-requires'),
('host', 'host-requires'),
('run', 'dependencies')
])
@pytest.mark.parametrize(
"purl, purl_translated", [
("virtual:compiler/c", '${{ compiler("c") }}'),
("bob", '# WARNING: no matching mapping was found for PURL "bob". The dependency has been omitted here.')
])
def test_pep725_section_lookup(conda_section, pep725_section, purl, purl_translated):
toml_metadata = {
"external": {
pep725_section: [purl],
}
}
assert add_pep725_metadata({}, toml_metadata) == {
"requirements": {
conda_section: [purl_translated]
}
}

0 comments on commit 35c3a0c

Please sign in to comment.