Skip to content

Commit f3d2e06

Browse files
committed
Improve Python version detection in PythonBuildPack
1 parent 5fcb062 commit f3d2e06

File tree

1 file changed

+21
-29
lines changed

1 file changed

+21
-29
lines changed

repo2docker/buildpacks/python/__init__.py

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
except ImportError:
1010
import tomli as tomllib
1111

12+
from packaging.specifiers import SpecifierSet, InvalidSpecifier
13+
from packaging.version import Version
14+
1215
from ...utils import is_local_pip_requirement, open_guess_encoding
1316
from ..conda import CondaBuildPack
1417

@@ -23,51 +26,40 @@ def python_version(self):
2326

2427
name, version, _ = self.runtime
2528

26-
if name != "python" or not version:
27-
# Either not specified, or not a Python runtime (e.g. R, which subclasses this)
29+
if name is not None and name != "python":
30+
# Either not a Python runtime (e.g. R, which subclasses this)
2831
# use the default Python
2932
self._python_version = self.major_pythons["3"]
3033
self.log.warning(
3134
f"Python version unspecified, using current default Python version {self._python_version}. This will change in the future."
3235
)
3336
return self._python_version
3437

35-
py_version_info = version.split(".")
36-
py_version = ""
37-
if len(py_version_info) == 1:
38-
py_version = self.major_pythons[py_version_info[0]]
38+
if name is None or version is None:
39+
self._python_version = self.major_pythons["3"]
40+
runtime_version = Version(self.major_pythons["3"])
41+
self.log.warning(
42+
f"Python version unspecified, using current default Python version {self._python_version}. This will change in the future."
43+
)
3944
else:
40-
# get major.minor
41-
py_version = ".".join(py_version_info[:2])
42-
self._python_version = py_version
45+
self._python_version = version
46+
runtime_version = Version(version)
4347

4448
pyproject_toml = "pyproject.toml"
4549
if not self.binder_dir and os.path.exists(pyproject_toml):
4650
with open(pyproject_toml, "rb") as _pyproject_file:
4751
pyproject = tomllib.load(_pyproject_file)
4852

49-
if "project" in pyproject:
50-
if "requires-python" in pyproject["project"]:
51-
# This is the minumum version!
52-
raw_pyproject_minimum_version = pyproject["project"][
53-
"requires-python"
54-
]
53+
if "project" in pyproject and "requires-python" in pyproject["project"]:
54+
# This is the minumum version!
55+
# https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#python-requires
56+
pyproject_python_specifier = SpecifierSet(pyproject["project"]["requires-python"])
5557

56-
match = re.compile(r"\d+(\.\d+)*").match(
57-
raw_pyproject_minimum_version
58-
)
59-
if match:
60-
pyproject_minimum_version = match.group()
61-
pyproject_minimum_version_info = (
62-
pyproject_minimum_version.split(".")
63-
)
6458

65-
if (py_version_info[0] < pyproject_minimum_version_info[0]) or (
66-
py_version_info[1] < pyproject_minimum_version_info[1]
67-
):
68-
raise RuntimeError(
69-
"runtime.txt version not supported by pyproject.toml."
70-
)
59+
if runtime_version not in pyproject_python_specifier:
60+
raise RuntimeError(
61+
"runtime.txt version not supported by pyproject.toml."
62+
)
7163

7264
return self._python_version
7365

0 commit comments

Comments
 (0)