Skip to content

Commit fd2723b

Browse files
committed
change paste and file to use proper private attributes
1 parent b389525 commit fd2723b

File tree

1 file changed

+52
-40
lines changed

1 file changed

+52
-40
lines changed

mystbin/paste.py

Lines changed: 52 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@
3838

3939

4040
class File:
41+
_lines_of_code: int
42+
_character_count: int
43+
4144
"""Represents a single file within a mystb.in paste.
4245
4346
Attributes
@@ -46,44 +49,42 @@ class File:
4649
The file's name.
4750
content: :class:`str`
4851
The file's contents.
49-
lines_of_code: Optional[:class:`int`]
50-
The lines of code within the file.
51-
character_count: Optional[:class:`int`]
52-
The character count of the file.
53-
54-
55-
.. note::
56-
The ``lines_of_code`` and ``character_count`` come from the API and should not be provided by the user.
5752
"""
5853

5954
__slots__ = (
6055
"filename",
6156
"content",
62-
"lines_of_code",
63-
"character_count",
57+
"_lines_of_code",
58+
"_character_count",
6459
)
6560

6661
def __init__(
6762
self,
6863
*,
6964
filename: str,
7065
content: str,
71-
lines_of_code: Optional[int] = None,
72-
character_count: Optional[int] = None,
7366
) -> None:
7467
self.filename: str = filename
7568
self.content: str = content
76-
self.lines_of_code: int = lines_of_code or content.count("\n")
77-
self.character_count: int = character_count or len(content)
69+
70+
@property
71+
def lines_of_code(self) -> int:
72+
return self._lines_of_code
73+
74+
@property
75+
def character_count(self) -> int:
76+
return self._character_count
7877

7978
@classmethod
8079
def _from_data(cls, payload: FileResponse, /) -> Self:
81-
return cls(
80+
self = cls(
8281
content=payload["content"],
8382
filename=payload["filename"],
84-
lines_of_code=payload["loc"],
85-
character_count=payload["charcount"],
8683
)
84+
self._lines_of_code = payload["loc"]
85+
self._character_count = payload["charcount"]
86+
87+
return self
8788

8889
def _to_dict(self) -> dict[str, Any]:
8990
ret: dict[str, Any] = {"content": self.content, "filename": self.filename}
@@ -92,6 +93,10 @@ def _to_dict(self) -> dict[str, Any]:
9293

9394

9495
class Paste:
96+
_last_edited: Optional[datetime.datetime]
97+
_expires: Optional[datetime.datetime]
98+
_views: Optional[int]
99+
95100
"""Represents a Paste object from mystb.in.
96101
97102
Attributes
@@ -100,47 +105,31 @@ class Paste:
100105
The ID of this paste.
101106
created_at: :class:`datetime.datetime`
102107
When this paste was created in UTC.
103-
expires: Optional[:class:`datetime.datetime`]
104-
When this paste expires, if at all.
105-
last_edited: Optional[:class:`datetime.datetime`]
106-
When this paste was last edited, if at all.
107108
files: list[:class:`mystbin.File`]
108109
The list of files within this Paste.
109-
views: Optional[:class:`int`]
110-
How many views this paste has had, if any.
111-
112-
113-
.. note::
114-
The ``last_edited``, ``expires`` and ``views`` attributes come from the API and are not user provided.
115110
"""
116111

117112
__slots__ = (
118113
"id",
119114
"author_id",
120115
"created_at",
121-
"expires",
122116
"files",
123117
"notice",
124-
"views",
125-
"last_edited",
118+
"_expires",
119+
"_views",
120+
"_last_edited",
126121
)
127122

128123
def __init__(
129124
self,
130125
*,
131126
id: str,
132127
created_at: str,
133-
expires: Optional[str] = None,
134-
last_edited: Optional[str] = None,
135128
files: list[File],
136-
views: Optional[int] = None,
137129
) -> None:
138130
self.id: str = id
139131
self.created_at: datetime.datetime = datetime.datetime.fromisoformat(created_at)
140-
self.expires: Optional[datetime.datetime] = datetime.datetime.fromisoformat(expires) if expires else None
141-
self.last_edited: Optional[datetime.datetime] = datetime.datetime.fromisoformat(last_edited) if last_edited else None
142132
self.files: list[File] = files
143-
self.views: Optional[int] = views
144133

145134
def __str__(self) -> str:
146135
return self.url
@@ -152,14 +141,37 @@ def __repr__(self) -> str:
152141
def url(self) -> str:
153142
return f"https://mystb.in/{self.id}"
154143

144+
@property
145+
def last_edited(self) -> Optional[datetime.datetime]:
146+
return self._last_edited
147+
148+
@property
149+
def expires(self) -> Optional[datetime.datetime]:
150+
return self._expires
151+
152+
@property
153+
def views(self) -> Optional[int]:
154+
return self._views
155+
155156
@classmethod
156157
def _from_data(cls, payload: PasteResponse, /) -> Self:
157158
files = [File._from_data(data) for data in payload["files"]]
158-
return cls(
159+
self = cls(
159160
id=payload["id"],
160161
created_at=payload["created_at"],
161-
expires=payload["expires"],
162162
files=files,
163-
views=payload.get("views"),
164-
last_edited=payload.get("last_edited"),
165163
)
164+
self._views = payload.get("views")
165+
last_edited = payload.get("last_edited")
166+
if last_edited:
167+
self._last_edited = datetime.datetime.fromisoformat(last_edited)
168+
else:
169+
self._last_edited = None
170+
171+
expires = payload.get("expires")
172+
if expires:
173+
self._expires = datetime.datetime.fromisoformat(expires)
174+
else:
175+
self._expires = None
176+
177+
return self

0 commit comments

Comments
 (0)