From eea59e99de59e81af64935e6602638a680e60736 Mon Sep 17 00:00:00 2001 From: Matt Mackay Date: Mon, 6 Jun 2022 14:13:48 -0400 Subject: [PATCH 1/7] feat: add py_pytest_main entrypoint --- examples/build_file_generation/BUILD | 28 ++- examples/build_file_generation/WORKSPACE | 10 + examples/build_file_generation/foo_test.py | 4 + .../build_file_generation/gazelle_python.yaml | 182 +++++++++++++++++- .../build_file_generation/requirements.txt | 1 + .../requirements_lock.txt | 34 +++- gazelle/README.md | 4 + python/py_pytest_main/BUILD.bazel | 1 + python/py_pytest_main/def.bzl | 64 ++++++ python/py_pytest_main/pytest.tmpl.py | 41 ++++ 10 files changed, 366 insertions(+), 3 deletions(-) create mode 100644 examples/build_file_generation/foo_test.py create mode 100644 python/py_pytest_main/BUILD.bazel create mode 100644 python/py_pytest_main/def.bzl create mode 100644 python/py_pytest_main/pytest.tmpl.py diff --git a/examples/build_file_generation/BUILD b/examples/build_file_generation/BUILD index ef9e967d5a..559a71620a 100644 --- a/examples/build_file_generation/BUILD +++ b/examples/build_file_generation/BUILD @@ -3,7 +3,14 @@ load("@pip//:requirements.bzl", "all_whl_requirements") load("@rules_python//gazelle:def.bzl", "GAZELLE_PYTHON_RUNTIME_DEPS") load("@rules_python//gazelle/manifest:defs.bzl", "gazelle_python_manifest") load("@rules_python//gazelle/modules_mapping:def.bzl", "modules_mapping") -load("@rules_python//python:defs.bzl", "py_binary", "py_library") +load("@rules_python//python:pip.bzl", "compile_pip_requirements") +load("@rules_python//python:defs.bzl", "py_binary", "py_library", "py_pytest_main", "py_test") + +compile_pip_requirements( + name = "pip_compile", + requirements_in = "requirements.txt", + requirements_txt = "requirements_lock.txt", +) # This rule fetches the metadata for python packages we depend on. That data is # required for the gazelle_python_manifest rule to update our manifest file. @@ -54,3 +61,22 @@ py_binary( visibility = ["//:__subpackages__"], deps = [":build_file_generation"], ) + +# Generates an entrypoint for pytest that is picked up by Gazelle for the py_test target below. +py_pytest_main( + name = "__test__", +) + +py_test( + name = "build_file_generation_test", + srcs = [ + "foo_test.py", + ":__test__", + ], + main = ":__test__.py", + deps = [ + ":__test__", + ":build_file_generation", + "@pip_pytest//:pkg", + ], +) diff --git a/examples/build_file_generation/WORKSPACE b/examples/build_file_generation/WORKSPACE index 51c923f133..09983b70b3 100644 --- a/examples/build_file_generation/WORKSPACE +++ b/examples/build_file_generation/WORKSPACE @@ -48,11 +48,21 @@ local_repository( path = "../..", ) +load("@rules_python//python:repositories.bzl", "python_register_toolchains") + +python_register_toolchains( + name = "python39", + python_version = "3.9", +) + +load("@python39//:defs.bzl", "interpreter") + load("@rules_python//python:pip.bzl", "pip_parse") pip_parse( name = "pip", requirements_lock = "//:requirements_lock.txt", + python_interpreter_target = interpreter, ) load("@pip//:requirements.bzl", "install_deps") diff --git a/examples/build_file_generation/foo_test.py b/examples/build_file_generation/foo_test.py new file mode 100644 index 0000000000..ea07a244f6 --- /dev/null +++ b/examples/build_file_generation/foo_test.py @@ -0,0 +1,4 @@ +import pytest + +def test_add(): + assert 1 + 1 == 2, "Expected 1 + 1 to equal 2" diff --git a/examples/build_file_generation/gazelle_python.yaml b/examples/build_file_generation/gazelle_python.yaml index a005b43d0f..e952da8684 100644 --- a/examples/build_file_generation/gazelle_python.yaml +++ b/examples/build_file_generation/gazelle_python.yaml @@ -5,6 +5,98 @@ manifest: modules_mapping: + _pytest: pytest + _pytest.__init__: pytest + _pytest._argcomplete: pytest + _pytest._code: pytest + _pytest._code.__init__: pytest + _pytest._code.code: pytest + _pytest._code.source: pytest + _pytest._io: pytest + _pytest._io.__init__: pytest + _pytest._io.saferepr: pytest + _pytest._io.terminalwriter: pytest + _pytest._io.wcwidth: pytest + _pytest._version: pytest + _pytest.assertion: pytest + _pytest.assertion.__init__: pytest + _pytest.assertion.rewrite: pytest + _pytest.assertion.truncate: pytest + _pytest.assertion.util: pytest + _pytest.cacheprovider: pytest + _pytest.capture: pytest + _pytest.compat: pytest + _pytest.config: pytest + _pytest.config.__init__: pytest + _pytest.config.argparsing: pytest + _pytest.config.compat: pytest + _pytest.config.exceptions: pytest + _pytest.config.findpaths: pytest + _pytest.debugging: pytest + _pytest.deprecated: pytest + _pytest.doctest: pytest + _pytest.faulthandler: pytest + _pytest.fixtures: pytest + _pytest.freeze_support: pytest + _pytest.helpconfig: pytest + _pytest.hookspec: pytest + _pytest.junitxml: pytest + _pytest.legacypath: pytest + _pytest.logging: pytest + _pytest.main: pytest + _pytest.mark: pytest + _pytest.mark.__init__: pytest + _pytest.mark.expression: pytest + _pytest.mark.structures: pytest + _pytest.monkeypatch: pytest + _pytest.nodes: pytest + _pytest.nose: pytest + _pytest.outcomes: pytest + _pytest.pastebin: pytest + _pytest.pathlib: pytest + _pytest.pytester: pytest + _pytest.pytester_assertions: pytest + _pytest.python: pytest + _pytest.python_api: pytest + _pytest.python_path: pytest + _pytest.recwarn: pytest + _pytest.reports: pytest + _pytest.runner: pytest + _pytest.scope: pytest + _pytest.setuponly: pytest + _pytest.setupplan: pytest + _pytest.skipping: pytest + _pytest.stash: pytest + _pytest.stepwise: pytest + _pytest.terminal: pytest + _pytest.threadexception: pytest + _pytest.timing: pytest + _pytest.tmpdir: pytest + _pytest.unittest: pytest + _pytest.unraisableexception: pytest + _pytest.warning_types: pytest + _pytest.warnings: pytest + attr: attrs + attr.__init__: attrs + attr._cmp: attrs + attr._compat: attrs + attr._config: attrs + attr._funcs: attrs + attr._make: attrs + attr._next_gen: attrs + attr._version_info: attrs + attr.converters: attrs + attr.exceptions: attrs + attr.filters: attrs + attr.setters: attrs + attr.validators: attrs + attrs: attrs + attrs.__init__: attrs + attrs.converters: attrs + attrs.exceptions: attrs + attrs.filters: attrs + attrs.setters: attrs + attrs.validators: attrs certifi: certifi certifi.__init__: certifi certifi.__main__: certifi @@ -61,6 +153,89 @@ manifest: idna.intranges: idna idna.package_data: idna idna.uts46data: idna + iniconfig: iniconfig + iniconfig.__init__: iniconfig + packaging: packaging + packaging.__about__: packaging + packaging.__init__: packaging + packaging._manylinux: packaging + packaging._musllinux: packaging + packaging._structures: packaging + packaging.markers: packaging + packaging.requirements: packaging + packaging.specifiers: packaging + packaging.tags: packaging + packaging.utils: packaging + packaging.version: packaging + pluggy: pluggy + pluggy.__init__: pluggy + pluggy._callers: pluggy + pluggy._hooks: pluggy + pluggy._manager: pluggy + pluggy._result: pluggy + pluggy._tracing: pluggy + pluggy._version: pluggy + py: py + py.__init__: py + py.__metainfo: py + py._builtin: py + py._code: py + py._code.__init__: py + py._code._assertionnew: py + py._code._assertionold: py + py._code._py2traceback: py + py._code.assertion: py + py._code.code: py + py._code.source: py + py._error: py + py._io: py + py._io.__init__: py + py._io.capture: py + py._io.saferepr: py + py._io.terminalwriter: py + py._log: py + py._log.__init__: py + py._log.log: py + py._log.warning: py + py._path: py + py._path.__init__: py + py._path.cacheutil: py + py._path.common: py + py._path.local: py + py._path.svnurl: py + py._path.svnwc: py + py._process: py + py._process.__init__: py + py._process.cmdexec: py + py._process.forkedfunc: py + py._process.killproc: py + py._std: py + py._vendored_packages: py + py._vendored_packages.__init__: py + py._vendored_packages.apipkg: py + py._vendored_packages.apipkg.__init__: py + py._vendored_packages.apipkg.version: py + py._vendored_packages.iniconfig: py + py._vendored_packages.iniconfig.__init__: py + py._version: py + py._xmlgen: py + py.test: py + pyparsing: pyparsing + pyparsing.__init__: pyparsing + pyparsing.actions: pyparsing + pyparsing.common: pyparsing + pyparsing.core: pyparsing + pyparsing.diagram: pyparsing + pyparsing.diagram.__init__: pyparsing + pyparsing.exceptions: pyparsing + pyparsing.helpers: pyparsing + pyparsing.results: pyparsing + pyparsing.testing: pyparsing + pyparsing.unicode: pyparsing + pyparsing.util: pyparsing + pytest: pytest + pytest.__init__: pytest + pytest.__main__: pytest requests: requests requests.__init__: requests requests.__version__: requests @@ -80,6 +255,11 @@ manifest: requests.status_codes: requests requests.structures: requests requests.utils: requests + tomli: tomli + tomli.__init__: tomli + tomli._parser: tomli + tomli._re: tomli + tomli._types: tomli urllib3: urllib3 urllib3.__init__: urllib3 urllib3._collections: urllib3 @@ -129,4 +309,4 @@ manifest: pip_repository: name: pip incremental: true -integrity: c47bf2ca0a185cf6b8815d4a61e26e7457564e931de76c70653277e4eccfadc8 +integrity: 71c787ef3d0dca470bb9c1913a5ef3ca4373db13cbd24acada1c7fcb40ef10ee diff --git a/examples/build_file_generation/requirements.txt b/examples/build_file_generation/requirements.txt index 9d84d35885..5bd551ad6d 100644 --- a/examples/build_file_generation/requirements.txt +++ b/examples/build_file_generation/requirements.txt @@ -1 +1,2 @@ requests==2.25.1 +pytest \ No newline at end of file diff --git a/examples/build_file_generation/requirements_lock.txt b/examples/build_file_generation/requirements_lock.txt index b66c41fef9..65b1b81ca8 100644 --- a/examples/build_file_generation/requirements_lock.txt +++ b/examples/build_file_generation/requirements_lock.txt @@ -2,8 +2,12 @@ # This file is autogenerated by pip-compile with python 3.9 # To update, run: # -# pip-compile --generate-hashes --output-file=requirements_lock.txt requirements.txt +# bazel run //:pip_compile.update # +attrs==21.4.0 \ + --hash=sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4 \ + --hash=sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd + # via pytest certifi==2020.12.5 \ --hash=sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c \ --hash=sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830 @@ -16,10 +20,38 @@ idna==2.10 \ --hash=sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6 \ --hash=sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0 # via requests +iniconfig==1.1.1 \ + --hash=sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3 \ + --hash=sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32 + # via pytest +packaging==21.3 \ + --hash=sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb \ + --hash=sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522 + # via pytest +pluggy==1.0.0 \ + --hash=sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159 \ + --hash=sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3 + # via pytest +py==1.11.0 \ + --hash=sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719 \ + --hash=sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378 + # via pytest +pyparsing==3.0.9 \ + --hash=sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb \ + --hash=sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc + # via packaging +pytest==7.1.2 \ + --hash=sha256:13d0e3ccfc2b6e26be000cb6568c832ba67ba32e719443bfe725814d3c42433c \ + --hash=sha256:a06a0425453864a270bc45e71f783330a7428defb4230fb5e6a731fde06ecd45 + # via -r requirements.txt requests==2.25.1 \ --hash=sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804 \ --hash=sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e # via -r requirements.txt +tomli==2.0.1 \ + --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \ + --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f + # via pytest urllib3==1.26.5 \ --hash=sha256:753a0374df26658f99d826cfe40394a686d05985786d946fbe4165b5148f5a7c \ --hash=sha256:a7acd0977125325f516bda9735fa7142b909a8d01e8b2e4c8108d0984e6e0098 diff --git a/gazelle/README.md b/gazelle/README.md index 51055cb953..7515c9bb6e 100644 --- a/gazelle/README.md +++ b/gazelle/README.md @@ -166,6 +166,10 @@ dependencies are added to the `deps` attribute. Python test files are those ending in `_test.py`. +Gazelle will add a `py_test` target whenever it finds either of the following: +* A target in the same Bazel package named __test__. The macro `py_pytest_main` provide these entrypoint wrappers. +* A file in the same directory named __test__.py. + A `py_test` target is added containing all test files as `srcs`. ### Binaries diff --git a/python/py_pytest_main/BUILD.bazel b/python/py_pytest_main/BUILD.bazel new file mode 100644 index 0000000000..cc2d302fe7 --- /dev/null +++ b/python/py_pytest_main/BUILD.bazel @@ -0,0 +1 @@ +exports_files(["pytest.tmpl.py"], visibility = ["//visibility:public"]) diff --git a/python/py_pytest_main/def.bzl b/python/py_pytest_main/def.bzl new file mode 100644 index 0000000000..d155fb7cbe --- /dev/null +++ b/python/py_pytest_main/def.bzl @@ -0,0 +1,64 @@ +""" +py_test entrypoint generation +""" + +def _py_pytest_main_impl(ctx): + substitutions = { + "$$FLAGS$$": ", ".join(['"{}"'.format(f) for f in ctx.attr.args]).strip(), + "$$CHDIR$$": "os.chdir('{}')".format(ctx.attr.chdir) if ctx.attr.chdir else "", + } + + ctx.actions.expand_template( + template = ctx.file.template, + output = ctx.outputs.out, + substitutions = dict(substitutions, **ctx.var), + is_executable = False, + ) + +_py_pytest_main = rule( + implementation = _py_pytest_main_impl, + attrs = { + "args": attr.string_list( + doc = "Additional arguments to pass to pytest.", + ), + "chdir": attr.string( + doc = "A path to a directory to chdir when the test starts.", + mandatory = False, + ), + "out": attr.output( + doc = "The output file.", + mandatory = True, + ), + "template": attr.label( + allow_single_file = True, + default = "//python/py_pytest_main:pytest.tmpl.py", + ), + }, +) + +def py_pytest_main(name, **kwargs): + """py_pytest_main wraps the template rendering target and the final py_library. + + Args: + name: The name of the runable target that updates the test entry file. + **kwargs: The extra arguments passed to the template rendering target. + """ + + test_main = name + ".py" + tags = kwargs.pop("tags", []) + visibility = kwargs.pop("visibility", []) + + _py_pytest_main( + name = "%s_template" % name, + out = test_main, + tags = tags, + visibility = visibility, + **kwargs + ) + + native.py_library( + name = name, + srcs = [test_main], + tags = tags, + visibility = visibility, + ) diff --git a/python/py_pytest_main/pytest.tmpl.py b/python/py_pytest_main/pytest.tmpl.py new file mode 100644 index 0000000000..ec0085d8f6 --- /dev/null +++ b/python/py_pytest_main/pytest.tmpl.py @@ -0,0 +1,41 @@ +import sys +import os + +import pytest + +if __name__ == "__main__": + $$CHDIR$$ + + os.environ["ENV"] = "testing" + + args = [ + "--verbose", + "--ignore=external/", + # Avoid loading of the plugin "cacheprovider". + "-p", + "no:cacheprovider", + ] + + junit_xml_out = os.environ.get("XML_OUTPUT_FILE") + if junit_xml_out is not None: + args.append(f"--junitxml={junit_xml_out}") + + test_filter = os.environ.get("TESTBRIDGE_TEST_ONLY") + if test_filter is not None: + args.append(f"-k={test_filter}") + + user_args = [$$FLAGS$$] + if len(user_args) > 0: + args.extend(user_args) + + cli_args = sys.argv[1:] + if len(cli_args) > 0: + args.extend(cli_args) + + exit_code = pytest.main(args) + + if exit_code != 0: + print("Pytest exit code: " + str(exit_code)) + print("Ran pytest.main with " + str(args)) + + sys.exit(exit_code) From 5fb49754b577ce90437a8c7a82760680f7ebc9ca Mon Sep 17 00:00:00 2001 From: Matt Mackay Date: Fri, 10 Jun 2022 09:49:32 -0400 Subject: [PATCH 2/7] cleanup, run buildifier --- examples/build_file_generation/WORKSPACE | 3 +-- examples/build_file_generation/requirements.txt | 2 +- python/py_pytest_main/BUILD.bazel | 5 ++++- python/py_pytest_main/def.bzl | 2 +- python/py_pytest_main/pytest.tmpl.py | 4 ++-- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/examples/build_file_generation/WORKSPACE b/examples/build_file_generation/WORKSPACE index 09983b70b3..63ea962920 100644 --- a/examples/build_file_generation/WORKSPACE +++ b/examples/build_file_generation/WORKSPACE @@ -56,13 +56,12 @@ python_register_toolchains( ) load("@python39//:defs.bzl", "interpreter") - load("@rules_python//python:pip.bzl", "pip_parse") pip_parse( name = "pip", - requirements_lock = "//:requirements_lock.txt", python_interpreter_target = interpreter, + requirements_lock = "//:requirements_lock.txt", ) load("@pip//:requirements.bzl", "install_deps") diff --git a/examples/build_file_generation/requirements.txt b/examples/build_file_generation/requirements.txt index 5bd551ad6d..cf505ba468 100644 --- a/examples/build_file_generation/requirements.txt +++ b/examples/build_file_generation/requirements.txt @@ -1,2 +1,2 @@ requests==2.25.1 -pytest \ No newline at end of file +pytest~=7.1 \ No newline at end of file diff --git a/python/py_pytest_main/BUILD.bazel b/python/py_pytest_main/BUILD.bazel index cc2d302fe7..f479736417 100644 --- a/python/py_pytest_main/BUILD.bazel +++ b/python/py_pytest_main/BUILD.bazel @@ -1 +1,4 @@ -exports_files(["pytest.tmpl.py"], visibility = ["//visibility:public"]) +exports_files( + ["pytest.tmpl.py"], + visibility = ["//visibility:public"], +) diff --git a/python/py_pytest_main/def.bzl b/python/py_pytest_main/def.bzl index d155fb7cbe..cf05caa7f8 100644 --- a/python/py_pytest_main/def.bzl +++ b/python/py_pytest_main/def.bzl @@ -33,7 +33,7 @@ _py_pytest_main = rule( allow_single_file = True, default = "//python/py_pytest_main:pytest.tmpl.py", ), - }, + }, ) def py_pytest_main(name, **kwargs): diff --git a/python/py_pytest_main/pytest.tmpl.py b/python/py_pytest_main/pytest.tmpl.py index ec0085d8f6..651c603028 100644 --- a/python/py_pytest_main/pytest.tmpl.py +++ b/python/py_pytest_main/pytest.tmpl.py @@ -35,7 +35,7 @@ exit_code = pytest.main(args) if exit_code != 0: - print("Pytest exit code: " + str(exit_code)) - print("Ran pytest.main with " + str(args)) + print("Pytest exit code: " + str(exit_code), file=sys.stderr) + print("Ran pytest.main with " + str(args), file=sys.stderr) sys.exit(exit_code) From aea44b569e0a61831c3442712a2c4a1600ba63bc Mon Sep 17 00:00:00 2001 From: Matt Mackay Date: Thu, 30 Jun 2022 12:43:16 -0400 Subject: [PATCH 3/7] refactor: move all re-exports to private/reexports.bzl (#739) --- python/defs.bzl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/python/defs.bzl b/python/defs.bzl index 88f28c5fc0..385bdb79bc 100644 --- a/python/defs.bzl +++ b/python/defs.bzl @@ -18,6 +18,7 @@ Core rules for building Python projects. load("@bazel_tools//tools/python:srcs_version.bzl", _find_requirements = "find_requirements") load("@bazel_tools//tools/python:toolchain.bzl", _py_runtime_pair = "py_runtime_pair") +load("//python/py_pytest_main:def.bzl", _py_pytest_main = "py_pytest_main") load( "//python/private:reexports.bzl", "internal_PyInfo", @@ -133,6 +134,8 @@ py_runtime_pair = _py_runtime_pair find_requirements = _find_requirements +py_pytest_main = _py_pytest_main + py_library = _py_library py_binary = _py_binary From a16bfa749af845929078ad2d6a2ddbc8b1d6212f Mon Sep 17 00:00:00 2001 From: Matt Mackay Date: Mon, 6 Jun 2022 14:13:48 -0400 Subject: [PATCH 4/7] feat: add py_pytest_main entrypoint --- examples/build_file_generation/WORKSPACE | 1 + examples/build_file_generation/requirements.txt | 2 +- python/defs.bzl | 4 ++-- python/py_pytest_main/def.bzl | 4 +++- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/examples/build_file_generation/WORKSPACE b/examples/build_file_generation/WORKSPACE index 63ea962920..526a0efb58 100644 --- a/examples/build_file_generation/WORKSPACE +++ b/examples/build_file_generation/WORKSPACE @@ -62,6 +62,7 @@ pip_parse( name = "pip", python_interpreter_target = interpreter, requirements_lock = "//:requirements_lock.txt", + python_interpreter_target = interpreter, ) load("@pip//:requirements.bzl", "install_deps") diff --git a/examples/build_file_generation/requirements.txt b/examples/build_file_generation/requirements.txt index cf505ba468..af4488e8cc 100644 --- a/examples/build_file_generation/requirements.txt +++ b/examples/build_file_generation/requirements.txt @@ -1,2 +1,2 @@ requests==2.25.1 -pytest~=7.1 \ No newline at end of file +pytest~=7.1 diff --git a/python/defs.bzl b/python/defs.bzl index 385bdb79bc..27b38d6b92 100644 --- a/python/defs.bzl +++ b/python/defs.bzl @@ -134,8 +134,6 @@ py_runtime_pair = _py_runtime_pair find_requirements = _find_requirements -py_pytest_main = _py_pytest_main - py_library = _py_library py_binary = _py_binary @@ -143,3 +141,5 @@ py_binary = _py_binary py_test = _py_test py_runtime = _py_runtime + +py_pytest_main = _py_pytest_main diff --git a/python/py_pytest_main/def.bzl b/python/py_pytest_main/def.bzl index cf05caa7f8..0089b81b48 100644 --- a/python/py_pytest_main/def.bzl +++ b/python/py_pytest_main/def.bzl @@ -2,6 +2,8 @@ py_test entrypoint generation """ +load("//python/private:reexports.bzl", _py_library = "py_library") + def _py_pytest_main_impl(ctx): substitutions = { "$$FLAGS$$": ", ".join(['"{}"'.format(f) for f in ctx.attr.args]).strip(), @@ -56,7 +58,7 @@ def py_pytest_main(name, **kwargs): **kwargs ) - native.py_library( + _py_library( name = name, srcs = [test_main], tags = tags, From ed124c69145e5941d4094df956db44fb3d9061e2 Mon Sep 17 00:00:00 2001 From: Matt Mackay Date: Fri, 10 Jun 2022 09:49:32 -0400 Subject: [PATCH 5/7] cleanup, run buildifier --- examples/build_file_generation/WORKSPACE | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/build_file_generation/WORKSPACE b/examples/build_file_generation/WORKSPACE index 526a0efb58..63ea962920 100644 --- a/examples/build_file_generation/WORKSPACE +++ b/examples/build_file_generation/WORKSPACE @@ -62,7 +62,6 @@ pip_parse( name = "pip", python_interpreter_target = interpreter, requirements_lock = "//:requirements_lock.txt", - python_interpreter_target = interpreter, ) load("@pip//:requirements.bzl", "install_deps") From 3f10990368981d47ce68408ad0b7d9902d54cecc Mon Sep 17 00:00:00 2001 From: Matt Mackay Date: Thu, 7 Jul 2022 13:43:36 -0400 Subject: [PATCH 6/7] tidy --- docs/BUILD | 1 + docs/python.md | 19 +++++++++++++ python/defs.bzl | 2 +- python/py_pytest_main/BUILD | 30 +++++++++++++++++++++ python/py_pytest_main/BUILD.bazel | 4 --- python/py_pytest_main/{def.bzl => defs.bzl} | 0 6 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 python/py_pytest_main/BUILD delete mode 100644 python/py_pytest_main/BUILD.bazel rename python/py_pytest_main/{def.bzl => defs.bzl} (100%) diff --git a/docs/BUILD b/docs/BUILD index d2958219f0..161ed26040 100644 --- a/docs/BUILD +++ b/docs/BUILD @@ -54,6 +54,7 @@ bzl_library( name = "defs", srcs = [ "//python:defs.bzl", + "//python/py_pytest_main:defs.bzl", "//python/private:reexports.bzl", ], deps = [":bazel_python_tools"], diff --git a/docs/python.md b/docs/python.md index bd14b8258e..24f38dfb26 100755 --- a/docs/python.md +++ b/docs/python.md @@ -165,6 +165,25 @@ See the Bazel core [py_library](https://docs.bazel.build/versions/master/be/pyth | attrs | Rule attributes | none | + + +## py_pytest_main + +
+py_pytest_main(name, kwargs)
+
+ +py_pytest_main wraps the template rendering target and the final py_library. + +**PARAMETERS** + + +| Name | Description | Default Value | +| :-------------: | :-------------: | :-------------: | +| name | The name of the runable target that updates the test entry file. | none | +| kwargs | The extra arguments passed to the template rendering target. | none | + + ## py_runtime diff --git a/python/defs.bzl b/python/defs.bzl index 27b38d6b92..dc6c0c4c85 100644 --- a/python/defs.bzl +++ b/python/defs.bzl @@ -18,7 +18,7 @@ Core rules for building Python projects. load("@bazel_tools//tools/python:srcs_version.bzl", _find_requirements = "find_requirements") load("@bazel_tools//tools/python:toolchain.bzl", _py_runtime_pair = "py_runtime_pair") -load("//python/py_pytest_main:def.bzl", _py_pytest_main = "py_pytest_main") +load("//python/py_pytest_main:defs.bzl", _py_pytest_main = "py_pytest_main") load( "//python/private:reexports.bzl", "internal_PyInfo", diff --git a/python/py_pytest_main/BUILD b/python/py_pytest_main/BUILD new file mode 100644 index 0000000000..ce3c261bb0 --- /dev/null +++ b/python/py_pytest_main/BUILD @@ -0,0 +1,30 @@ +exports_files( + ["pytest.tmpl.py"], + visibility = ["//visibility:public"], +) + +licenses(["notice"]) # Apache 2.0 + +filegroup( + name = "distribution", + srcs = glob(["**"]), + visibility = ["//python:__pkg__"], +) + +# Filegroup of bzl files that can be used by downstream rules for documentation generation +# Using a filegroup rather than bzl_library to not give a transitive dependency on Skylib +filegroup( + name = "bzl", + srcs = glob(["**/*.bzl"]), + visibility = ["//python:__pkg__"], +) + +# Needed to define bzl_library targets for docgen. (We don't define the +# bzl_library target here because it'd give our users a transitive dependency +# on Skylib.) +exports_files( + [ + "defs.bzl", + ], + visibility = ["//docs:__pkg__"], +) diff --git a/python/py_pytest_main/BUILD.bazel b/python/py_pytest_main/BUILD.bazel deleted file mode 100644 index f479736417..0000000000 --- a/python/py_pytest_main/BUILD.bazel +++ /dev/null @@ -1,4 +0,0 @@ -exports_files( - ["pytest.tmpl.py"], - visibility = ["//visibility:public"], -) diff --git a/python/py_pytest_main/def.bzl b/python/py_pytest_main/defs.bzl similarity index 100% rename from python/py_pytest_main/def.bzl rename to python/py_pytest_main/defs.bzl From 4e9bd006e33a4505666d06442367e36a145106b7 Mon Sep 17 00:00:00 2001 From: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com> Date: Mon, 11 Jul 2022 16:03:07 -0700 Subject: [PATCH 7/7] fix: load order Signed-off-by: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com> --- python/defs.bzl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/defs.bzl b/python/defs.bzl index dc6c0c4c85..e1cd3d83db 100644 --- a/python/defs.bzl +++ b/python/defs.bzl @@ -18,7 +18,6 @@ Core rules for building Python projects. load("@bazel_tools//tools/python:srcs_version.bzl", _find_requirements = "find_requirements") load("@bazel_tools//tools/python:toolchain.bzl", _py_runtime_pair = "py_runtime_pair") -load("//python/py_pytest_main:defs.bzl", _py_pytest_main = "py_pytest_main") load( "//python/private:reexports.bzl", "internal_PyInfo", @@ -28,6 +27,7 @@ load( _py_runtime = "py_runtime", _py_test = "py_test", ) +load("//python/py_pytest_main:defs.bzl", _py_pytest_main = "py_pytest_main") # Exports of native-defined providers.