Skip to content

Commit dbf7c71

Browse files
committed
Merge PyprojectBuildPack into PythonBuildPack
1 parent 8e96d3e commit dbf7c71

File tree

3 files changed

+59
-158
lines changed

3 files changed

+59
-158
lines changed

repo2docker/app.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
LegacyBinderDockerBuildPack,
3434
NixBuildPack,
3535
PipfileBuildPack,
36-
PyprojectBuildPack,
3736
PythonBuildPack,
3837
RBuildPack,
3938
)
@@ -101,7 +100,6 @@ def _default_log_level(self):
101100
RBuildPack,
102101
CondaBuildPack,
103102
PipfileBuildPack,
104-
PyprojectBuildPack,
105103
PythonBuildPack,
106104
],
107105
config=True,

repo2docker/buildpacks/pyproject/__init__.py

Lines changed: 0 additions & 149 deletions
This file was deleted.

repo2docker/buildpacks/python/__init__.py

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
"""Generates Dockerfiles based on an input matrix based on Python."""
22

33
import os
4+
import re
45
from functools import lru_cache
56

7+
try:
8+
import tomllib
9+
except ImportError:
10+
import tomli as tomllib
11+
612
from ...utils import is_local_pip_requirement, open_guess_encoding
713
from ..conda import CondaBuildPack
814

@@ -34,6 +40,37 @@ def python_version(self):
3440
# get major.minor
3541
py_version = ".".join(py_version_info[:2])
3642
self._python_version = py_version
43+
44+
pyproject_toml = "pyproject.toml"
45+
if not self.binder_dir and os.path.exists(pyproject_toml):
46+
with open(pyproject_toml, "rb") as _pyproject_file:
47+
pyproject = tomllib.load(_pyproject_file)
48+
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+
]
55+
56+
match = re.compile(r"\d+(\.\d+)*").match(raw_pyproject_minimum_version)
57+
if match:
58+
pyproject_minimum_version = match.group()
59+
pyproject_minimum_version_info = pyproject_minimum_version.split(
60+
"."
61+
)
62+
63+
if (
64+
py_version_info[0]
65+
< pyproject_minimum_version_info[0]
66+
) or (
67+
py_version_info[1]
68+
< pyproject_minimum_version_info[1]
69+
):
70+
raise RuntimeError(
71+
"runtime.txt version not supported by pyproject.toml."
72+
)
73+
3774
return self._python_version
3875

3976
def _get_pip_scripts(self):
@@ -78,9 +115,11 @@ def _should_preassemble_pip(self):
78115
If there are any local references, e.g. `-e .`,
79116
stage the whole repo prior to installation.
80117
"""
81-
if not os.path.exists("binder") and os.path.exists("setup.py"):
82-
# can't install from subset if we're using setup.py
83-
return False
118+
# can't install from subset
119+
for _configuration_file in ("pyproject.toml", "setup.py"):
120+
if not os.path.exists("binder") and os.path.exists():
121+
return False
122+
84123
for name in ("requirements.txt", "requirements3.txt"):
85124
requirements_txt = self.binder_path(name)
86125
if not os.path.exists(requirements_txt):
@@ -119,26 +158,39 @@ def get_assemble_scripts(self):
119158
# and requirements3.txt (if it exists)
120159
# will be installed in the python 3 notebook server env.
121160
assemble_scripts = super().get_assemble_scripts()
122-
setup_py = "setup.py"
123161
# KERNEL_PYTHON_PREFIX is the env with the kernel,
124162
# whether it's distinct from the notebook or the same.
125163
pip = "${KERNEL_PYTHON_PREFIX}/bin/pip"
126164
if not self._should_preassemble_pip:
127165
assemble_scripts.extend(self._get_pip_scripts())
128166

129-
# setup.py exists *and* binder dir is not used
130-
if not self.binder_dir and os.path.exists(setup_py):
131-
assemble_scripts.append(("${NB_USER}", f"{pip} install --no-cache-dir ."))
167+
for _configuration_file in ("pyproject.toml", "setup.py"):
168+
if not self.binder_dir and os.path.exists(_configuration_file):
169+
assemble_scripts.append(("${NB_USER}", f"{pip} install --no-cache-dir ."))
170+
break
171+
132172
return assemble_scripts
133173

134174
def detect(self):
135175
"""Check if current repo should be built with the Python buildpack."""
136176
requirements_txt = self.binder_path("requirements.txt")
177+
pyproject_toml = "pyproject.toml"
137178
setup_py = "setup.py"
138179

139180
name = self.runtime[0]
140181
if name:
141182
return name == "python"
183+
if not self.binder_dir and os.path.exists(pyproject_toml):
184+
with open(pyproject_toml, "rb") as _pyproject_file:
185+
pyproject = tomllib.load(_pyproject_file)
186+
187+
if (
188+
("project" in pyproject)
189+
and ("build-system" in pyproject)
190+
and ("requires" in pyproject["build-system"])
191+
):
192+
return True
193+
142194
if not self.binder_dir and os.path.exists(setup_py):
143195
return True
144196
return os.path.exists(requirements_txt)

0 commit comments

Comments
 (0)