Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,16 @@ public ResolvedPythonEnvironment setup(final Property<String> containerImage, fi
}

String pythonInterpreter = "python";
if (pythonVersion != null && (taskRunner instanceof Process || RunnerType.PROCESS.equals(runnerType))) {
pythonInterpreter = resolver.getPythonPath(targetPythonVersion);
if (taskRunner instanceof Process || RunnerType.PROCESS.equals(runnerType)) {
// The Process runner executes commands directly on the worker host, which may only ship
// 'python3' (Debian/Ubuntu, the standard Kestra worker image) and not the bare 'python'
// literal. When an explicit pythonVersion is set, resolve it through the configured package
// manager (may provision a managed Python via 'uv'). Otherwise, probe for an interpreter
// that is already installed (python3, then python) rather than forcing a managed-Python
// download just to run a script with no dependencies.
pythonInterpreter = pythonVersion != null
? resolver.getPythonPath(targetPythonVersion)
: PackageManagerType.PIP.getPythonPath(resolver, targetPythonVersion);
}

return new ResolvedPythonEnvironment(cached, resolvedPythonPackages, pythonInterpreter);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package io.kestra.plugin.scripts.python.internals;

import java.util.Map;
import java.util.UUID;

import org.junit.jupiter.api.Test;

import io.kestra.core.junit.annotations.KestraTest;
import io.kestra.core.models.property.Property;
import io.kestra.core.runners.RunContext;
import io.kestra.core.runners.RunContextFactory;
import io.kestra.plugin.scripts.exec.scripts.models.RunnerType;
import io.kestra.plugin.scripts.python.Script;

import jakarta.inject.Inject;

import static io.kestra.core.utils.TestsUtils.mockRunContext;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;

@KestraTest
class PythonEnvironmentManagerTest {

@Inject
RunContextFactory runContextFactory;

@Test
void shouldResolveARunnableInterpreterForProcessRunnerWithoutExplicitPythonVersion() throws Exception {
// Regression test: without an explicit pythonVersion, the Process runner used to default the
// interpreter to the literal "python", which doesn't exist on python3-only hosts (Debian/Ubuntu,
// the standard Kestra worker image), causing "/bin/sh: python: not found" (exit code 127).
Script task = Script.builder()
.id("python-env-manager-test-" + UUID.randomUUID())
.type(Script.class.getName())
.script(Property.ofValue("print('hello')"))
.build();
RunContext runContext = mockRunContext(runContextFactory, task, Map.of());

PythonEnvironmentManager manager = new PythonEnvironmentManager(runContext, task);
PythonEnvironmentManager.ResolvedPythonEnvironment environment = manager.setup(task.getContainerImage(), null, RunnerType.PROCESS);

assertThat(environment.interpreter(), is(not("python")));

Process process = new ProcessBuilder(environment.interpreter(), "--version").start();
assertThat(process.waitFor(), is(0));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ tasks:
main.py: |
print("Hello, World from the Commands Task and Process Task Runner")
commands:
- python main.py
- python3 main.py

- id: python_script_logs
type: io.kestra.plugin.scripts.python.Script
Expand Down
Loading