bazel: 0.5.3 no longer allows to enforce Python3

Description of the problem / feature request / question:

I have a python script, that worked fine in 0.5.2.

Switching to 0.5.3 running

import concurrent.futures

gives me:

ImportError: No module named concurrent.futures

Environment info

  • Operating System: Ubuntu 16.04.2
  • Bazel version (output of bazel info release): 0.5.3

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 4
  • Comments: 23 (19 by maintainers)

Commits related to this issue

Most upvoted comments

I just wanted to offer a temporary workaround that we’re using to allow multiple python runtimes in a single workspace. You can set your py_runtime to a decorator script that inspects the shebang on the first line of the script to invoke a particular interpreter. You could make this a simple shell script which someone had suggested in another thread I can’t seem to find.

If you’re using distroless images (py_image or py3_image) using a shell script might be an issue so I wrote a statically linked go application. This is pretty heavy handed but not so bad if you’re already using go in your workspace. Hopefully either one of these options is viable until someone gets this sorted out.

.bazelrc

build --python_top=//:python-2-or-3

BUILD

load(
    "@io_bazel_rules_go//go:def.bzl",
    "go_binary",
)

go_binary(
    name = "python_decorator",
    srcs = ["python.go"],
    gc_linkopts = [
        "-linkmode",
        "external",
        "-extldflags",
        "-static",
    ],
)

py_runtime(
    name = "python-2-or-3",
    files = [],
    interpreter = ":python_decorator",
)

python.go

package main

import (
	"bufio"
	"log"
	"os"
	"strings"
	"syscall"
)

func python2Binary() string {
	return "/usr/bin/python"
}

func python3Binary() string {
	return "/usr/bin/python3"
}

func main() {
	if len(os.Args) < 2 {
		log.Fatal("No python script provided!")
	}
	file, err := os.Open(os.Args[1])
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)
	scanner.Scan()
	firstLine := scanner.Text()
	if err := scanner.Err(); err != nil {
		log.Fatal(err)
	}

	switch {
	case strings.Contains(firstLine, "python3"):
		if err := syscall.Exec(python3Binary(), append([]string{python3Binary()}, os.Args[1:]...), os.Environ()); err != nil {
			log.Fatal(err)
		}
	default:
		if err := syscall.Exec(python2Binary(), append([]string{python2Binary()}, os.Args[1:]...), os.Environ()); err != nil {
			log.Fatal(err)
		}
	}

}