Skip to content

Commit 9cdcd02

Browse files
committed
Make dataclasses frozen, use tuples instead of lists
1 parent be0a722 commit 9cdcd02

18 files changed

+73
-70
lines changed

setup.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ def readme():
1010

1111
setup(
1212
name="soundcloud-v2",
13-
version="1.4.2",
13+
version="1.5.0",
1414
description=(
1515
"Python wrapper for the internal v2 SoundCloud API."
1616
"Does not require an API key."
@@ -23,7 +23,7 @@ def readme():
2323
packages=["soundcloud", "soundcloud.resource"],
2424
package_data={"soundcloud": ["py.typed"]},
2525
install_requires=[
26-
"dacite",
26+
"dacite>=1.8.1",
2727
"python-dateutil>=2.8.2",
2828
"requests",
2929
"typing_extensions; python_version<'3.8'",

soundcloud/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,6 @@
6464
from soundcloud.soundcloud import *
6565
from soundcloud.soundcloud import __all__ as sc_all
6666

67-
__version__ = "1.4.2"
67+
__version__ = "1.5.0"
6868

6969
__all__ = sc_all + ex_all + res_all

soundcloud/requests.py

+9-8
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
Generic,
1010
List,
1111
Optional,
12+
Tuple,
1213
Type,
1314
TypeVar,
1415
Union,
@@ -67,7 +68,7 @@ def _convert_dict(d, return_type: Type[BaseData]):
6768
T = TypeVar("T", bound=BaseData)
6869

6970

70-
@dataclass
71+
@dataclass(frozen=True)
7172
class Request(Generic[T]):
7273
base = "https://api-v2.soundcloud.com"
7374
format_url: str
@@ -107,7 +108,7 @@ def __call__(
107108
return _convert_dict(r.json(), self.return_type)
108109

109110

110-
@dataclass
111+
@dataclass(frozen=True)
111112
class CollectionRequest(Request, Generic[T]):
112113
def __call__(
113114
self,
@@ -149,7 +150,7 @@ def __call__(
149150
resource_url = urljoin(resource_url, parsed.path)
150151

151152

152-
@dataclass
153+
@dataclass(frozen=True)
153154
class ListRequest(Request, Generic[T]):
154155
"""
155156
Requests the resource list at the given url with
@@ -181,7 +182,7 @@ class DataclassInstance(Protocol):
181182
Q = TypeVar("Q", bound=DataclassInstance)
182183

183184

184-
@dataclass
185+
@dataclass(frozen=True)
185186
class GraphQLRequest(Generic[Q, T]):
186187
base = "https://graph.soundcloud.com/graphql"
187188
operation_name: str
@@ -322,13 +323,13 @@ def __call__(
322323
"""
323324

324325

325-
@dataclass
326+
@dataclass(frozen=True)
326327
class UserInteractionsQueryResult(BaseData):
327-
user: List[UserInteraction]
328-
creator: List[UserInteraction]
328+
user: Tuple[UserInteraction, ...]
329+
creator: Tuple[UserInteraction, ...]
329330

330331

331-
@dataclass
332+
@dataclass(frozen=True)
332333
class UserInteractionsQueryParams:
333334
createdByProfileUrn: str
334335
interactionTypeUrn: str

soundcloud/resource/base.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
from dacite import Config, from_dict
66

77

8-
@dataclass
8+
@dataclass(frozen=True)
99
class BaseData:
10-
dacite_config = Config(type_hooks={datetime.datetime: dateutil.parser.isoparse})
10+
dacite_config = Config(
11+
type_hooks={datetime.datetime: dateutil.parser.isoparse}, cast=[tuple]
12+
)
1113

1214
@classmethod
1315
def from_dict(cls, d: dict):

soundcloud/resource/base_item.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from soundcloud.resource.base import BaseData
66

77

8-
@dataclass
8+
@dataclass(frozen=True)
99
class BaseItem(BaseData):
1010
artwork_url: Optional[str]
1111
created_at: datetime.datetime

soundcloud/resource/comment.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66
from soundcloud.resource.user import BasicUser
77

88

9-
@dataclass
9+
@dataclass(frozen=True)
1010
class CommentSelf(BaseData):
1111
urn: str
1212

1313

14-
@dataclass
14+
@dataclass(frozen=True)
1515
class BasicComment(BaseData):
1616
"""Comment without a specified track"""
1717

@@ -26,7 +26,7 @@ class BasicComment(BaseData):
2626
user: BasicUser
2727

2828

29-
@dataclass
29+
@dataclass(frozen=True)
3030
class Comment(BasicComment):
3131
"""Comment with a specified track"""
3232

soundcloud/resource/conversation.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import datetime
22
from dataclasses import dataclass
3-
from typing import List, Union
3+
from typing import Tuple, Union
44

55
from soundcloud.resource.base import BaseData
66
from soundcloud.resource.message import Message
77
from soundcloud.resource.user import BasicUser, MissingUser
88

99

10-
@dataclass
10+
@dataclass(frozen=True)
1111
class Conversation(BaseData):
1212
"""DM conversation between two users"""
1313

@@ -16,4 +16,4 @@ class Conversation(BaseData):
1616
read: bool
1717
started_at: datetime.datetime
1818
summary: str
19-
users: List[Union[BasicUser, MissingUser]]
19+
users: Tuple[Union[BasicUser, MissingUser], ...]

soundcloud/resource/download.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from soundcloud.resource.base import BaseData
44

55

6-
@dataclass
6+
@dataclass(frozen=True)
77
class OriginalDownload(BaseData):
88
"""Contains a download link for a track"""
99

soundcloud/resource/graphql.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
11
from dataclasses import dataclass
2-
from typing import List, Optional
2+
from typing import Optional, Tuple
33

44
from soundcloud.resource.base import BaseData
55
from soundcloud.resource.comment import BasicComment
66

77
InteractionTypeValue = str
88

99

10-
@dataclass
10+
@dataclass(frozen=True)
1111
class InteractionCount(BaseData):
1212
count: Optional[int]
1313
interactionTypeValueUrn: Optional[InteractionTypeValue]
1414

1515

16-
@dataclass
16+
@dataclass(frozen=True)
1717
class UserInteraction(BaseData):
1818
targetUrn: Optional[str]
1919
userInteraction: Optional[InteractionTypeValue]
20-
interactionCounts: Optional[List[InteractionCount]]
20+
interactionCounts: Optional[Tuple[InteractionCount, ...]]
2121
interactionTypeUrn: Optional[str]
2222

2323

24-
@dataclass
24+
@dataclass(frozen=True)
2525
class CommentWithInteractions(BaseData):
2626
comment: BasicComment
2727
likes: int

soundcloud/resource/history.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from soundcloud.resource.track import BasicTrack
55

66

7-
@dataclass
7+
@dataclass(frozen=True)
88
class HistoryItem(BaseData):
99
"""Item in user's listen history"""
1010

soundcloud/resource/like.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,20 @@
66
from soundcloud.resource.track import BasicTrack
77

88

9-
@dataclass
9+
@dataclass(frozen=True)
1010
class BaseLike(BaseData):
1111
created_at: datetime.datetime
1212
kind: str
1313

1414

15-
@dataclass
15+
@dataclass(frozen=True)
1616
class TrackLike(BaseLike):
1717
"""Like on a track"""
1818

1919
track: BasicTrack
2020

2121

22-
@dataclass
22+
@dataclass(frozen=True)
2323
class PlaylistLike(BaseLike):
2424
"""Like on a playlist"""
2525

soundcloud/resource/message.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from soundcloud.resource.user import BasicUser, MissingUser
77

88

9-
@dataclass
9+
@dataclass(frozen=True)
1010
class Message(BaseData):
1111
"""Single DM between two users"""
1212

soundcloud/resource/playlist.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,38 @@
11
import datetime
22
from dataclasses import dataclass
3-
from typing import List, Optional, Union
3+
from typing import Optional, Tuple, Union
44

55
from soundcloud.resource.base import BaseData
66
from soundcloud.resource.base_item import BaseItem
77
from soundcloud.resource.track import BasicTrack, MiniTrack
88
from soundcloud.resource.user import BasicUser, User
99

1010

11-
@dataclass
11+
@dataclass(frozen=True)
1212
class BaseAlbumPlaylist(BaseItem):
1313
managed_by_feeds: bool
1414
set_type: str
1515
is_album: bool
1616
published_at: Optional[datetime.datetime]
1717
track_count: int
18-
tracks: List[Union[BasicTrack, MiniTrack]]
18+
tracks: Tuple[Union[BasicTrack, MiniTrack], ...]
1919

2020

21-
@dataclass
21+
@dataclass(frozen=True)
2222
class AlbumPlaylist(BaseAlbumPlaylist):
2323
"""Playlist or album with full user info"""
2424

2525
user: User
2626

2727

28-
@dataclass
28+
@dataclass(frozen=True)
2929
class BasicAlbumPlaylist(BaseAlbumPlaylist):
3030
"""Playlist or album with partial user info"""
3131

3232
user: BasicUser
3333

3434

35-
@dataclass
35+
@dataclass(frozen=True)
3636
class AlbumPlaylistNoTracks(BaseData):
3737
"""Playlist or album with no track info"""
3838

soundcloud/resource/stream.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from soundcloud.resource.user import BasicUser
99

1010

11-
@dataclass
11+
@dataclass(frozen=True)
1212
class BaseStreamItem(BaseData):
1313
created_at: datetime.datetime
1414
type: str
@@ -17,40 +17,40 @@ class BaseStreamItem(BaseData):
1717
caption: Optional[str]
1818

1919

20-
@dataclass
20+
@dataclass(frozen=True)
2121
class Reposted(BaseData):
2222
target_urn: str
2323
user_urn: str
2424
caption: Optional[str]
2525

2626

27-
@dataclass
27+
@dataclass(frozen=True)
2828
class BaseStreamRepostItem(BaseStreamItem):
2929
reposted: Optional[Reposted]
3030

3131

32-
@dataclass
32+
@dataclass(frozen=True)
3333
class TrackStreamItem(BaseStreamItem):
3434
"""Track post in user's feed"""
3535

3636
track: BasicTrack
3737

3838

39-
@dataclass
39+
@dataclass(frozen=True)
4040
class TrackStreamRepostItem(BaseStreamRepostItem):
4141
"""Track repost in user's feed"""
4242

4343
track: BasicTrack
4444

4545

46-
@dataclass
46+
@dataclass(frozen=True)
4747
class PlaylistStreamItem(BaseStreamItem):
4848
"""Album or playlist post in user's feed"""
4949

5050
playlist: BasicAlbumPlaylist
5151

5252

53-
@dataclass
53+
@dataclass(frozen=True)
5454
class PlaylistStreamRepostItem(BaseStreamRepostItem):
5555
"""Album or playlist repost in user's feed"""
5656

0 commit comments

Comments
 (0)