Skip to content

Commit 37bc219

Browse files
committed
modernise codebase
1 parent b01544c commit 37bc219

File tree

10 files changed

+794
-817
lines changed

10 files changed

+794
-817
lines changed

docs/conf.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import sys
1616
from typing import Dict, List, Tuple
1717

18-
1918
# from typing import Literal, Optional
2019

2120

mystbin/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@
2828

2929
from .client import Client as Client
3030
from .errors import *
31-
from .paste import File as File
32-
from .paste import Paste as Paste
31+
from .paste import File as File, Paste as Paste
3332

3433

3534
class VersionInfo(NamedTuple):

mystbin/client.py

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,24 @@
2222

2323
from __future__ import annotations
2424

25-
import datetime
26-
from typing import List, Literal, Optional, Sequence, Union, overload
27-
28-
import aiohttp
25+
from typing import TYPE_CHECKING, Literal, Sequence, overload
2926

3027
from .http import HTTPClient
3128
from .paste import File, Paste
3229
from .utils import require_authentication
3330

31+
if TYPE_CHECKING:
32+
import datetime
33+
34+
from aiohttp import ClientSession
3435

3536
__all__ = ("Client",)
3637

3738

3839
class Client:
3940
__slots__ = ("http",)
4041

41-
def __init__(self, *, token: Optional[str] = None, session: Optional[aiohttp.ClientSession] = None) -> None:
42+
def __init__(self, *, token: str | None = None, session: ClientSession | None = None) -> None:
4243
self.http: HTTPClient = HTTPClient(token=token, session=session)
4344

4445
async def close(self) -> None:
@@ -56,8 +57,8 @@ async def create_paste(
5657
content: str,
5758
file: None = ...,
5859
files: None = ...,
59-
password: Optional[str] = ...,
60-
expires: Optional[datetime.datetime] = ...,
60+
password: str | None = ...,
61+
expires: datetime.datetime | None = ...,
6162
) -> Paste:
6263
...
6364

@@ -69,8 +70,8 @@ async def create_paste(
6970
content: None = ...,
7071
file: File,
7172
files: None = ...,
72-
password: Optional[str] = ...,
73-
expires: Optional[datetime.datetime] = ...,
73+
password: str | None = ...,
74+
expires: datetime.datetime | None = ...,
7475
) -> Paste:
7576
...
7677

@@ -82,20 +83,20 @@ async def create_paste(
8283
content: None = ...,
8384
file: None = ...,
8485
files: Sequence[File],
85-
password: Optional[str] = ...,
86-
expires: Optional[datetime.datetime] = ...,
86+
password: str | None = ...,
87+
expires: datetime.datetime | None = ...,
8788
) -> Paste:
8889
...
8990

9091
async def create_paste(
9192
self,
9293
*,
93-
filename: Optional[str] = None,
94-
content: Optional[str] = None,
95-
file: Optional[File] = None,
96-
files: Optional[Sequence[File]] = None,
97-
password: Optional[str] = None,
98-
expires: Optional[datetime.datetime] = None,
94+
filename: str | None = None,
95+
content: str | None = None,
96+
file: File | None = None,
97+
files: Sequence[File] | None = None,
98+
password: str | None = None,
99+
expires: datetime.datetime | None = None,
99100
) -> Paste:
100101
"""|coro|
101102
@@ -162,7 +163,7 @@ async def delete_paste(self, paste_id: str, /) -> None:
162163
await self.http.delete_pastes(paste_ids=[paste_id])
163164

164165
@require_authentication
165-
async def delete_pastes(self, paste_ids: List[str], /) -> None:
166+
async def delete_pastes(self, paste_ids: list[str], /) -> None:
166167
"""|coro|
167168
168169
Delete multiple pastes.
@@ -175,16 +176,14 @@ async def delete_pastes(self, paste_ids: List[str], /) -> None:
175176
await self.http.delete_pastes(paste_ids=paste_ids)
176177

177178
@overload
178-
async def get_paste(self, paste_id: str, *, password: Optional[str] = ..., raw: Literal[False]) -> Paste:
179+
async def get_paste(self, paste_id: str, *, password: str | None = ..., raw: Literal[False]) -> Paste:
179180
...
180181

181182
@overload
182-
async def get_paste(self, paste_id: str, *, password: Optional[str] = ..., raw: Literal[True]) -> list[str]:
183+
async def get_paste(self, paste_id: str, *, password: str | None = ..., raw: Literal[True]) -> list[str]:
183184
...
184185

185-
async def get_paste(
186-
self, paste_id: str, *, password: Optional[str] = None, raw: bool = False
187-
) -> Union[Paste, list[str]]:
186+
async def get_paste(self, paste_id: str, *, password: str | None = None, raw: bool = False) -> Paste | list[str]:
188187
"""|coro|
189188
190189
Fetch a paste.
@@ -210,7 +209,7 @@ async def get_paste(
210209
return Paste.from_data(data)
211210

212211
@require_authentication
213-
async def get_user_pastes(self, *, limit: int = 100) -> List[Paste]:
212+
async def get_user_pastes(self, *, limit: int = 100) -> list[Paste]:
214213
"""|coro|
215214
216215
Get all pastes belonging to the current authenticated user.

mystbin/errors.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@
1919
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2020
DEALINGS IN THE SOFTWARE.
2121
"""
22-
import aiohttp
23-
22+
from aiohttp import ClientResponse
2423

2524
__all__ = (
2625
"APIException",
@@ -29,7 +28,7 @@
2928

3029

3130
class APIException(Exception):
32-
def __init__(self, *, response: aiohttp.ClientResponse, status_code: int) -> None:
31+
def __init__(self, *, response: ClientResponse, status_code: int) -> None:
3332
self.response = response
3433
self.status_code = status_code
3534
super().__init__(self.status_code)

mystbin/http.py

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,9 @@
3333
Any,
3434
ClassVar,
3535
Coroutine,
36-
Dict,
3736
Literal,
38-
Optional,
3937
Sequence,
40-
Type,
4138
TypeVar,
42-
Union,
4339
)
4440
from urllib.parse import quote as _uriquote
4541

@@ -49,7 +45,6 @@
4945
from .errors import APIException
5046
from .utils import MISSING
5147

52-
5348
if TYPE_CHECKING:
5449
from types import TracebackType
5550

@@ -74,7 +69,7 @@ def _clean_dt(dt: datetime.datetime) -> str:
7469
return dt.isoformat()
7570

7671

77-
async def json_or_text(response: aiohttp.ClientResponse, /) -> Union[Dict[str, Any], str]:
72+
async def json_or_text(response: aiohttp.ClientResponse, /) -> dict[str, Any] | str:
7873
"""A quick method to parse a `aiohttp.ClientResponse` and test if it's json or text."""
7974
text = await response.text(encoding="utf-8")
8075
try:
@@ -102,9 +97,9 @@ def defer(self) -> None:
10297

10398
def __exit__(
10499
self,
105-
exc_type: Optional[Type[BE]],
106-
exc: Optional[BE],
107-
traceback: Optional[TracebackType],
100+
exc_type: type[BE] | None,
101+
exc: BE | None,
102+
traceback: TracebackType | None,
108103
) -> None:
109104
if self._unlock:
110105
self.lock.release()
@@ -137,9 +132,9 @@ class HTTPClient:
137132
"user_agent",
138133
)
139134

140-
def __init__(self, *, token: Optional[str], session: Optional[aiohttp.ClientSession] = None) -> None:
141-
self._token: Optional[str] = token
142-
self._session: Optional[aiohttp.ClientSession] = session
135+
def __init__(self, *, token: str | None, session: aiohttp.ClientSession | None = None) -> None:
136+
self._token: str | None = token
137+
self._session: aiohttp.ClientSession | None = session
143138
self._locks: weakref.WeakValueDictionary[str, asyncio.Lock] = weakref.WeakValueDictionary()
144139
user_agent = "mystbin.py (https://github.com/PythonistaGuild/mystbin.py {0}) Python/{1[0]}.{1[1]} aiohttp/{2}"
145140
self.user_agent: str = user_agent.format(__version__, sys.version_info, aiohttp.__version__)
@@ -178,7 +173,7 @@ async def request(self, route: Route, **kwargs: Any) -> Any:
178173
LOGGER.debug("Current request headers: %s", headers)
179174
LOGGER.debug("Current request url: %s", route.url)
180175

181-
response: Optional[aiohttp.ClientResponse] = None
176+
response: aiohttp.ClientResponse | None = None
182177
await lock.acquire()
183178
with MaybeUnlock(lock) as maybe_lock:
184179
for tries in range(5):
@@ -246,14 +241,14 @@ async def request(self, route: Route, **kwargs: Any) -> Any:
246241
def create_paste(
247242
self,
248243
*,
249-
file: Optional[File] = None,
250-
files: Optional[Sequence[File]] = None,
251-
password: Optional[str],
252-
expires: Optional[datetime.datetime],
244+
file: File | None = None,
245+
files: Sequence[File] | None = None,
246+
password: str | None,
247+
expires: datetime.datetime | None,
253248
) -> Response[PasteResponse]:
254249
route = Route("PUT", "/paste")
255250

256-
json_: Dict[str, Any] = {}
251+
json_: dict[str, Any] = {}
257252
if file:
258253
json_["files"] = [file.to_dict()]
259254
elif files:
@@ -273,7 +268,7 @@ def delete_pastes(self, *, paste_ids: Sequence[str]) -> Response[None]:
273268
route = Route("DELETE", "/paste")
274269
return self.request(route=route, json={"pastes": paste_ids})
275270

276-
def get_paste(self, *, paste_id: str, password: Optional[str]) -> Response[PasteResponse]:
271+
def get_paste(self, *, paste_id: str, password: str | None) -> Response[PasteResponse]:
277272
route = Route("GET", "/paste/{paste_id}", paste_id=paste_id)
278273

279274
if password:
@@ -290,7 +285,7 @@ def edit_paste(
290285
) -> Response[EditPasteResponse]:
291286
route = Route("PATCH", "/paste/{paste_id}", paste_id=paste_id)
292287

293-
json_: Dict[str, Any] = {}
288+
json_: dict[str, Any] = {}
294289

295290
if new_content is not MISSING:
296291
json_["new_content"] = new_content

mystbin/paste.py

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@
2323
from __future__ import annotations
2424

2525
import datetime
26-
from typing import TYPE_CHECKING, Any, Dict, List, Optional
27-
26+
from typing import TYPE_CHECKING, Any
2827

2928
if TYPE_CHECKING:
3029
from typing_extensions import Self
@@ -59,10 +58,10 @@ class File:
5958
"_character_count",
6059
)
6160

62-
def __init__(self, *, filename: str, content: str, attachment_url: Optional[str] = None) -> None:
61+
def __init__(self, *, filename: str, content: str, attachment_url: str | None = None) -> None:
6362
self.filename: str = filename
6463
self.content: str = content
65-
self.attachment_url: Optional[str] = attachment_url
64+
self.attachment_url: str | None = attachment_url
6665

6766
@property
6867
def lines_of_code(self) -> int:
@@ -74,22 +73,26 @@ def character_count(self) -> int:
7473

7574
@classmethod
7675
def from_data(cls, payload: FileResponse, /) -> Self:
77-
self = cls(content=payload["content"], filename=payload["filename"], attachment_url=payload["attachment"])
76+
self = cls(
77+
content=payload["content"],
78+
filename=payload["filename"],
79+
attachment_url=payload["attachment"],
80+
)
7881
self._lines_of_code = payload["loc"]
7982
self._character_count = payload["charcount"]
8083

8184
return self
8285

83-
def to_dict(self) -> Dict[str, Any]:
84-
ret: Dict[str, Any] = {"content": self.content, "filename": self.filename}
86+
def to_dict(self) -> dict[str, Any]:
87+
ret: dict[str, Any] = {"content": self.content, "filename": self.filename}
8588

8689
return ret
8790

8891

8992
class Paste:
90-
_last_edited: Optional[datetime.datetime]
91-
_expires: Optional[datetime.datetime]
92-
_views: Optional[int]
93+
_last_edited: datetime.datetime | None
94+
_expires: datetime.datetime | None
95+
_views: int | None
9396

9497
"""Represents a Paste object from mystb.in.
9598
@@ -114,11 +117,11 @@ class Paste:
114117
"_last_edited",
115118
)
116119

117-
def __init__(self, *, id: str, created_at: str, files: List[File], notice: Optional[str]) -> None:
120+
def __init__(self, *, id: str, created_at: str, files: list[File], notice: str | None) -> None:
118121
self.id: str = id
119122
self.created_at: datetime.datetime = datetime.datetime.fromisoformat(created_at)
120-
self.files: List[File] = files
121-
self.notice: Optional[str] = notice
123+
self.files: list[File] = files
124+
self.notice: str | None = notice
122125

123126
def __str__(self) -> str:
124127
return self.url
@@ -131,21 +134,26 @@ def url(self) -> str:
131134
return f"https://mystb.in/{self.id}"
132135

133136
@property
134-
def last_edited(self) -> Optional[datetime.datetime]:
137+
def last_edited(self) -> datetime.datetime | None:
135138
return self._last_edited
136139

137140
@property
138-
def expires(self) -> Optional[datetime.datetime]:
141+
def expires(self) -> datetime.datetime | None:
139142
return self._expires
140143

141144
@property
142-
def views(self) -> Optional[int]:
145+
def views(self) -> int | None:
143146
return self._views
144147

145148
@classmethod
146149
def from_data(cls, payload: PasteResponse, /) -> Self:
147150
files = [File.from_data(data) for data in payload["files"]]
148-
self = cls(id=payload["id"], created_at=payload["created_at"], files=files, notice=payload["notice"])
151+
self = cls(
152+
id=payload["id"],
153+
created_at=payload["created_at"],
154+
files=files,
155+
notice=payload.get("notice"),
156+
)
149157
self._views = payload.get("views")
150158
last_edited = payload.get("last_edited")
151159
if last_edited:

0 commit comments

Comments
 (0)