Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there a way to detect from within a LintRule if it's being run under test? #466

Open
jarshwah opened this issue Jun 24, 2024 · 1 comment
Labels
enhancement New feature or request

Comments

@jarshwah
Copy link

I'd like to be able to detect when a LintRule is being run under test. I know it's possible to use the FilePathProvider to detect if the filename is valid.py or invalid.py but that can lead to false positives. Here's a full example of a rule I'm [re]implementing below.

From within the rule, I want to check that we're linting an __init__.py file, so use the FilePathProvider to retrieve that information. Unfortunately unit tests will fail unless we also allow-through tests.

Is there a better way to detect if we're running under test?

import libcst.matchers as m
from fixit import LintRule
from libcst import Module, metadata
from tools.fixit.utils.general_utils import fixit_invalid, fixit_valid

CONVENIENCE_IMPORTS_OR_DOCSTRING = (
    m.SimpleStatementLine(body=[m.Import()])
    | m.SimpleStatementLine(body=[m.ImportFrom()])
    | m.SimpleStatementLine(
        body=[m.Assign(targets=[m.AssignTarget(target=m.Name(value="__all__"))])]
    )
    | m.SimpleStatementLine(body=[m.Expr(value=m.SimpleString() | m.ConcatenatedString())])
)


class EmptyInitModule(LintRule):
    """
    Ensure that __init__ files only contain convenience imports.

    Reimplements EIM002 from https://github.com/samueljsb/flake8-empty-init-modules
    """

    VALID = [VALID_IMPORTS_WITH_ALL, VALID_IMPORTS]  # noqa: RUF012
    INVALID = [BAD_ASSIGNMENT, BAD_FUNCTION_CALL]  # noqa: RUF012
    METADATA_DEPENDENCIES = (metadata.FilePathProvider,)

    def visit_Module(self, node: Module) -> bool | None:
        filepath = str(self.get_metadata(metadata.FilePathProvider, node))
        if not filepath.endswith("__init__.py") and not filepath.endswith("valid.py"):
            return

        for child in node.body:
            if not m.matches(child, CONVENIENCE_IMPORTS_OR_DOCSTRING):
                self.report(
                    child, message="Only convenience imports are allowed in __init__ modules"
                )
@amyreese amyreese added the enhancement New feature or request label Jul 30, 2024
@amyreese
Copy link
Member

Currently no, but I wouldn't be opposed to adding a global flag in libcst.testing that gets set to True by the generated test methods, similar to PEP484's typing.TYPE_CHECKING.

If you're interested in contributing this, I'd probably suggest something like libcst.testing.RULE_TESTING as the name, and toggling the flag in the setUp/tearDown methods of LintRuleTestCase.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants