From 1bb085fac33c72d94939f0ae62b48ae77054d743 Mon Sep 17 00:00:00 2001 From: Jochen Kupperschmidt Date: Sun, 19 Jan 2020 14:37:21 +0100 Subject: [PATCH] Change remaining value objects from `attrs` to `dataclass` --- byceps/blueprints/admin/newsletter/views.py | 4 ++-- byceps/blueprints/admin/party/views.py | 5 +++-- byceps/blueprints/admin/shop/order/service.py | 6 ++---- byceps/services/board/transfer/models.py | 9 ++++----- byceps/services/brand/transfer/models.py | 6 +++--- byceps/services/consent/transfer/models.py | 7 +++---- byceps/services/email/transfer/models.py | 9 ++++----- byceps/services/metrics/models.py | 9 ++++----- byceps/services/news/transfer/models.py | 9 ++++----- byceps/services/newsletter/transfer/models.py | 7 +++---- byceps/services/orga_presence/transfer/models.py | 11 +++++------ byceps/services/party/transfer/models.py | 7 +++---- byceps/services/shop/order/email/service.py | 4 ++-- byceps/services/shop/order/models/orderer.py | 4 ++-- byceps/services/shop/order/transfer/models.py | 9 ++++----- byceps/services/shop/sequence/transfer/models.py | 5 ++--- byceps/services/shop/shipping/service.py | 5 ++--- byceps/services/shop/shipping/transfer/models.py | 4 ++-- byceps/services/shop/shop/transfer/models.py | 5 ++--- byceps/services/site/transfer/models.py | 7 +++---- byceps/services/snippet/transfer/models.py | 4 +--- byceps/services/terms/transfer/models.py | 5 ++--- byceps/services/ticketing/transfer/models.py | 4 +--- byceps/services/user_badge/transfer/models.py | 9 ++++----- byceps/services/user_message/service.py | 4 ++-- pyproject.toml | 1 - requirements.txt | 1 - 27 files changed, 69 insertions(+), 91 deletions(-) diff --git a/byceps/blueprints/admin/newsletter/views.py b/byceps/blueprints/admin/newsletter/views.py index 518292e2e1..456d7e5fec 100644 --- a/byceps/blueprints/admin/newsletter/views.py +++ b/byceps/blueprints/admin/newsletter/views.py @@ -6,9 +6,9 @@ :License: Modified BSD, see LICENSE for details. """ +from dataclasses import dataclass from operator import attrgetter -from attr import attrs from flask import abort from ....services.newsletter import service as newsletter_service @@ -30,7 +30,7 @@ permission_registry.register_enum(NewsletterPermission) -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class ListWithStats(List): subscriber_count: int diff --git a/byceps/blueprints/admin/party/views.py b/byceps/blueprints/admin/party/views.py index 8fc08e1c21..1226789e00 100644 --- a/byceps/blueprints/admin/party/views.py +++ b/byceps/blueprints/admin/party/views.py @@ -6,7 +6,8 @@ :License: Modified BSD, see LICENSE for details. """ -import attr +import dataclasses + from flask import abort, request from ....services.brand import service as brand_service @@ -159,7 +160,7 @@ def update_form(party_id, erroneous_form=None): party = _get_party_or_404(party_id) brand = brand_service.find_brand(party.brand_id) - party = attr.evolve( + party = dataclasses.replace( party, starts_at=utc_to_local_tz(party.starts_at), ends_at=utc_to_local_tz(party.ends_at), diff --git a/byceps/blueprints/admin/shop/order/service.py b/byceps/blueprints/admin/shop/order/service.py index 4735c44321..a9aaff6d23 100644 --- a/byceps/blueprints/admin/shop/order/service.py +++ b/byceps/blueprints/admin/shop/order/service.py @@ -6,11 +6,9 @@ :License: Modified BSD, see LICENSE for details. """ +from dataclasses import dataclass from typing import Dict, Iterator, Sequence -import attr -from attr import attrs - from .....services.shop.article.models.article import Article from .....services.shop.article import service as article_service from .....services.shop.article.transfer.models import ArticleNumber @@ -29,7 +27,7 @@ from .....typing import UserID -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class OrderWithOrderer(Order): placed_by: DbUser diff --git a/byceps/services/board/transfer/models.py b/byceps/services/board/transfer/models.py index 728cb0920b..b6bc1200da 100644 --- a/byceps/services/board/transfer/models.py +++ b/byceps/services/board/transfer/models.py @@ -6,12 +6,11 @@ :License: Modified BSD, see LICENSE for details. """ +from dataclasses import dataclass from datetime import datetime from typing import NewType from uuid import UUID -from attr import attrs - from ....typing import BrandID from ...user.transfer.models import User @@ -29,14 +28,14 @@ TopicID = NewType('TopicID', UUID) -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class Board: id: BoardID brand_id: BrandID access_restricted: bool -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class Category: id: CategoryID board_id: BoardID @@ -49,7 +48,7 @@ class Category: hidden: bool -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class CategoryWithLastUpdate(Category): last_posting_updated_at: datetime last_posting_updated_by: User diff --git a/byceps/services/brand/transfer/models.py b/byceps/services/brand/transfer/models.py index 37fadf4a4b..adce058e6e 100644 --- a/byceps/services/brand/transfer/models.py +++ b/byceps/services/brand/transfer/models.py @@ -6,18 +6,18 @@ :License: Modified BSD, see LICENSE for details. """ -from attr import attrs +from dataclasses import dataclass from ....typing import BrandID -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class Brand: id: BrandID title: str -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class BrandSetting: brand_id: BrandID name: str diff --git a/byceps/services/consent/transfer/models.py b/byceps/services/consent/transfer/models.py index 40a9f3e9ae..81c8738e81 100644 --- a/byceps/services/consent/transfer/models.py +++ b/byceps/services/consent/transfer/models.py @@ -6,19 +6,18 @@ :License: Modified BSD, see LICENSE for details. """ +from dataclasses import dataclass from datetime import datetime from typing import NewType from uuid import UUID -from attr import attrs - from ....typing import UserID SubjectID = NewType('SubjectID', UUID) -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class Subject: id: SubjectID name: str @@ -26,7 +25,7 @@ class Subject: type_: str -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class Consent: user_id: UserID subject_id: SubjectID diff --git a/byceps/services/email/transfer/models.py b/byceps/services/email/transfer/models.py index 96628d80a8..c87b33610c 100644 --- a/byceps/services/email/transfer/models.py +++ b/byceps/services/email/transfer/models.py @@ -6,13 +6,12 @@ :License: Modified BSD, see LICENSE for details. """ +from dataclasses import dataclass from email.utils import formataddr from typing import List -from attr import attrs - -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class Sender: address: str name: str @@ -23,14 +22,14 @@ def format(self): return formataddr((realname, self.address)) -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class EmailConfig: id: str sender: Sender contact_address: str -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class Message: sender: Sender recipients: List[str] diff --git a/byceps/services/metrics/models.py b/byceps/services/metrics/models.py index 0326fd460e..6b545c2688 100644 --- a/byceps/services/metrics/models.py +++ b/byceps/services/metrics/models.py @@ -6,12 +6,11 @@ :License: Modified BSD, see LICENSE for details. """ +from dataclasses import dataclass, field from typing import List -from attr import attrib, attrs - -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class Label: name: str value: str @@ -35,11 +34,11 @@ def escape(char): return ''.join(map(escape, value)) -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class Metric: name: str value: float - labels: List[Label] = attrib(factory=dict, kw_only=True) + labels: List[Label] = field(default_factory=dict) def serialize(self) -> str: labels_str = '' diff --git a/byceps/services/news/transfer/models.py b/byceps/services/news/transfer/models.py index 56bed07e20..274ca843ca 100644 --- a/byceps/services/news/transfer/models.py +++ b/byceps/services/news/transfer/models.py @@ -6,12 +6,11 @@ :License: Modified BSD, see LICENSE for details. """ +from dataclasses import dataclass from datetime import datetime from typing import List, NewType from uuid import UUID -from attr import attrs - from ....typing import BrandID, UserID @@ -27,14 +26,14 @@ ImageID = NewType('ImageID', UUID) -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class Channel: id: ChannelID brand_id: BrandID url_prefix: str -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class Image: id: ImageID created_at: datetime @@ -45,7 +44,7 @@ class Image: caption: str -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class Item: id: ItemID channel: Channel diff --git a/byceps/services/newsletter/transfer/models.py b/byceps/services/newsletter/transfer/models.py index 679b1f9789..f36e1294b7 100644 --- a/byceps/services/newsletter/transfer/models.py +++ b/byceps/services/newsletter/transfer/models.py @@ -6,24 +6,23 @@ :License: Modified BSD, see LICENSE for details. """ +from dataclasses import dataclass from datetime import datetime from typing import NewType -from attr import attrs - from ....typing import UserID ListID = NewType('ListID', str) -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class List: id: ListID title: str -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class Subscription: user_id: UserID list_id: ListID diff --git a/byceps/services/orga_presence/transfer/models.py b/byceps/services/orga_presence/transfer/models.py index 5767e3babf..c6a116a9d9 100644 --- a/byceps/services/orga_presence/transfer/models.py +++ b/byceps/services/orga_presence/transfer/models.py @@ -7,11 +7,10 @@ """ from __future__ import annotations +from dataclasses import dataclass from datetime import datetime from enum import Enum -from attr import attrs - from ...party.transfer.models import Party from ...user.transfer.models import User @@ -21,7 +20,7 @@ TimeSlotType = Enum('TimeSlotType', ['party', 'presence', 'task']) -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class TimeSlot: type: TimeSlotType starts_at: datetime @@ -32,7 +31,7 @@ def range(self) -> DateTimeRange: return DateTimeRange(self.starts_at, self.ends_at) -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class PartyTimeSlot(TimeSlot): party: Party @@ -46,7 +45,7 @@ def from_party(cls, party: Party) -> PartyTimeSlot: ) -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class PresenceTimeSlot(TimeSlot): orga: User @@ -62,7 +61,7 @@ def from_( ) -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class TaskTimeSlot(TimeSlot): title: str diff --git a/byceps/services/party/transfer/models.py b/byceps/services/party/transfer/models.py index 97346cb1dc..bb2add069b 100644 --- a/byceps/services/party/transfer/models.py +++ b/byceps/services/party/transfer/models.py @@ -6,17 +6,16 @@ :License: Modified BSD, see LICENSE for details. """ +from dataclasses import dataclass from datetime import datetime from typing import Optional -from attr import attrs - from ....typing import BrandID, PartyID from ...shop.shop.transfer.models import ShopID -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class Party: id: PartyID brand_id: BrandID @@ -30,7 +29,7 @@ class Party: archived: bool -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class PartySetting: party_id: PartyID name: str diff --git a/byceps/services/shop/order/email/service.py b/byceps/services/shop/order/email/service.py index 320a334fa2..6e84796efa 100644 --- a/byceps/services/shop/order/email/service.py +++ b/byceps/services/shop/order/email/service.py @@ -8,10 +8,10 @@ :License: Modified BSD, see LICENSE for details. """ +from dataclasses import dataclass import os.path from typing import Any, Dict, Optional -from attr import attrs from flask import current_app from jinja2 import FileSystemLoader @@ -30,7 +30,7 @@ from ...shop.transfer.models import ShopID -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class OrderEmailData: order: Order email_config_id: str diff --git a/byceps/services/shop/order/models/orderer.py b/byceps/services/shop/order/models/orderer.py index 4c822ea5a1..807da831c8 100644 --- a/byceps/services/shop/order/models/orderer.py +++ b/byceps/services/shop/order/models/orderer.py @@ -6,12 +6,12 @@ :License: Modified BSD, see LICENSE for details. """ -from attr import attrs +from dataclasses import dataclass from .....typing import UserID -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class Orderer: """Someone who orders articles.""" diff --git a/byceps/services/shop/order/transfer/models.py b/byceps/services/shop/order/transfer/models.py index be76ad786f..af1456dc54 100644 --- a/byceps/services/shop/order/transfer/models.py +++ b/byceps/services/shop/order/transfer/models.py @@ -6,14 +6,13 @@ :License: Modified BSD, see LICENSE for details. """ +from dataclasses import dataclass from datetime import datetime from decimal import Decimal from enum import Enum from typing import List, NewType from uuid import UUID -from attr import attrs - from .....typing import UserID from ...article.transfer.models import ArticleNumber @@ -42,7 +41,7 @@ ]) -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class Address: country: str zip_code: str @@ -50,7 +49,7 @@ class Address: street: str -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class OrderItem: order_number: OrderNumber article_number: ArticleNumber @@ -61,7 +60,7 @@ class OrderItem: line_amount: Decimal -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class Order: id: OrderID shop_id: ShopID diff --git a/byceps/services/shop/sequence/transfer/models.py b/byceps/services/shop/sequence/transfer/models.py index 631721cdfd..7d19d0ec3b 100644 --- a/byceps/services/shop/sequence/transfer/models.py +++ b/byceps/services/shop/sequence/transfer/models.py @@ -6,17 +6,16 @@ :License: Modified BSD, see LICENSE for details. """ +from dataclasses import dataclass from enum import Enum -from attr import attrs - from ...shop.transfer.models import ShopID Purpose = Enum('Purpose', ['article', 'order']) -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class NumberSequence: shop_id: ShopID purpose: Purpose diff --git a/byceps/services/shop/shipping/service.py b/byceps/services/shop/shipping/service.py index 8f8c898803..fb44ec10d0 100644 --- a/byceps/services/shop/shipping/service.py +++ b/byceps/services/shop/shipping/service.py @@ -7,10 +7,9 @@ """ from collections import Counter, defaultdict +from dataclasses import dataclass from typing import Dict, Iterator, Sequence, Set -from attr import attrs - from ..article.models.article import Article as DbArticle from ....database import db @@ -49,7 +48,7 @@ def get_articles_to_ship(shop_id: ShopID) -> Sequence[ArticleToShip]: return articles_to_ship -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class OrderItemQuantity: article_number: ArticleNumber payment_state: PaymentState diff --git a/byceps/services/shop/shipping/transfer/models.py b/byceps/services/shop/shipping/transfer/models.py index c62f5f549c..655ce63134 100644 --- a/byceps/services/shop/shipping/transfer/models.py +++ b/byceps/services/shop/shipping/transfer/models.py @@ -6,12 +6,12 @@ :License: Modified BSD, see LICENSE for details. """ -from attr import attrs +from dataclasses import dataclass from ...article.transfer.models import ArticleNumber -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class ArticleToShip: article_number: ArticleNumber description: str diff --git a/byceps/services/shop/shop/transfer/models.py b/byceps/services/shop/shop/transfer/models.py index 45f584e4b9..821702b372 100644 --- a/byceps/services/shop/shop/transfer/models.py +++ b/byceps/services/shop/shop/transfer/models.py @@ -6,15 +6,14 @@ :License: Modified BSD, see LICENSE for details. """ +from dataclasses import dataclass from typing import NewType -from attr import attrs - ShopID = NewType('ShopID', str) -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class Shop: id: ShopID title: str diff --git a/byceps/services/site/transfer/models.py b/byceps/services/site/transfer/models.py index 684958ecb6..83c874e125 100644 --- a/byceps/services/site/transfer/models.py +++ b/byceps/services/site/transfer/models.py @@ -6,17 +6,16 @@ :License: Modified BSD, see LICENSE for details. """ +from dataclasses import dataclass from typing import NewType -from attr import attrs - from ....typing import PartyID SiteID = NewType('SiteID', str) -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class Site: id: SiteID title: str @@ -29,7 +28,7 @@ class Site: archived: bool -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class SiteSetting: site_id: SiteID name: str diff --git a/byceps/services/snippet/transfer/models.py b/byceps/services/snippet/transfer/models.py index bf027f2f7f..0c614654f1 100644 --- a/byceps/services/snippet/transfer/models.py +++ b/byceps/services/snippet/transfer/models.py @@ -12,14 +12,12 @@ from typing import NewType from uuid import UUID -from attr import attrs - from ...site.transfer.models import SiteID from ....typing import BrandID -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class Scope: type_: str name: str diff --git a/byceps/services/terms/transfer/models.py b/byceps/services/terms/transfer/models.py index 00a0924da1..cdfeb22ae2 100644 --- a/byceps/services/terms/transfer/models.py +++ b/byceps/services/terms/transfer/models.py @@ -6,11 +6,10 @@ :License: Modified BSD, see LICENSE for details. """ +from dataclasses import dataclass from typing import NewType from uuid import UUID -from attr import attrs - DocumentID = NewType('DocumentID', str) @@ -18,7 +17,7 @@ VersionID = NewType('VersionID', UUID) -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class Document: id: DocumentID title: str diff --git a/byceps/services/ticketing/transfer/models.py b/byceps/services/ticketing/transfer/models.py index 769d1c3266..fe37378c27 100644 --- a/byceps/services/ticketing/transfer/models.py +++ b/byceps/services/ticketing/transfer/models.py @@ -10,15 +10,13 @@ from typing import NewType, Optional from uuid import UUID -from attr import attrs - from ....typing import PartyID TicketCategoryID = NewType('TicketCategoryID', UUID) -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class TicketCategory: id: TicketCategoryID party_id: PartyID diff --git a/byceps/services/user_badge/transfer/models.py b/byceps/services/user_badge/transfer/models.py index 722eaed3bc..8d39b39f17 100644 --- a/byceps/services/user_badge/transfer/models.py +++ b/byceps/services/user_badge/transfer/models.py @@ -6,19 +6,18 @@ :License: Modified BSD, see LICENSE for details. """ +from dataclasses import dataclass from datetime import datetime from typing import NewType from uuid import UUID -from attr import attrs - from ....typing import BrandID, UserID BadgeID = NewType('BadgeID', UUID) -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class Badge: id: BadgeID brand_id: BrandID @@ -29,7 +28,7 @@ class Badge: featured: bool -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class BadgeAwarding: id: UUID badge_id: BadgeID @@ -37,7 +36,7 @@ class BadgeAwarding: awarded_at: datetime -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class QuantifiedBadgeAwarding: badge_id: BadgeID user_id: UserID diff --git a/byceps/services/user_message/service.py b/byceps/services/user_message/service.py index 8d9d729e81..f396a2c733 100644 --- a/byceps/services/user_message/service.py +++ b/byceps/services/user_message/service.py @@ -8,11 +8,11 @@ :License: Modified BSD, see LICENSE for details. """ +from dataclasses import dataclass from email.utils import formataddr import os.path from typing import Any, Dict, Optional -from attr import attrs from flask import current_app from jinja2 import Environment, FileSystemLoader, Template @@ -27,7 +27,7 @@ from ..user.transfer.models import User -@attrs(auto_attribs=True, frozen=True, slots=True) +@dataclass(frozen=True) class MessageTemplateRenderResult: subject: str body: str diff --git a/pyproject.toml b/pyproject.toml index fecd7e9ff7..e558caed9c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,6 @@ homepage = "https://byceps.nwsnet.de/" [tool.poetry.dependencies] python = "^3.7" -attrs = "^19.3.0" bbcode = "^1.0.33" blinker = "^1.4" click = ">=7.0, <8.0" diff --git a/requirements.txt b/requirements.txt index 21296b39d1..1d13733074 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,4 @@ arrow==0.15.2 -attrs==19.3.0 bbcode==1.0.33 blinker==1.4 click==7.0