From 0b76380191ad0a56d148bb98a3c22cde1ab4678f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Mon, 2 Jan 2023 23:11:51 +0200 Subject: [PATCH 1/4] Add dataclasses dependency for Python 3.6 --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index b3cf464..55f5d38 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ deprecated~=1.2.13 requests-oauthlib>=1.3 requests>=2.25 +dataclasses; python_version<"3.7" From 0e1605951fe466cf29db656782a78f5fe60f157a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Tue, 18 Apr 2023 21:25:06 +0300 Subject: [PATCH 2/4] Convert UserList to dataclass --- trakt/users.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/trakt/users.py b/trakt/users.py index 90717ef..7cb1133 100644 --- a/trakt/users.py +++ b/trakt/users.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- """Interfaces to all of the User objects offered by the Trakt.tv API""" from collections import namedtuple +from dataclasses import dataclass from trakt.core import delete, get, post from trakt.mixins import IdsMixin @@ -62,6 +63,7 @@ def unfollow(user_name): yield 'users/{username}/follow'.format(username=slugify(user_name)) +@dataclass class UserList(namedtuple('UserList', ['name', 'description', 'privacy', 'share_link', 'type', 'display_numbers', 'allow_comments', 'sort_by', From 2cd1d66a58bef4a2c4ff4b2adaaeebd7891907f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Tue, 18 Apr 2023 21:27:48 +0300 Subject: [PATCH 3/4] fixup! Convert UserList to dataclass --- trakt/users.py | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/trakt/users.py b/trakt/users.py index 7cb1133..98566ac 100644 --- a/trakt/users.py +++ b/trakt/users.py @@ -64,13 +64,26 @@ def unfollow(user_name): @dataclass -class UserList(namedtuple('UserList', ['name', 'description', 'privacy', - 'share_link', 'type', 'display_numbers', - 'allow_comments', 'sort_by', - 'sort_how', 'created_at', - 'updated_at', 'item_count', - 'comment_count', 'likes', 'ids', - 'user', 'creator']), IdsMixin): +class UserList(IdsMixin): + name: str + description: str + privacy: str + share_link: str + type: str + display_numbers: str + allow_comments: str + sort_by: str + sort_how: str + created_at: str + updated_at: str + item_count: str + comment_count: str + likes: str + trakt: str + slug: str + user: str + creator: str + """A list created by a Trakt.tv :class:`User`""" def __init__(self, *args, ids=None, **kwargs): From c97f69ea686a4e025eb4177756236f743621d07a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Tue, 18 Apr 2023 23:03:28 +0300 Subject: [PATCH 4/4] Composition over inehritance solution or dataclass Problem is that dataclasses can't inherit IdsMixin. --- trakt/mixins.py | 14 ++++++++++++-- trakt/users.py | 34 +++++++++++++++++++++------------- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/trakt/mixins.py b/trakt/mixins.py index 4b39195..3222faf 100644 --- a/trakt/mixins.py +++ b/trakt/mixins.py @@ -14,8 +14,10 @@ class IdsMixin: __ids = ['imdb', 'slug', 'tmdb', 'trakt'] - def __init__(self): - self._ids = {} + def __init__(self, ids=None): + if ids is None: + ids = {} + self._ids = ids @property def ids(self): @@ -51,3 +53,11 @@ def tvdb(self): @property def tvrage(self): return self._ids.get('tvrage', None) + + @property + def slug(self): + return self._ids.get('slug', None) + + @slug.setter + def slug(self, value): + self._ids['slug'] = value diff --git a/trakt/users.py b/trakt/users.py index 98566ac..3d2224f 100644 --- a/trakt/users.py +++ b/trakt/users.py @@ -1,7 +1,8 @@ # -*- coding: utf-8 -*- """Interfaces to all of the User objects offered by the Trakt.tv API""" -from collections import namedtuple -from dataclasses import dataclass +from collections import UserDict, namedtuple +from dataclasses import dataclass, field +from typing import Optional, Union from trakt.core import delete, get, post from trakt.mixins import IdsMixin @@ -63,8 +64,8 @@ def unfollow(user_name): yield 'users/{username}/follow'.format(username=slugify(user_name)) -@dataclass -class UserList(IdsMixin): +@dataclass(frozen=True) +class UserListData: name: str description: str privacy: str @@ -79,26 +80,33 @@ class UserList(IdsMixin): item_count: str comment_count: str likes: str - trakt: str - slug: str user: str creator: str + +def DataClassMixin(data_class): + class DataClassMixinClass: + def __init__(self, **kwargs): + self.data = data_class(**kwargs) + + def __getattr__(self, item): + return getattr(self.data, item) + + return DataClassMixinClass + + +class UserList(DataClassMixin(UserListData), IdsMixin): """A list created by a Trakt.tv :class:`User`""" - def __init__(self, *args, ids=None, **kwargs): - super().__init__() + def __init__(self, ids=None, **kwargs): + super().__init__(**kwargs) self._ids = ids - self._items = list() + self._items = [] def __iter__(self): """Iterate over the items in this user list""" return self._items.__iter__() - @property - def slug(self): - return self._ids.get('slug', None) - @classmethod @post def create(cls, name, creator, description=None, privacy='private',