Skip to content

Commit 5339545

Browse files
authored
[tools] Remove py_test isolation (#24748)
This is no longer necessary, so we can simplify the code. Also remove some pre-bzlmod drake_py_unittest_main support code.
1 parent fa08f04 commit 5339545

8 files changed

Lines changed: 26 additions & 152 deletions

File tree

bindings/pydrake/math/BUILD.bazel

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ install(
7272
drake_py_binary(
7373
name = "math_example",
7474
srcs = ["math_example.py"],
75-
isolate = True,
7675
deps = [
7776
"//bindings/pydrake:module_py",
7877
],

common/proto/BUILD.bazel

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,6 @@ drake_py_unittest(
8484
],
8585
# TODO(eric.cousineau): Find the source of sporadic CI failures.
8686
flaky = 1,
87-
# We wish to access neighboring files.
88-
isolate = 0,
8987
)
9088

9189
drake_cc_googletest(

common/test_utilities/drake_py_unittest_main.py

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -79,28 +79,20 @@ def main():
7979
main_py = sys.argv[0]
8080

8181
# Parse the test case name out of the runfiles directory name.
82-
match = re.search("^(.*bin/(.*?/)?(py/)?([^/]*_test).runfiles/)", main_py)
82+
match = re.search("^(.*bin/(.*?/)?([^/]*_test).runfiles/)", main_py)
8383
if not match:
8484
print(f"error: no test name match in {main_py}")
8585
sys.exit(1)
86-
runfiles, test_package, _, test_name, = match.groups()
86+
runfiles, test_package, test_name, = match.groups()
8787
test_basename = test_name + ".py"
8888

8989
# Find the test's source file.
90-
runfiles_test_filenames = [
91-
# With bzlmod disabled.
92-
runfiles + "drake/" + test_package + "test/" + test_basename,
93-
# With bzlmod enabled.
94-
runfiles + "_main/" + test_package + "test/" + test_basename,
95-
]
96-
runfiles_test_filename = None
97-
for x in runfiles_test_filenames:
98-
if os.path.exists(x):
99-
runfiles_test_filename = x
100-
break
101-
if runfiles_test_filename is None:
102-
raise RuntimeError("Could not find {} at any of {}".format(
103-
test_basename, runfiles_test_filenames))
90+
runfiles_test_filename = (
91+
runfiles + "_main/" + test_package + "test/" + test_basename
92+
)
93+
if not os.path.exists(runfiles_test_filename):
94+
raise RuntimeError("Could not find {} at {}".format(
95+
test_basename, runfiles_test_filename))
10496

10597
# Check the test's source code for a (misleading) __main__.
10698
realpath_test_filename = os.path.realpath(runfiles_test_filename)

tools/lint/bazel_lint.bzl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
load("//tools/skylark:drake_py.bzl", "py_test_isolated")
1+
load("//tools/skylark:drake_py.bzl", "py_linter_test")
22

33
#------------------------------------------------------------------------------
44
# Internal helper; set up test given name and list of files. Will do nothing
@@ -7,7 +7,7 @@ def _bazel_lint(name, files):
77
if files:
88
locations = ["$(locations %s)" % f for f in files]
99

10-
py_test_isolated(
10+
py_linter_test(
1111
name = name + "_buildifier",
1212
size = "small",
1313
srcs = ["@drake//tools/lint:buildifier"],

tools/lint/cpplint.bzl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
load("//tools/skylark:drake_py.bzl", "py_test_isolated")
1+
load("//tools/skylark:drake_py.bzl", "py_linter_test")
22

33
# From https://bazel.build/reference/be/c-cpp#cc_library.srcs.
44
# Keep this list in sync with clang_format_lint.py.
@@ -74,7 +74,7 @@ def _add_linter_rules(
7474
cpplint_data.append(item)
7575

7676
# Google cpplint.
77-
py_test_isolated(
77+
py_linter_test(
7878
name = name + "_cpplint",
7979
srcs = ["@cpplint_internal//:cpplint"],
8080
data = cpplint_data + source_labels,
@@ -85,7 +85,7 @@ def _add_linter_rules(
8585
)
8686

8787
# Additional Drake lint.
88-
py_test_isolated(
88+
py_linter_test(
8989
name = name + "_drakelint",
9090
srcs = ["@drake//tools/lint:drakelint"],
9191
data = data + source_labels,
@@ -96,7 +96,7 @@ def _add_linter_rules(
9696
)
9797

9898
# Idempotence during clang-format.
99-
py_test_isolated(
99+
py_linter_test(
100100
name = name + "_clang_format_lint",
101101
srcs = ["@drake//tools/lint:clang_format_lint"],
102102
data = data + source_labels,

tools/lint/library_lint.bzl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
load("//tools/skylark:drake_py.bzl", "py_test_isolated")
1+
load("//tools/skylark:drake_py.bzl", "py_linter_test")
22

33
# Keep this constant in sync with library_lint_reporter.py.
44
_TAG_EXCLUDE_FROM_PACKAGE = "exclude_from_package"
@@ -80,7 +80,7 @@ def library_lint(
8080
reporter_args += ["--extra", item]
8181

8282
# Report all of the library_lint results.
83-
py_test_isolated(
83+
py_linter_test(
8484
name = "library_lint",
8585
size = "small",
8686
srcs = ["@drake//tools/lint:library_lint_reporter"],

tools/lint/python_lint.bzl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
load("//tools/skylark:drake_py.bzl", "py_test_isolated")
1+
load("//tools/skylark:drake_py.bzl", "py_linter_test")
22
load("//tools/skylark:sh.bzl", "sh_test")
33

44
# Internal helper.
@@ -34,7 +34,7 @@ def _python_lint(
3434
if disallow_executable:
3535
drakelint_args += ["--disallow_executable"]
3636
drakelint_args += locations
37-
py_test_isolated(
37+
py_linter_test(
3838
name = name_prefix + "_drakelint",
3939
size = "small",
4040
srcs = ["@drake//tools/lint:drakelint"],

tools/skylark/drake_py.bzl

Lines changed: 8 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -20,102 +20,12 @@ def drake_py_library(
2020
**kwargs
2121
)
2222

23-
def _redirect_test_impl(ctx):
24-
info = dict(
25-
bad_target = ctx.attr.bad_target,
26-
good_target = ctx.attr.good_target,
27-
)
28-
content = """#!/bin/bash
29-
echo "ERROR: Please use\n {good_target}\n The label\n {bad_target}\n" \
30-
" does not exist." >&2
31-
exit 1
32-
""".format(**info)
33-
ctx.actions.write(
34-
output = ctx.outputs.executable,
35-
content = content,
36-
)
37-
return [DefaultInfo()]
38-
39-
# Defines a test which will fail when run via `bazel run` or `bazel test`,
40-
# redirecting the user to the correct binary to use. This should typically have
41-
# a "manual" tag.
42-
_redirect_test = rule(
43-
attrs = {
44-
"bad_target": attr.string(mandatory = True),
45-
"good_target": attr.string(mandatory = True),
46-
},
47-
test = True,
48-
implementation = _redirect_test_impl,
49-
)
50-
51-
def _py_target_isolated(
52-
name,
53-
py_target = None,
54-
srcs = None,
55-
main = None,
56-
isolate = True,
57-
visibility = None,
58-
legacy_create_init = False,
59-
**kwargs):
60-
# See #8041 for more details.
61-
# TODO(eric.cousineau): See if we can remove these shims once we stop
62-
# supporting Python 2 (#10606).
63-
if py_target == None:
64-
fail("Must supply macro function for defining `py_target`.")
65-
66-
# Targets that are already isolated (with a `py/` prefix) don't require any
67-
# additional work. This can happen when linting tests (isolated by
68-
# definition) are invoked for isolated Python targets. Otherwise, they get
69-
# "doubly isolated" as `py/py/{name}`.
70-
prefix = "py/"
71-
if isolate and not name.startswith(prefix):
72-
actual = prefix + name
73-
74-
# Preserve original functionality.
75-
if not main:
76-
main = name + ".py"
77-
if not srcs:
78-
srcs = [name + ".py"]
79-
py_target(
80-
name = actual,
81-
srcs = srcs,
82-
main = main,
83-
visibility = visibility,
84-
legacy_create_init = legacy_create_init,
85-
**kwargs
86-
)
87-
88-
# Disable and redirect original name.
89-
package_prefix = "//" + native.package_name() + ":"
90-
91-
# N.B. Make sure that a test (visible to both `bazel run` and
92-
# `bazel test`) with the original name redirects to the isolated
93-
# instantiation so users unfamiliar with isolation that use the
94-
# "obvious" spelling will be properly informed.
95-
_redirect_test(
96-
name = name,
97-
good_target = package_prefix + actual,
98-
bad_target = package_prefix + name,
99-
tags = ["manual"],
100-
visibility = visibility,
101-
)
102-
else:
103-
py_target(
104-
name = name,
105-
srcs = srcs,
106-
main = main,
107-
visibility = visibility,
108-
legacy_create_init = legacy_create_init,
109-
**kwargs
110-
)
111-
11223
def drake_py_binary(
11324
name,
11425
srcs = None,
11526
main = None,
11627
data = [],
11728
deps = None,
118-
isolate = False,
11929
tags = [],
12030
add_test_rule = False,
12131
test_rule_args = [],
@@ -127,18 +37,11 @@ def drake_py_binary(
12737
test_rule_rendering = False,
12838
**kwargs):
12939
"""A wrapper to insert Drake-specific customizations.
130-
131-
@param isolate (optional, default is False)
132-
If True, the binary will be placed in a folder isolated from the
133-
library code. This prevents submodules from leaking in as top-level
134-
submodules. For more detail, see #8041.
13540
"""
13641
if main == None and len(srcs) == 1:
13742
main = srcs[0]
138-
_py_target_isolated(
43+
py_binary(
13944
name = name,
140-
py_target = py_binary,
141-
isolate = isolate,
14245
srcs = srcs,
14346
main = main,
14447
data = data,
@@ -160,7 +63,6 @@ def drake_py_binary(
16063
# files from their build actions and bazel would error out because
16164
# of the malformed BUILD file.
16265
precompile = "disabled",
163-
isolate = isolate,
16466
args = test_rule_args,
16567
data = data + test_rule_data,
16668
size = test_rule_size,
@@ -217,7 +119,6 @@ def drake_py_test(
217119
size = None,
218120
srcs = None,
219121
deps = None,
220-
isolate = True,
221122
allow_import_unittest = False,
222123
allow_network = None,
223124
display = False,
@@ -228,11 +129,6 @@ def drake_py_test(
228129
**kwargs):
229130
"""A wrapper to insert Drake-specific customizations.
230131
231-
@param isolate (optional, default is True)
232-
If True, the test binary will be placed in a folder isolated from the
233-
library code. This prevents submodules from leaking in as top-level
234-
submodules. For more detail, see #8041.
235-
236132
@param allow_import_unittest (optional, default is False)
237133
If False, this test (and anything it imports) is prevented from doing
238134
`import unittest`. This is a guard against writing `unittest`-based
@@ -288,10 +184,8 @@ def drake_py_test(
288184
opt_in_condition = opt_in_condition,
289185
opt_out_conditions = opt_out_conditions,
290186
)
291-
_py_target_isolated(
187+
py_test(
292188
name = name,
293-
py_target = py_test,
294-
isolate = isolate,
295189
size = size,
296190
srcs = srcs,
297191
deps = deps,
@@ -301,25 +195,16 @@ def drake_py_test(
301195
**kwargs
302196
)
303197

304-
def py_test_isolated(
198+
def py_linter_test(
305199
name,
306200
**kwargs):
307-
"""Provides a directory-isolated Python test, robust against shadowing
308-
(#8041).
309-
"""
310-
if "lint" in (kwargs.get("tags") or []):
311-
# Skip lint tests in coverage builds.
201+
"""Wrapper for py_test, to be used for running a linter."""
202+
py_test(
203+
name = name,
312204
target_compatible_with = select({
205+
# Skip lint tests in coverage builds.
313206
"@drake//tools/kcov:enabled": ["@platforms//:incompatible"],
314207
"//conditions:default": [],
315-
})
316-
else:
317-
target_compatible_with = None
318-
319-
_py_target_isolated(
320-
name = name,
321-
py_target = py_test,
322-
isolate = True,
323-
target_compatible_with = target_compatible_with,
208+
}),
324209
**kwargs
325210
)

0 commit comments

Comments
 (0)