Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions docs/reference/plugins/_python_common.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,22 @@ Dependencies
------------

Whether the Python interpreter needs to be included in the snap depends on its
``confinement``. Specifically:
base and confinement.

core26
~~~~~~

- The core26 base snap doesn't include Python, so the snap must always include it. This
is typically done with the :ref:`stage-packages <PartSpec.stage_packages>` key.

core24 and lower
~~~~~~~~~~~~~~~~

- Projects with ``strict`` or ``devmode`` confinement can safely use the base
snap's interpreter, so they typically do **not** need to include Python.
- Projects with ``classic`` confinement **cannot** use the base snap's
interpreter and thus must always bundle it (typically via ``stage-packages``).
interpreter and thus must always bundle it. This is typically done with the
:ref:`stage-packages <PartSpec.stage_packages>` key.
- In both cases, a specific/custom Python installation can always be included
in the snap. This can be useful, for example, when using a different Python
version or building an interpreter with custom flags.
Expand Down
28 changes: 28 additions & 0 deletions docs/release-notes/snapcraft-8-14.rst
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,31 @@ Snapcraft 8.14.1

- `craft-providers#898`_ Snapcraft retries calls to snapd when setting up the build
environment.
- `#5831`_ Files and directories for the test command, ``spread.yaml`` and ``spread/``,
no longer cause a part's build directory to be marked as dirty by Git.

.. _release-notes-fixes-8.14.2:

Snapcraft 8.14.2
~~~~~~~~~~~~~~~~

- `craft-parts#1476`_ Parts using the ``source-commit`` key can now disable the shallow
cloning behavior by specifying ``source-depth: 0``.

.. _release-notes-fixes-8.14.3:

Snapcraft 8.14.3
~~~~~~~~~~~~~~~~

- `#6020 <https://github.com/canonical/snapcraft/issues/6020>`__ The Python plugin can
now be used for strictly-confined core26 snaps.

.. _release-notes-fixes-8.14.4:

Snapcraft 8.14.4
~~~~~~~~~~~~~~~~

- `#5817`_ Unclear remote build error with ``--build-for`` on core20

Contributors
------------
Expand All @@ -146,3 +171,6 @@ and :literalref:`@tigarmo<https://github.com/tigarmo>`.

.. _craft-parts#1346: https://github.com/canonical/craft-parts/pull/1346
.. _craft-providers#898: https://github.com/canonical/craft-providers/pull/898
.. _#5831: https://github.com/canonical/snapcraft/issues/5831
.. _craft-parts#1476: https://github.com/canonical/craft-parts/pull/1476
.. _#5817: https://github.com/canonical/snapcraft/issues/5817
2 changes: 1 addition & 1 deletion extensions/desktop/common/desktop-exports
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ fi

# GTK theme and behavior modifier
# Those can impact the theme engine used by Qt as well
gtk_configs=(gtk-3.0/settings.ini gtk-3.0/bookmarks gtk-2.0/gtkfilechooser.ini)
gtk_configs=(gtk-4.0/settings.ini gtk-4.0/gtk.css gtk-4.0/bookmarks gtk-4.0/colors.css gtk-3.0/settings.ini gtk-3.0/gtk.css gtk-3.0/bookmarks gtk-3.0/colors.css gtk-2.0/gtkfilechooser.ini)
for f in "${gtk_configs[@]}"; do
dest="$XDG_CONFIG_HOME/$f"
if [ ! -L "$dest" ]; then
Expand Down
11 changes: 11 additions & 0 deletions extensions/desktop/kde-neon-6/launcher-specific
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ append_dir LD_LIBRARY_PATH "$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/blas"
# lapack
append_dir LD_LIBRARY_PATH "$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/lapack"

# lxqt-support
append_dir LD_LIBRARY_PATH "$SNAP/lxqt-support/usr/lib/$ARCH"

# KConfig uses QStandardPaths:GenericConfigLocation to get the config dir paths
# and checks for the kdeglobals file there for theming. The kdeglobals file is
# stored in $SNAP_REAL_HOME/.config folder.
Expand All @@ -26,6 +29,7 @@ append_dir QT_PLUGIN_PATH "$SNAP/usr/lib/$ARCH/qt6/plugins"
append_dir QT_PLUGIN_PATH "$SNAP/usr/lib/$ARCH"
append_dir QT_PLUGIN_PATH "$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/qt6/plugins"
append_dir QT_PLUGIN_PATH "$SNAP_DESKTOP_RUNTIME/usr/lib/$ARCH/"
append_dir QT_PLUGIN_PATH "$SNAP/lxqt-support/usr/lib/$ARCH/qt6/plugins"
# And QML2_IMPORT_PATH (Qt Modules).
append_dir QML2_IMPORT_PATH "$SNAP/usr/lib/$ARCH/qt6/qml"
append_dir QML2_IMPORT_PATH "$SNAP/lib/$ARCH"
Expand Down Expand Up @@ -58,3 +62,10 @@ if [ -e "$SNAP_DESKTOP_RUNTIME/usr/share/i18n" ]; then
export LOCPATH="$locpath:/usr/lib/locale"
LC_ALL=C.UTF-8 async_exec "$SNAP/snap/command-chain/locale-gen"
fi

# Kvantum configuration folder
KVANTUM_CONFIG_PATH="$XDG_CONFIG_HOME/Kvantum"
if [ ! -L "$KVANTUM_CONFIG_PATH" ] && [ -d "$SNAP_REAL_HOME/.config/Kvantum" ]; then
ensure_dir_exists "$(dirname "$KVANTUM_CONFIG_PATH")"
ln -sfn "$SNAP_REAL_HOME/.config/Kvantum" "$KVANTUM_CONFIG_PATH"
fi
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ dependencies = [
"attrs",
"catkin-pkg==1.1.0; sys_platform == 'linux'",
"click>=8.2",
"craft-application[remote]>=6.1.0",
"craft-application[remote]>=6.2.0",
"craft-archives>=2.2.0",
"craft-cli>=3.3.0",
"craft-grammar>=2.3.0",
Expand Down
15 changes: 2 additions & 13 deletions snapcraft/extensions/kde_neon_6.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,23 +228,15 @@ def get_root_snippet(self) -> dict[str, Any]:
lxqt_support_snap: {
"content": lxqt_support_snap,
"interface": "content",
"target": f"$SNAP/{lxqt_support_snap}",
"default-provider": lxqt_support_snap,
"target": "$SNAP/lxqt-support",
},
**gpu_plugs,
},
"environment": {
"SNAP_DESKTOP_RUNTIME": "$SNAP/kf6",
"GTK_USE_PORTAL": "1",
"PLATFORM_PLUG": platform_kf6_snap,
"LD_LIBRARY_PATH": (
f"$SNAP/{lxqt_support_snap}/usr/lib/"
"${CRAFT_ARCH_TRIPLET_BUILD_FOR}:${LD_LIBRARY_PATH}"
),
"QT_PLUGIN_PATH": (
f"$SNAP/{lxqt_support_snap}/usr/lib/"
"${CRAFT_ARCH_TRIPLET_BUILD_FOR}/qt6/plugins:${QT_PLUGIN_PATH}"
),
},
"hooks": {
"configure": {
Expand All @@ -255,11 +247,8 @@ def get_root_snippet(self) -> dict[str, Any]:
"layout": {
"/usr/share/X11": {"symlink": "$SNAP/kf6/usr/share/X11"},
"/usr/share/qt6": {"symlink": "$SNAP/kf6/usr/share/qt6"},
"/usr/share/color-schemes": {
"symlink": f"$SNAP/{lxqt_support_snap}/usr/share/color-schemes"
},
"/usr/share/Kvantum": {
"symlink": f"$SNAP/{lxqt_support_snap}/usr/share/Kvantum"
"symlink": "$SNAP/lxqt-support/usr/share/Kvantum"
},
**gpu_layouts,
},
Expand Down
24 changes: 16 additions & 8 deletions snapcraft/parts/plugins/python_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,16 @@ def get_system_interpreter(part_info: PartInfo) -> str | None:
base = part_info.project_base
confinement = part_info.confinement

if confinement == "classic" or base == "bare":
# classic snaps, and snaps without bases, must always provision Python
if confinement == "classic" or base in {"bare", "core26"}:
# Classic snaps, and snaps without bases, must always provision Python.
# The core26 base won't include Python, so even strictly confined snaps must provision Python.
interpreter = None
logger.debug(
"No system Python interpreter available (base=%s, confinement=%s). "
"Python will be provisioned by the snap.",
base,
confinement,
)
else:
# otherwise, we should always know which Python is present on the
# base. If this fails on a new base, update _CONFINED_PYTHON_PATH
Expand All @@ -59,12 +66,13 @@ def get_system_interpreter(part_info: PartInfo) -> str | None:
resolution = "Please contact the Snapcraft team."
raise errors.PartsError(brief=brief, resolution=resolution)

logger.debug(
"Using python interpreter '%s' for base '%s', confinement '%s'",
interpreter,
base,
confinement,
)
logger.debug(
"Using system Python interpreter '%s' (base=%s, confinement=%s)",
interpreter,
base,
confinement,
)

return interpreter


Expand Down
3 changes: 3 additions & 0 deletions snapcraft/templates/test/spread/.extension
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ restore_each() {
true
}

# If you want to allocate LXD VMs from remotes other than
# "ubuntu", such as "ubuntu-daily", this function should be
# modified to point there.
allocate_lxdvm() {
name=$(echo "$SPREAD_SYSTEM" | tr '[:punct:]' -)
system=$(echo "$SPREAD_SYSTEM" | tr / -)
Expand Down
30 changes: 30 additions & 0 deletions tests/spread/core26/python-hello/classic/snap/snapcraft.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: python-hello-classic
version: "1.0"
summary: simple python application
description: build a python application using core26
base: core26
build-base: devel
grade: devel
confinement: classic

apps:
python-hello-classic:
# Note that since commit 9b6e58337e0 we need to explicitly call bin/python,
# otherwise the wrong "python3" will be picked up by the shebang in
# $SNAP/bin/hello.
command: bin/python $SNAP/bin/hello

parts:
hello:
plugin: python
source: src
python-packages:
- black
build-attributes:
- enable-patchelf
stage-packages:
- libpython3.13-minimal
- libpython3.13-stdlib
- python3.13-minimal
- python3-venv
- python3-minimal # (for the "python3" symlink)
22 changes: 22 additions & 0 deletions tests/spread/core26/python-hello/poetry/snap/snapcraft.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: python-hello-poetry
version: "1.0"
summary: simple python application
description: build a python application using core26
base: core26
build-base: devel
grade: devel
confinement: strict

apps:
python-hello-poetry:
command: bin/hello
parts:
hello:
plugin: poetry
source: src
stage-packages:
- libpython3.13-minimal
- libpython3.13-stdlib
- python3.13-minimal
- python3-venv
- python3-minimal # (for the "python3" symlink)
18 changes: 18 additions & 0 deletions tests/spread/core26/python-hello/poetry/src/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[tool.poetry]
name = "hello"
version = "0.1.0"
description = ""
authors = ["Your Name <you@example.com>"]

[tool.poetry.dependencies]
python = "^3.10"
black = "^24.8.0"

[tool.poetry.dev-dependencies]

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

[tool.poetry.scripts]
hello = "hello:main"
5 changes: 5 additions & 0 deletions tests/spread/core26/python-hello/src/hello/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import black


def main():
print(f"hello world! black version: {black.__version__}")
10 changes: 10 additions & 0 deletions tests/spread/core26/python-hello/src/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env python3

from setuptools import setup

setup(
name="hello",
version="0.1",
entry_points={"console_scripts": ["hello=hello:main"]},
packages=["hello"],
)
24 changes: 24 additions & 0 deletions tests/spread/core26/python-hello/strict/snap/snapcraft.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: python-hello-strict
version: "1.0"
summary: simple python application
description: build a python application using core26
base: core26
build-base: devel
grade: devel
confinement: strict

apps:
python-hello-strict:
command: bin/python $SNAP/bin/hello
parts:
hello:
plugin: python
source: src
python-packages:
- black
stage-packages:
- libpython3.13-minimal
- libpython3.13-stdlib
- python3.13-minimal
- python3-venv
- python3-minimal # (for the "python3" symlink)
34 changes: 34 additions & 0 deletions tests/spread/core26/python-hello/task.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
summary: Build and run Python-based snaps in core26

environment:
PARAM/strict: ""
PARAM/classic: "--classic"

# failing because 26.04 uses poetry v2, which isn't compatible with the poetry v1 plugin
# PARAM/poetry: ""

# failing due to a broken symlink:
# /snap/python-hello-uv/current/bin/python -> /root/parts/hello/install/usr/bin/python3
# PARAM/uv: ""

prepare: |
# remove after core26 is stable (#6088)
snap install core26 --edge

restore: |
cd ./"${SPREAD_VARIANT}"
snapcraft clean
rm -f ./*.snap
snap remove "python-hello-${SPREAD_VARIANT}"
# remove after core26 is stable (#6088)
snap remove core26 --purge

execute: |
cp -r src ./"${SPREAD_VARIANT}"/
cd ./"${SPREAD_VARIANT}"

snapcraft
# shellcheck disable=SC2086
snap install python-hello-"${SPREAD_VARIANT}"_1.0_*.snap --dangerous ${PARAM}

python-hello-"${SPREAD_VARIANT}" | MATCH "hello world! black version"
24 changes: 24 additions & 0 deletions tests/spread/core26/python-hello/uv/snap/snapcraft.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: python-hello-uv
version: "1.0"
summary: simple python application
description: build a python application using core26
base: core26
build-base: devel
grade: devel
confinement: strict

apps:
python-hello-uv:
command: bin/python $SNAP/bin/hello
parts:
hello:
plugin: uv
source: src
build-snaps:
- astral-uv
stage-packages:
- libpython3.13-minimal
- libpython3.13-stdlib
- python3.13-minimal
- python3-venv
- python3-minimal # (for the "python3" symlink)
5 changes: 5 additions & 0 deletions tests/spread/core26/python-hello/uv/src/hello/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import black


def main():
print(f"hello world! black version: {black.__version__}")
16 changes: 16 additions & 0 deletions tests/spread/core26/python-hello/uv/src/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[project]
name = "hello"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.10"
dependencies = [
"black==24.8.0",
]

[build-system]
requires = ["setuptools>61"]
build-backend = "setuptools.build_meta"

[project.scripts]
hello = "hello:main"
Loading
Loading