From d28a169b5d4213bdca7d856aa600165f392cb07e Mon Sep 17 00:00:00 2001 From: Pierre Sassoulas Date: Tue, 19 Dec 2023 14:02:08 +0100 Subject: [PATCH] Put ruff into place --- .pre-commit-config.yaml | 33 ++++--------------- example_project/manage.py | 4 +-- pyproject.toml | 20 +++++++++++ survey/exporter/survey2x.py | 6 ++-- survey/exporter/tex/question2tex_chart.py | 2 +- survey/exporter/tex/question2tex_sankey.py | 2 +- survey/exporter/tex/survey2tex.py | 14 +++----- survey/models/answer.py | 8 ++--- survey/tests/exporter/test_survey2x.py | 6 ++-- .../management/commands/test_exportresult.py | 5 ++- survey/tests/management/test_management.py | 10 +++--- 11 files changed, 54 insertions(+), 56 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1f496e36..76ec1910 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,29 +3,19 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: check-merge-conflict - id: trailing-whitespace - id: end-of-file-fixer - id: check-json - - repo: https://github.com/myint/autoflake - rev: v2.0.1 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: "v0.1.8" hooks: - - id: autoflake - args: - - --in-place - - --remove-all-unused-imports - - --expand-star-imports - - --remove-duplicate-keys - - --remove-unused-variables - - repo: https://github.com/asottile/pyupgrade - rev: v3.3.1 - hooks: - - id: pyupgrade - args: [--py36-plus] + - id: ruff + args: ["--fix"] - repo: https://github.com/psf/black - rev: 23.1.0 + rev: 23.12.0 hooks: - id: black args: [--line-length, "120"] @@ -33,17 +23,8 @@ repos: rev: v1.1.3 hooks: - id: black-disable-checker - - repo: https://github.com/PyCQA/flake8 - rev: 6.0.0 - hooks: - - id: flake8 - additional_dependencies: [flake8-bugbear, flake8-typing-imports==1.12.0] - - repo: https://github.com/PyCQA/isort - rev: 5.12.0 - hooks: - - id: isort - repo: https://github.com/pre-commit/mirrors-prettier - rev: v3.0.0-alpha.6 + rev: v3.1.0 hooks: - id: prettier args: [--prose-wrap=always, --print-width=88] diff --git a/example_project/manage.py b/example_project/manage.py index 5ea5a516..0e37d048 100644 --- a/example_project/manage.py +++ b/example_project/manage.py @@ -14,11 +14,11 @@ import django print(django.__version__) - except ImportError: + except ImportError as e: raise ImportError( "Couldn't import Django. Are you sure it's installed and " "available on your PYTHONPATH environment variable? Did you " "forget to activate a virtual environment?" - ) + ) from e raise execute_from_command_line(sys.argv) diff --git a/pyproject.toml b/pyproject.toml index 08957545..bcb57308 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,3 +59,23 @@ sankey = [ [tool.setuptools.dynamic] dependencies = {file = "requirements.txt"} + + + +[tool.ruff] + +line-length = 120 + +select = [ + "E", # pycodestyle + "F", # pyflakes + "W", # pycodestyle + "B", # bugbear + "I", # isort + "RUF", # ruff + "UP", # pyupgrade +] + +ignore = [ + "RUF012", # mutable default values in class attributes +] diff --git a/survey/exporter/survey2x.py b/survey/exporter/survey2x.py index 760d83fc..63d42f8a 100755 --- a/survey/exporter/survey2x.py +++ b/survey/exporter/survey2x.py @@ -38,8 +38,8 @@ def directory(self): directory_name = f"{self.mime_type.upper()}_DIRECTORY" try: self.__directory = str(Path(getattr(settings, directory_name)).absolute()) - except AttributeError: - raise ImproperlyConfigured(f"Please define a value for {directory_name} in your settings") + except AttributeError as e: + raise ImproperlyConfigured(f"Please define a value for {directory_name} in your settings") from e return self.__directory @property @@ -101,4 +101,4 @@ def generate_file(self): f.write(str(self)) LOGGER.info("Wrote %s in %s", self.mime_type, self.filename) except OSError as exc: - raise OSError(f"Unable to create <{self.filename}> : {exc} ") + raise OSError(f"Unable to create <{self.filename}> : {exc} ") from exc diff --git a/survey/exporter/tex/question2tex_chart.py b/survey/exporter/tex/question2tex_chart.py index ca24cb94..26ba84b4 100755 --- a/survey/exporter/tex/question2tex_chart.py +++ b/survey/exporter/tex/question2tex_chart.py @@ -74,7 +74,7 @@ def get_results(self): final_answers.append(answer) return " {}".format(",\n ".join(final_answers)) - def get_pie_options(self): # noqa: C901 + def get_pie_options(self): r"""Return the options of the pie for: \pie[options]{data}""" options = "" if self.pos: diff --git a/survey/exporter/tex/question2tex_sankey.py b/survey/exporter/tex/question2tex_sankey.py index e8abbdb7..1633f205 100755 --- a/survey/exporter/tex/question2tex_sankey.py +++ b/survey/exporter/tex/question2tex_sankey.py @@ -12,7 +12,7 @@ warnings.warn( "Cannot import 'sankey', please install the package using" "the sankey extra. (pip install django-survey-and-report[sankey])" - ": '{}'".format(e), + f": '{e}'", stacklevel=2, ) SANKEY = False diff --git a/survey/exporter/tex/survey2tex.py b/survey/exporter/tex/survey2tex.py index ce95045c..90a07f76 100755 --- a/survey/exporter/tex/survey2tex.py +++ b/survey/exporter/tex/survey2tex.py @@ -96,19 +96,15 @@ def treat_question(self, question): q2tex = q2tex_class(question, latex_label=i, **opts) question_synthesis += q2tex.tex() section_title = Question2Tex.html2latex(question.text) - return """ + return f""" \\clearpage{{}} -\\section{{{}}} +\\section{{{section_title}}} -\\label{{sec:{}}} +\\label{{sec:{question.pk}}} -{} +{question_synthesis} -""".format( - section_title, - question.pk, - question_synthesis, - ) +""" @property def file_modification_time(self): diff --git a/survey/models/answer.py b/survey/models/answer.py index 63f6a49e..015fc0d2 100644 --- a/survey/models/answer.py +++ b/survey/models/answer.py @@ -60,15 +60,15 @@ def check_answer_body(self, question, body): if question.type == Question.INTEGER and body and body != "": try: body = int(body) - except ValueError: + except ValueError as e: msg = "Answer is not an integer" - raise ValidationError(msg) + raise ValidationError(msg) from e if question.type == Question.FLOAT and body and body != "": try: body = float(body) - except ValueError: + except ValueError as e: msg = "Answer is not a number" - raise ValidationError(msg) + raise ValidationError(msg) from e def check_answer_for_select(self, choices, body): answers = [] diff --git a/survey/tests/exporter/test_survey2x.py b/survey/tests/exporter/test_survey2x.py index e1dd5277..bb7940b3 100755 --- a/survey/tests/exporter/test_survey2x.py +++ b/survey/tests/exporter/test_survey2x.py @@ -49,7 +49,7 @@ def test_initially_need_update(self): self.actual_survey2x.need_update(), "No file exported and the survey " "contain response : we should need an update. " - "{}".format(self.get_fail_info(self.actual_survey2x)), + f"{self.get_fail_info(self.actual_survey2x)}", ) @patch.object(Survey2Survey, "file_modification_time", RIGHT_NOW) @@ -59,7 +59,7 @@ def test_need_update_after_generation(self): self.actual_survey2x.need_update(), "We exported the file and there" " is no new response, we should not need an update. " - "{}".format(self.get_fail_info(self.actual_survey2x)), + f"{self.get_fail_info(self.actual_survey2x)}", ) @patch.object(Survey2Survey, "file_modification_time", LONG_TIME_AGO) @@ -69,5 +69,5 @@ def test_need_update_after_new_response(self): self.actual_survey2x.need_update(), "We exported the file but there" " is a new response, we should need an update. " - "{}".format(self.get_fail_info(self.actual_survey2x)), + f"{self.get_fail_info(self.actual_survey2x)}", ) diff --git a/survey/tests/management/commands/test_exportresult.py b/survey/tests/management/commands/test_exportresult.py index 570b32a7..c0a5360a 100755 --- a/survey/tests/management/commands/test_exportresult.py +++ b/survey/tests/management/commands/test_exportresult.py @@ -30,7 +30,10 @@ def test_no_options(self): call_command("exportresult", "--pdf", survey_id="1") call_command("exportresult", "--pdf", "--force", survey_id="1") except XelatexNotInstalled: - warn("xelatex is not installed, some features regarding report generation in PDF were not tested!") + warn( + "xelatex is not installed, some features regarding report generation in PDF were not tested!", + stacklevel=0, + ) def test_handle(self): """The custom command export result create the right csv file.""" diff --git a/survey/tests/management/test_management.py b/survey/tests/management/test_management.py index cd75592d..a6fee9b2 100755 --- a/survey/tests/management/test_management.py +++ b/survey/tests/management/test_management.py @@ -83,15 +83,13 @@ def create_big_ranking_survey(self, with_user=False): def setUp(self): super().setUp() self.create_survey() - self.expected_content = """\ + self.expected_content = f"""\ user,Aèbc?,Bècd?,Cède?,Dèef? ps250112,1é,2é,3é, pierre,,,, -{},1|1a|1b,2|2a|2b,3|3a|3b, -{},1e|1é|1ë,2e|2é|2ë,3e|3é|3ë, -Anonymous,,,,""".format( - self.username, self.other_username - ) +{self.username},1|1a|1b,2|2a|2b,3|3a|3b, +{self.other_username},1e|1é|1ë,2e|2é|2ë,3e|3é|3ë, +Anonymous,,,,""" self.expected_header = ["user", "Aèbc?", "Bècd?", "Cède?", "Dèef?"] self.conf_dir = Path(HERE, "..", "exporter", "tex") self.test_conf_path = Path(self.conf_dir, "test_conf.yaml")