From 5ce80d875e8dc99ef06990560d7557320a2ce697 Mon Sep 17 00:00:00 2001 From: Nikita Marchant Date: Mon, 9 Dec 2024 10:12:19 +0100 Subject: [PATCH] Upgrade requirements and pre-commit --- .pre-commit-config.yaml | 10 +- catalog/management/commands/load_tree.py | 2 +- catalog/management/parser/build_tree.py | 2 +- catalog/tests/load_tree_test.py | 4 +- documents/tasks.py | 9 +- documents/tests/celery_test.py | 8 +- documents/tests/document_test.py | 2 +- documents/tests/logic_test.py | 4 +- documents/thumbnail.py | 6 +- integration/test_webtest.py | 8 +- pyproject.toml | 6 +- requirements.txt | 173 +++++++++--------- search/tests/test_postgresql.py | 4 +- users/tests/auth_backend_authenticate_test.py | 2 +- users/tests/perm_test.py | 6 +- 15 files changed, 123 insertions(+), 123 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a022c051..72224401 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/psf/black - rev: 24.3.0 + rev: 24.10.0 hooks: - id: black @@ -17,26 +17,26 @@ repos: files: \.html$ - repo: https://github.com/asottile/pyupgrade - rev: v3.15.1 + rev: v3.19.0 hooks: - id: pyupgrade args: [ "--py310-plus" ] - repo: https://github.com/rtts/djhtml - rev: '3.0.6' + rev: '3.0.7' hooks: - id: djhtml - id: djcss - id: djjs - repo: https://github.com/adamchainz/django-upgrade - rev: 1.16.0 + rev: 1.22.2 hooks: - id: django-upgrade args: [ --target-version, "4.1" ] - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: 'v0.3.4' + rev: 'v0.8.2' hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] diff --git a/catalog/management/commands/load_tree.py b/catalog/management/commands/load_tree.py index cfdb8971..23393b04 100644 --- a/catalog/management/commands/load_tree.py +++ b/catalog/management/commands/load_tree.py @@ -37,7 +37,7 @@ def slugify0(name): class Command(BaseCommand): - def handle(self, *args: Any, **options: Any) -> None: + def handle(self, *args: Any, **options: Any) -> None: # noqa: PLR0912 with open("csv/programs.json") as f: programs = json.load(f) diff --git a/catalog/management/parser/build_tree.py b/catalog/management/parser/build_tree.py index b8127480..c2666ed6 100644 --- a/catalog/management/parser/build_tree.py +++ b/catalog/management/parser/build_tree.py @@ -28,7 +28,7 @@ def get_or_create_bloc(fac: dict, program: dict, bloc: dict) -> dict: fac = get_or_create_fac(fac) program = get_or_create_program(fac, program) - bloc = bloc["val"] if bloc["val"] != "U" else "1" + bloc = bloc["val"] if bloc["val"] != "U" else "1" # type: ignore if bloc not in program["blocs"]: program["blocs"][bloc] = {"val": bloc, "courses": {}} return program["blocs"][bloc] diff --git a/catalog/tests/load_tree_test.py b/catalog/tests/load_tree_test.py index 8b9d2e9c..0ac44005 100644 --- a/catalog/tests/load_tree_test.py +++ b/catalog/tests/load_tree_test.py @@ -73,8 +73,8 @@ def test_fill_twice(): assert course.name == new_course.name -@pytest.mark.slow() -@pytest.mark.network() +@pytest.mark.slow +@pytest.mark.network def test_load_tree_hit_ulb(): call_command("loadtree", REAL_TREE, hitulb=True) diff --git a/documents/tasks.py b/documents/tasks.py index 54dd87da..05e5ef57 100644 --- a/documents/tasks.py +++ b/documents/tasks.py @@ -258,14 +258,11 @@ def repair(self, document_id: int) -> int: @contextlib.contextmanager def file_as_local(fileobj, prefix="", suffix=""): - tmpfile = tempfile.NamedTemporaryFile(prefix=prefix, suffix=suffix) - tmpfile.write(fileobj.read()) - tmpfile.flush() + with tempfile.NamedTemporaryFile(prefix=prefix, suffix=suffix) as tmpfile: + tmpfile.write(fileobj.read()) + tmpfile.flush() - try: yield tmpfile - finally: - tmpfile.close() @contextlib.contextmanager diff --git a/documents/tests/celery_test.py b/documents/tests/celery_test.py index 9c463de5..406f2a64 100644 --- a/documents/tests/celery_test.py +++ b/documents/tests/celery_test.py @@ -47,7 +47,7 @@ def create_doc(name, ext): return doc -@pytest.mark.slow() +@pytest.mark.slow def test_add_to_queue(): doc = create_doc("Document name", ".pdf") with open("documents/tests/files/3pages.pdf", "rb") as fd: @@ -63,7 +63,7 @@ def test_add_to_queue(): assert doc.original.path == doc.pdf.path -@pytest.mark.slow() +@pytest.mark.slow def test_send_duplicate(): test_add_to_queue() @@ -80,8 +80,8 @@ def test_send_duplicate(): # TODO : mock unoconv and provide a fake pdf instead -@pytest.mark.unoconv() -@pytest.mark.slow() +@pytest.mark.unoconv +@pytest.mark.slow def test_send_office(): doc = create_doc("My office doc", ".docx") diff --git a/documents/tests/document_test.py b/documents/tests/document_test.py index cdaeb771..e820d5bc 100644 --- a/documents/tests/document_test.py +++ b/documents/tests/document_test.py @@ -12,7 +12,7 @@ pytestmark = pytest.mark.django_db -@pytest.fixture() +@pytest.fixture def doc(): user = User.objects.create_user(netid="test_user") doc = Document.objects.create(name="A document", user=user) diff --git a/documents/tests/logic_test.py b/documents/tests/logic_test.py index d30ede0f..b7a0405b 100644 --- a/documents/tests/logic_test.py +++ b/documents/tests/logic_test.py @@ -12,12 +12,12 @@ pytestmark = pytest.mark.django_db -@pytest.fixture() +@pytest.fixture def user(): return User.objects.create_user(netid="test_user") -@pytest.fixture() +@pytest.fixture def course(): return Course.objects.create(slug="test-t-100") diff --git a/documents/thumbnail.py b/documents/thumbnail.py index 9b3e552f..719dd3b0 100644 --- a/documents/thumbnail.py +++ b/documents/thumbnail.py @@ -2,11 +2,11 @@ import statistics -import fitz +import pymupdf from PIL import Image, ImageOps -def _get_thumb_from_page(page: fitz.fitz.Page): +def _get_thumb_from_page(page: pymupdf.Page): pix = page.get_pixmap() mode = "RGBA" if pix.alpha else "RGB" img = Image.frombytes(mode, (pix.width, pix.height), pix.samples) @@ -18,7 +18,7 @@ def get_thumbnail( pdf: str | None = None, stream: IO[bytes] | None = None ) -> tuple[int, Image.Image]: s = stream.read() if stream else None - doc = fitz.open(filename=pdf, stream=s, filetype="pdf") + doc = pymupdf.open(filename=pdf, stream=s, filetype="pdf") # Iterate on the first 10 pages to find an interesting one to thumbnail for i in range(min(doc.page_count, 10)): diff --git a/integration/test_webtest.py b/integration/test_webtest.py index be4019e5..cc2d4d81 100644 --- a/integration/test_webtest.py +++ b/integration/test_webtest.py @@ -12,7 +12,7 @@ pytestmark = [pytest.mark.django_db, pytest.mark.webtest] -@pytest.fixture() +@pytest.fixture def app(): wtm = django_webtest.WebTestMixin() wtm._patch_settings() @@ -20,19 +20,19 @@ def app(): wtm._unpatch_settings() -@pytest.fixture() +@pytest.fixture def user(): return User.objects.create_user( netid="nimarcha", email="lol@lol.be", first_name="Nikita", last_name="Marchant" ) -@pytest.fixture() +@pytest.fixture def tags(): return [Tag.objects.create(name="my tag"), Tag.objects.create(name="my other tag")] -@pytest.fixture() +@pytest.fixture def tree(): root = Category.objects.create(name="ULB") science = Category.objects.create(name="science") diff --git a/pyproject.toml b/pyproject.toml index e5114084..604fe3df 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ markers = """ postgresql: needs a postgresql database to run """ -[tool.ruff] +[tool.ruff.lint] select = [ "F", "E", "W", "YTT", "B", "COM818", "C4", "DTZ", "T10", "EXE", "ISC", @@ -26,7 +26,6 @@ ignore = [ "E501", # Line too long "B905", # Not available <3.10 "PT011", # `pytest.raises(Exception)` is too broad - "PT004", # Fixture does not return anything "SIM108", # Use ternary operator "SIM105", # Use `contextlib.suppress(Alarm)` "PLR2004", # Magic value used in comparison @@ -34,9 +33,10 @@ ignore = [ "PLR0911", # Too many return statements "PLC1901", # if x != "" is not the same as if x "RUF012", # Mutable class attributes should be annotated with `typing.ClassVar` + "SIM103", # Return the condition directly ] -[tool.ruff.per-file-ignores] +[tool.ruff.lint.per-file-ignores] "__init__.py" = ["F401"] # imported but unused "www/settings.py" = ["F403"] # import *` used; unable to detect undefined names "www/test_settings.py" = ["F403"] # import *` used; unable to detect undefined names diff --git a/requirements.txt b/requirements.txt index 5d54bfc2..4aff0f9a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,39 +4,41 @@ # # pip-compile # -amqp==5.2.0 +amqp==5.3.1 # via kombu -asgiref==3.8.0 - # via django -asttokens==2.4.1 +asgiref==3.8.1 + # via + # django + # django-stubs +asttokens==3.0.0 # via stack-data beautifulsoup4==4.12.3 # via # -r requirements.in # webtest -billiard==4.2.0 +billiard==4.2.1 # via celery -black==24.3.0 +black==24.10.0 # via -r requirements.in -boto3==1.34.68 +boto3==1.35.76 # via -r requirements.in -botocore==1.34.68 +botocore==1.35.76 # via # boto3 # s3transfer brotli==1.1.0 # via whitenoise -build==1.1.1 +build==1.2.2.post1 # via pip-tools -celery==5.3.6 +celery==5.4.0 # via -r requirements.in -certifi==2024.2.2 +certifi==2024.8.30 # via # requests # sentry-sdk cfgv==3.4.0 # via pre-commit -charset-normalizer==3.3.2 +charset-normalizer==3.4.0 # via requests click==8.1.7 # via @@ -46,7 +48,7 @@ click==8.1.7 # click-plugins # click-repl # pip-tools -click-didyoumean==0.3.0 +click-didyoumean==0.3.1 # via celery click-plugins==1.1.1 # via celery @@ -54,17 +56,18 @@ click-repl==0.3.0 # via celery coolname==2.2.0 # via -r requirements.in -crispy-bootstrap5==2024.2 +crispy-bootstrap5==2024.10 # via -r requirements.in decorator==5.1.1 # via ipython -distlib==0.3.8 +distlib==0.3.9 # via virtualenv -django==5.0.3 +django==5.1.4 # via # -r requirements.in # crispy-bootstrap5 # django-appconf + # django-compressor # django-crispy-forms # django-debug-toolbar # django-extensions @@ -76,13 +79,13 @@ django==5.0.3 # jsonfield django-appconf==1.0.6 # via django-compressor -django-compressor==4.4 +django-compressor==4.5.1 # via -r requirements.in -django-crispy-forms==2.1 +django-crispy-forms==2.3 # via # -r requirements.in # crispy-bootstrap5 -django-debug-toolbar==4.3.0 +django-debug-toolbar==4.4.6 # via -r requirements.in django-environ==0.11.2 # via -r requirements.in @@ -96,41 +99,41 @@ django-jsonfield-compat==0.4.4 # via -r requirements.in django-mptt==0.16.0 # via -r requirements.in -django-pipeline==3.0.0 +django-pipeline==4.0.0 # via -r requirements.in -django-storages==1.14.2 +django-storages==1.14.4 # via -r requirements.in -django-stubs==4.2.7 +django-stubs==5.1.1 # via -r requirements.in -django-stubs-ext==4.2.7 +django-stubs-ext==5.1.1 # via django-stubs -django-webtest==1.9.11 +django-webtest==1.9.12 # via -r requirements.in -executing==2.0.1 +executing==2.1.0 # via stack-data -filelock==3.13.1 +filelock==3.16.1 # via virtualenv filemagic==1.6 # via -r requirements.in furl==2.1.3 # via -r requirements.in -gunicorn==21.2.0 +gunicorn==23.0.0 # via -r requirements.in -honcho==1.1.0 +honcho==2.0.0 # via -r requirements.in html5lib==1.1 # via -r requirements.in -identify==2.5.35 +identify==2.6.3 # via pre-commit -idna==3.6 +idna==3.10 # via requests iniconfig==2.0.0 # via pytest -ipython==8.22.2 +ipython==8.30.0 # via -r requirements.in isort==5.13.2 # via -r requirements.in -jedi==0.19.1 +jedi==0.19.2 # via ipython jmespath==1.0.1 # via @@ -138,82 +141,80 @@ jmespath==1.0.1 # botocore jsonfield==3.1.0 # via -r requirements.in -kombu==5.3.5 +kombu==5.4.2 # via celery markdown-it-py==3.0.0 # via rich -matplotlib-inline==0.1.6 +matplotlib-inline==0.1.7 # via ipython mdurl==0.1.2 # via markdown-it-py mock==5.1.0 # via -r requirements.in -mypy==1.9.0 +mypy==1.13.0 # via -r requirements.in mypy-extensions==1.0.0 # via # black # mypy -nodeenv==1.8.0 +nodeenv==1.9.1 # via pre-commit orderedmultidict==1.0.1 # via furl -packaging==24.0 +packaging==24.2 # via # black # build # gunicorn # pytest -parso==0.8.3 +parso==0.8.4 # via jedi pathspec==0.12.1 # via black pexpect==4.9.0 # via ipython -pillow==10.2.0 +pillow==11.0.0 # via -r requirements.in pip-tools==7.4.1 # via -r requirements.in -platformdirs==4.2.0 +platformdirs==4.3.6 # via # black # virtualenv -pluggy==1.4.0 +pluggy==1.5.0 # via pytest -pre-commit==3.6.2 +pre-commit==4.0.1 # via -r requirements.in -prompt-toolkit==3.0.43 +prompt-toolkit==3.0.48 # via # click-repl # ipython -psycopg[binary,pool]==3.1.18 +psycopg[binary,pool]==3.2.3 # via -r requirements.in -psycopg-binary==3.1.18 +psycopg-binary==3.2.3 # via psycopg -psycopg-pool==3.2.1 +psycopg-pool==3.2.4 # via psycopg ptyprocess==0.7.0 # via pexpect -pure-eval==0.2.2 +pure-eval==0.2.3 # via stack-data -pygments==2.17.2 +pygments==2.18.0 # via # -r requirements.in # ipython # rich -pymupdf==1.24.0 +pymupdf==1.25.0 # via -r requirements.in -pymupdfb==1.24.0 - # via pymupdf -pypdf==4.1.0 +pypdf==5.1.0 # via -r requirements.in -pyproject-hooks==1.0.0 +pyproject-hooks==1.2.0 # via # build # pip-tools -pytest==8.1.1 +pytest==8.3.4 # via pytest-django -pytest-django==4.8.0 +pytest-django==4.9.0 # via -r requirements.in python-dateutil==2.9.0.post0 # via @@ -224,40 +225,39 @@ python-memcached==1.62 # via -r requirements.in python-slugify==8.0.4 # via -r requirements.in -pyyaml==6.0.1 +pyyaml==6.0.2 # via # -r requirements.in # pre-commit # responses -rcssmin==1.1.1 +rcssmin==1.1.2 # via django-compressor -redis==5.0.3 +redis==5.2.1 # via -r requirements.in -requests==2.31.0 +requests==2.32.3 # via # -r requirements.in # responses -responses==0.25.0 +responses==0.25.3 # via -r requirements.in -rich==13.7.1 +rich==13.9.4 # via -r requirements.in -rjsmin==1.2.1 +rjsmin==1.2.2 # via django-compressor -s3transfer==0.10.1 +s3transfer==0.10.4 # via boto3 -sentry-sdk==1.43.0 +sentry-sdk==2.19.2 # via -r requirements.in -six==1.16.0 +six==1.17.0 # via - # asttokens # django-jsonfield # furl # html5lib # orderedmultidict # python-dateutil -soupsieve==2.5 +soupsieve==2.6 # via beautifulsoup4 -sqlparse==0.4.4 +sqlparse==0.5.2 # via # django # django-debug-toolbar @@ -265,32 +265,33 @@ stack-data==0.6.3 # via ipython text-unidecode==1.3 # via python-slugify -time-machine==2.14.0 +time-machine==2.16.0 # via -r requirements.in -traitlets==5.14.2 +traitlets==5.14.3 # via # ipython # matplotlib-inline types-python-slugify==8.0.2.20240310 # via -r requirements.in -types-pytz==2024.1.0.20240203 - # via django-stubs -types-pyyaml==6.0.12.20240311 +types-pyyaml==6.0.12.20240917 # via # -r requirements.in # django-stubs -types-requests==2.31.0.20240311 +types-requests==2.32.0.20241016 # via -r requirements.in -typing-extensions==4.10.0 +typing-extensions==4.12.2 # via # django-stubs # django-stubs-ext + # ipython # mypy # psycopg # psycopg-pool -tzdata==2024.1 - # via celery -urllib3==2.2.1 +tzdata==2024.2 + # via + # celery + # kombu +urllib3==2.2.3 # via # botocore # requests @@ -302,21 +303,23 @@ vine==5.1.0 # amqp # celery # kombu -virtualenv==20.25.1 +virtualenv==20.28.0 # via pre-commit -waitress==3.0.0 +waitress==3.0.2 # via webtest wcwidth==0.2.13 # via prompt-toolkit webencodings==0.5.1 # via html5lib -webob==1.8.7 +webob==1.8.9 # via webtest -webtest==3.0.0 +webtest==3.0.2 # via django-webtest -wheel==0.43.0 - # via pip-tools -whitenoise[brotli]==6.6.0 +wheel==0.45.1 + # via + # django-pipeline + # pip-tools +whitenoise[brotli]==6.8.2 # via -r requirements.in # The following packages are considered to be unsafe in a requirements file: diff --git a/search/tests/test_postgresql.py b/search/tests/test_postgresql.py index 92e2f7b6..a71c1d8f 100644 --- a/search/tests/test_postgresql.py +++ b/search/tests/test_postgresql.py @@ -4,8 +4,8 @@ def needs_postgres(fn): - @pytest.mark.django_db() - @pytest.mark.postgresql() + @pytest.mark.django_db + @pytest.mark.postgresql @pytest.mark.skipif( connection.vendor != "postgresql", reason="This test requires a PostgreSQL database", diff --git a/users/tests/auth_backend_authenticate_test.py b/users/tests/auth_backend_authenticate_test.py index a265a4f6..d533cac0 100644 --- a/users/tests/auth_backend_authenticate_test.py +++ b/users/tests/auth_backend_authenticate_test.py @@ -8,7 +8,7 @@ pytestmark = pytest.mark.django_db -@pytest.fixture() +@pytest.fixture def fake_base_url(settings): settings.BASE_URL = "http://example.com/" diff --git a/users/tests/perm_test.py b/users/tests/perm_test.py index cf7d9cc3..9411a5cd 100644 --- a/users/tests/perm_test.py +++ b/users/tests/perm_test.py @@ -7,7 +7,7 @@ pytestmark = pytest.mark.django_db -@pytest.fixture() +@pytest.fixture def tree(): root = Category.objects.create(name="ULB", slug="ulb") science = Category.objects.create(name="science", slug="science") @@ -24,14 +24,14 @@ def tree(): return root -@pytest.fixture() +@pytest.fixture def user(): return User.objects.create_user( netid="myuser", email="myuser@lol.be", first_name="My", last_name="User" ) -@pytest.fixture() +@pytest.fixture def other_user(): return User.objects.create_user( netid="otheruser",