Skip to content

Commit

Permalink
Deprecate Python 3.9 support (#314)
Browse files Browse the repository at this point in the history
  • Loading branch information
edmorley authored Jan 8, 2025
1 parent ed10970 commit ab247ed
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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))

Expand Down
31 changes: 29 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)?;

Expand Down
2 changes: 1 addition & 1 deletion tests/django_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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! {"
Expand Down
54 changes: 51 additions & 3 deletions tests/python_version_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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! {"
Expand All @@ -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");

Expand Down Expand Up @@ -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! {"
Expand Down

0 comments on commit ab247ed

Please sign in to comment.