Is there a way to test subsystems (and only subsys...
# development
w
Is there a way to test subsystems (and only subsystems)?
Copy code
class CowsayTool(NpxToolBase):
    options_scope = "cowsay"
    name = "Cowsay"
    # Intentionally older version.
    default_version = "cowsay@1.4.0"
    help = "The Cowsay utility for printing cowsay messages"
I want to ensure that the version option is present, but the
create_subsystem
utility doesn't seem to do any checking to see if fields exist or not:
cowsaytool = create_subsystem(CowsayTool, versionXYZ="cowsay@1.5.0")
My hope was to do something like this:
rule_runner.set_options(["--backend-packages=['pants.backend.experimental.javascript']", "--cowsay-version='cowsay@1.5.0'"])
and then somehow get the subsystem and verify that the version was picked up correctly. Would I only be able to do this via the
run_pants
mechanism (which seems heavy for what I want)
โœ… 1
w
can do that and then request the subsystem
Copy code
rule_runner.set_options(..)
rule_runner.request(MySubsystem, [])
w
rule_runner.request(MySubsystem, [])
๐Ÿคฏ
Oh.
Copy code
return RuleRunner(
        rules=[
            *nodejs.rules(),
            *CowsayTool.rules(),
            QueryRule(ProcessResult, [nodejs.NpxProcess]),        
        ],
    )
Copy code
Exception: No installed QueryRules return the type CowsayTool. Try registering QueryRule(CowsayTool for EnvironmentName).
w
Yea, you will need the queryrule
w
Neat! Thanks!
Copy code
@pytest.fixture
def rule_runner() -> RuleRunner:
    return RuleRunner(
        rules=[
            *nodejs.rules(),
            *CowsayTool.rules(),
            QueryRule(CowsayTool, []),
        ],
    )

def test_installing(rule_runner: RuleRunner):
    rule_runner.set_options(["--backend-packages=['pants.backend.experimental.javascript']", "--cowsay-version=cowsay@1.5.0"])
    tool = rule_runner.request(CowsayTool, [])
    assert tool.default_version == "cowsay@1.4.0"
    assert tool.version == "cowsay@1.5.0"
Well, this is weird...
SubsystemRule(CowsayTool),
complains that this usage is deprecated
*CowsayTool.rules()
gets a typecheck error because of missing the
cls
*Subsystem.rules(CowsayTool),
fails on : TypeError: rules() takes 1 positional argument but 2 were given Using SubsystemRule for now, as it seems to pass at least
w
cc @ancient-vegetable-10556 ^
๐Ÿ‘€ 1
a
@wide-midnight-78598 this (gets a typecheck error because of missing the) is a tediousness arising from MyPy not liking
@memoized_classmethod
I suggest using
CowsayTool.rules()
and shoving a
# type: ignore[ERROR_CODE]
at the end of the line for now.
(possibly worth raising a ticket on Pants for us to address that with a MyPy plugin)
w
Thanks @ancient-vegetable-10556 - I figured it was because of memoized_classmethod, but didn't know if ignoring the error was cool beans or not
a
Yeah, the solution is to either fix
@memoized
so that it works with
@classmethod
and
@staticmethod
, or to get a mypy plugin to understand the situation
until then, ignoring is the only solution afaict
w
๐Ÿ‘ Done!
a
In case you havenโ€™t already, keeping the
ignore
as tightly scoped as possible is the best practice
so that if you refactor the line and introduce a new type error, you still get alerted
w
),  # type: ignore[call-arg]
?
a
exactly
whereas
# type: ignore
would be a bad idea ๐Ÿ™‚
w
Yep, always. Even ignoring stuff like this gives me the queasies, so as tightly scoped as possible ๐Ÿ™‚