From 69b79bdfe11c80eeb5b87f3682654c236d8304bf Mon Sep 17 00:00:00 2001 From: Aditya Kumar Singh Date: Thu, 22 Oct 2026 22:00:44 +0530 Subject: [PATCH 1/2] fix(python): handle numeric timestamps and build dates in looksLikePythonVersion --- .../internals/PythonEnvironmentManager.java | 13 +++-- .../internals/PythonVersionParserTest.java | 50 ++++++++++++++----- 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/plugin-script-python/src/main/java/io/kestra/plugin/scripts/python/internals/PythonEnvironmentManager.java b/plugin-script-python/src/main/java/io/kestra/plugin/scripts/python/internals/PythonEnvironmentManager.java index 40bc82d3..af99fb88 100644 --- a/plugin-script-python/src/main/java/io/kestra/plugin/scripts/python/internals/PythonEnvironmentManager.java +++ b/plugin-script-python/src/main/java/io/kestra/plugin/scripts/python/internals/PythonEnvironmentManager.java @@ -14,7 +14,6 @@ import io.kestra.core.models.executions.metrics.Timer; import io.kestra.core.models.property.Property; import io.kestra.core.models.tasks.runners.TaskRunner; -import io.kestra.core.runners.DefaultRunContext; import io.kestra.core.runners.RunContext; import io.kestra.plugin.core.runner.Process; import io.kestra.plugin.scripts.exec.scripts.models.RunnerType; @@ -188,8 +187,16 @@ private Optional getTargetPythonVersion(final Property container * that the parser extracted because the image name contained "python". */ static boolean looksLikePythonVersion(String version) { - int major = Integer.parseInt(version.split("\\.")[0]); - return major >= 2; + if (version == null || version.isEmpty()) { + return false; + } + + try { + int major = Integer.parseInt(version.split("\\.")[0]); + return major >= 2 && major <= 9; + } catch (NumberFormatException e) { + return false; + } } /** diff --git a/plugin-script-python/src/test/java/io/kestra/plugin/scripts/python/internals/PythonVersionParserTest.java b/plugin-script-python/src/test/java/io/kestra/plugin/scripts/python/internals/PythonVersionParserTest.java index dc1658e7..ec9dd3e8 100644 --- a/plugin-script-python/src/test/java/io/kestra/plugin/scripts/python/internals/PythonVersionParserTest.java +++ b/plugin-script-python/src/test/java/io/kestra/plugin/scripts/python/internals/PythonVersionParserTest.java @@ -1,11 +1,11 @@ package io.kestra.plugin.scripts.python.internals; +import java.util.Optional; + import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; -import java.util.Optional; - import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; @@ -57,17 +57,19 @@ void shouldParsePython27() { } @ParameterizedTest - @ValueSource(strings = { - "python:3.6", - "python:3.7", - "python:3.8", - "python:3.9", - "python:3.10", - "python:3.11", - "python:3.12", - "python:3.13", - "python:3.14" - }) + @ValueSource( + strings = { + "python:3.6", + "python:3.7", + "python:3.8", + "python:3.9", + "python:3.10", + "python:3.11", + "python:3.12", + "python:3.13", + "python:3.14" + } + ) void shouldParseValidPythonVersions(String image) { var result = PythonVersionParser.parsePyVersionFromDockerImage(image); assertThat(result.isPresent(), is(true)); @@ -112,4 +114,26 @@ void looksLikePythonVersion_rejectsVersion0() { void looksLikePythonVersion_rejectsVersion1() { assertThat(PythonEnvironmentManager.looksLikePythonVersion("1.5.2"), is(false)); } + + @Test + void looksLikePythonVersion_rejectsNumericTimestampTag() { + assertThat(PythonEnvironmentManager.looksLikePythonVersion("20261021113000"), is(false)); + } + + @Test + void looksLikePythonVersion_rejectsBuildDateTag() { + assertThat(PythonEnvironmentManager.looksLikePythonVersion("20241021"), is(false)); + } + + @Test + void looksLikePythonVersion_rejectsBuildYearTag() { + assertThat(PythonEnvironmentManager.looksLikePythonVersion("2024.1"), is(false)); + } + + @Test + void looksLikePythonVersion_rejectsNonNumericOrNull() { + assertThat(PythonEnvironmentManager.looksLikePythonVersion(null), is(false)); + assertThat(PythonEnvironmentManager.looksLikePythonVersion(""), is(false)); + assertThat(PythonEnvironmentManager.looksLikePythonVersion("abc"), is(false)); + } } From 9d150f13a8f7b35854c4b5bc07a101b33fcdb7de Mon Sep 17 00:00:00 2001 From: Malay Dewangan Date: Mon, 26 Oct 2026 03:20:27 +0530 Subject: [PATCH 2/2] fix(python): drop the unreachable null guard in looksLikePythonVersion --- .../python/internals/PythonEnvironmentManager.java | 9 +++------ .../python/internals/PythonVersionParserTest.java | 7 ------- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/plugin-script-python/src/main/java/io/kestra/plugin/scripts/python/internals/PythonEnvironmentManager.java b/plugin-script-python/src/main/java/io/kestra/plugin/scripts/python/internals/PythonEnvironmentManager.java index af99fb88..503a6c6b 100644 --- a/plugin-script-python/src/main/java/io/kestra/plugin/scripts/python/internals/PythonEnvironmentManager.java +++ b/plugin-script-python/src/main/java/io/kestra/plugin/scripts/python/internals/PythonEnvironmentManager.java @@ -182,19 +182,16 @@ private Optional getTargetPythonVersion(final Property container } /** - * Returns true if the version looks like a real Python version (major >= 2). + * Returns true if the version looks like a real Python version (single-digit major from 2, so future majors keep working). * This filters out non-Python version tags (e.g. "0.0.10" from a custom image) * that the parser extracted because the image name contained "python". */ static boolean looksLikePythonVersion(String version) { - if (version == null || version.isEmpty()) { - return false; - } - try { - int major = Integer.parseInt(version.split("\\.")[0]); + var major = Integer.parseInt(version.split("\\.")[0]); return major >= 2 && major <= 9; } catch (NumberFormatException e) { + // Timestamp tags overflow an int, they are not Python versions return false; } } diff --git a/plugin-script-python/src/test/java/io/kestra/plugin/scripts/python/internals/PythonVersionParserTest.java b/plugin-script-python/src/test/java/io/kestra/plugin/scripts/python/internals/PythonVersionParserTest.java index ec9dd3e8..defe2c56 100644 --- a/plugin-script-python/src/test/java/io/kestra/plugin/scripts/python/internals/PythonVersionParserTest.java +++ b/plugin-script-python/src/test/java/io/kestra/plugin/scripts/python/internals/PythonVersionParserTest.java @@ -129,11 +129,4 @@ void looksLikePythonVersion_rejectsBuildDateTag() { void looksLikePythonVersion_rejectsBuildYearTag() { assertThat(PythonEnvironmentManager.looksLikePythonVersion("2024.1"), is(false)); } - - @Test - void looksLikePythonVersion_rejectsNonNumericOrNull() { - assertThat(PythonEnvironmentManager.looksLikePythonVersion(null), is(false)); - assertThat(PythonEnvironmentManager.looksLikePythonVersion(""), is(false)); - assertThat(PythonEnvironmentManager.looksLikePythonVersion("abc"), is(false)); - } }