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

[BUG] Accepting prereleases as valid python version #389

Merged
merged 11 commits into from
Dec 29, 2024
9 changes: 9 additions & 0 deletions .all-contributorsrc
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,15 @@
"contributions": [
"maintenance"
]
},
{
"login": "Abelarm",
"name": "Luigi Giugliano",
"avatar_url": "https://avatars.githubusercontent.com/u/6976921?v=4",
"profile": "https://github.com/Abelarm",
"contributions": [
"code"
]
}
],
"projectName": "skbase",
Expand Down
16 changes: 14 additions & 2 deletions skbase/utils/dependencies/_dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,9 @@ def _get_pkg_version(package_name):
return pkg_env_version


def _check_python_version(obj, package=None, msg=None, severity="error"):
def _check_python_version(
obj, package=None, msg=None, severity="error", prereleases=True
):
"""Check if system python version is compatible with requirements of obj.

Parameters
Expand All @@ -259,6 +261,13 @@ def _check_python_version(obj, package=None, msg=None, severity="error"):
* "none" - does not raise exception or warning
function returns False if one of packages is not installed, otherwise True

prereleases: str, default = True
Whether prerelease versions are considered compatible.
If True, allows prerelease versions to be considered compatible.
If False, always considers prerelease versions as incompatible, i.e., always
raises error, warning, or returns False, if the system python version is a
prerelease.

Returns
-------
compatible : bool, whether obj is compatible with system python version
Expand All @@ -276,7 +285,7 @@ def _check_python_version(obj, package=None, msg=None, severity="error"):
return True

try:
est_specifier = SpecifierSet(est_specifier_tag)
est_specifier = SpecifierSet(est_specifier_tag, prereleases=prereleases)
except InvalidSpecifier:
msg_version = (
f"wrong format for python_version tag, "
Expand All @@ -303,6 +312,9 @@ def _check_python_version(obj, package=None, msg=None, severity="error"):
f" but system python version is {sys.version}."
)

if "rc" in sys_version:
msg += " This is due to the release candidate status of your system Python."

if package is not None:
msg += (
f" This is due to python version requirements of the {package} package."
Expand Down
54 changes: 53 additions & 1 deletion skbase/utils/dependencies/tests/test_check_dependencies.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# -*- coding: utf-8 -*-
"""Tests for _check_soft_dependencies utility."""
from unittest.mock import patch

import pytest
from packaging.requirements import InvalidRequirement

from skbase.utils.dependencies._dependencies import _check_soft_dependencies
from skbase.utils.dependencies import _check_python_version, _check_soft_dependencies


def test_check_soft_deps():
Expand Down Expand Up @@ -47,3 +49,53 @@
assert _check_soft_dependencies(
("pytest", "!!numpy<~><>0.1.0"), severity="none"
)


@patch("skbase.utils.dependencies._dependencies.sys")
@pytest.mark.parametrize(
"mock_release_version, prereleases, expect_exception",
[
(True, True, False),
(True, False, True),
(False, False, False),
(False, True, False),
],
)
def test_check_python_version(
mock_sys, mock_release_version, prereleases, expect_exception
):
from skbase.base import BaseObject

if mock_release_version:
mock_sys.version = "3.8.1rc"
else:
mock_sys.version = "3.8.1"

class DummyObjectClass(BaseObject):
_tags = {
"python_version": ">=3.7.1", # PEP 440 version specifier, e.g., ">=3.7"
"python_dependencies": None, # PEP 440 dependency strs, e.g., "pandas>=1.0"
"env_marker": None, # PEP 508 environment marker, e.g., "os_name=='posix'"
}
"""Define dummy class to test set_tags."""

dummy_object_instance = DummyObjectClass()

try:
_check_python_version(dummy_object_instance, prereleases=prereleases)
except ModuleNotFoundError as exception:
expected_msg = (
f"{type(dummy_object_instance).__name__} requires python version "
f"to be {dummy_object_instance.get_tags()['python_version']}, "
f"but system python version is {mock_sys.version}. "
"This is due to the release candidate status of your system Python."
)

if not expect_exception or exception.msg != expected_msg:
# Throw Error since exception is not expected or has not the correct message
raise AssertionError(

Check warning on line 96 in skbase/utils/dependencies/tests/test_check_dependencies.py

View check run for this annotation

Codecov / codecov/patch

skbase/utils/dependencies/tests/test_check_dependencies.py#L96

Added line #L96 was not covered by tests
"ModuleNotFoundError should be NOT raised by:",
f"\n\t - mock_release_version: {mock_release_version},",
f"\n\t - prereleases: {prereleases},",
f"\nERROR MESSAGE: {exception.msg}",
) from exception
Loading