From ab247ed6d2b32acf4d2ddaecab84499a407061e7 Mon Sep 17 00:00:00 2001 From: Ed Morley <501702+edmorley@users.noreply.github.com> Date: Wed, 8 Jan 2025 18:46:46 +0000 Subject: [PATCH] Deprecate Python 3.9 support (#314) In accordance with the Python version support policy: https://devcenter.heroku.com/articles/python-support#python-version-support-policy See also: https://devcenter.heroku.com/changelog-items/3095 https://github.com/heroku/heroku-buildpack-python/pull/1732 GUS-W-14846951. --- CHANGELOG.md | 1 + src/main.rs | 31 +++++++++++++++++++-- tests/django_test.rs | 2 +- tests/python_version_test.rs | 54 ++++++++++++++++++++++++++++++++++-- 4 files changed, 82 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f811df7..d497d8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Deprecated support for Python 3.9. ([#314](https://github.com/heroku/buildpacks-python/pull/314)) - Buildpack detection now recognises more Python-related file and directory names. ([#312](https://github.com/heroku/buildpacks-python/pull/312)) - Improved the error messages shown for EOL or unrecognised major Python versions. ([#313](https://github.com/heroku/buildpacks-python/pull/313)) diff --git a/src/main.rs b/src/main.rs index aad573a..da037b4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,14 +20,15 @@ use crate::layers::python::PythonLayerError; use crate::layers::{pip, pip_cache, pip_dependencies, poetry, poetry_dependencies, python}; use crate::package_manager::{DeterminePackageManagerError, PackageManager}; use crate::python_version::{ - PythonVersionOrigin, RequestedPythonVersionError, ResolvePythonVersionError, + PythonVersionOrigin, RequestedPythonVersion, RequestedPythonVersionError, + ResolvePythonVersionError, }; use indoc::formatdoc; use libcnb::build::{BuildContext, BuildResult, BuildResultBuilder}; use libcnb::detect::{DetectContext, DetectResult, DetectResultBuilder}; use libcnb::generic::{GenericMetadata, GenericPlatform}; use libcnb::{buildpack_main, Buildpack, Env}; -use libherokubuildpack::log::{log_header, log_info}; +use libherokubuildpack::log::{log_header, log_info, log_warning}; use std::io; struct PythonBuildpack; @@ -91,6 +92,32 @@ impl Buildpack for PythonBuildpack { )), } + if let RequestedPythonVersion { + major: 3, + minor: 9, + origin, + .. + } = requested_python_version + { + log_warning( + "Support for Python 3.9 is deprecated", + formatdoc! {" + Python 3.9 will reach its upstream end-of-life in October 2025, + at which point it will no longer receive security updates: + https://devguide.python.org/versions/#supported-versions + + As such, support for Python 3.9 will be removed from this + buildpack on 7th January 2026. + + Upgrade to a newer Python version as soon as possible, by + changing the version in your {origin} file. + + For more information, see: + https://devcenter.heroku.com/articles/python-support#supported-python-versions + "}, + ); + } + log_header("Installing Python"); let python_layer_path = python::install_python(&context, &mut env, &python_version)?; diff --git a/tests/django_test.rs b/tests/django_test.rs index 4cceb09..6c0c89a 100644 --- a/tests/django_test.rs +++ b/tests/django_test.rs @@ -34,7 +34,7 @@ fn django_staticfiles_legacy_django() { TestRunner::default().build( default_build_config("tests/fixtures/django_staticfiles_legacy_django"), |context| { - assert_empty!(context.pack_stderr); + // We can't `assert_empty!(context.pack_stderr)` here, due to the Python 3.9 deprecation warning. assert_contains!( context.pack_stdout, indoc! {" diff --git a/tests/python_version_test.rs b/tests/python_version_test.rs index e366237..3fd4f98 100644 --- a/tests/python_version_test.rs +++ b/tests/python_version_test.rs @@ -60,14 +60,38 @@ fn python_3_13() { } fn builds_with_python_version(fixture_path: &str, python_version: &PythonVersion) { - let PythonVersion { + let &PythonVersion { major, minor, patch, } = python_version; TestRunner::default().build(default_build_config(fixture_path), |context| { - assert_empty!(context.pack_stderr); + if major == 3 && minor == 9 { + assert_eq!( + context.pack_stderr, + indoc! {" + + [Warning: Support for Python 3.9 is deprecated] + Python 3.9 will reach its upstream end-of-life in October 2025, + at which point it will no longer receive security updates: + https://devguide.python.org/versions/#supported-versions + + As such, support for Python 3.9 will be removed from this + buildpack on 7th January 2026. + + Upgrade to a newer Python version as soon as possible, by + changing the version in your .python-version file. + + For more information, see: + https://devcenter.heroku.com/articles/python-support#supported-python-versions + + "} + ); + } else { + assert_empty!(context.pack_stderr); + } + assert_contains!( context.pack_stdout, &formatdoc! {" @@ -78,6 +102,7 @@ fn builds_with_python_version(fixture_path: &str, python_version: &PythonVersion Installing Python {major}.{minor}.{patch} "} ); + // There's no sensible default process type we can set for Python apps. assert_contains!(context.pack_stdout, "no default process type"); @@ -294,13 +319,36 @@ fn python_version_non_existent_minor() { }); } +// This tests that: +// - The Python version can be specified using runtime.txt +// - pip works with the oldest currently supported Python version (3.9.0). +// - The Python 3.9 deprecation warning correctly lists the origin as runtime.txt. #[test] #[ignore = "integration test"] fn runtime_txt() { let config = default_build_config("tests/fixtures/runtime_txt_and_python_version_file"); TestRunner::default().build(config, |context| { - assert_empty!(context.pack_stderr); + assert_eq!( + context.pack_stderr, + indoc! {" + + [Warning: Support for Python 3.9 is deprecated] + Python 3.9 will reach its upstream end-of-life in October 2025, + at which point it will no longer receive security updates: + https://devguide.python.org/versions/#supported-versions + + As such, support for Python 3.9 will be removed from this + buildpack on 7th January 2026. + + Upgrade to a newer Python version as soon as possible, by + changing the version in your runtime.txt file. + + For more information, see: + https://devcenter.heroku.com/articles/python-support#supported-python-versions + + "} + ); assert_contains!( context.pack_stdout, indoc! {"