Skip to content

Commit 8ea46d3

Browse files
author
Tristan Daniël Maat
committed
WIP: Add python+coverage example
Currently WIP because: - `$(location)` and `$(rootpath)` make vars aren't working correctly - This is what we tried to fix with the `PYTHON_COVERAGE_TARGET` variable, which was ultimately not accepted. See also next point. - Does not use the new toolchain feature that supports adding coveragepy directly to the python toolchain - Added together with the new coveragepy support in bazelbuild/bazel#15590, and is probably better to use than the `$(rootpath)` and `pip_install` solution we're showing here - While I'd love to rewrite the blog post to show this instead, I'd need a bit more time for that - Python imports are wonky - For some reason, the sibling module can only be imported under a parent `python` module. I confirmed this by looking through `PYTHON_PATH` - Seems to be a Bazel regression? Strangely nobody is complaining about this yet, we should probably raise an issue - Not tested in remote execution - No access to an engflow setup to test this right this instant - Since we're not using a toolchain (and even if we were we're using `pip_install`), this requires a python on the host, so there's a decent chance it won't work - Requires bumping Bazel to a version with bazelbuild/bazel#15590 merged, which currently is only available in prereleases
1 parent 163ad01 commit 8ea46d3

File tree

7 files changed

+89
-15
lines changed

7 files changed

+89
-15
lines changed

.bazelversion

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
5.2.0
1+
6.0.0-pre.20221020.1

WORKSPACE

+18-14
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,24 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
44
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
55
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
66

7+
http_archive(
8+
name = "rules_python",
9+
sha256 = "8c8fe44ef0a9afc256d1e75ad5f448bb59b81aba149b8958f02f7b3a98f5d9b4",
10+
strip_prefix = "rules_python-0.13.0",
11+
url = "https://github.com/bazelbuild/rules_python/archive/refs/tags/0.13.0.tar.gz",
12+
)
13+
14+
load("@rules_python//python:pip.bzl", "pip_parse")
15+
16+
pip_parse(
17+
name = "coveragepy",
18+
requirements = "//python:requirements.txt",
19+
)
20+
21+
load("@coveragepy//:requirements.bzl", "install_deps")
22+
23+
install_deps()
24+
725
# Some file dependencies
826
http_file(
927
name = "emacs",
@@ -167,17 +185,3 @@ load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_depe
167185
go_rules_dependencies()
168186

169187
go_register_toolchains(version = "1.19.3")
170-
171-
http_archive(
172-
name = "io_bazel_rules_kotlin",
173-
sha256 = "a57591404423a52bd6b18ebba7979e8cd2243534736c5c94d35c89718ea38f94",
174-
urls = ["https://github.com/bazelbuild/rules_kotlin/releases/download/v1.6.0/rules_kotlin_release.tgz"],
175-
)
176-
177-
load("@io_bazel_rules_kotlin//kotlin:repositories.bzl", "kotlin_repositories")
178-
179-
kotlin_repositories()
180-
181-
load("@io_bazel_rules_kotlin//kotlin:core.bzl", "kt_register_toolchains")
182-
183-
kt_register_toolchains()

python/BUILD

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
"""Example of a python build/test with coverage.
2+
"""
3+
4+
load("@coveragepy//:requirements.bzl", "entry_point")
5+
6+
alias(
7+
name = "python_coverage_tools",
8+
actual = entry_point("coverage"),
9+
)
10+
11+
py_library(
12+
name = "example",
13+
srcs = [
14+
"__init__.py",
15+
"example.py",
16+
],
17+
)
18+
19+
py_test(
20+
name = "test_example",
21+
size = "small",
22+
srcs = ["test_example.py"],
23+
env = {
24+
# In theory this should be `$(execpath :python_coverage_tool)`,
25+
#
26+
# however this will not resolve correctly as Bazel will
27+
# resolve this relative to the runfiles directory. Instead, we
28+
# just manually specify the path in the runfiles directory the
29+
# coverage tools will be placed in.
30+
#
31+
# For a better solution involving setting the coverage tool in
32+
# the toolchain, see
33+
# https://github.com/bazelbuild/bazel/pull/15590
34+
"PYTHON_COVERAGE": "coveragepy_coverage/rules_python_wheel_entry_point_coverage",
35+
},
36+
deps = [
37+
":example",
38+
":python_coverage_tools",
39+
],
40+
)

python/__init__.py

Whitespace-only changes.

python/example.py

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
def fizzbuzz(i: int) -> str:
2+
if i % 3 == 0:
3+
if i % 5 == 0:
4+
return "FizzBuzz"
5+
else:
6+
return "Fizz"
7+
elif i % 5 == 0:
8+
return "Buzz"
9+
else:
10+
return str(i)

python/requirements.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
coverage==6.5.0

python/test_example.py

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import unittest
2+
3+
# Bazel seems to be setting the PYTHON_PATH wrong, resulting in a
4+
# parent "python" module. This might be a regression.
5+
from python.example import fizzbuzz
6+
7+
8+
class ExampleTest(unittest.TestCase):
9+
def test_fizzbuzz(self):
10+
self.assertEqual(fizzbuzz(1), "1")
11+
self.assertEqual(fizzbuzz(2), "2")
12+
self.assertEqual(fizzbuzz(3), "Fizz")
13+
self.assertEqual(fizzbuzz(4), "4")
14+
self.assertEqual(fizzbuzz(5), "Buzz")
15+
self.assertEqual(fizzbuzz(15), "FizzBuzz")
16+
17+
18+
if __name__ == "__main__":
19+
unittest.main()

0 commit comments

Comments
 (0)