Skip to content

Commit a9d4a4a

Browse files
committed
migrate to uv, modernize ruff rules and cover
1 parent 916154e commit a9d4a4a

File tree

14 files changed

+3231
-1685
lines changed

14 files changed

+3231
-1685
lines changed

.github/workflows/build.yaml

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -13,49 +13,40 @@ on:
1313

1414
jobs:
1515
build:
16-
if: ${{ github.event.workflow_run.conclusion == 'success' || startsWith(github.ref, 'refs/tags') }}
1716
runs-on: ubuntu-latest
18-
strategy:
19-
fail-fast: false
20-
matrix:
21-
python-version: ["3.8", "3.x"]
2217

23-
name: "Build @ ${{ matrix.python-version }}"
18+
name: "Build"
2419
steps:
2520
- name: "Checkout Repository"
26-
uses: actions/checkout@v4
21+
uses: actions/checkout@v5
2722
with:
2823
fetch-depth: 0
2924

30-
- name: "Setup PDM @ ${{ matrix.python-version }}"
31-
uses: pdm-project/setup-pdm@v4
25+
- name: Install uv
26+
uses: astral-sh/setup-uv@v6
3227
with:
33-
python-version: ${{matrix.python-version}}
34-
cache: true
28+
enable-cache: true
29+
python-version: "3.13"
30+
activate-environment: true
3531

36-
- name: "Install deps @ ${{ matrix.python-version }}"
32+
- name: "Install deps"
3733
run: |
38-
pdm install --prod --check --no-editable
34+
uv sync --locked --all-extras --all-groups --no-dev
3935
40-
- name: "Activate venv @ ${{ matrix.python-version }}"
36+
- name: "Check it imports"
4137
run: |
42-
echo "$(pdm info --where)/.venv/bin" >> $GITHUB_PATH
38+
uv run python -c 'import mystbin'
4339
44-
- name: "Check it imports @ ${{ matrix.python-version }}"
40+
- name: "Build wheels"
4541
run: |
46-
pdm run python -c 'import mystbin'
42+
uv build
4743
48-
- name: "Build wheels @ ${{ matrix.python-version}}"
49-
run: |
50-
pdm build
51-
52-
- name: "Build docs @ ${{ matrix.python-version}}"
44+
- name: "Build docs"
5345
working-directory: docs/
5446
run: |
55-
pdm run docs
47+
uv run sphinx-build -aEWT --keep-going ./ ./build
5648
57-
- name: "Upload artifacts @ ${{ matrix.python-version}}"
58-
if: ${{ matrix.python-version != '3.x' }}
49+
- name: "Upload artifacts"
5950
uses: actions/upload-artifact@v4
6051
with:
6152
name: distributions
@@ -73,13 +64,13 @@ jobs:
7364
id-token: write
7465

7566
steps:
76-
- uses: actions/checkout@v4
67+
- uses: actions/checkout@v5
7768
with:
7869
fetch-depth: 0
7970
submodules: true
8071

8172
- name: Download Artifacts
82-
uses: actions/download-artifact@v4
73+
uses: actions/download-artifact@v5
8374
with:
8475
name: distributions
8576
path: dist
@@ -97,12 +88,12 @@ jobs:
9788
tag_name="${GITHUB_REF##*/}"
9889
gh release create "$tag_name" -F "CHANGELOG.md" "${assets[@]}"
9990
100-
- name: Set up PDM
101-
uses: pdm-project/setup-pdm@v4
91+
- name: Install uv
92+
uses: astral-sh/setup-uv@v6
10293
with:
103-
python-version: 3.8
104-
cache: true
94+
python-version: "3.13"
95+
activate-environment: true
10596

10697
- name: Publish to PyPI
10798
run: |
108-
pdm publish
99+
uv publish

.github/workflows/coverage_and_lint.yaml

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,46 +10,44 @@ on:
1010
types: [opened, reopened, synchronize]
1111

1212
jobs:
13-
job:
13+
check:
1414
runs-on: ubuntu-latest
1515
strategy:
1616
fail-fast: false
1717
matrix:
18-
python-version: [ '3.8', '3.x' ]
18+
python-version: ["3.11", "3.x"]
1919

2020
name: "Type Coverage and Linting @ ${{ matrix.python-version }}"
2121
steps:
2222
- name: "Checkout Repository"
23-
uses: actions/checkout@v4
23+
uses: actions/checkout@v5
2424
with:
2525
fetch-depth: 0
2626

27-
- name: Setup PDM @ ${{ matrix.python-version }}
28-
uses: pdm-project/setup-pdm@v4
27+
- name: Install uv
28+
uses: astral-sh/setup-uv@v6
2929
with:
30-
python-version: ${{ matrix.python-version }}
31-
cache: true
30+
enable-cache: true
31+
activate-environment: true
3232

3333
- name: Install deps @ ${{ matrix.python-version }}
3434
run: |
35-
pdm install --check --no-editable
36-
37-
- name: Activate venv @ ${{ matrix.python-version }}
38-
run: |
39-
echo "$(pdm info --where)/.venv/bin" >> $GITHUB_PATH
35+
uv sync --locked --all-extras --all-groups
4036
4137
- name: "Run Pyright @ ${{ matrix.python-version }}"
4238
uses: jakebailey/pyright-action@v2
4339
with:
4440
warnings: false
45-
annotate: "${{ matrix.python-version != '3.x' }}"
41+
verify-types: "mystbin"
42+
ignore-external: true
43+
annotate: ${{ matrix.python-version != '3.x' && 'all' || 'none' }}
4644

47-
- name: Lint check
48-
uses: astral-sh/ruff-action@v3
45+
- uses: astral-sh/ruff-action@v3
4946
with:
50-
args: check .
47+
version-file: "pyproject.toml"
5148

52-
- name: Formatting check
53-
uses: chartboost/ruff-action@v1
54-
with:
55-
args: format --check
49+
- name: Lint
50+
run: ruff check .
51+
52+
- name: Format check
53+
run: ruff format --check .

.python-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.8

mystbin/__init__.py

100755100644
File mode changed.

mystbin/client.py

100755100644
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class Client:
4242
The main client class that interacts with the mystb.in API.
4343
4444
Parameters
45-
-----------
45+
----------
4646
session: Optional[:class:`aiohttp.ClientSession`]
4747
The session to use for the HTTP requests.
4848
If not provided, a new session will be created.
@@ -56,10 +56,10 @@ class Client:
5656
def __init__(self, *, session: ClientSession | None = None, root_url: str = "https://mystb.in") -> None:
5757
self.http: HTTPClient = HTTPClient(session=session, root_url=root_url)
5858

59-
async def __aenter__(self) -> Self:
59+
async def __aenter__(self) -> Self: # noqa: D105
6060
return self
6161

62-
async def __aexit__(
62+
async def __aexit__( # noqa: D105
6363
self,
6464
exc_cls: type[BaseException] | None,
6565
exc_value: BaseException | None,
@@ -86,7 +86,7 @@ async def create_paste(
8686
Create a single file paste on mystb.in.
8787
8888
Parameters
89-
-----------
89+
----------
9090
files: List[:class:`~mystbin.File`]
9191
The pre-creates list of files you wish to upload.
9292
password: Optional[:class:`str`]
@@ -95,7 +95,7 @@ async def create_paste(
9595
When the paste expires, if any.
9696
9797
Returns
98-
--------
98+
-------
9999
:class:`mystbin.Paste`
100100
The paste that was created.
101101
"""
@@ -108,7 +108,7 @@ async def delete_paste(self, security_token: str, /) -> None:
108108
Delete a paste.
109109
110110
Parameters
111-
-----------
111+
----------
112112
security_token: :class:`str`
113113
The security token relating to the paste to delete.
114114
"""
@@ -129,7 +129,7 @@ async def get_paste(self, paste_id: str, *, password: str | None = None, raw: bo
129129
Fetch a paste.
130130
131131
Parameters
132-
-----------
132+
----------
133133
paste_id: :class:`str`
134134
The paste id to fetch.
135135
password: Optional[:class:`str`]
@@ -139,7 +139,7 @@ async def get_paste(self, paste_id: str, *, password: str | None = None, raw: bo
139139
Defaults to ``False``.
140140
141141
Returns
142-
--------
142+
-------
143143
Union[:class:`~mystbin.Paste`, List[:class:`str`]]
144144
The paste data returned.
145145
"""

mystbin/errors.py

100755100644
File mode changed.

mystbin/http.py

100755100644
Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1919
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2020
DEALINGS IN THE SOFTWARE.
21-
""" # noqa: A005 # we access this via namespace
21+
"""
2222

2323
from __future__ import annotations
2424

@@ -40,6 +40,7 @@
4040
from urllib.parse import quote as _uriquote
4141

4242
import aiohttp
43+
from typing_extensions import Self
4344

4445
from . import __version__
4546
from .errors import APIException
@@ -52,14 +53,14 @@
5253
T = TypeVar("T")
5354
Response = Coroutine[None, None, T]
5455
MU = TypeVar("MU", bound="MaybeUnlock")
55-
from .types.responses import CreatePasteResponse, GetPasteResponse
56+
from .types_.responses import CreatePasteResponse, GetPasteResponse
5657

5758

5859
SupportedHTTPVerb = Literal["GET", "POST", "PUT", "DELETE", "PATCH"]
5960

6061
LOGGER: logging.Logger = logging.getLogger(__name__)
6162

62-
__all__ = ("HTTPClient",)
63+
__all__ = ()
6364

6465

6566
def _clean_dt(dt: datetime.datetime) -> str:
@@ -72,7 +73,7 @@ async def _json_or_text(response: aiohttp.ClientResponse, /) -> dict[str, Any] |
7273
"""A quick method to parse a `aiohttp.ClientResponse` and test if it's json or text.
7374
7475
Returns
75-
--------
76+
-------
7677
Union[Dict[:class:`str`, Any], :class:`str`]
7778
The JSON object, or request text.
7879
"""
@@ -94,7 +95,7 @@ def __init__(self, lock: asyncio.Lock) -> None:
9495
self.lock: asyncio.Lock = lock
9596
self._unlock: bool = True
9697

97-
def __enter__(self: MU) -> MU:
98+
def __enter__(self) -> Self:
9899
return self
99100

100101
def defer(self) -> None:
@@ -162,7 +163,7 @@ async def _generate_session(self) -> aiohttp.ClientSession:
162163
self._owns_session = True
163164
return self._session
164165

165-
async def request(self, route: Route, **kwargs: Any) -> Any:
166+
async def request(self, route: Route, **kwargs: Any) -> Any: # noqa: C901, PLR0915
166167
if self._session is None:
167168
self._session = await self._generate_session()
168169

@@ -178,7 +179,7 @@ async def request(self, route: Route, **kwargs: Any) -> Any:
178179
if "json" in kwargs:
179180
headers["Content-Type"] = "application/json"
180181
kwargs["data"] = json.dumps(kwargs.pop("json"), separators=(",", ":"), ensure_ascii=True)
181-
LOGGER.debug("Current json body is: %s", str(kwargs["data"]))
182+
LOGGER.debug("Current json body is: %s", kwargs["data"])
182183

183184
kwargs["headers"] = headers
184185

@@ -232,7 +233,7 @@ async def request(self, route: Route, **kwargs: Any) -> Any:
232233
continue
233234

234235
assert isinstance(data, dict)
235-
LOGGER.exception("Unhandled HTTP error occurred: %s -> %s", response.status, data)
236+
LOGGER.error("Unhandled HTTP error occurred: %s -> %s", response.status, data)
236237
raise APIException(
237238
response=response,
238239
status_code=response.status,

mystbin/paste.py

100755100644
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
from typing_extensions import Self
3232

3333
from .http import HTTPClient
34-
from .types.responses import CreatePasteResponse, FileResponse, GetPasteResponse
34+
from .types_.responses import CreatePasteResponse, FileResponse, GetPasteResponse
3535

3636

3737
__all__ = (

mystbin/py.typed

100755100644
File mode changed.

mystbin/types/__init__.py renamed to mystbin/types_/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@
2020
DEALINGS IN THE SOFTWARE.
2121
"""
2222

23-
from mystbin.types import responses as responses
23+
from mystbin.types_ import responses as responses

0 commit comments

Comments
 (0)