Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue where python_version not correctly handled in converted package #97

Draft
wants to merge 12 commits into
base: main
Choose a base branch
from
7 changes: 6 additions & 1 deletion src/rez_pip/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,8 @@ def pythonReqToRezReq(
) -> rez.version.Requirement:
"""Convert packaging requirement object to equivalent rez requirement.

TODO: How are environment markers ignored here? There's no clear indication
in the code.
Note that environment markers are ignored.

:param pythonReq: Python requirement.
Expand Down Expand Up @@ -413,7 +415,7 @@ def convertMarker(marker: str) -> typing.List[str]:

See:
* vendor/packaging/markers.py:line=76
* https://www.python.org/dev/peps/pep-0508/#id23
* https://www.python.org/dev/peps/pep-0508

:param marker: Environment marker string, eg 'python_version == "3"'.
:returns: System requirements (unversioned).
Expand Down Expand Up @@ -460,6 +462,8 @@ def convertMarker(marker: str) -> typing.List[str]:
if varname in marker_parts:
sys_requires.update(sys_reqs)

# TODO: This shouldn't return "python" when given a marker like
# "python_version < '3.8'" right?
return list(sys_requires)


Expand Down Expand Up @@ -574,6 +578,7 @@ def getRezRequirements(
marker_reqs = convertMarker(str(req.marker))

if marker_reqs:
# TODO: Shouldn't this add to result_variant_requires instead?
sys_requires.update(marker_reqs)
to_variant = True

Expand Down
148 changes: 148 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
import os
import sys
import typing
import unittest.mock

import pytest
import rez.version
import packaging.version
import packaging.specifiers
import packaging.requirements

if sys.version_info >= (3, 10):
import importlib.metadata as importlib_metadata
else:
import importlib_metadata


import rez_pip.utils


Expand Down Expand Up @@ -81,6 +90,7 @@ def test_pythonSpecifierToRezRequirement_raises():
["package>1", "package-1.1+"],
["package", "package"],
["package[extra]", "package"],
["package;python_version<'2.7'", "package"]
],
)
def test_packaging_req_to_rez_req(pythonReq: str, rezReq: str):
Expand Down Expand Up @@ -237,3 +247,141 @@ def test_normalizeRequirement(
assert [str(req) for req in result] == [str(req) for req in expected]
for index, req in enumerate(result):
assert req.conditional_extras == conditional_extras[index]


@pytest.mark.parametrize(
"pkg_requires,python_version,expected",
[
[
["importlib-metadata", "click"],
rez.version.Version("3.7.9"),
rez_pip.utils.RequirementsDict(
requires=["importlib_metadata", "click", "python"],
variant_requires=[],
metadata={"is_pure_python": True},
),
],
],
)
def test_getRezRequirements_simple(
pkg_requires: typing.List[str],
python_version: rez.version.Version,
expected: rez_pip.utils.RequirementsDict
):
dist = importlib_metadata.Distribution()
with unittest.mock.patch.object(
importlib_metadata.Distribution,
"requires",
new_callable=unittest.mock.PropertyMock
) as mock_property:
mock_property.return_value = pkg_requires
result = rez_pip.utils.getRezRequirements(dist,
python_version,
True)
assert result == expected

@pytest.mark.parametrize(
"pkg_requires,python_version,expected",
[
[
# Actual result right now is:
#
# rez_pip.utils.RequirementsDict(
# requires=["python"],
# variant_requires=["importlib_metadata"],
# metadata={"is_pure_python": True},
# )
['importlib-metadata ; python_version < "3.8"'],
rez.version.Version("3.7.9"),
rez_pip.utils.RequirementsDict(
requires=[],
variant_requires=["importlib_metadata", "python<3.8"],
metadata={"is_pure_python": True},
),
],
# Actual result right now is:
#
# rez_pip.utils.RequirementsDict(
# requires=["python"],
# variant_requires=[],
# metadata={"is_pure_python": True},
# )
[
['importlib-metadata ; python_version < "3.8"'],
rez.version.Version("3.8.3"),
rez_pip.utils.RequirementsDict(
requires=[],
variant_requires=["python>3.8"],
metadata={"is_pure_python": True},
),
],
# TODO: Define expected behavior here.
# [
# [
# 'importlib-metadata ; python_version < "3.8"',
# 'click ; python_version > "3.6"'
# ],
# rez.version.Version("3.9.1"),
# rez_pip.utils.RequirementsDict(
# requires=["?"],
# variant_requires=["?"],
# metadata={"is_pure_python": True},
# ),
# ],
],
)
def test_getRezRequirements_environment_markers(
pkg_requires: typing.List[str],
python_version: rez.version.Version,
expected: rez_pip.utils.RequirementsDict
):
dist = importlib_metadata.Distribution()
with unittest.mock.patch.object(
importlib_metadata.Distribution,
"requires",
new_callable=unittest.mock.PropertyMock
) as mock_property:
mock_property.return_value = pkg_requires
result = rez_pip.utils.getRezRequirements(dist,
python_version,
True)

assert result == expected


@pytest.mark.parametrize(
"pkg_requires,python_version,expected",
[
# Actual result right now is:
#
# rez_pip.utils.RequirementsDict(
# requires=["python"],
# variant_requires=["platform-windows", "click"],
# metadata={"is_pure_python": True},
# )
[
['click; python_version > "3.6" or (python_version == "3.6" and os_name == "unix")'],
rez.version.Version("3.6.15"),
rez_pip.utils.RequirementsDict(
requires=[],
variant_requires=["click", "python>3.6"],
metadata={"is_pure_python": True},
),
],
],
)
def test_getRezRequirements_mocked_os(pkg_requires: typing.List[str],
python_version: rez.version.Version,
expected: rez_pip.utils.RequirementsDict):
dist = importlib_metadata.Distribution()
with unittest.mock.patch.object(
importlib_metadata.Distribution,
"requires",
new_callable=unittest.mock.PropertyMock
) as mock_property:
with unittest.mock.patch("os.name", new="unix"):
mock_property.return_value = pkg_requires
result = rez_pip.utils.getRezRequirements(dist,
python_version,
True)
assert result == expected
Loading