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

More pre-commit filters, e.g. isort #3216

Open
3 tasks done
boxydog opened this issue Oct 26, 2023 · 18 comments · May be fixed by #3239
Open
3 tasks done

More pre-commit filters, e.g. isort #3216

boxydog opened this issue Oct 26, 2023 · 18 comments · May be fixed by #3239

Comments

@boxydog
Copy link
Contributor

boxydog commented Oct 26, 2023

  • I have searched the issues (including closed ones) and believe that this is not a duplicate.
  • I have searched the documentation and believe that my question is not covered.
  • I am willing to lend a hand to help implement this feature.

Feature Request

I submitted a pull request that passed pre-commit but failed lint checks, because of import order.

isort is a pre-commit filter that I think would've fixed my import order. I feel like we should add it.

Some others I'd recommend, in rough order:

  • pyupgrade

  • autoflake

  • black

  • pylint

  • pre-commit check-case-conflict, check-docstring-first, check-merge-conflict, check-symlinks, debug-statement, mixed-line-ending, forbid-crlf, forbid-tabs

I understand that adding each of these would result in code shift getting the project to pass. My approach would be to add them all, see which are easy to keep, and drop the rest for now. Time box to a couple hours.

It has this problem that it would conflict with every other PR, so I would want permission to get it in fairly quickly, otherwise resolving conflicts becomes too painful.

Below is a sample pre-commit from one of my projects. It's not a perfect fit, but I could adjust it. For example, versions. I was targeting newer pythons, but could tune it back to python 3.7, which seems to be the oldest one you test.

# See http://pre-commit.com/#python
# See https://github.com/pre-commit/pre-commit-hooks
# Run 'pre-commit install' to install the pre-commit hooks
repos:

# See also https://adamj.eu/tech/2021/09/16/introducing-django-upgrade/
- repo: https://github.com/asottile/pyupgrade
  rev: v3.15.0
  hooks:
    - id: pyupgrade
      args: [ --py39-plus ]

- repo: https://github.com/pre-commit/pre-commit-hooks
  rev: v4.5.0
  hooks:
  - id: check-added-large-files
  - id: check-ast
  - id: check-case-conflict
  - id: check-docstring-first
  - id: check-merge-conflict
  - id: check-symlinks
  - id: debug-statements
  - id: detect-private-key
  # black handles quoting
  # - id: double-quote-string-fixer
  - id: end-of-file-fixer
  - id: mixed-line-ending
  - id: trailing-whitespace
    exclude: (.csv|.tsv)$
  - id: pretty-format-json
    args: ['--no-sort-keys', '--autofix']
  # don't commit directly to main or master
  - id: no-commit-to-branch

- repo: https://github.com/myint/autoflake
  rev: v2.2.1
  hooks:
  - id: autoflake
    args:
      - --in-place
      - --remove-unused-variables
      - --remove-all-unused-imports

- repo: https://github.com/psf/black
  rev: 23.9.1
  hooks:
  - id: black
    language_version: python3.11
    exclude: migrations/

# flake8 after black, so black can fix formatting first
- repo: https://github.com/pycqa/flake8
  rev: 6.1.0
  hooks:
  - id: flake8
    exclude: migrations/

- repo: https://github.com/PyCQA/isort
  rev: 5.12.0
  hooks:
    - id: isort
      args:
        - --src=dir1,dir2
        # See also https://jugmac00.github.io/blog/isort-and-pre-commit-a-friendship-with-obstacles/
        - --filter-files
        - --skip-glob=*/migrations/*.py
        # line length must match black and flake8
        - --profile=black

- repo: https://github.com/PyCQA/pylint
  rev: v3.0.1
  hooks:
    - id: pylint
      args:
        # black is controlling line length:
        - --disable=line-too-long
        # let's not worry too much right now about dup code.
        - --disable=duplicate-code
        - --disable=fixme
        - --disable=import-error
        - --disable=logging-fstring-interpolation
        - --disable=missing-class-docstring
        - --disable=missing-function-docstring
        - --disable=missing-module-docstring
        - --disable=too-few-public-methods
        - --disable=too-many-arguments
        # - --disable=too-many-branches
        - --disable=too-many-locals
        # isort is taking care of import order:
        - --disable=wrong-import-order
        # re-enable these args
        - --disable=unused-argument
        - --disable=invalid-name
        - --disable=raise-missing-from

- repo: https://github.com/Lucas-C/pre-commit-hooks
  rev: v1.5.4
  hooks:
  - id: forbid-crlf
    exclude: ^dir1/.*.csv
  # don't just remove, seems dangerous
  # - id: remove-crlf
  - id: forbid-tabs
    # tests.py has a test with a tab in it
    # jquery is auto-generated code
    exclude: (.tsv|dir2/tests/tests.py)$
  # don't just remove, seems dangerous
  # - id: remove-tabs
@boxydog
Copy link
Contributor Author

boxydog commented Oct 26, 2023

By the way, even the existing pre-commit filters fail (see below). I'd probably fix that first.

Then I'd put pre-commit run --all into the github workflow. Then I'd start adding new filters. Probably separate PRs?

=====

$ pre-commit run --all
check for added large files..............................................Passed
check python ast.........................................................Passed
check toml...............................................................Passed
check yaml...............................................................Passed
debug statements (python)................................................Passed
detect private key.......................................................Passed
fix end of files.........................................................Failed
- hook id: end-of-file-fixer
- exit code: 1
- files were modified by this hook

Fixing pelican/tests/content/empty_with_bom.md
Fixing pelican/themes/simple/templates/category.html
Fixing pelican/tests/content/article_with_uppercase_metadata.rst
Fixing pelican/tests/TestPages/draft_page_markdown.md
Fixing pelican/tests/content/bloggerexport.xml
Fixing pelican/themes/notmyidea/static/css/reset.css
Fixing pelican/tests/content/2012-11-30_md_w_filename_meta#foo-bar.md
Fixing samples/content/pages/hidden_page.rst
Fixing pelican/themes/simple/templates/author.html
Fixing pelican/tests/content/wordpress_content_encoded
Fixing pelican/tests/content/article_without_category.rst
Fixing MANIFEST.in
Fixing .coveragerc
Fixing pelican/tests/content/article_with_markdown_markup_extensions.md
Fixing docs/_static/pelican-logo.svg

forbid new submodules................................(no files to check)Skipped
trim trailing whitespace.................................................Failed
- hook id: trailing-whitespace
- exit code: 1
- files were modified by this hook

Fixing docs/_static/theme_overrides.css
Fixing samples/content/unbelievable.rst
Fixing pelican/tests/content/wordpressexport.xml

@boxydog boxydog mentioned this issue Oct 26, 2023
4 tasks
@justinmayer
Copy link
Member

isort is already listed among the dev dependencies in pyproject.toml but hasn't made its way to the pre-commit configuration because the existing codebase does not yet have Black, Flake8, and isort applied en-masse. That is intentional, because we didn't want to cause all the existing PRs in the queue to instantly become unmergeable without fixing a bunch of conflicts caused by mass-applying code style changes in master.

Part of my vision for the upcoming sprint was to merge or close most of the existing pull requests, and then apply code style standards to the entire codebase, along with adding more code style configuration to pyproject.toml and the Pre-commit configuration.

There is already an open issue regarding using Ruff instead of a half-dozen different tools: #3123

@justinmayer
Copy link
Member

That is intentional, because we didn't want to cause all the existing PRs in the queue to instantly become unmergeable without fixing a bunch of conflicts caused by mass-applying code style changes in master.

I should point out that #2898 was never merged for the same reason noted above.

@boxydog
Copy link
Contributor Author

boxydog commented Oct 26, 2023

I see. Well, feel free to close this then.

I still think ruff is unlikely to replace everything above. For example, pyupgrade. So, maybe ruff plus others? In general I think more pre-commit, more better.

@boxydog
Copy link
Contributor Author

boxydog commented Oct 26, 2023

That is intentional, because we didn't want to cause all the existing PRs in the queue to instantly become unmergeable without fixing a bunch of conflicts caused by mass-applying code style changes in master.

I should point out that #2898 was never merged for the same reason noted above.

Ha ha, I see this comes up over and over.

@justinmayer
Copy link
Member

I still think ruff is unlikely to replace everything above. For example, pyupgrade.

Ahem: https://docs.astral.sh/ruff/rules/#pyupgrade-up

But your point stands, in the sense that Ruff probably won't do everything. To which I would say replacing everything isn't the intent. The intent is to reduce overheard by limiting the number of tools that have to be installed and configured.

So yeah — Ruff plus others. And if you look at how I've done things in some of the latest plugins, you'll see that Pre-commit should be completely in sync and in unison with what invoke lint checks.

@boxydog
Copy link
Contributor Author

boxydog commented Oct 26, 2023

Ha ha, I stand corrected!

From https://docs.astral.sh/ruff/:

Ruff can be used to replace Flake8 (plus dozens of plugins), Black, isort, pydocstyle, pyupgrade, autoflake, and more, all while executing tens or hundreds of times faster than any individual tool.

In that case, I would look through my list and see if there's anything I like that's not in ruff!

@boxydog
Copy link
Contributor Author

boxydog commented Oct 26, 2023

In that case, I would look through my list and see if there's anything I like that's not in ruff!

And I see nothing big missing! Well done Ruff. There might be some of those "pre-commit" checks (e.g., no-commit-to-branch), but that's littler stuff.

@boxydog
Copy link
Contributor Author

boxydog commented Oct 28, 2023

Ruff still seems good, but FYI there is a bunch of pylint it does not implement. See astral-sh/ruff#970.

That is awkward, because pylint is pretty slow, so you might not want to use it.

You likely already know this.

@justinmayer
Copy link
Member

Yeah, I think I would rather start with a smaller set of rules and then expand the “strictness” as time goes on. Even with the smaller set of rules that Ruff supports, I have put myself in situations where I enabled some rules and then spent unholy amounts of time trying to manually cajole an existing codebase to pass that relatively small set of rules. So unless there’s a strong reason not to do so, I am totally okay with skipping Pylint for now.

@boxydog
Copy link
Contributor Author

boxydog commented Oct 28, 2023

I would be willing to grind away at the menial task of getting some rules to pass if you wish. I find it satisfying, not saying it's needed. Let me know.

@justinmayer
Copy link
Member

On the contrary, that would be really helpful. As I mentioned, my only hesitation at the moment is causing a bunch of merge conflicts with existing PRs in the queue. Would you consider helping out with existing PR triage? The sooner we get them either merged or closed, the sooner we can start applying code style without fear of causing widespread merge conflicts.

@offbyone offbyone mentioned this issue Oct 29, 2023
2 tasks
@justinmayer
Copy link
Member

@boxydog: I think the pre-commit configuration is now fairly robust. If there's anything specific that you think is missing, by all means send a pull request to address it. Thanks for helping out with this!

@boxydog
Copy link
Contributor Author

boxydog commented Nov 1, 2023

I can't re-open this (no button), but you should consider the following list:

  • Ruff "UP" - pyupgrade
  • Ruff "B" - flake8-bugbear

pre-commit:

  • check-merge-conflict
  • check-case-conflict
  • mixed-line-endings

Lucas-C pre-commit:

  • forbid-crlf
  • forbid-tabs

If you wish, I can open another issue about it.

@boxydog
Copy link
Contributor Author

boxydog commented Nov 1, 2023

FYI, here is the Ruff default config (the one we're currently using): https://docs.astral.sh/ruff/configuration/#using-pyprojecttoml.

select = ["E4", "E7", "E9", "F"]

There is tons of Ruff (the majority) that is not enabled.

@boxydog
Copy link
Contributor Author

boxydog commented Nov 1, 2023

Below is an abbreviated version of the Ruff config in the pyproject.toml of one of my projects. A bunch of the rules are commented-out as a signal to me that I tried it, it complained, and I was not willing to fix it at the moment.

[tool.ruff.lint]
# default rules include pyflakes ("F")
# see https://docs.astral.sh/ruff/configuration/#using-pyprojecttoml
# "F" contains autoflake, see https://github.com/astral-sh/ruff/issues/1647
# add more rules
extend-select = [
  # TODO: "A",   # flake8-builtins
  # TODO: "ARG", # flake8-unused-arguments
  "B",   # flake8-bugbear
  "BLE", # flake8-blind-except
  # TODO: Do I want "COM", # flake8-commas
  "C4",  # flake8-comprehensions
  # TODO: "DJ",  # flake8-django
  # TODO: "DTZ", # flake8-datetimez
  # TODO: "EM",  # flake8-errmsg
  "EXE", # flake8-executable
  # TODO: "FURB", # refurb
  # TODO: "FBT", # flake8-boolean-trap
  # TODO: "G",   # flake8-logging-format
  "I",   # isort
  "ICN", # flake8-import-conventions
  "INP", # flake8-no-pep420
  # TODO: "INT", # flake8-gettext
  "ISC", # flake8-implicit-str-concat
  # TODO: "LOG", # flake8-logging
  "PERF", # perflint
  "PIE", # flake8-pie
  "PL",  # pylint
  "PYI", # flake8-pyi
  # TODO: "RET", # flake8-return
  "RSE", # flake8-raise
  "RUF",
  # TODO: "SIM", # flake8-simplify
  "SLF", # flake8-self
  "SLOT", # flake8-slots
  "TID", # flake8-tidy-imports
  "UP",  # pyupgrade
  "Q",   # flake8-quotes
  "TCH", # flake8-type-checking
  "T10", # flake8-debugger
  "T20", # flake8-print
  # TODO: "S",   # flake8-bandit
  "YTT", # flake8-2020
  # TODO: add more flake8 rules
]

ignore = [
  "RUF012"
]

[tool.ruff.lint.extend-per-file-ignores]

"**/migrations/*" = ["Q"]
"**/management/commands/*" = ["T20"]

@justinmayer justinmayer reopened this Nov 1, 2023
@justinmayer
Copy link
Member

justinmayer commented Nov 1, 2023 via email

@boxydog boxydog linked a pull request Nov 3, 2023 that will close this issue
1 task
@boxydog
Copy link
Contributor Author

boxydog commented Nov 3, 2023

Okay, submitted 3239.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants