Skip to content

Commit

Permalink
Merge branch 'ruff' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
lukasjuhrich committed Feb 4, 2023
2 parents eaf7e6f + 56f24ea commit 2debeee
Show file tree
Hide file tree
Showing 67 changed files with 223 additions and 171 deletions.
22 changes: 15 additions & 7 deletions .github/workflows/docker-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: pre-commit/action@v2.0.3
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
- uses: pre-commit/action@v3.0.0
python-lint:
runs-on: ubuntu-latest
steps:
- name: Check out pycroft and submodules
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
submodules: recursive
- uses: actions/setup-python@v4
Expand All @@ -29,13 +29,21 @@ jobs:
run: pip install wheel
- name: install pip dependencies
run: pip install -r requirements.txt -r requirements.dev.txt
id: pip-install
# now come the tests
- name: Execute ruff
run: ruff check --format=github .
if: success() || steps.pip-install.conclusion == 'success'
- name: Execute mypy
run: ./scripts/run_mypy.sh
if: success() || steps.pip-install.conclusion == 'success'
# docs stuff
- name: Build sphinx docs
run: make SPHINXOPTS="-EN -w sphinx.log" -C doc html
if: success() || steps.pip-install.conclusion == 'success'
- name: Render sphinx warnings as annotations
run: python ./scripts/render_sphinx_log.py doc/sphinx.log
if: success() || steps.pip-install.conclusion == 'success'
- name: Publish sphinx docs as pages artifact
uses: actions/upload-pages-artifact@v1
with:
Expand Down Expand Up @@ -63,7 +71,7 @@ jobs:
npm-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
Expand All @@ -77,7 +85,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
submodules: 'true'
- name: Fix permissions
Expand All @@ -98,7 +106,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
submodules: 'true'
- name: Fix permissions
Expand Down
11 changes: 10 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
# see https://github.com/topics/pre-commit-hook for more
repos:
- repo: https://github.com/akaihola/darker
rev: 1.6.1
hooks:
- id: darker
- repo: https://github.com/asottile/pyupgrade
rev: v2.29.0
hooks:
- id: pyupgrade
args: ["--py310-plus"]
- repo: https://github.com/charliermarsh/ruff-pre-commit
# Ruff version.
rev: 'v0.0.241'
hooks:
- id: ruff
- repo: https://github.com/returntocorp/semgrep
rev: 'v0.91.0'
hooks:
- id: semgrep
# See semgrep.dev/rulesets to select a ruleset and copy its URL
args: ['--config', 'tools/semgrep.yml', '--metrics=off', '--error', '--skip-unknown-extensions']
args: ['--config', 'tools/semgrep.yml', '--metrics=off', '--error', '--skip-unknown-extensions']
6 changes: 4 additions & 2 deletions hades_logs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,9 @@ def _get_extension():
try:
return current_app.extensions['hades_logs']
except KeyError:
raise HadesConfigError("No HadesLogs instance registered to current Flask app")
raise HadesConfigError(
"No HadesLogs instance registered to current Flask app"
) from None

hades_logs: HadesLogs = LocalProxy(_get_extension)

hades_logs: HadesLogs = LocalProxy(_get_extension)
6 changes: 4 additions & 2 deletions hades_logs/parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ def parse_vlan(vlan):
raise ParsingError(f"VLAN identifier has no Name: {name}")
try:
taggedness = {'1': "tagged", '2': "untagged"}[prefix]
except KeyError:
raise ParsingError(f"VLAN identifier must start with '1' or '2': {stripped}")
except KeyError as e:
raise ParsingError(
f"VLAN identifier must start with '1' or '2': {stripped}"
) from e
return f"{name} ({taggedness})"


Expand Down
2 changes: 0 additions & 2 deletions helpers/interactive.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
"""
import logging
import os

from flask import _request_ctx_stack
from sqlalchemy.orm import scoped_session, sessionmaker
Expand All @@ -24,7 +23,6 @@
from scripts.connection import try_create_connection, get_connection_string

from pycroft.model._all import *
from pycroft import config

connection_string = get_connection_string()

Expand Down
1 change: 0 additions & 1 deletion ldap_sync/concepts/record.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

from __future__ import annotations

import abc
import dataclasses
import typing

Expand Down
2 changes: 1 addition & 1 deletion ldap_sync/sources/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import typing
from typing import NamedTuple

from sqlalchemy import and_, func, select, join, text, literal
from sqlalchemy import and_, func, select, join, literal
from sqlalchemy.dialects import postgresql
from sqlalchemy.orm import scoped_session, sessionmaker, joinedload, foreign, Session

Expand Down
1 change: 0 additions & 1 deletion ldap_sync/sources/ldap.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
from ..concepts.record import UserRecord, GroupRecord
from ..config import SyncConfig
from ..concepts.types import LdapRecord
from ..conversion import ldap_user_to_record, ldap_group_to_record


def establish_and_return_ldap_connection(config: SyncConfig) -> ldap3.Connection:
Expand Down
10 changes: 8 additions & 2 deletions pycroft/helpers/i18n/babel.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,14 @@

_unspecified_locale = Locale("en", "US")
_null_translations = Translations()
_locale_lookup: typing.Callable[[], Locale] = lambda: _unspecified_locale
_translations_lookup: typing.Callable[[], Translations] = lambda: _null_translations


def _locale_lookup() -> Locale:
return _unspecified_locale


def _translations_lookup() -> Translations:
return _null_translations


def get_locale() -> Locale:
Expand Down
2 changes: 1 addition & 1 deletion pycroft/helpers/i18n/formatting.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ def format_param(p, options: dict[type, dict[str, typing.Any]]) -> Formattable:
raise TypeError(
f"No formatter available for type {qualified_typename(concrete_type)}"
" or any supertype."
)
) from None
option_policy: OptionPolicy | None = getattr(formatter, "__option_policy__", None)
if option_policy == "ignore":
formatter_options: dict[str, typing.Any] = {}
Expand Down
8 changes: 4 additions & 4 deletions pycroft/helpers/i18n/serde.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ def identity(x):
def deserialize_money(v):
try:
return Money(Decimal(v[0]), v[1])
except IndexError:
raise ValueError()
except IndexError as e:
raise ValueError from e


def serialize_interval(interval: Interval) -> dict[str, typing.Any]:
Expand Down Expand Up @@ -147,7 +147,7 @@ def serialize_param(param):
raise TypeError(
"No serialization available for type {} or any"
"supertype".format(qualified_typename(concrete_type))
)
) from None
return {"type": qualified_typename(type_), "value": serializer(param)}


Expand All @@ -156,5 +156,5 @@ def deserialize_param(param):
try:
deserializer = deserialize_map[type_name]
except KeyError:
raise TypeError(f"No deserialization available for type {type_name}")
raise TypeError(f"No deserialization available for type {type_name}") from None
return deserializer(param["value"])
2 changes: 1 addition & 1 deletion pycroft/helpers/interval.py
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,7 @@ def _complement(intervals: t.Iterable[Interval[T]]) -> t.Iterator[Interval[T]]:
yield Interval(Bound(NegativeInfinity, False), ~first.lower_bound)
a, b = tee(intervals)
last = first
for current_, next_ in zip(chain((first,), a), b):
for current_, next_ in zip(chain((first,), a), b, strict=False):
yield Interval(~current_.upper_bound, ~next_.lower_bound)
last = next_
if not last.upper_bound.unbounded:
Expand Down
6 changes: 4 additions & 2 deletions pycroft/helpers/printing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,10 @@ def generate_user_sheet(
style = getStyleSheet()
story = []

PAGE_WIDTH = defaultPageSize[0]
PAGE_HEIGHT = defaultPageSize[1]
# noinspection Ruff
defaultPageSize[0]
# noinspection Ruff
defaultPageSize[1]

# HEADER
im_web = Image(ASSETS_WEB_FILENAME, 0.4 * cm, 0.4 * cm)
Expand Down
1 change: 0 additions & 1 deletion pycroft/lib/facilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import logging
import re
import typing as t
from collections import defaultdict
from dataclasses import dataclass
from itertools import groupby

Expand Down
19 changes: 9 additions & 10 deletions pycroft/lib/finance.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
text, future
from sqlalchemy.orm import aliased, contains_eager, joinedload, Session, Query
from sqlalchemy.orm.exc import NoResultFound
from sqlalchemy.sql import Select

from pycroft import config
from pycroft.helpers.date import diff_month, last_day_of_month
Expand Down Expand Up @@ -162,7 +161,7 @@ def complex_transaction(
def transferred_amount(
from_account: Account,
to_account: Account,
when: Interval[date] = t.cast(Interval[date], UnboundedInterval),
when: Interval[date] = t.cast(Interval[date], UnboundedInterval), # noqa: B008
) -> Decimal:
"""
Determine how much has been transferred from one account to another in a
Expand Down Expand Up @@ -472,7 +471,7 @@ def is_ordered(
except StopIteration:
# iterable is empty
return True
return all(relation(x, y) for x, y in zip(a, b))
return all(relation(x, y) for x, y in zip(a, b, strict=False))


@with_transaction
Expand Down Expand Up @@ -506,9 +505,9 @@ def import_bank_account_activities_csv(
process_record(index, record, imported_at=imported_at)
for index, record in records)
except StopIteration:
raise CSVImportError(gettext("No data present."))
raise CSVImportError(gettext("No data present.")) from None
except csv.Error as e:
raise CSVImportError(gettext("Could not read CSV."), e)
raise CSVImportError(gettext("Could not read CSV."), e) from e
if not activities:
raise CSVImportError(gettext("No data present."))
if not is_ordered((a[8] for a in activities), operator.ge):
Expand Down Expand Up @@ -617,23 +616,23 @@ def process_record(
"Record {1}: {2}")
raw_record = restore_record(record)
raise CSVImportError(
message.format(record.our_account_number, index, raw_record), e)
message.format(record.our_account_number, index, raw_record), e
) from None

try:
valid_on = datetime.strptime(record.valid_on, "%d.%m.%y").date()
posted_on = datetime.strptime(record.posted_on, "%d.%m.%y").date()
except ValueError as e:
message = gettext("Illegal date format. Record {1}: {2}")
raw_record = restore_record(record)
raise CSVImportError(message.format(index, raw_record), e)
raise CSVImportError(message.format(index, raw_record), e) from e

try:
amount = Decimal(record.amount.replace(",", "."))
except ValueError as e:
message = gettext("Illegal value format {0}. Record {1}: {2}")
raw_record = restore_record(record)
raise CSVImportError(
message.format(record.amount, index, raw_record), e)
raise CSVImportError(message.format(record.amount, index, raw_record), e) from e

return (amount, bank_account.id, cleanup_description(record.reference),
record.reference, record.other_account_number,
Expand Down Expand Up @@ -897,7 +896,7 @@ def build_transactions_query(
):
sort_by = "valid_on"

descending = (sort_order == "desc") ^ (positive == False)
descending = (sort_order == "desc") ^ (positive is False)
ordering = sort_by + " desc" if descending else sort_by
if search:
query = query.filter(Transaction.description.ilike(f'%{search}%'))
Expand Down
20 changes: 12 additions & 8 deletions pycroft/lib/mail.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def send_mails(mails: list[Mail]) -> tuple[bool, int]:
'trace': True,
'data': {'exception_arguments': e.args}
})
raise RetryableException
raise RetryableException from e

try:
smtp: smtplib.SMTP
Expand All @@ -143,13 +143,17 @@ def send_mails(mails: list[Mail]) -> tuple[bool, int]:
traceback.print_exc()

# smtp.connect failed to connect
logger.critical(f'Unable to connect to SMTP server: %s', e, extra={
'trace': True,
'tags': {'mailserver': f"{smtp_host}:{smtp_host}"},
'data': {'exception_arguments': e.args}
})

raise RetryableException
logger.critical(
"Unable to connect to SMTP server: %s",
e,
extra={
"trace": True,
"tags": {"mailserver": f"{smtp_host}:{smtp_host}"},
"data": {"exception_arguments": e.args},
},
)

raise RetryableException from e
else:
failures: int = 0

Expand Down
Loading

0 comments on commit 2debeee

Please sign in to comment.