Skip to content

Commit f12269f

Browse files
authored
Fix mypy linting non-python source files with custom rules (#105)
If you write a custom rule that is designed to interop with python rules you need to return PyInfo, in this case rules_mypy was attempting to lint the source files of the target even if they were not python. This is now scoped to only `.py` and `.pyi` files. One example case for this is if you write a custom rule that creates a python native extension and you want to be able to add it to the `deps` of python rules.
1 parent 4677665 commit f12269f

File tree

4 files changed

+39
-1
lines changed

4 files changed

+39
-1
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
load(":foo.bzl", "foo")
2+
3+
foo(
4+
name = "foo",
5+
srcs = ["foo.txt"],
6+
)

examples/demo/custom_rule/foo.bzl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
"""A custom rule that exposes PyInfo"""
2+
3+
load("@rules_python//python:py_info.bzl", "PyInfo")
4+
5+
def _impl(ctx):
6+
return [
7+
DefaultInfo(
8+
files = depset(ctx.files.srcs),
9+
),
10+
PyInfo(
11+
transitive_sources = depset(ctx.files.srcs),
12+
),
13+
]
14+
15+
foo = rule(
16+
implementation = _impl,
17+
attrs = {
18+
"data": attr.label_list(allow_files = True),
19+
"srcs": attr.label_list(allow_files = True),
20+
"deps": attr.label_list(),
21+
},
22+
)

examples/demo/custom_rule/foo.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Invalid python syntax example

mypy/private/mypy.bzl

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,15 @@ def _mypy_impl(target, ctx):
8484
if not hasattr(ctx.rule.files, "srcs"):
8585
return []
8686

87+
# Exclude non-python sources from custom rules that return PyInfo
88+
lintable_srcs = [
89+
s
90+
for s in ctx.rule.files.srcs
91+
if "/_virtual_imports/" not in s.short_path and s.extension in ("py", "pyi")
92+
]
93+
if not lintable_srcs:
94+
return []
95+
8796
# we need to help mypy map the location of external deps by setting
8897
# MYPYPATH to include the site-packages directories.
8998
external_deps = {}
@@ -188,7 +197,7 @@ def _mypy_impl(target, ctx):
188197
outputs = [output_file]
189198

190199
args.add_all([c.path for c in upstream_caches], before_each = "--upstream-cache")
191-
args.add_all([s for s in ctx.rule.files.srcs if "/_virtual_imports/" not in s.short_path])
200+
args.add_all(lintable_srcs)
192201

193202
if hasattr(ctx.attr, "_mypy_ini"):
194203
args.add("--mypy-ini", ctx.file._mypy_ini.path)

0 commit comments

Comments
 (0)