~homeworkprod/byceps

335b42be5889f981f2ac866cd12175d66fec7e4a — Jochen Kupperschmidt a month ago e242f51
Fix type hint(-related) issues
M byceps/services/authentication/session/models/current_user.py => byceps/services/authentication/session/models/current_user.py +1 -1
@@ 19,7 19,7 @@ class CurrentUser(User):
    """The current user, anonymous or logged in."""

    authenticated: bool
    permissions: set[Enum]
    permissions: frozenset[Enum]
    locale: Optional[str]

    def __eq__(self, other) -> bool:

M byceps/services/authentication/session/service.py => byceps/services/authentication/session/service.py +5 -2
@@ 184,11 184,14 @@ def get_anonymous_current_user(*, locale: Optional[str] = None) -> CurrentUser:


def get_authenticated_current_user(
    user: User, *, permissions: set[Enum] = None, locale: Optional[str] = None
    user: User,
    *,
    permissions: Optional[frozenset[Enum]] = None,
    locale: Optional[str] = None,
) -> CurrentUser:
    """Return an authenticated current user object."""
    if permissions is None:
        permissions = set()
        permissions = frozenset()

    return CurrentUser(
        id=user.id,

M byceps/services/image/service.py => byceps/services/image/service.py +4 -4
@@ 7,7 7,7 @@ byceps.services.image.service
"""

from __future__ import annotations
from typing import BinaryIO, FrozenSet, Iterable
from typing import BinaryIO, Iterable, Union

from ...util.image import read_dimensions
from ...util.image.models import Dimensions, ImageType


@@ 18,18 18,18 @@ class ImageTypeProhibited(ValueError):
    pass


def get_image_type_names(types: Iterable[ImageType]) -> FrozenSet[str]:
def get_image_type_names(types: Iterable[ImageType]) -> frozenset[str]:
    """Return the names of the image types."""
    return frozenset(t.name.upper() for t in types)


def determine_image_type(
    stream: BinaryIO, allowed_types: set[ImageType]
    stream: BinaryIO, allowed_types: Union[frozenset[ImageType], set[ImageType]]
) -> ImageType:
    """Extract image type from stream."""
    image_type = guess_type(stream)

    if image_type not in allowed_types:
    if (image_type is None) or (image_type not in allowed_types):
        allowed_type_names = get_image_type_names(allowed_types)
        allowed_type_names_string = ', '.join(sorted(allowed_type_names))


M byceps/services/news/image_service.py => byceps/services/news/image_service.py +1 -1
@@ 58,7 58,7 @@ def create_image(
        image_dimensions = image_service.determine_dimensions(stream)
        _check_image_dimensions(image_dimensions)

    image_id = generate_uuid()
    image_id = ImageID(generate_uuid())
    number = _get_next_available_number(item.id)
    filename = f'{image_id}.{image_type.name}'


M byceps/services/orga/birthday_service.py => byceps/services/orga/birthday_service.py +8 -8
@@ 8,7 8,7 @@ byceps.services.orga.birthday_service

from __future__ import annotations
from itertools import islice
from typing import Iterator, Optional, Sequence
from typing import Iterable, Iterator, Optional

from ...database import db



@@ 32,8 32,8 @@ def get_orgas_with_birthday_today() -> set[User]:

def collect_orgas_with_next_birthdays(
    *, limit: Optional[int] = None
) -> Iterator[tuple[User, Birthday]]:
    """Yield the next birthdays of organizers, sorted by month and day."""
) -> list[tuple[User, Birthday]]:
    """Return the next birthdays of organizers, sorted by month and day."""
    orgas_with_birthdays = _collect_orgas_with_known_birthdays()

    sorted_orgas = sort_users_by_next_birthday(orgas_with_birthdays)


@@ 45,7 45,7 @@ def collect_orgas_with_next_birthdays(


def _collect_orgas_with_known_birthdays() -> Iterator[tuple[User, Birthday]]:
    """Return all organizers whose birthday is known."""
    """Yield all organizers whose birthday is known."""
    users = DbUser.query \
        .join(DbOrgaFlag) \
        .join(DbUserDetail) \


@@ 81,12 81,12 @@ def _to_user_dto(


def sort_users_by_next_birthday(
    users_and_birthdays: Sequence[tuple[User, Birthday]]
) -> Sequence[tuple[User, Birthday]]:
    return sorted(
    users_and_birthdays: Iterable[tuple[User, Birthday]]
) -> list[tuple[User, Birthday]]:
    return list(sorted(
        users_and_birthdays,
        key=lambda user_and_birthday: (
            user_and_birthday[1].days_until_next_birthday,
            -user_and_birthday[1].age,
        ),
    )
    ))

M byceps/services/shop/order/email/service.py => byceps/services/shop/order/email/service.py +1 -1
@@ 143,7 143,7 @@ def _get_order_email_data(order_id: OrderID) -> OrderEmailData:

    shop = shop_service.get_shop(order.shop_id)
    orderer_id = order.placed_by_id
    screen_name = user_service.get_user(orderer_id).screen_name
    screen_name = user_service.get_user(orderer_id).screen_name or 'UnknownUser'
    email_address = user_service.get_email_address(orderer_id)

    return OrderEmailData(

M byceps/services/terms/document_service.py => byceps/services/terms/document_service.py +6 -1
@@ 59,7 59,12 @@ def find_document_id_for_brand(brand_id: BrandID) -> Optional[DocumentID]:
    none is configured.
    """
    setting_name = 'terms_document_id'
    return brand_settings_service.find_setting_value(brand_id, setting_name)
    value = brand_settings_service.find_setting_value(brand_id, setting_name)

    if value is None:
        return None

    return DocumentID(value)


def _db_entity_to_document(document: DbDocument) -> Document:

M byceps/util/authorization.py => byceps/util/authorization.py +2 -2
@@ 39,7 39,7 @@ def register_permission_enum(enum: Enum):
    permission_registry.register_enum(enum)


def get_permissions_for_user(user_id: UserID) -> set[Enum]:
def get_permissions_for_user(user_id: UserID) -> frozenset[Enum]:
    """Return the permissions this user has been granted."""
    permission_ids = authorization_service.get_permission_ids_for_user(user_id)
    return permission_registry.get_enum_members(permission_ids)


@@ 83,7 83,7 @@ class PermissionRegistry:
            )
            return None

    def get_enum_members(self, permission_ids):
    def get_enum_members(self, permission_ids) -> frozenset[Enum]:
        """Return the enums that are registered for the permission IDs.

        If no enum is found for a permission ID, it is silently ignored.

M byceps/util/templating.py => byceps/util/templating.py +1 -1
@@ 66,7 66,7 @@ class SiteTemplateOverridesLoader(BaseLoader):
    def __init__(self) -> None:
        self._loaders_by_site_id: dict[str, BaseLoader] = {}

    def get_source(self, environment: Environment, template: Template) -> str:
    def get_source(self, environment: Environment, template: str) -> str:
        site_id = getattr(g, 'site_id', None)
        if site_id is None:
            # Site could not be determined. Thus, no site-specific

M tests/integration/services/authentication/test_current_user.py => tests/integration/services/authentication/test_current_user.py +2 -2
@@ 27,10 27,10 @@ def test_get_anonymous_current_user():

def test_get_authenticated_current_user(user):
    permission_enum = create_permission_enum('example', ['do_this', 'do_that'])
    permissions = {
    permissions = frozenset([
        permission_enum.do_this,
        permission_enum.do_that,
    }
    ])
    locale = 'de'

    current_user = session_service.get_authenticated_current_user(