fresh-cat-90827
07/10/2024, 7:45 PME AttributeError: 'coroutine' object has no attribute 'directory' when attempting to access an object that was available when running with 2.18.
The rule wasn't async and I was able to run a pytest test calling it directly result = construct_existing_python_requirement_object(tgt) in 2.18 inside the test case function body. With 2.19, however, I had to make the test pass by making the @rule async, calling it as result = await construct_existing_python_requirement_object(tgt) and making a pytest test case async def test_case(...).
Is there a way to avoid doing that and just keep things as they were? It's an extremely simple rule for which I don't want to involve rule runners (https://www.pantsbuild.org/2.19/docs/writing-plugins/the-rules-api/testing-plugins#approach-3-rulerunner-integration-tests-for-rules) as it just takes an object and returns a data class.fresh-cat-90827
07/10/2024, 7:46 PMfresh-cat-90827
07/10/2024, 7:47 PMSome `@rule`s may now need to passin preparation for "call by name". (#19755)canonical_name_suffix
broad-processor-92400
07/10/2024, 7:47 PM@rule that’s not async suggests it’s not calling any other rules/interacting with the pants scheduler, so maybe it can be a normal function without that decorator?broad-processor-92400
07/10/2024, 7:47 PMfresh-cat-90827
07/10/2024, 7:49 PMconstruct_existing_python_requirement_object.
@rule(desc="Get a basic info object from a python_requirement target")
def construct_existing_python_requirement_object(target: PythonRequirementTarget) -> ExistingPythonRequirementInfo:
return ExistingPythonRequirementInfo(
directory=target.address.spec_path, project_name=target.get(PythonRequirementsField).value[0].project_name
)
@rule(desc="Get basic info objects from all existing python_requirement targets")
async def determine_all_existing_python_requirement_targets(
all_targets: AllUnexpandedTargets,
) -> AllExistingPythonRequirementTargets:
results = await MultiGet(
Get(ExistingPythonRequirementInfo, PythonRequirementTarget, target)
for target in all_targets
if target.has_field(PythonRequirementsField)
)
return AllExistingPythonRequirementTargets(results)fresh-cat-90827
07/10/2024, 7:49 PMMultiGet as in
results = await MultiGet(
Get(ExistingPythonRequirementInfo, PythonRequirementTarget, target)
for target in all_targets
if target.has_field(PythonRequirementsField)
)broad-processor-92400
07/10/2024, 7:52 PM@rule “ idea may indeed be applicablefresh-cat-90827
07/10/2024, 7:57 PMresults = await MultiGet(
Get(ExistingPythonRequirementInfo, PythonRequirementTarget, target)
for target in all_targets
if target.has_field(PythonRequirementsField)
)
with
results = [construct_existing_python_requirement_object(target)
for target in all_targets
if target.has_field(PythonRequirementsField)
]
and it seemed to give me the expected results when running the pluginbroad-processor-92400
07/10/2024, 7:58 PM