Skip to content

Commit

Permalink
fix: Warn instead of crashing when schema helpers cannot append `null…
Browse files Browse the repository at this point in the history
…` to types (#1970)

* Add failing test

* Warn instead of crashing

---------

Co-authored-by: Ken Payne <[email protected]>
  • Loading branch information
edgarrmondragon and Ken Payne authored Sep 22, 2023
1 parent 68be7ce commit bb98db5
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 6 deletions.
13 changes: 7 additions & 6 deletions singer_sdk/helpers/_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@

import copy
import datetime
import logging
import typing as t
from enum import Enum
from functools import lru_cache

import pendulum

if t.TYPE_CHECKING:
import logging

_MAX_TIMESTAMP = "9999-12-31 23:59:59.999999"
_MAX_TIME = "23:59:59.999999"
JSONSCHEMA_ANNOTATION_SECRET = "secret" # noqa: S105
JSONSCHEMA_ANNOTATION_WRITEONLY = "writeOnly"
UTC = datetime.timezone.utc

logger = logging.getLogger(__name__)


class DatetimeErrorTreatmentEnum(Enum):
"""Enum for treatment options for date parsing error."""
Expand Down Expand Up @@ -67,11 +67,12 @@ def append_type(type_dict: dict, new_type: str) -> dict:
result["type"] = [*type_array, new_type]
return result

msg = (
logger.warning(
"Could not append type because the JSON schema for the dictionary "
f"`{type_dict}` appears to be invalid."
"`%s` appears to be invalid.",
type_dict,
)
raise ValueError(msg)
return result


def is_secret_type(type_dict: dict) -> bool:
Expand Down
20 changes: 20 additions & 0 deletions singer_sdk/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,26 @@ def type_dict(self) -> dict: # type: ignore[override]
return {"type": "array", "items": self.wrapped_type.type_dict, **self.extras}


class AnyType(JSONTypeHelper):
"""Any type."""

def __init__(
self,
*args: t.Any,
**kwargs: t.Any,
) -> None:
super().__init__(*args, **kwargs)

@DefaultInstanceProperty
def type_dict(self) -> dict:
"""Get type dictionary.
Returns:
A dictionary describing the type.
"""
return {**self.extras}


class Property(JSONTypeHelper[T], t.Generic[T]):
"""Generic Property. Should be nested within a `PropertiesList`."""

Expand Down
22 changes: 22 additions & 0 deletions tests/core/test_jsonschema_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import re
import typing as t
from logging import WARNING
from textwrap import dedent

import pytest
Expand All @@ -26,6 +27,7 @@
)
from singer_sdk.tap_base import Tap
from singer_sdk.typing import (
AnyType,
ArrayType,
BooleanType,
CustomType,
Expand Down Expand Up @@ -130,6 +132,26 @@ def test_to_json():
)


def test_any_type(caplog: pytest.LogCaptureFixture):
schema = PropertiesList(
Property("any_type", AnyType, description="Can be anything"),
)
with caplog.at_level(WARNING):
assert schema.to_dict() == {
"type": "object",
"properties": {
"any_type": {
"description": "Can be anything",
},
},
}
assert caplog.records[0].levelname == "WARNING"
assert caplog.records[0].message == (
"Could not append type because the JSON schema for the dictionary `{}` "
"appears to be invalid."
)


def test_nested_complex_objects():
test1a = Property(
"Datasets",
Expand Down

0 comments on commit bb98db5

Please sign in to comment.