diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 55d2025..ff261ba 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -3,7 +3,7 @@ FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT} USER vscode -RUN curl -sSf https://rye.astral.sh/get | RYE_VERSION="0.35.0" RYE_INSTALL_OPTION="--yes" bash +RUN curl -sSf https://rye.astral.sh/get | RYE_VERSION="0.44.0" RYE_INSTALL_OPTION="--yes" bash ENV PATH=/home/vscode/.rye/shims:$PATH RUN echo "[[ -d .venv ]] && source .venv/bin/activate || export PATH=\$PATH" >> /home/vscode/.bashrc diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c8a8a4f..3b286e5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: curl -sSf https://rye.astral.sh/get | bash echo "$HOME/.rye/shims" >> $GITHUB_PATH env: - RYE_VERSION: '0.35.0' + RYE_VERSION: '0.44.0' RYE_INSTALL_OPTION: '--yes' - name: Install dependencies @@ -42,7 +42,7 @@ jobs: curl -sSf https://rye.astral.sh/get | bash echo "$HOME/.rye/shims" >> $GITHUB_PATH env: - RYE_VERSION: '0.35.0' + RYE_VERSION: '0.44.0' RYE_INSTALL_OPTION: '--yes' - name: Bootstrap diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index 3e178a6..13dc1e5 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -21,7 +21,7 @@ jobs: curl -sSf https://rye.astral.sh/get | bash echo "$HOME/.rye/shims" >> $GITHUB_PATH env: - RYE_VERSION: '0.35.0' + RYE_VERSION: '0.44.0' RYE_INSTALL_OPTION: '--yes' - name: Publish to PyPI diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 9ffa609..dc8ed9b 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "1.8.3" + ".": "1.8.4" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index d4b713b..2de8424 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,2 +1,4 @@ configured_endpoints: 29 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/open-transit%2Fopen-transit-6f08502508c8ad25235971add3124a1cde4f1c3ec705d5df455d750e0adcb90b.yml +openapi_spec_hash: 84d082f35446d29c7db3cfcd259e9859 +config_hash: c7e112ec9853ad18fe92551ae0d97656 diff --git a/CHANGELOG.md b/CHANGELOG.md index 879b685..3934b2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +## 1.8.4 (2025-03-27) + +Full Changelog: [v1.8.3...v1.8.4](https://github.com/OneBusAway/python-sdk/compare/v1.8.3...v1.8.4) + +### Bug Fixes + +* **ci:** ensure pip is always available ([#284](https://github.com/OneBusAway/python-sdk/issues/284)) ([959d15e](https://github.com/OneBusAway/python-sdk/commit/959d15edcf912b2742e3598a35396041492ecbb7)) +* **ci:** remove publishing patch ([#285](https://github.com/OneBusAway/python-sdk/issues/285)) ([43691e0](https://github.com/OneBusAway/python-sdk/commit/43691e0b16c2c885b8e75d07e82f1ff26d961ac8)) +* **types:** handle more discriminated union shapes ([#283](https://github.com/OneBusAway/python-sdk/issues/283)) ([d55c08a](https://github.com/OneBusAway/python-sdk/commit/d55c08ad0ff636bf899c7a989185f30f431649bb)) + + +### Chores + +* fix typos ([#286](https://github.com/OneBusAway/python-sdk/issues/286)) ([e45e047](https://github.com/OneBusAway/python-sdk/commit/e45e04798e64b912d4ba598ebc3ef0cdaf031203)) +* **internal:** bump rye to 0.44.0 ([#282](https://github.com/OneBusAway/python-sdk/issues/282)) ([217ce3f](https://github.com/OneBusAway/python-sdk/commit/217ce3f97be80d4861ffc277336ec196c6873788)) +* **internal:** remove extra empty newlines ([#280](https://github.com/OneBusAway/python-sdk/issues/280)) ([3ca5c73](https://github.com/OneBusAway/python-sdk/commit/3ca5c734669aad9252aca2761537f2cf6dc9cfab)) + ## 1.8.3 (2025-03-04) Full Changelog: [v1.8.2...v1.8.3](https://github.com/OneBusAway/python-sdk/compare/v1.8.2...v1.8.3) diff --git a/bin/publish-pypi b/bin/publish-pypi index 05bfccb..826054e 100644 --- a/bin/publish-pypi +++ b/bin/publish-pypi @@ -3,7 +3,4 @@ set -eux mkdir -p dist rye build --clean -# Patching importlib-metadata version until upstream library version is updated -# https://github.com/pypa/twine/issues/977#issuecomment-2189800841 -"$HOME/.rye/self/bin/python3" -m pip install 'importlib-metadata==7.2.1' rye publish --yes --token=$PYPI_TOKEN diff --git a/pyproject.toml b/pyproject.toml index 1f496a3..6b048b7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "onebusaway" -version = "1.8.3" +version = "1.8.4" description = "The official Python library for the onebusaway-sdk API" dynamic = ["readme"] license = "Apache-2.0" @@ -38,7 +38,6 @@ Homepage = "https://github.com/OneBusAway/python-sdk" Repository = "https://github.com/OneBusAway/python-sdk" - [tool.rye] managed = true # version pins are in requirements-dev.lock @@ -87,7 +86,7 @@ typecheck = { chain = [ "typecheck:mypy" = "mypy ." [build-system] -requires = ["hatchling", "hatch-fancy-pypi-readme"] +requires = ["hatchling==1.26.3", "hatch-fancy-pypi-readme"] build-backend = "hatchling.build" [tool.hatch.build] @@ -152,7 +151,6 @@ reportImplicitOverride = true reportImportCycles = false reportPrivateUsage = false - [tool.ruff] line-length = 120 output-format = "grouped" diff --git a/scripts/test b/scripts/test index 4fa5698..2b87845 100755 --- a/scripts/test +++ b/scripts/test @@ -52,6 +52,8 @@ else echo fi +export DEFER_PYDANTIC_BUILD=false + echo "==> Running tests" rye run pytest "$@" diff --git a/src/onebusaway/_models.py b/src/onebusaway/_models.py index c4401ff..3493571 100644 --- a/src/onebusaway/_models.py +++ b/src/onebusaway/_models.py @@ -65,7 +65,7 @@ from ._constants import RAW_RESPONSE_HEADER if TYPE_CHECKING: - from pydantic_core.core_schema import ModelField, LiteralSchema, ModelFieldsSchema + from pydantic_core.core_schema import ModelField, ModelSchema, LiteralSchema, ModelFieldsSchema __all__ = ["BaseModel", "GenericModel"] @@ -646,15 +646,18 @@ def _build_discriminated_union_meta(*, union: type, meta_annotations: tuple[Any, def _extract_field_schema_pv2(model: type[BaseModel], field_name: str) -> ModelField | None: schema = model.__pydantic_core_schema__ + if schema["type"] == "definitions": + schema = schema["schema"] + if schema["type"] != "model": return None + schema = cast("ModelSchema", schema) fields_schema = schema["schema"] if fields_schema["type"] != "model-fields": return None fields_schema = cast("ModelFieldsSchema", fields_schema) - field = fields_schema["fields"].get(field_name) if not field: return None @@ -678,7 +681,7 @@ def set_pydantic_config(typ: Any, config: pydantic.ConfigDict) -> None: setattr(typ, "__pydantic_config__", config) # noqa: B010 -# our use of subclasssing here causes weirdness for type checkers, +# our use of subclassing here causes weirdness for type checkers, # so we just pretend that we don't subclass if TYPE_CHECKING: GenericModel = BaseModel diff --git a/src/onebusaway/_utils/_transform.py b/src/onebusaway/_utils/_transform.py index 18afd9d..7ac2e17 100644 --- a/src/onebusaway/_utils/_transform.py +++ b/src/onebusaway/_utils/_transform.py @@ -126,7 +126,7 @@ def _get_annotated_type(type_: type) -> type | None: def _maybe_transform_key(key: str, type_: type) -> str: """Transform the given `data` based on the annotations provided in `type_`. - Note: this function only looks at `Annotated` types that contain `PropertInfo` metadata. + Note: this function only looks at `Annotated` types that contain `PropertyInfo` metadata. """ annotated_type = _get_annotated_type(type_) if annotated_type is None: diff --git a/src/onebusaway/_version.py b/src/onebusaway/_version.py index af5f659..e4402cd 100644 --- a/src/onebusaway/_version.py +++ b/src/onebusaway/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "onebusaway" -__version__ = "1.8.3" # x-release-please-version +__version__ = "1.8.4" # x-release-please-version diff --git a/tests/test_models.py b/tests/test_models.py index 95fa41d..d3499d2 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -854,3 +854,35 @@ class Model(BaseModel): m = construct_type(value={"cls": "foo"}, type_=Model) assert isinstance(m, Model) assert isinstance(m.cls, str) + + +def test_discriminated_union_case() -> None: + class A(BaseModel): + type: Literal["a"] + + data: bool + + class B(BaseModel): + type: Literal["b"] + + data: List[Union[A, object]] + + class ModelA(BaseModel): + type: Literal["modelA"] + + data: int + + class ModelB(BaseModel): + type: Literal["modelB"] + + required: str + + data: Union[A, B] + + # when constructing ModelA | ModelB, value data doesn't match ModelB exactly - missing `required` + m = construct_type( + value={"type": "modelB", "data": {"type": "a", "data": True}}, + type_=cast(Any, Annotated[Union[ModelA, ModelB], PropertyInfo(discriminator="type")]), + ) + + assert isinstance(m, ModelB)