I'm wanting to reduce some boilerplate for linters...
# development
b
I'm wanting to reduce some boilerplate for linters/formatters, both in terms of in-function (repeating the tool name) and between the functions. My motivation is mostly because I want to add a field to
LintResults
and think it's a shame that each linter will have to supply the field, even though they all supply it with the same expression. (There's also the "make linters/formatters easier" camp too) So I'm wondering if it'd be worthwhile to improve the rule parser to follow call-trees (still doing things "dumb"ly where it makes sense, nothing crazy) to allow for some re-use for this and many other cases. I don't think it'd be too difficult. 🤔 Thoughts? @witty-crayon-22786
c
I for one would love that (and have also pondered on the feasibility to implement something of the sorts..)
b
I think it's relatively easy, given some sane constraints (and error messaging), and remembering the point is to improve current art so it doesn't have to go the extra mile.
👍 1
I think I can whip up a PoC
PoC done (and looking good! 👍 )
🙌 1
Teaser:
Copy code
@rule(desc="Format with Black", level=LogLevel.DEBUG)
async def black_fmt(field_sets: BlackRequest, black: Black) -> FmtResult:
    return _run_black(field_sets, black, is_lint=False)
Copy code
joshuacannon@CEPHANDRIUS:~/work/pants$ ./pants help LintResults | grep black
10:08:38.82 [INFO] Initializing scheduler...
10:08:39.20 [INFO] Scheduler initialized.
pants.backend.python.lint.black.rules.black_lint
    activated by pants.backend.python.lint.black
c
ooohhh… sweet ❤️
is
_run_black
a regular function, then?
b
Next: Try and define a
fmt
or
lint
template out-of-tool
Note: I know this muddies the rule graph, right now it's just for exposition.
Copy code
async def _run_black(
    field_sets: BlackRequest,
    black: Black,
    *,
    is_lint: bool,
) -> FmtResult | LintResults:
c
Cool.. right, it would have to be an async 🙉 😛
h
I think one big semantic change is that the
_run_black
rule doesn't get memoized with the engine. It would be equivalent fwict to copying and pasting (inlining) all that code into both the
fmt_black
and
lint_black
rules. I'm pretty sure that's okay, only something to be aware of I like that this allows you to DRY without having to create wrapper types because it's just an async function, not a proper rule
Do you have a WIP you can post for the parsing change? I'm curious how it works, including whether we follow imports
b
I like that this allows you to DRY without having to create wrapper types because it's just an async function, not a proper rule
Yeah that's the idea. Add the ability to make helpers, so all your code doesn't have to choose between "inline everything" or "rule overhead"
1
👍 1
Do you have a WIP you can post for the parsing change? I'm curious how it works, including whether we follow imports
I will once I do a smidge more smoke testing. And yes it follows imports (albeit dumbly)
h
Cool, that makes a lot of sense to want to optimize for. Lower the friction with making rules readable
1
b