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

Switch from black/pylint/isort to ruff & move to Python 3.9 #1127

Merged
merged 4 commits into from
Oct 20, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: Pre-commit hooks

on:

Check warning on line 4 in .github/workflows/pre-commit.yml

View workflow job for this annotation

GitHub Actions / build

4:1 [truthy] truthy value should be one of [false, true]
push:
branches: [master]
pull_request:
Expand All @@ -22,5 +22,3 @@

- name: Run pre-commit hooks
uses: pre-commit/[email protected]
with:
python-version: '3.x'
6 changes: 0 additions & 6 deletions .mega-linter.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
ENABLE_LINTERS:

Check warning on line 1 in .mega-linter.yml

View workflow job for this annotation

GitHub Actions / build

1:1 [document-start] missing document start "---"
- PYTHON_PYLINT
bhirsz marked this conversation as resolved.
Show resolved Hide resolved
- PYTHON_BLACK
- PYTHON_ISORT
- MARKDOWN_MARKDOWNLINT
- YAML_YAMLLINT
DISABLE_ERRORS_LINTERS:
- RST_RSTCHECK
EXCLUDED_DIRECTORIES:
- build
PRE_COMMANDS:
- command: pip install robotframework-robocop[dev]
venv: pylint
- command: pip install robotframework-robocop[doc]
venv: rstcheck
PYTHON_PYLINT_FILTER_REGEX_EXCLUDE: "invalid_file.py"
14 changes: 4 additions & 10 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
---
repos:

Check warning on line 1 in .pre-commit-config.yaml

View workflow job for this annotation

GitHub Actions / build

1:1 [document-start] missing document start "---"
- repo: https://github.com/pycqa/isort
rev: 5.12.0
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.9
hooks:
- id: isort
name: isort (python)

- repo: https://github.com/psf/black
rev: 23.1.0
hooks:
- id: black
- id: ruff
- id: ruff-format

Check failure on line 6 in .pre-commit-config.yaml

View workflow job for this annotation

GitHub Actions / build

6:24 [new-line-at-end-of-file] no new line character at the end of file
144 changes: 139 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,144 @@
[tool.black]
[tool.ruff]
line-length = 120
force-exclude = "invalid_file.py"
show-fixes = true
target-version = "py39"
lint.select = [
"ALL", # include all the rules, including new ones
]
extend-exclude = [
"tests/test_data/"
]
lint.ignore = [
#### modules
"DJ", # django
"PD", # pandas
#"C90", # mccabe complexity

[tool.isort]
profile = "black"
line_length = 120
#"EXE", # flake8-executable
#"PTH", # flake8-use-pathlib
#"TID", # flake8-tidy-imports
#### specific rules
"D100", # missing docstring in public module
"D101", # missing docstring in public class
"D102", # missing docstring in public method
"D103", # missing docstring in public function
"D104", # missing docstring in public package
"D105", # missing docstring in magic method
"D107", # missing docstring in __init__
"D203", # blank line before class
"D400", # first line should end with a period
"D415", # first line should end with period, question mark or exlamation point
"ANN204", # missing type annotation for __init__
"EM102", # exception with fstring
"TD002", # 'to do' without author
"PT011", # pytest.raises is too broad
"S101", # use of assert
"COM812", # trailing commas
"FIX002", # code with to do - check all of them later
"PERF203", # try except in for loop - check all of them for possible refactors
"C901", # code too complex (duplicate with other rules)
"EM101", # exception with string literal
"W291", # TODO: trailing whitespace
"W293", # TODO: blankline with whitespace
"D200", # TODO: fit one-line docstrign in one line
"D205", # TODO: 1 blank line between summary and description - see if makes sense
"D209", # TODO: multi-line docstring closing quites on a separate line
"D212", # TODO: multi-line docstring summary should start at the first line OR pick rule D213
"D213", # TODO: multi-line docstring summary should start at the second line
"D401", # TODO: imperative mood. Low priority
"ANN001", # TODO: type annotation for function argument (900 issues)
"ANN002", # TODO: type annotation for private function
"ANN003", # TODO: type annotation for *kwargs
"ANN201", # TODO: type annotation for return type (800 issues)
"ANN202", # TODO: type annotation for return type of private function
"ANN205", # TODO: type annotation for return type of staticmethod (30 issues)
"PT006", # TODO: pytest.parametrize with ("param", "param2") instead of "param,param2" (30 issues)
"RUF100", # TODO: unused blanked noqa directive
"C408", # TODO: rewrite dict() to {}
"SIM108", # TODO: ternary operator
"FBT002", # TODO: boolean default positional argument in function definition
"RUF012", # TODO: mutable class attributes should be annotated with typing.classvar
"PLW0129", # TODO: assert on non-empty string literal
"SIM300", # TODO: yoda conditions (lol)
"T201", # TODO: print
"FBT003", # TODO: boolean positional value in function call
"ARG002", # TODO: unused method argument
"FLY002", # TODO: use fstring instead of string join
"SLF001", # TODO: private member accessed
"PT001", # TODO: fixture instead of fixture()
"PT012", # TODO: pytest.raises should contain a signle simple statement
"PLR0913", # TODO: too many arguments in fn def (consider if it's good to keep the rule)
"B007", # TODO: loop variable not used
"PT018", # TODO: split assertion
"TRY003", # TODO: exception with long message outside exception class
"D210", # TODO: docstring wrapped with whitespace
"INP001", # TODO: file part of implicit namespace package
"FA100", # TODO: Use from future import to replace Optional with | None
"A001", # TODO: variable shadowing python builtin
"A002", # TODO: argument shadowing python builtin
"FBT001", # TODO: boolean positional argument in fn def. Check if fn can be splitted on two depending on flag
"UP006", # TODO: List -> list
"UP035", # TODO: List -> list
"RET504", # TODO: unnecessary assigment
"E501", # TODO: line too long
"FIX001", # TODO: code with fixme
"TD003", # TODO: code with fixme and without issue link
"TD004", # TODO: missing colon in TODO
"TD001", # TODO: invalid TODO tag
"N802", # TODO: function name should be lowercase (use noqa for visitors)
"N815", # TODO: same as N802
"N818", # TODO: exception without error in name
"N999", # TODO: invalid module name unused-keyword
"PGH004", # TODO: use specific rule codes when using noqa (300 issues)
"F541", # TODO: f-string without any placeholders (6 issues)
"PLR2004", # TODO: magic value used in comparison (50 issues)
"RET505", # TODO: else after return
"F401", # TODO: not used import
"RET503", # TODO: missing explicit return
"D403", # TODO: capitalize first word
"C401", # TODO: unnecessary generator
"C414", # TODO: unnecessary list with sorted
"PYI024", # TODO: namedtuple -> NamedTuple
"SIM212", # TODO: reverse condition to simplify it
"TRY201", # TODO: use raise without exception name
"ISC001", # TODO: implicitly concatenated string literals on one line
"PTH100", # TODO: use Path
"PTH109", # TODO: use Path
"PTH110", # TODO: use Path
"PTH111", # TODO: use Path
"PTH123", # TODO: use Path.open()
"D301", # TODO: use r if any backslashes in a docstring
"RUF013", # TODO: implicit Optional
"ANN401", # TODO: replace Any
"B009", # TODO: getattr with constant attribute value
"B028", # TODO: no explicit stacklevel in warn
"PLW3301", # TODO: nested max can be flattened
"UP011", # TODO: unnecessary paranthesis
"B904", # TODO: raise from
"RUF005", # TODO: replace ['item'] + ['second']
"PLW2901", # TODO: for loop variable overwritten
"PLR0912", # TODO: too many branches
"SIM110", # TODO: use any instead of for loop
"RUF010", # TODO: use explicit conversion flag
"PLR5501", # TODO: convert to elif
"D413", # TODO: missing blank line after last section
"FURB187", # TODO: assignment of reversed list
"SIM102", # TODO: combine if
"SIM103", # TODO: return condition directly
"PIE810", # TODO: merge startswith
"ERA001", # TODO: commented out code
"RET502", # TODO: return -> return None if function return non-None value
"SIM105", # TODO: use supress
"C416", # TODO: unnecessary list comprehension
"UP037", # TODO: remove quotes from type annotation
"ARG001", # TODO: unused function argument
"DTZ005", # TODO: `datetime.datetime.now()` called without a `tz` argument
]
lint.unfixable = [
# PT022 replace empty `yield` to empty `return`. Might be fixed with a combination of PLR1711
# In addition, it can't do anything with invalid typing annotations, protected by mypy.
"PT022",
]

[tool.coverage.run]
omit = ["*tests*"]
Expand Down
1 change: 1 addition & 0 deletions robocop/checkers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
Rule ID as well as rule name can be used to refer to the rule (e.g. in include/exclude statements,
configurations etc.). You can optionally configure rule severity or other parameters.
"""

import ast
import importlib.util
import inspect
Expand Down
1 change: 1 addition & 0 deletions robocop/checkers/comments.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Comments checkers
"""

import re
from codecs import BOM_UTF8, BOM_UTF16_BE, BOM_UTF16_LE, BOM_UTF32_BE, BOM_UTF32_LE

Expand Down
1 change: 1 addition & 0 deletions robocop/checkers/documentation.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Documentation checkers
"""

from pathlib import Path

from robot.parsing.model.blocks import SettingSection
Expand Down
1 change: 1 addition & 0 deletions robocop/checkers/duplications.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Duplications checkers
"""

from collections import defaultdict

from robot.api import Token
Expand Down
1 change: 1 addition & 0 deletions robocop/checkers/errors.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Errors checkers
"""

import re

from robot.api import Token
Expand Down
1 change: 1 addition & 0 deletions robocop/checkers/lengths.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Lengths checkers
"""

import re
from typing import List, Optional

Expand Down
33 changes: 6 additions & 27 deletions robocop/checkers/misc.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Miscellaneous checkers
"""

import ast
from dataclasses import dataclass
from pathlib import Path
Expand Down Expand Up @@ -1369,35 +1370,13 @@ def visit_LibraryImport(self, node): # noqa
for token in node.get_tokens(Token.NAME, Token.ARGUMENT):
self.find_not_nested_variable(token.value, is_var=False)

visit_TestTags = (
visit_ForceTags
) = (
visit_Metadata
) = (
visit_DefaultTags
) = (
visit_Variable
) = (
visit_ReturnStatement
) = (
visit_TestTags = visit_ForceTags = visit_Metadata = visit_DefaultTags = visit_Variable = visit_ReturnStatement = (
visit_ReturnSetting
) = (
visit_Teardown
) = (
visit_Timeout
) = (
visit_Return
) = (
visit_SuiteSetup
) = (
visit_SuiteTeardown
) = (
visit_TestSetup
) = (
) = visit_Teardown = visit_Timeout = visit_Return = visit_SuiteSetup = visit_SuiteTeardown = visit_TestSetup = (
visit_TestTeardown
) = (
visit_Setup
) = visit_ResourceImport = visit_VariablesImport = visit_Tags = visit_Documentation = visit_LibraryImport
) = visit_Setup = visit_ResourceImport = visit_VariablesImport = visit_Tags = visit_Documentation = (
visit_LibraryImport
)

def clear_variables_after_loop(self):
"""Remove used variables after loop finishes."""
Expand Down
29 changes: 6 additions & 23 deletions robocop/checkers/naming.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Naming checkers
"""

import re
import string
from collections import defaultdict
Expand Down Expand Up @@ -887,31 +888,13 @@ def visit_Setup(self, node): # noqa
self.check_setting_name(node.data_tokens[0].value, node)
self.check_settings_consistency(node.data_tokens[0].value, node)

visit_SuiteSetup = (
visit_TestSetup
) = (
visit_Teardown
) = (
visit_SuiteTeardown
) = (
visit_TestTeardown
) = (
visit_SuiteSetup = visit_TestSetup = visit_Teardown = visit_SuiteTeardown = visit_TestTeardown = (
visit_TestTimeout
) = (
visit_TestTemplate
) = (
visit_TestTags
) = (
visit_ForceTags
) = (
visit_DefaultTags
) = (
visit_ResourceImport
) = (
) = visit_TestTemplate = visit_TestTags = visit_ForceTags = visit_DefaultTags = visit_ResourceImport = (
visit_VariablesImport
) = (
visit_Documentation
) = visit_Tags = visit_Timeout = visit_Template = visit_Arguments = visit_ReturnSetting = visit_Return = visit_Setup
) = visit_Documentation = visit_Tags = visit_Timeout = visit_Template = visit_Arguments = visit_ReturnSetting = (
visit_Return
) = visit_Setup

def visit_LibraryImport(self, node): # noqa
self.check_setting_name(node.data_tokens[0].value, node)
Expand Down
1 change: 1 addition & 0 deletions robocop/checkers/spacing.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Spacing checkers
"""

import re
from collections import Counter
from contextlib import contextmanager
Expand Down
1 change: 1 addition & 0 deletions robocop/checkers/tags.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Tags checkers
"""

from collections import defaultdict

from robot.api import Token
Expand Down
4 changes: 2 additions & 2 deletions robocop/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def expand_argument_files(self, args, config_dir=None):
parsed_args.append(arg)
continue
if not args: # argumentfile option declared but filename was not provided
raise exceptions.ArgumentFileNotFoundError("") from None
raise exceptions.ArgumentFileNotFoundError("") from None # TODO: denote that file was not provided
argfile = args.pop(0)
argfile_path = Path(argfile)
if argfile_path.is_file():
Expand Down Expand Up @@ -596,7 +596,7 @@ def parse_toml_to_config(self, toml_data: Dict, config_dir: Path):
elif key == "threshold":
self.threshold = RuleSeverity(value)
elif key == "output":
self.output = open(value, "w")
self.output = open(value, "w") # noqa: SIM115
elif key == "no_recursive":
self.recursive = not value
elif key == "verbose":
Expand Down
1 change: 1 addition & 0 deletions robocop/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
* ``desc``: description of the rule

"""

from enum import Enum
from functools import total_ordering
from textwrap import dedent
Expand Down
1 change: 1 addition & 0 deletions robocop/run.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Main class of Robocop module. Gathers files to be scanned, checkers, parses CLI arguments and scans files.
"""

import os
import sys
from collections import Counter
Expand Down
1 change: 1 addition & 0 deletions robocop/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Parsing utils
"""

from robocop.utils.disablers import DisablersFinder
from robocop.utils.file_types import FileType, FileTypeChecker
from robocop.utils.misc import (
Expand Down
1 change: 1 addition & 0 deletions robocop/utils/disablers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Collection of classes for detecting checker disablers (like # robocop: disable) in robot files
"""

import re
from collections import defaultdict
from copy import deepcopy
Expand Down
Loading
Loading