Skip to content

Commit

Permalink
Merge master
Browse files Browse the repository at this point in the history
  • Loading branch information
BreathingFlesh committed Jan 17, 2025
2 parents c0088a2 + 991f2c5 commit 8732bb8
Show file tree
Hide file tree
Showing 1,230 changed files with 12,085 additions and 9,504 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ jobs:
--recursive \
--configfile pyproject.toml \
--format custom \
--msg-template '::error file={abspath},line={line},col={col},title=Bandit {test_id})::{msg}' \
--msg-template '::error file={abspath},line={line},col={col},title=Bandit ({test_id})::{msg}' \
src/ 2> /dev/null
- name: Static type checking
Expand Down
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ repos:
exclude: .pre-commit-config.yaml
- id: pt_structure
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.8.6
rev: v0.9.2
hooks:
- id: ruff
args: [ "--fix" ]
Expand All @@ -32,14 +32,14 @@ repos:
- id: sass-lint
files: '^src/.*\.scss'
- repo: https://github.com/pre-commit/mirrors-eslint
rev: v9.17.0
rev: v9.18.0
hooks:
- id: eslint
files: '^src/.*\.jsx?$'
additional_dependencies:
- eslint-react
- repo: https://github.com/PyCQA/bandit
rev: 1.8.0
rev: 1.8.2
hooks:
- id: bandit
args: ["-c", "pyproject.toml", "--quiet"]
Expand Down
24 changes: 11 additions & 13 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,12 @@ python_version = "3.11"
follow_imports = "silent"
namespace_packages = true
explicit_package_bases = true
warn_unused_ignores = true
warn_redundant_casts = true
warn_unused_configs = true
strict = true
implicit_reexport = true
warn_unreachable = true
disallow_any_generics = true
disallow_incomplete_defs = true
disallow_untyped_defs = true
strict_equality = true
extra_checks = true
warn_return_any = false
# FIXME: remove sqlalchemy when upgrading to SQlAlchemy 2.0
untyped_calls_exclude = "sqlalchemy,pycurl,onegov.core.types"
plugins = "sqlmypy"
mypy_path = "$MYPY_CONFIG_FILE_DIR/src:$MYPY_CONFIG_FILE_DIR/stubs"

Expand Down Expand Up @@ -72,13 +69,10 @@ exclude_dirs = [
skips = [
# ignore asserts
"B101",
# ignore lxml.etree.fromstring (we may want to revisit this in the future)
"B320",
# ignore meta-codes, we are aware of the implications
"B403",
"B404",
"B405",
"B410",
]

[tool.ruff]
Expand Down Expand Up @@ -134,6 +128,7 @@ select = [
"E",
"F",
"FLY002",
"I002",
"ISC",
"N",
"PERF",
Expand Down Expand Up @@ -190,7 +185,6 @@ ignore = [
"UP009",
"UP012",
"UP032",
"UP037",
"UP038",
]
unfixable = []
Expand All @@ -200,7 +194,7 @@ preview = true

[tool.ruff.lint.extend-per-file-ignores]
"src/onegov/core/types.py" = ["B018"]
"reportlab_settings.py" = ["N"]
"reportlab_settings.py" = ["N", "I002"]
"*.pyi" = [
"E501",
"N",
Expand All @@ -221,6 +215,7 @@ preview = true
"E306",
"F841",
"FLY002",
"I002",
"ISC",
"N",
"Q",
Expand All @@ -233,6 +228,9 @@ preview = true
"UP",
]

[tool.ruff.lint.isort]
required-imports = ["from __future__ import annotations"]

[tool.ruff.lint.pep8-naming]
extend-ignore-names = [
"afterFlowable",
Expand Down
3 changes: 2 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ dev =
honyaku@git+https://github.com/seantis/honyaku#egg=honyaku
lingua==3.12
pre-commit
pre-commit-uv
pytest-profiling
pytest-split
pytest-testmon
Expand Down Expand Up @@ -334,7 +335,7 @@ onegov_upgrades =
onegov.winterthur = onegov.winterthur.upgrade

[flake8]
select = TC0,TC2
select = TC0,TC1
per_file_ignores =
*.pyi: TC
tests/**.py: TC
2 changes: 2 additions & 0 deletions src/onegov/activity/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import logging
log = logging.getLogger('onegov.activity')
log.addHandler(logging.NullHandler())
Expand Down
2 changes: 2 additions & 0 deletions src/onegov/activity/collections/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

from onegov.activity.collections.activity import ActivityFilter
from onegov.activity.collections.activity import ActivityCollection
from onegov.activity.collections.attendee import AttendeeCollection
Expand Down
52 changes: 27 additions & 25 deletions src/onegov/activity/collections/activity.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import secrets
import sedate

Expand Down Expand Up @@ -90,15 +92,15 @@ class ToggledArgs(TypedDict, total=False):


ActivityT = TypeVar('ActivityT', bound=Activity)
AVAILABILITY_VALUES: set['AvailabilityType'] = {'none', 'few', 'many'}
AVAILABILITY_VALUES: set[AvailabilityType] = {'none', 'few', 'many'}


class ActivityFilter:

# supported filters - should be named with a plural version that can
# be turned into a singular with the removal of the last s
# (i.e. slots => slot)
__slots__: tuple['FilterKey', ...] = (
__slots__: tuple[FilterKey, ...] = (
'age_ranges',
'available',
'price_ranges',
Expand All @@ -119,20 +121,20 @@ class ActivityFilter:
}

age_ranges: set[tuple[int, int]]
available: set['AvailabilityType']
available: set[AvailabilityType]
price_ranges: set[tuple[int, int]]
dateranges: set[tuple['date', 'date']]
dateranges: set[tuple[date, date]]
durations: set[int]
municipalities: set[str]
owners: set[str]
period_ids: set[UUID]
states: set['ActivityState']
states: set[ActivityState]
tags: set[str]
timelines: set[str]
weekdays: set[int]
volunteers: set[bool]

def __init__(self, **keywords: 'Unpack[FilterArgs]') -> None:
def __init__(self, **keywords: Unpack[FilterArgs]) -> None:
for key in self.__slots__:
if key in keywords:
values = set(v) if (v := keywords[key]) else set()
Expand All @@ -148,14 +150,14 @@ def __init__(self, **keywords: 'Unpack[FilterArgs]') -> None:
setattr(self, key, set())

@property
def keywords(self) -> dict['FilterKey', str | list[str]]:
def keywords(self) -> dict[FilterKey, str | list[str]]:
return {
key: self.encode(key, value)
for key in self.__slots__
if (value := getattr(self, key))
}

def toggled(self, **keywords: 'Unpack[ToggledArgs]') -> 'Self':
def toggled(self, **keywords: Unpack[ToggledArgs]) -> Self:
# create a new filter with the toggled values
toggled = copy(self)

Expand Down Expand Up @@ -191,7 +193,7 @@ def adapt_age_ranges(self, values: set[str]) -> set[tuple[int, int]]:
def adapt_price_ranges(self, values: set[str]) -> set[tuple[int, int]]:
return self.adapt_num_ranges(values)

def adapt_dateranges(self, values: set[str]) -> set[tuple['date', 'date']]:
def adapt_dateranges(self, values: set[str]) -> set[tuple[date, date]]:
return {v for v in map(date_range_decode, values) if v}

def adapt_weekdays(self, values: set[str]) -> set[int]:
Expand Down Expand Up @@ -243,7 +245,7 @@ def encode(self, key: str, value: object) -> str | list[str]:
def contains_num_range(
self,
value: tuple[int, int],
ranges: 'Iterable[tuple[int, int]]'
ranges: Iterable[tuple[int, int]]
) -> bool:
for r in ranges:
if overlaps(r, value):
Expand All @@ -261,8 +263,8 @@ class ActivityCollection(RangedPagination[ActivityT]):

@overload
def __init__(
self: 'ActivityCollection[Activity]',
session: 'Session',
self: ActivityCollection[Activity],
session: Session,
type: Literal['*', 'generic'] = '*',
pages: tuple[int, int] | None = None,
filter: ActivityFilter | None = None
Expand All @@ -271,15 +273,15 @@ def __init__(
@overload
def __init__(
self,
session: 'Session',
session: Session,
type: str,
pages: tuple[int, int] | None = None,
filter: ActivityFilter | None = None
) -> None: ...

def __init__(
self,
session: 'Session',
session: Session,
type: str = '*',
pages: tuple[int, int] | None = None,
filter: ActivityFilter | None = None
Expand All @@ -289,14 +291,14 @@ def __init__(
self.pages = pages or (0, 0)
self.filter = filter or ActivityFilter()

def subset(self) -> 'Query[ActivityT]':
def subset(self) -> Query[ActivityT]:
return self.query()

@property
def page_range(self) -> tuple[int, int]:
return self.pages

def by_page_range(self, page_range: tuple[int, int] | None) -> 'Self':
def by_page_range(self, page_range: tuple[int, int] | None) -> Self:
return self.__class__(
self.session,
type=self.type,
Expand All @@ -311,7 +313,7 @@ def model_class(self) -> type[ActivityT]:
Activity # type:ignore[arg-type]
)

def query_base(self) -> 'Query[ActivityT]':
def query_base(self) -> Query[ActivityT]:
""" Returns the query based used by :meth:`query`. Overriding this
function is useful to apply a general filter to the query before
any other filter is applied.
Expand All @@ -322,7 +324,7 @@ def query_base(self) -> 'Query[ActivityT]':
"""
return self.session.query(self.model_class)

def query(self) -> 'Query[ActivityT]':
def query(self) -> Query[ActivityT]:
query = self.query_base()
model_class = self.model_class

Expand Down Expand Up @@ -460,8 +462,8 @@ def query(self) -> 'Query[ActivityT]':

def for_filter(
self,
**keywords: 'Unpack[ToggledArgs]'
) -> 'Self':
**keywords: Unpack[ToggledArgs]
) -> Self:
""" Returns a new collection instance.
The given tag is excluded if already in the list, included if not
Expand All @@ -486,10 +488,10 @@ def by_id(self, id: UUID) -> ActivityT | None:
def by_name(self, name: str) -> ActivityT | None:
return self.query().filter(Activity.name == name).first()

def by_user(self, user: 'User') -> 'Query[ActivityT]':
def by_user(self, user: User) -> Query[ActivityT]:
return self.query().filter(Activity.username == user.username)

def by_username(self, username: str) -> 'Query[ActivityT]':
def by_username(self, username: str) -> Query[ActivityT]:
return self.query().filter(Activity.username == username)

@property
Expand Down Expand Up @@ -546,7 +548,7 @@ def add(
title: str,
username: str,
lead: str | None = None,
text: 'Markup | None' = None,
text: Markup | None = None,
tags: set[str] | None = None,
name: str | None = None
) -> ActivityT:
Expand Down Expand Up @@ -579,8 +581,8 @@ def delete(self, activity: Activity) -> None:

def available_weeks(
self,
period: 'Period | PeriodMeta | None'
) -> 'Iterator[tuple[date, date]]':
period: Period | PeriodMeta | None
) -> Iterator[tuple[date, date]]:
if not period:
return

Expand Down
10 changes: 6 additions & 4 deletions src/onegov/activity/collections/attendee.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

from onegov.activity.models import Attendee
from onegov.core.collection import GenericCollection

Expand All @@ -15,17 +17,17 @@ class AttendeeCollection(GenericCollection[Attendee]):
def model_class(self) -> type[Attendee]:
return Attendee

def by_user(self, user: 'User') -> 'Query[Attendee]':
def by_user(self, user: User) -> Query[Attendee]:
return self.query().filter(self.model_class.username == user.username)

def by_username(self, username: str) -> 'Query[Attendee]':
def by_username(self, username: str) -> Query[Attendee]:
return self.query().filter(self.model_class.username == username)

def add( # type:ignore[override]
self,
user: 'User',
user: User,
name: str,
birth_date: 'date',
birth_date: date,
gender: str | None,
notes: str | None = None,
differing_address: bool = False,
Expand Down
Loading

0 comments on commit 8732bb8

Please sign in to comment.