Skip to content

Commit f0bd718

Browse files
committed
allow 3.8+
1 parent e928724 commit f0bd718

File tree

12 files changed

+228
-126
lines changed

12 files changed

+228
-126
lines changed

.github/linters/.isort.cfg

-5
This file was deleted.

.github/linters/.python-black

-2
This file was deleted.

.github/workflows/build.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
strategy:
1919
fail-fast: false
2020
matrix:
21-
python-version: ["3.11", "3.x"]
21+
python-version: ["3.8", "3.x"]
2222

2323
name: "Build @ ${{ matrix.python-version }}"
2424
steps:

.github/workflows/coverage_and_lint.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
strategy:
1616
fail-fast: false
1717
matrix:
18-
python-version: [ '3.11' ]
18+
python-version: [ '3.8', '3.9', '3.10', '3.11', '3.x' ]
1919

2020
name: "Type Coverage and Linting @ ${{ matrix.python-version }}"
2121
steps:

.gitignore

+3-7
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
.vscode/
2-
__ignore__/
3-
__pycache__/
4-
*.pyc
5-
/dist/
6-
/*.egg-info/
2+
*.py[cod]
3+
.venv/
4+
.idea/
75
docs/build
8-
docs/_static/
9-
*.ipynb

README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ python -m pip install git+https://github.com/PythonistaGuild/mystbin.py.git
4343
```
4444

4545
### Usage examples
46-
Since the project is considered multi-sync, it will work in a sync/async environment, see the optional dependency of `requests` below.
4746

4847
```py
4948
# async example - it will default to async
@@ -52,6 +51,8 @@ import mystbin
5251
client = mystbin.Client()
5352

5453
paste = await client.create_paste(filename="Hello.txt", content="Hello there!")
54+
# we also support passing a mystbin.File directly to the `file=` kwarg!
55+
5556
str(paste)
5657
>>> 'https://mystb.in/<your generated ID>'
5758

@@ -70,7 +71,7 @@ import mystbin
7071
file = mystbin.File(filename="File1.txt", content="Hello there!")
7172
file2 = mystbin.File(filename="test.py", content="print('hello!')")
7273

73-
paste = await client.create_multifile_paste(files=[file, file2])
74+
paste = await client.create_paste(files=[file, file2])
7475

7576
for file in paste.files:
7677
print(file.content)

docs/conf.py

+8-7
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import os
1414
import re
1515
import sys
16+
from typing import Dict, List, Tuple
1617

1718

1819
# from typing import Literal, Optional
@@ -65,7 +66,7 @@
6566
sys.path.insert(0, os.path.abspath(".."))
6667
sys.path.append(os.path.abspath("extensions"))
6768

68-
extensions: list[str] = [
69+
extensions: List[str] = [
6970
"sphinx.ext.autodoc",
7071
"sphinx.ext.extlinks",
7172
"sphinx.ext.intersphinx",
@@ -74,10 +75,10 @@
7475
"sphinxcontrib_trio",
7576
]
7677

77-
extlinks: dict[str, tuple[str, str]] = {"issue": (f"{_GITHUB}/issues/%s", "GH-%s")}
78+
extlinks: Dict[str, Tuple[str, str]] = {"issue": (f"{_GITHUB}/issues/%s", "GH-%s")}
7879

7980
# Add any paths that contain templates here, relative to this directory.
80-
templates_path: list[str] = ["_templates"]
81+
templates_path: List[str] = ["_templates"]
8182

8283
autodoc_typehints: str = "both"
8384
autodoc_typehints_format: str = "short"
@@ -90,10 +91,10 @@
9091
# List of patterns, relative to source directory, that match files and
9192
# directories to ignore when looking for source files.
9293
# This pattern also affects html_static_path and html_extra_path.
93-
exclude_patterns: list[str] = ["build", "Thumbs.db", ".DS_Store"]
94+
exclude_patterns: List[str] = ["build", "Thumbs.db", ".DS_Store"]
9495

9596
# Links used for cross-referencing other documentation
96-
intersphinx_mapping: dict[str, tuple[str, None]] = {
97+
intersphinx_mapping: Dict[str, Tuple[str, None]] = {
9798
"python": ("https://docs.python.org/3", None),
9899
"aiohttp": ("https://docs.aiohttp.org/en/stable/", None),
99100
"requests": ("https://requests.readthedocs.io/en/latest/", None),
@@ -113,15 +114,15 @@
113114
# a list of builtin themes.
114115
#
115116
html_theme: str = "furo"
116-
html_theme_options: dict[str, list[dict[str, str]]] = {
117+
html_theme_options: Dict[str, List[Dict[str, str]]] = {
117118
"footer_icons": [
118119
{"name": "Discord", "url": _DISCORD, "html": _DISCORD_SVG, "class": ""},
119120
{"name": "Github", "url": _GITHUB, "html": _GITHUB_SVG, "class": ""},
120121
{"name": "readthedocs.io", "url": _RTD, "html": _RTD_SVG, "class": ""},
121122
],
122123
}
123124

124-
resource_links: dict[str, str] = {
125+
resource_links: Dict[str, str] = {
125126
"github": _GITHUB,
126127
"issues": f"{_GITHUB}/issues",
127128
"discussions": f"{_GITHUB}/discussions",

mystbin/client.py

+73-76
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from __future__ import annotations
2424

2525
import datetime
26-
from typing import Optional
26+
from typing import List, Optional, Sequence, overload
2727

2828
import aiohttp
2929

@@ -48,11 +48,52 @@ async def close(self) -> None:
4848
"""
4949
await self.http.close()
5050

51+
@overload
5152
async def create_paste(
5253
self,
5354
*,
5455
filename: str,
5556
content: str,
57+
file: None = ...,
58+
files: None = ...,
59+
password: Optional[str] = ...,
60+
expires: Optional[datetime.datetime] = ...,
61+
) -> Paste:
62+
...
63+
64+
@overload
65+
async def create_paste(
66+
self,
67+
*,
68+
filename: None = ...,
69+
content: None = ...,
70+
file: File,
71+
files: None = ...,
72+
password: Optional[str] = ...,
73+
expires: Optional[datetime.datetime] = ...,
74+
) -> Paste:
75+
...
76+
77+
@overload
78+
async def create_paste(
79+
self,
80+
*,
81+
filename: None = ...,
82+
content: None = ...,
83+
file: None = ...,
84+
files: Sequence[File],
85+
password: Optional[str] = ...,
86+
expires: Optional[datetime.datetime] = ...,
87+
) -> Paste:
88+
...
89+
90+
async def create_paste(
91+
self,
92+
*,
93+
filename: Optional[str] = None,
94+
content: Optional[str] = None,
95+
file: Optional[File] = None,
96+
files: Optional[Sequence[File]] = None,
5697
password: Optional[str] = None,
5798
expires: Optional[datetime.datetime] = None,
5899
) -> Paste:
@@ -62,46 +103,49 @@ async def create_paste(
62103
63104
Parameters
64105
-----------
65-
filename: :class:`str`
106+
filename: Optional[:class:`str`]
66107
The filename to create.
67-
content: :class:`str`
108+
content: Optional[:class:`str`]
68109
The content of the file you are creating.
110+
file: Optional[:class:`~mystbin.File`]
111+
The pre-created file you wish to upload.
112+
files: Optional[List[:class:`~mystbin.File`]]
113+
The pre-creates list of files you wish to upload.
69114
password: Optional[:class:`str`]
70115
The password of the paste, if any.
71116
expires: Optional[:class:`datetime.datetime`]
72117
When the paste expires, if any.
73118
119+
Raises
120+
-------
121+
:exc:`ValueError`
122+
A bad combinarion of singular and plural pastes were passed.
123+
74124
Returns
75125
--------
76126
:class:`mystbin.Paste`
77127
The paste that was created.
128+
129+
130+
..note::
131+
Passing combinations of both singular and plural files is not supports and will raise an exception.
132+
Internally the order of precesence is ``files`` > ``file`` > ``filename and content``.
78133
"""
79-
file = File(filename=filename, content=content)
80-
data = await self.http.create_paste(file=file, password=password, expires=expires)
81-
return Paste.from_data(data)
134+
if (filename and content) and file:
135+
raise ValueError("Cannot provide both `file` and `filename`/`content`")
82136

83-
async def create_multifile_paste(
84-
self, *, files: list[File], password: Optional[str] = None, expires: Optional[datetime.datetime] = None
85-
) -> Paste:
86-
"""|coro|
137+
resolved_files: Sequence[File] = []
138+
if filename and content:
139+
resolved_files = [File(filename=filename, content=content)]
140+
elif file:
141+
resolved_files = [file]
87142

88-
Create a paste with multiple files on mystb.in.
143+
if resolved_files and files:
144+
raise ValueError("Cannot provide both singular and plural files.")
89145

90-
Parameters
91-
------------
92-
files: list[:class:`mystbin.File`]
93-
A list of files to create on mystbin.
94-
password: Optional[:class:`str`]
95-
The password for this paste, if any.
96-
expires: Optional[:class:`datetime.datetime`]
97-
When this paste expires, if any.
146+
resolved_files = files or resolved_files
98147

99-
Returns
100-
--------
101-
:class:`mystbin.Paste`
102-
The paste that was created.
103-
"""
104-
data = await self.http.create_paste(files=files, password=password, expires=expires)
148+
data = await self.http.create_paste(files=resolved_files, password=password, expires=expires)
105149
return Paste.from_data(data)
106150

107151
@require_authentication
@@ -118,14 +162,14 @@ async def delete_paste(self, paste_id: str, /) -> None:
118162
await self.http.delete_pastes(paste_ids=[paste_id])
119163

120164
@require_authentication
121-
async def delete_pastes(self, paste_ids: list[str], /) -> None:
165+
async def delete_pastes(self, paste_ids: List[str], /) -> None:
122166
"""|coro|
123167
124168
Delete multiple pastes.
125169
126170
Parameters
127171
-----------
128-
paste_ids: list[:class:`str`]
172+
paste_ids: List[:class:`str`]
129173
The pastes to delete.
130174
"""
131175
await self.http.delete_pastes(paste_ids=paste_ids)
@@ -145,55 +189,8 @@ async def get_paste(self, paste_id: str, *, password: Optional[str] = None) -> P
145189
data = await self.http.get_paste(paste_id=paste_id, password=password)
146190
return Paste.from_data(data)
147191

148-
# @overload
149-
# async def edit_paste(self, paste_id: str, *, new_content: str, new_filename: ..., new_expires: ...) -> None:
150-
# ...
151-
152-
# @overload
153-
# async def edit_paste(self, paste_id: str, *, new_content: ..., new_filename: str, new_expires: ...) -> None:
154-
# ...
155-
156-
# @overload
157-
# async def edit_paste(
158-
# self, paste_id: str, *, new_content: ..., new_filename: ..., new_expires: datetime.datetime
159-
# ) -> None:
160-
# ...
161-
162-
# @overload
163-
# async def edit_paste(self, paste_id: str, *, new_content: str, new_filename: str, new_expires: ...) -> None:
164-
# ...
165-
166-
# @overload
167-
# async def edit_paste(
168-
# self, paste_id: str, *, new_content: str, new_filename: ..., new_expires: datetime.datetime
169-
# ) -> None:
170-
# ...
171-
172-
# @overload
173-
# async def edit_paste(
174-
# self, paste_id: str, *, new_content: ..., new_filename: str, new_expires: datetime.datetime
175-
# ) -> None:
176-
# ...
177-
178-
# @overload
179-
# async def edit_paste(
180-
# self, paste_id: str, *, new_content: str, new_filename: str, new_expires: datetime.datetime
181-
# ) -> None:
182-
# ...
183-
184-
# @require_authentication
185-
# async def edit_paste(
186-
# self,
187-
# paste_id: str,
188-
# *,
189-
# new_content: Optional[str] = MISSING,
190-
# new_filename: Optional[str] = MISSING,
191-
# new_expires: Optional[datetime.datetime] = MISSING,
192-
# ) -> None:
193-
# await self.http._edit_paste(paste_id, new_content=new_content, new_filename=new_filename, new_expires=new_expires)
194-
195192
@require_authentication
196-
async def get_user_pastes(self, *, limit: int = 100) -> list[Paste]:
193+
async def get_user_pastes(self, *, limit: int = 100) -> List[Paste]:
197194
"""|coro|
198195
199196
Get all pastes belonging to the current authenticated user.
@@ -205,7 +202,7 @@ async def get_user_pastes(self, *, limit: int = 100) -> list[Paste]:
205202
206203
Returns
207204
--------
208-
list[:class:`Paste`]
205+
List[:class:`Paste`]
209206
The pastes that were fetched.
210207
"""
211208
data = await self.http.get_my_pastes(limit=limit)

0 commit comments

Comments
 (0)