Skip to content

Commit

Permalink
release: 0.1.3 (#42)
Browse files Browse the repository at this point in the history
* chore(internal): codegen related update (#41)

* chore(internal): add jsonl unit tests (#43)

* release: 0.1.3

---------

Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com>
  • Loading branch information
stainless-app[bot] authored Feb 18, 2025
1 parent c16c250 commit e388ba1
Showing 6 changed files with 101 additions and 9 deletions.
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.1.2"
".": "0.1.3"
}
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

## 0.1.3 (2025-02-14)

Full Changelog: [v0.1.2...v0.1.3](https://github.com/gitpod-io/gitpod-sdk-python/compare/v0.1.2...v0.1.3)

### Chores

* **internal:** add jsonl unit tests ([#43](https://github.com/gitpod-io/gitpod-sdk-python/issues/43)) ([8641b53](https://github.com/gitpod-io/gitpod-sdk-python/commit/8641b53116b20dd8e329f229afd84ec6a100fcef))
* **internal:** codegen related update ([#41](https://github.com/gitpod-io/gitpod-sdk-python/issues/41)) ([e5dceda](https://github.com/gitpod-io/gitpod-sdk-python/commit/e5dceda109bb01cf538dce83c3ab16d60461eb3d))

## 0.1.2 (2025-02-14)

Full Changelog: [v0.1.1...v0.1.2](https://github.com/gitpod-io/gitpod-sdk-python/compare/v0.1.1...v0.1.2)
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "gitpod-sdk"
version = "0.1.2"
version = "0.1.3"
description = "The official Python library for the gitpod API"
dynamic = ["readme"]
license = "Apache-2.0"
7 changes: 1 addition & 6 deletions src/gitpod/_exceptions.py
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@

from __future__ import annotations

from typing import TYPE_CHECKING, Any, Optional, cast
from typing import Any, Optional, cast
from typing_extensions import Literal

import httpx
@@ -53,11 +53,6 @@ class APIError(GitpodError):
Contains an arbitrary serialized message along with a @type that describes the
type of the serialized message.
"""
if TYPE_CHECKING:
# Stub to indicate that arbitrary properties are accepted.
# To access properties that are not valid identifiers you can use `getattr`, e.g.
# `getattr(obj, '$type')`
def __getattr__(self, attr: str) -> object: ...

def __init__(self, message: str, request: httpx.Request, *, body: object | None) -> None:
super().__init__(message)
2 changes: 1 addition & 1 deletion src/gitpod/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

__title__ = "gitpod"
__version__ = "0.1.2" # x-release-please-version
__version__ = "0.1.3" # x-release-please-version
88 changes: 88 additions & 0 deletions tests/decoders/test_jsonl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
from __future__ import annotations

from typing import Any, Iterator, AsyncIterator
from typing_extensions import TypeVar

import httpx
import pytest

from gitpod._decoders.jsonl import JSONLDecoder, AsyncJSONLDecoder

_T = TypeVar("_T")


@pytest.mark.asyncio
@pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"])
async def test_basic(sync: bool) -> None:
def body() -> Iterator[bytes]:
yield b'{"foo":true}\n'
yield b'{"bar":false}\n'

iterator = make_jsonl_iterator(
content=body(),
sync=sync,
line_type=object,
)

assert await iter_next(iterator) == {"foo": True}
assert await iter_next(iterator) == {"bar": False}

await assert_empty_iter(iterator)


@pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"])
async def test_new_lines_in_json(
sync: bool,
) -> None:
def body() -> Iterator[bytes]:
yield b'{"content":"Hello, world!\\nHow are you doing?"}'

iterator = make_jsonl_iterator(content=body(), sync=sync, line_type=object)

assert await iter_next(iterator) == {"content": "Hello, world!\nHow are you doing?"}


@pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"])
async def test_multi_byte_character_multiple_chunks(
sync: bool,
) -> None:
def body() -> Iterator[bytes]:
yield b'{"content":"'
# bytes taken from the string 'известни' and arbitrarily split
# so that some multi-byte characters span multiple chunks
yield b"\xd0"
yield b"\xb8\xd0\xb7\xd0"
yield b"\xb2\xd0\xb5\xd1\x81\xd1\x82\xd0\xbd\xd0\xb8"
yield b'"}\n'

iterator = make_jsonl_iterator(content=body(), sync=sync, line_type=object)

assert await iter_next(iterator) == {"content": "известни"}


async def to_aiter(iter: Iterator[bytes]) -> AsyncIterator[bytes]:
for chunk in iter:
yield chunk


async def iter_next(iter: Iterator[_T] | AsyncIterator[_T]) -> _T:
if isinstance(iter, AsyncIterator):
return await iter.__anext__()
return next(iter)


async def assert_empty_iter(decoder: JSONLDecoder[Any] | AsyncJSONLDecoder[Any]) -> None:
with pytest.raises((StopAsyncIteration, RuntimeError)):
await iter_next(decoder)


def make_jsonl_iterator(
content: Iterator[bytes],
*,
sync: bool,
line_type: type[_T],
) -> JSONLDecoder[_T] | AsyncJSONLDecoder[_T]:
if sync:
return JSONLDecoder(line_type=line_type, raw_iterator=content, http_response=httpx.Response(200))

return AsyncJSONLDecoder(line_type=line_type, raw_iterator=to_aiter(content), http_response=httpx.Response(200))

0 comments on commit e388ba1

Please sign in to comment.