-
Notifications
You must be signed in to change notification settings - Fork 382
Add buildpack for pyproject.toml to configure container image #1444
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
Open
rgaiacs
wants to merge
7
commits into
jupyterhub:main
Choose a base branch
from
rgaiacs:1427-support-pyproject
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+140
−7
Open
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
210eba9
Start implementation of support for pyproject.yml
rgaiacs 1770126
Add builldpack for pyproject to list of buildpack
rgaiacs 232bed7
Change requirement to Python 3.11
rgaiacs c79e344
Remove test with Python 3.9
rgaiacs 54bbc5c
Avoid change PATH during bash command
rgaiacs 6f1f9a8
Change Python version used by ReadTheDocks
rgaiacs 974a559
Reduce code duplication in PyprojectBuildPack
rgaiacs File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,7 +11,7 @@ sphinx: | |
build: | ||
os: ubuntu-22.04 | ||
tools: | ||
python: "3.10" | ||
python: "3.11" | ||
|
||
python: | ||
install: | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
"""Buildpack for Git repositories with pyproject.toml | ||
|
||
Support to pyproject.toml was added to pip v10.0, | ||
see https://pip.pypa.io/en/latest/reference/build-system/pyproject-toml/. | ||
""" | ||
|
||
import os | ||
import re | ||
import tomllib | ||
from functools import lru_cache | ||
|
||
from ..conda import CondaBuildPack | ||
|
||
VERSION_PAT = re.compile(r"\d+(\.\d+)*") | ||
|
||
|
||
class PyprojectBuildPack(CondaBuildPack): | ||
"""Setup Python with pyproject.toml for use with a repository.""" | ||
|
||
@property | ||
def python_version(self): | ||
""" | ||
Detect the Python version declared in a `pyproject.toml`. | ||
Will return 'x.y' if version is found (e.g '3.6'), | ||
or a Falsy empty string '' if not found. | ||
""" | ||
|
||
if hasattr(self, "_python_version"): | ||
return self._python_version | ||
|
||
name, version, _ = self.runtime | ||
|
||
if name == "python": | ||
runtime_python_version = version | ||
else: | ||
runtime_python_version = self.major_pythons["3"] | ||
self.log.warning( | ||
f"Python version unspecified in runtime.txt, using current default Python version {runtime_python_version}. This will change in the future." | ||
) | ||
|
||
runtime_python_version_info = runtime_python_version.split(".") | ||
|
||
pyproject_file = self.binder_path("pyproject.toml") | ||
with open(pyproject_file, "rb") as _pyproject_file: | ||
pyproject_toml = tomllib.load(_pyproject_file) | ||
|
||
if "project" in pyproject_toml: | ||
if "requires-python" in pyproject_toml["project"]: | ||
# This is the minumum version! | ||
raw_pyproject_minimum_version = pyproject_toml["project"][ | ||
"requires-python" | ||
] | ||
|
||
match = VERSION_PAT.match(raw_pyproject_minimum_version) | ||
if match: | ||
pyproject_minimum_version = match.group() | ||
pyproject_minimum_version_info = pyproject_minimum_version.split( | ||
"." | ||
) | ||
|
||
if ( | ||
runtime_python_version_info[0] | ||
< pyproject_minimum_version_info[0] | ||
) or ( | ||
runtime_python_version_info[1] | ||
< pyproject_minimum_version_info[1] | ||
): | ||
raise RuntimeError( | ||
"runtime.txt version not supported by pyproject.toml." | ||
) | ||
|
||
self._python_version = runtime_python_version | ||
return self._python_version | ||
|
||
@lru_cache | ||
def get_preassemble_script_files(self): | ||
"""Return files needed for preassembly""" | ||
files = super().get_preassemble_script_files() | ||
path = self.binder_path("pyproject.toml") | ||
if os.path.exists(path): | ||
files[path] = path | ||
return files | ||
|
||
@lru_cache | ||
def get_preassemble_scripts(self): | ||
"""scripts to run prior to staging the repo contents""" | ||
scripts = super().get_preassemble_scripts() | ||
return scripts | ||
|
||
@lru_cache | ||
def get_assemble_scripts(self): | ||
"""Return series of build-steps specific to this repository.""" | ||
# If we have pyproject.toml declare the | ||
# use of Python 2, Python 2.7 will be made available in the *kernel* | ||
# environment. The notebook servers environment on the other hand | ||
# requires Python 3 but may require something additional installed in it | ||
# still such as `nbgitpuller`. For this purpose, a "requirements3.txt" | ||
# file will be used to install dependencies for the notebook servers | ||
# environment, if Python 2 had been specified for the kernel | ||
# environment. | ||
assemble_scripts = super().get_assemble_scripts() | ||
|
||
if self.separate_kernel_env: | ||
# using legacy Python (e.g. 2.7) as a kernel | ||
|
||
# requirements3.txt allows for packages to be installed to the | ||
# notebook servers Python environment | ||
nb_requirements_file = self.binder_path("requirements3.txt") | ||
if os.path.exists(nb_requirements_file): | ||
assemble_scripts.append( | ||
( | ||
"${NB_USER}", | ||
f'${{NB_PYTHON_PREFIX}}/bin/pip install --no-cache-dir -r "{nb_requirements_file}"', | ||
) | ||
) | ||
|
||
assemble_scripts.append( | ||
( | ||
"${NB_USER}", | ||
"${KERNEL_PYTHON_PREFIX}/bin/pip install --no-cache-dir --editable .", | ||
) | ||
) | ||
|
||
return assemble_scripts | ||
|
||
def detect(self): | ||
"""Check if current repo should be built with the pyproject.toml buildpack.""" | ||
# first make sure python is not explicitly unwanted | ||
name, _, _ = self.runtime | ||
if name != "python": | ||
return False | ||
|
||
pyproject_file = self.binder_path("pyproject.toml") | ||
|
||
return os.path.exists(pyproject_file) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -62,7 +62,7 @@ def get_identifier(json): | |
"toml", | ||
"traitlets", | ||
], | ||
python_requires=">=3.9", | ||
python_requires=">=3.11", | ||
author="Project Jupyter Contributors", | ||
author_email="[email protected]", | ||
url="https://repo2docker.readthedocs.io/en/latest/", | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed here, we should not consider the presence of
pyproject.toml
sufficient. We should return False if pyproject.toml does not contain bothproject
andbuild-system.requires
.