source/tools/python/defs.bzl

265 lines
6.2 KiB
Python
Raw Normal View History

2021-04-08 06:37:51 +00:00
load("@arrdem_source_pypi//:requirements.bzl",
_py_requirement = "requirement"
)
load("@rules_python//python:defs.bzl",
2021-08-30 01:23:39 +00:00
"py_runtime",
"py_runtime_pair",
2021-04-08 06:37:51 +00:00
_py_binary = "py_binary",
_py_test = "py_test",
_py_library = "py_library",
)
load("@rules_zapp//zapp:zapp.bzl",
"zapp_binary",
)
load("@bazel_skylib//lib:sets.bzl", "sets")
2021-04-08 06:37:51 +00:00
def py_requirement(*args, **kwargs):
"""A re-export of requirement()"""
return _py_requirement(*args, **kwargs)
2021-04-08 06:37:51 +00:00
def py_test(python_version=None, **kwargs):
"""A re-export of py_test()"""
2021-04-08 06:37:51 +00:00
if python_version and python_version != "PY3":
fail("py3k only!")
2021-04-08 06:37:51 +00:00
return _py_test(
python_version="PY3",
**kwargs,
)
2021-04-08 06:37:51 +00:00
def py_pytest(name, srcs, deps, main=None, python_version=None, args=None, **kwargs):
"""A py_test target which uses pytest."""
2021-04-08 06:37:51 +00:00
if python_version and python_version != "PY3":
fail("py3k only!")
2021-04-08 06:37:51 +00:00
f = "//tools/python:bzl_pytest_shim.py"
deps = sets.to_list(sets.make([
py_requirement("pytest"),
# py_requirement("pytest-pudb"),
py_requirement("pytest-cov"),
2022-06-11 06:27:52 +00:00
py_requirement("pytest-timeout"),
] + deps))
2021-04-08 06:37:51 +00:00
srcs = [f] + srcs
2022-06-15 07:11:44 +00:00
py_test(
name = name,
srcs = srcs,
2021-04-08 06:37:51 +00:00
main = f,
args = args,
python_version="PY3",
deps = deps,
**kwargs,
)
2022-06-15 07:11:44 +00:00
# zapp_test(
# name = name + ".zapp",
# main = f,
# args = args,
# srcs = srcs,
# deps = deps,
# test = True,
# zip_safe = False,
# **kwargs,
# )
2022-06-15 07:11:44 +00:00
# FIXME (arrdem 2020-09-27):
# Generate a py_image_test.
# Not clear how to achieve that.
def py_unittest(srcs=[], **kwargs):
"""A helper for running unittest tests"""
f = "//tools/python:bzl_unittest_shim.py"
return py_test(
main = f,
srcs = [f] + srcs,
**kwargs
)
2021-04-08 06:37:51 +00:00
def py_binary(python_version=None, main=None, srcs=None, **kwargs):
"""A re-export of py_binary()"""
2021-04-08 06:37:51 +00:00
if python_version and python_version != "PY3":
fail("py3k only!")
2021-04-08 06:37:51 +00:00
srcs = srcs or []
if main not in srcs:
srcs = [main] + srcs
2021-04-08 06:37:51 +00:00
return _py_binary(
python_version = "PY3",
main = main,
srcs = srcs,
**kwargs,
)
2021-04-08 06:37:51 +00:00
def py_library(srcs_version=None, **kwargs):
"""A re-export of py_library()"""
2021-04-08 06:37:51 +00:00
if srcs_version and srcs_version != "PY3":
fail("py3k only!")
2021-04-08 06:37:51 +00:00
return _py_library(
srcs_version="PY3",
**kwargs
)
2021-04-08 06:37:51 +00:00
ResourceGroupInfo = provider(
fields = {
"srcs": "files to use from Python",
},
)
def _resource_impl(ctx):
srcs = []
for target in ctx.attr.srcs:
srcs.extend(target.files.to_list())
transitive_srcs = depset(direct = srcs)
return [
ResourceGroupInfo(
srcs = ctx.attr.srcs,
),
PyInfo(
has_py2_only_sources = False,
has_py3_only_sources = True,
uses_shared_libraries = False,
transitive_sources = transitive_srcs,
),
]
py_resources = rule(
implementation = _resource_impl,
attrs = {
"srcs": attr.label_list(
allow_empty = True,
mandatory = True,
allow_files = True,
doc = "Files to hand through to Python",
),
},
)
def py_project(name=None,
main=None,
2021-08-22 03:38:07 +00:00
main_deps=None,
main_data=None,
2022-11-20 06:54:45 +00:00
shebang=None,
2023-06-03 07:34:57 +00:00
zip_safe=True,
lib_srcs=None,
lib_deps=None,
2021-08-04 02:02:50 +00:00
lib_data=None,
test_srcs=None,
2021-08-04 02:02:50 +00:00
test_deps=None,
2024-04-07 07:30:45 +00:00
test_data=None,
test_tags=[]):
"""
A helper for defining conventionally-formatted python project.
2024-02-06 18:17:32 +00:00
Assumes that there's a {src,test}/ where src/ is a library and test/ is local tests only.
2021-08-14 01:55:41 +00:00
Each test_*.py source generates its own implicit test target. This allows for automatic test parallelism. Non
test_*.py files are implicitly srcs for the generated test targets. This is the same as making them implicitly a
testonly lib.
"""
2023-06-03 07:34:57 +00:00
lib_srcs = (lib_srcs or []) + \
2024-02-06 18:17:32 +00:00
native.glob(["src/**/*.py"],
2023-06-03 07:34:57 +00:00
exclude=[
"**/*.pyc",
])
lib_data = (lib_data or []) + \
2024-02-06 18:17:32 +00:00
native.glob(["src/**/*"],
2023-06-03 07:34:57 +00:00
exclude=[
"**/*.py",
"**/*.pyc",
])
test_srcs = (test_srcs or []) + \
2024-02-06 18:17:32 +00:00
native.glob(["test/**/*.py"],
2023-06-03 07:34:57 +00:00
exclude=[
"**/*.pyc",
])
test_data = (test_data or []) + \
2024-02-06 18:17:32 +00:00
native.glob(["test/**/*"],
2023-06-03 07:34:57 +00:00
exclude=[
"**/*.py",
"**/*.pyc",
])
lib_name = name if not main else "lib"
py_library(
name=lib_name,
srcs=lib_srcs,
deps=lib_deps,
2021-08-04 02:02:50 +00:00
data=lib_data,
2021-08-14 01:55:41 +00:00
imports=[
2024-02-06 18:20:44 +00:00
"src",
2021-08-14 01:55:41 +00:00
],
2021-08-04 02:02:50 +00:00
visibility = [
"//visibility:public",
],
)
if main:
py_binary(
name=name,
main=main,
2021-08-30 01:23:39 +00:00
deps=(main_deps or []) + [lib_name],
data=(main_data or []),
imports=[
2024-02-06 18:20:44 +00:00
"src",
],
visibility = [
"//visibility:public",
],
)
zapp_binary(
name=name + ".zapp",
main=main,
2021-08-30 01:23:39 +00:00
deps=(main_deps or []) + [lib_name],
data=lib_data,
imports=[
2024-02-06 18:20:44 +00:00
"src",
],
visibility = [
"//visibility:public",
],
2022-11-20 06:54:45 +00:00
shebang = shebang,
2023-06-03 07:34:57 +00:00
zip_safe=zip_safe,
)
for src in test_srcs:
if "test_" in src:
py_pytest(
2024-02-07 03:55:36 +00:00
name=src.split("/")[-1].replace(".py", ""),
2021-08-04 02:02:50 +00:00
srcs=[src] + [f for f in test_srcs if "test_" not in f],
deps=[lib_name] + (test_deps or []),
2021-08-04 02:02:50 +00:00
data=test_data,
2021-08-14 01:55:41 +00:00
imports=[
"test/python",
"test/resources",
],
2024-04-07 07:30:45 +00:00
tags=test_tags,
)