The first line of: <https://www.pantsbuild.org/doc...
# general
r
The first line of: https://www.pantsbuild.org/docs/reference-python_tests is "Generate a
python_test
target for each file in the
sources
field." Should that be
sources
"argument", rather than "field"? I've seen this in a number of places and it had me hunting for a "sources field" until I guessed that it probably meant the function argument.
1
f
Technically no because
python_tests
is actually a target; just a special kind of target: “generator target”
So
sources
is actually a field.
c
On the page you linked to, there’s a
sources
section: https://www.pantsbuild.org/docs/reference-python_tests#codesourcescode
r
Yes there is a
sources
section and that's how I figured out what was going on. So you're saying
python_tests
is not a function? It's usage inside
BUILD
sure reads like a function call.
f
It is a target that can dynamically create other targets. Unlike a function, generators like
python_tests
have a
name
and can be referenced via a target address just like any other target type.
b
I think both are correct whether you have pants-tinted goggles or not. In pure python nomenclature those are functions and arguments. In Pants-BUILD nomenclature those are targets and fields
☝️ 1
f
The issue for me is that, while target declarations like
python_tests
can look like a function call to a developer, they behave semantically like declarations. The declarations have names and are part of the build graph just like any other target, If we start to document them as "functions," then a user might expect them to be something they can call which is not the case. A similar issue exists in plugin code. Plugin code use
async ... await
syntax to represent invoking other rules. One reasonable first interpretation is that it is an RPC call, but in fact Pants uses the
async ... await
syntax to represent a query to the Pants rule engine. That query is deduplicated and cached as applicable. Even though it looks like an RPC call, it semantically behaves like a query to an expert system.
We should probably explain the semantics better in the docs if it is not clear to the ordinary reader.
b
Better docs on the subject would be ideal. And while we're there, explaining what a field is, why it matters, and documenting field types would go a long way too. For instance you can run any target whose
sources
field inherits from type
PythonSourceField
. Right now that is meaningless to the user because it's unclear which targets have fields of that type
r
I wonder if this distinction isn't primarily important to Pants developers rather than users. A BUILD file appears to contain a set of function calls that configure the build. Is there a big payoff for giving these different names? If it's not a function call, or something quite similar, why use something that looks that way, rather than, say, just sticking with the toml format? There are plenty of hurdles to learning and using Pants already, and the more complications that are introduced, the less friendly the whole experience is for new users.
c
@fast-nail-55400
a user might expect them to be something they can call which is not the case.
what do you mean with this? From a macro function for instance, you can declare any number of targets by “calling them”..
Copy code
def my_macro(some, inputs):
  # do stuff
  files(name=f"{inputs}-files")
  python_sources(name=f"{some}-sources")
  ...
to me it makes sense to view targets and fields as functions and arguments if that helps (as that is how it is implemented any way, really..)
b
@rich-kite-32423 I definitely think user-focused is how we try to structure things. (I was just acknowledging the "Curse of Knowledge") As to why to use Python re:TOML, tons of BUILD files have dynamic data (f strings, loops, etc...) So it'd always have to be some kind of dynamic declaration. I think leaning into the functional side in the docs might be a good idea, but we still need to have something to help the user also map the concept further into "fields" because in some places we really are talking about fields
I've long since wanted us to have a volunteer tech writer. Know anyone? 🤓
b
I'd love for Pants to have a staff technical writer. But of course there's the question of funding such a position.
b
Maybe we express something like the following in the docs to bridge the gap, but still keep it vanilla: Essentially BUILD files contain functions which define targets. The functions arguments become the target's fields. For demonstration, you can think of it as if we had the following definition
Copy code
@attr.s
class python_source:
    name: str
    source: PythonSourceField = attr.field(..., converter=from_str)
    ...
👍 2
To be a broken record the important thing is that fields do matter to users in some cases. Like I said before, any target with a PythonSourceField is runnable. So doing it this way helps explain the relationship between the function/args and the target/fields and also helps document field types
I wonder if we should break from Python though. I think we ought to namespace more things, including fields. This is illegal in Python but IMO is much nicer UX (however there's a cognitive price to pay to introducing a new language/syntax)
Copy code
# today...
python_source(
    run_goal_use_sandbox=True,
)
# would be nice
python_source(
    run.use_sandbox=True
)
An alternative might also be switching from functions to classes (or other declarative-style paradigm)
c
just throwing it out there, as a configuration language: https://cuelang.org if looking for options/alternatives 😛
b
@bitter-ability-32190 would you open a PR for those suggested revisions?
b
I'm not sure I have concrete changes to suggest. Just floating general thoughts...
b
Seemed reasonably concrete. If you mark it a draft PR and solicit feedback, others can bring it across the finish line with their feedback.
b
I'll consider it 😛
b
Thank you ❤️