Skip to content

Commit

Permalink
Sync CI with DipDup one
Browse files Browse the repository at this point in the history
  • Loading branch information
droserasprout committed Dec 27, 2023
1 parent 070d15e commit 2800309
Show file tree
Hide file tree
Showing 15 changed files with 128 additions and 159 deletions.
13 changes: 6 additions & 7 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,25 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
python-version: '3.12'

- name: Set up Poetry
uses: snok/install-poetry@v1
with:
version: '1.3.2'

- name: Install project
run: make install
run: poetry install
- name: Run lint
run: make lint
run: poetry run make lint
- name: Run tests
run: make test
run: poetry run make test

- name: Publish package on PyPi
run: |
poetry config http-basic.pypi __token__ ${{secrets.PYPI_TOKEN}}
poetry build
poetry publish
# FIXME: Fails on prereleases; https://github.com/mindsers/changelog-reader-action/pull/39
- name: Parse changelog
id: changelog
uses: mindsers/changelog-reader-action@v2
Expand All @@ -53,5 +52,5 @@ jobs:
## ${{ steps.changelog.outputs.version }} - ${{ steps.changelog.outputs.date }}
${{ steps.changelog.outputs.changes }}
draft: true
draft: false
prerelease: ${{ steps.changelog.outputs.status == 'prereleased' }}
26 changes: 22 additions & 4 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,32 @@ jobs:
strategy:
matrix:
include:
# Architectures
- os: ubuntu-latest
arch: amd64
python-version: '3.12'
- os: ubuntu-latest
arch: arm64
python-version: '3.12'
- os: macos-latest
arch: amd64
python-version: '3.12'
- os: macos-latest
arch: arm64
python-version: '3.12'
# Python versions
- os: ubuntu-latest
arch: amd64
python-version: '3.8'
- os: ubuntu-latest
arch: amd64
python-version: '3.9'
- os: ubuntu-latest
arch: amd64
python-version: '3.10'
- os: ubuntu-latest
arch: amd64
python-version: '3.11'
steps:
- name: Check out the repo
uses: actions/checkout@v3
Expand All @@ -36,12 +54,12 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
python-version: ${{ matrix.python-version }}
cache: 'poetry'

- name: Install project
run: make install
run: poetry install
- name: Run lint
run: make lint
run: poetry run make lint
- name: Run tests
run: make test
run: poetry run make test
33 changes: 7 additions & 26 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,55 +3,36 @@
##
## 🚧 pysignalr developer tools
##
## DEV=1 Install dev dependencies
DEV=1

##

help: ## Show this help (default)
@grep -F -h "##" $(MAKEFILE_LIST) | grep -F -v fgrep | sed -e 's/\\$$//' | sed -e 's/##//'

all: ## Run a whole CI pipeline: formatters, linters and tests
make install lint test docs

install: ## Install project dependencies
poetry install \
`if [ "${DEV}" = "0" ]; then echo "--without dev"; fi`
make lint test docs

lint: ## Lint with all tools
make isort black ruff mypy
make black ruff mypy

test: ## Run test suite
poetry run pytest --cov-report=term-missing --cov=pysignalr --cov-report=xml -s -v tests
pytest --cov-report=term-missing --cov=pysignalr --cov-report=xml -s -v tests

##

isort: ## Format with isort
poetry run isort src tests example.py

black: ## Format with black
poetry run black src tests example.py
black src tests example.py

ruff: ## Lint with ruff
poetry run ruff check src tests example.py
ruff check --fix --unsafe-fixes src tests example.py

mypy: ## Lint with mypy
poetry run mypy --strict src tests example.py
mypy --strict src tests example.py

cover: ## Print coverage for the current branch
poetry run diff-cover --compare-branch `git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'` coverage.xml

build: ## Build Python wheel package
poetry build
diff-cover --compare-branch `git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'` coverage.xml

##

clean: ## Remove all files from .gitignore except for `.venv`
git clean -xdf --exclude=".venv"
rm -r ~/.cache/flakeheaven

update: ## Update dependencies, export requirements.txt
rm requirements.* poetry.lock
make install
poetry export --without-hashes -o requirements.txt

6 changes: 3 additions & 3 deletions example.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from __future__ import annotations

import asyncio
from contextlib import suppress
from typing import Any
from typing import Dict
from typing import List

from pysignalr.client import SignalRClient
from pysignalr.messages import CompletionMessage
Expand All @@ -16,7 +16,7 @@ async def on_close() -> None:
print('Disconnected from the server')


async def on_message(message: List[Dict[str, Any]]) -> None:
async def on_message(message: list[dict[str, Any]]) -> None:
print(f'Received message: {message}')


Expand Down
16 changes: 1 addition & 15 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 14 additions & 11 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,43 +47,46 @@ black = "*"
diff-cover = "*"
docker = "*"
ruff = "*"
isort = "*"
mypy = "*"
pytest = "*"
pytest-asyncio = "*"
pytest-cov = "*"

[tool.isort]
line_length = 120
force_single_line = true

[tool.black]
line-length = 120
target-version = ["py38", "py39", "py310", "py311", "py312"]
skip-string-normalization = true

[tool.ruff]
line-length = 120
ignore = ["E501", "B905"]
target-version = "py312"
extend-select = ["B", "C4", "Q"] # todo: G, PTH, RET, RUF, S, TCH
flake8-quotes = {inline-quotes = "single", multiline-quotes = "double"}
ignore = [
"E402", # module level import not at top of file
"E501", # line too long
"TCH001", # breaks our runtime Pydantic magic
]
target-version = "py38"
extend-select = ["B", "C4", "FA", "G", "I", "PTH", "Q", "RUF", "TCH", "UP"]
flake8-quotes = { inline-quotes = "single", multiline-quotes = "double" }
isort = { force-single-line = true, known-first-party = ["pysignalr"] }

[tool.mypy]
python_version = "3.11"
python_version = "3.8"
strict = true

[tool.pytest.ini_options]
asyncio_mode = "auto"
log_cli_level = "WARNING"

[tool.coverage.report]
precision = 2
exclude_lines = [
"pragma: no cover",
"def __repr__",
"raise FrameworkError",
"raise NotImplementedError",
"if __name__ == .__main__.:",
"class .*\\bProtocol\\):",
"@(abc\\.)?abstractmethod",
"if TYPE_CHECKING:",
]

[build-system]
Expand Down
11 changes: 0 additions & 11 deletions requirements.txt

This file was deleted.

35 changes: 16 additions & 19 deletions src/pysignalr/client.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
from __future__ import annotations

import uuid
from collections import defaultdict
from contextlib import asynccontextmanager
from typing import Any
from typing import AsyncIterator
from typing import Awaitable
from typing import Callable
from typing import DefaultDict
from typing import Dict
from typing import List
from typing import Optional
from typing import Tuple

from pysignalr.exceptions import ServerError
from pysignalr.messages import CancelInvocationMessage
Expand Down Expand Up @@ -64,21 +61,21 @@ class SignalRClient:
def __init__(
self,
url: str,
protocol: Optional[Protocol] = None,
headers: Optional[Dict[str, str]] = None,
protocol: Protocol | None = None,
headers: dict[str, str] | None = None,
ping_interval: int = DEFAULT_PING_INTERVAL,
connection_timeout: int = DEFAULT_CONNECTION_TIMEOUT,
max_size: Optional[int] = DEFAULT_MAX_SIZE,
max_size: int | None = DEFAULT_MAX_SIZE,
) -> None:
self._url = url
self._protocol = protocol or JSONProtocol()
self._headers = headers or {}

self._message_handlers: DefaultDict[str, List[Optional[MessageCallback]]] = defaultdict(list)
self._stream_handlers: Dict[
str, Tuple[Optional[MessageCallback], Optional[MessageCallback], Optional[CompletionMessageCallback]]
self._message_handlers: defaultdict[str, list[MessageCallback | None]] = defaultdict(list)
self._stream_handlers: dict[
str, tuple[MessageCallback | None, MessageCallback | None, CompletionMessageCallback | None]
] = {}
self._invocation_handlers: Dict[str, Optional[MessageCallback]] = {}
self._invocation_handlers: dict[str, MessageCallback | None] = {}

self._transport = WebsocketTransport(
url=self._url,
Expand All @@ -89,7 +86,7 @@ def __init__(
connection_timeout=connection_timeout,
max_size=max_size,
)
self._error_callback: Optional[CompletionMessageCallback] = None
self._error_callback: CompletionMessageCallback | None = None

async def run(self) -> None:
await self._transport.run()
Expand All @@ -113,8 +110,8 @@ def on_error(self, callback: CompletionMessageCallback) -> None:
async def send(
self,
method: str,
arguments: List[Dict[str, Any]],
on_invocation: Optional[MessageCallback] = None,
arguments: list[dict[str, Any]],
on_invocation: MessageCallback | None = None,
) -> None:
"""Send a message to the server"""
invocation_id = str(uuid.uuid4())
Expand All @@ -125,10 +122,10 @@ async def send(
async def stream(
self,
event: str,
event_params: List[str],
on_next: Optional[MessageCallback] = None,
on_complete: Optional[MessageCallback] = None,
on_error: Optional[CompletionMessageCallback] = None,
event_params: list[str],
on_next: MessageCallback | None = None,
on_complete: MessageCallback | None = None,
on_error: CompletionMessageCallback | None = None,
) -> None:
"""Invoke stream on the specified event"""
invocation_id = str(uuid.uuid4())
Expand Down
5 changes: 3 additions & 2 deletions src/pysignalr/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

from dataclasses import dataclass
from typing import Optional


@dataclass(frozen=True)
Expand All @@ -19,4 +20,4 @@ class ConnectionError(HubError):

@dataclass(frozen=True)
class ServerError(HubError):
message: Optional[str]
message: str | None
Loading

0 comments on commit 2800309

Please sign in to comment.