Search code examples
pythoncontinuous-integrationpull-requestpylintpre-commit.com

Running pylint scoped to particular PR


In my opinion, pylint is a great tool and I love it. However, some individuals don't prefer pylint, and I find myself collaborating on projects with individuals who don't like pylint.

Our CI pipeline has multiple workflows, one of which is an optional "lint" workflow that runs pylint. Several PRs have been merged with pylint not passing, so the lint workflow will never pass when run on the entire repo.

My question: how can I run pylint on just the files associated with a particular pull request?

That way, I can bring the lint workflow's pylint step to pass again, despite pylint failing when run on the full repo.

Food for Thought

We use pre-commit to run flake8/isort/black. I am wondering if there's some way to invoke pre-commit a second time in CI, with a second config (specified via --config) to feed pylint with just the files scoped to a given PR.

Requested detail: we use Git/GitHub.


Solution

  • Stating the obvious first, if you want to use pylint on a project you need to convince your team that they want to use pylint so everyone is on board.

    Second I think you already know that, but you can use git tricks to do what you want. For example git show --pretty="" --name-only HEAD|xargs pylint.

    This is not going to fix your change management problem though. pylint can be adopted more easily by using its features to disable the messages you don't want to fix (yet?).

    What I advise you do it create a .pylintrc and disable globally messages that would be too long or not worth it to fix right now.

    [MESSAGES CONTROL]
    
    # Enable the message, report, category or checker with the given id(s). You can
    # either give multiple identifier separated by comma (,) or put this option
    # multiple time (only on the command line, not in the configuration file where
    # it should appear only once). See also the "--disable" option for examples.
    enable=
        use-symbolic-message-instead,
        useless-suppression,
    
    # Disable the message, report, category or checker with the given id(s). You
    # can either give multiple identifiers separated by comma (,) or put this
    # option multiple times (only on the command line, not in the configuration
    # file where it should appear only once).You can also use "--disable=all" to
    # disable everything first and then re-enable specific checks. For example, if
    # you want to run only the similarities checker, you can use "--disable=all
    # --enable=similarities". If you want to run only the classes checker, but have
    # no Warning level messages displayed, use"--disable=all --enable=classes
    # --disable=W"
    
    disable=
        attribute-defined-outside-init
    
    

    If you only have a few message instead of disabling globally, disable them locally directly in the code or per-file.

    # All the violations on a single line
    a, b = ... # pylint: disable=unbalanced-tuple-unpacking
    
    All the violations on the following line
    # pylint: disable-next=unbalanced-tuple-unpacking
    a, b = ...
    

    Do that until you identify real problems that are worth the fix in the current state of your project. Then show the value pylint bring to the team. Once you've done that you can run pylint in CI and only new/valuable problems will be shown by the CI. And you can remove disables progressively.

    There's a feature request to facilitate your use case in pylint by creating a baseline of the repository. This would make sure that only new messages would get reported. There's another one to help with the triaging of important issues vs nitpicky one. It would make it easier to disable the message without thinking a lot about what you do. But it's not in pylint yet (as of 2.13.0).