I've working on a PR and am befuddled by some rule...
# development
c
I've working on a PR and am befuddled by some rule graph errors that behave differently between
PANTS_SOURCE=
and pants itself. I thought my code was working because when I run through various scenarios in another repo with
PANTS_SOURCE=/pants/with/my/change
my code seems to work (new CLI flags accepted, different behavior, new output, etc) But when I try to run
pants list ::
in pants itself I get
[ERROR] Encountered 8 rule graph errors
. I don't understand how the rules can be valid in one case, but not the other. • WIP change https://github.com/cburroughs/pants/commit/4a1f6d10ea82e09615c5d03669b0ba7c34c00b31 (Sorry it's very rough as uhh, I can't run
pants fmt
on it) • rule graph errors: https://gist.github.com/cburroughs/beb4054b73c377373f1195f20a6a477d
h
Possibly due to differences in config (particularly loaded plugins) between the other repo and the pants repo?
c
hmm, well to be concrete the "other repo" is
example-python
. I think
pants
itself is a superset of backends. I noticed most rules files just call
*collect_rules()
, but a few do something like:
Copy code
def rules():
    return [
        *collect_rules(),
        *external_tool.rules(),
        *pex_environment.rules(),
        *adhoc_binaries.rules(),
    ]
Is there some rules dependency/bootstrapping one has to do when working with the python backend?
h
You have to make sure some backend brings in all the rules you're using, but unfortunately the error messages on rule graph construction errors are terrible right now
https://github.com/pantsbuild/pants/issues/19730 should make all these problems go away
c
I have re-read that recently with renewed interest!
Copy code
src/python/pants/backend/python/goals/lockfile.py | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/python/pants/core/goals/generate_lockfiles.py | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
I think in this case though the everything in
lockfile.py
is safely within the python backend. The only thing different in this Get snippet is is the alternative return type
Copy code
check_results = await MultiGet(
            Get(
                CheckLockfileResult,
                {
                    req: GenerateLockfile,
                    _preferred_environment(req, local_environment.val): EnvironmentName,
                },
            )
            for req in all_requests
        )
Yet when I "install" my rule:
Copy code
@rule(desc="Checking Python lockfile", level=LogLevel.DEBUG)
async def check_lockfile(
        req: GeneratePythonLockfile,
        generate_lockfiles_subsystem: GenerateLockfilesSubsystem,
        python_setup: PythonSetup,
) -> CheckLockfileResult:
Pants (and only the pants repo) fails with
No installed rules return the type GeneratePythonLockfile
, yet this pre-existing rule can find
GeneratePythonLockfile
just fine.
Copy code
@rule(desc="Generate Python lockfile", level=LogLevel.DEBUG)
async def generate_lockfile(
    req: GeneratePythonLockfile,
    generate_lockfiles_subsystem: GenerateLockfilesSubsystem,
    python_setup: PythonSetup,
) -> GenerateLockfileResult:
(Branch updated with latest but still not working WIP in case anyone is able to follow down this thread.) https://github.com/pantsbuild/pants/compare/main...cburroughs:pants:dep-check
🔥 After sleeping on it few a few nights I figured out how to reproduce it while bike riding! Adding the
"pants.backend.experimental.java"
backed causes example-python to fail with the same
No installed rules return the type GeneratePythonLockfile,
error as pants itself. Clearly I need to think more about how to handle
--check
for multiple backends, but yeah I agree that rule graph error message is the opposite of helpful.