Skip to content

Raise more descriptive exceptions when wrapped JSON typing classes needs to be instantiated

Summary

Some JSON typing helper classes need to be instantiated so they can be converted to a JSON type dictionary. For example, th.Property("parameters_schema", th.ArrayType).to_dict() will produce an error while th.Property("parameters_schema", th.ArrayType(th.StringType)).to_dict() will not but the exception raised is not very descriptive of the underlying error.

Slack: https://meltano.slack.com/archives/C01PKLU5D1R/p1649694338239079

Steps to reproduce

import singer_sdk.typing as th

th.Property("parameters_schema", th.ArrayType).to_dict()

What is the current bug behavior?

An error is raised downstream when the type_dict is tried to be iterated assuming it's a dictionary, looking for specific keys, so the root cause gets lost.

What is the expected correct behavior?

A descriptive exception is raised. Something like

>>> import singer_sdk.typing as th
>>> th.Property("parameters_schema", th.ArrayType).to_dict()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/edgarramirez/Code/sdk/singer_sdk/typing.py", line 361, in to_dict
    type_dict = self.type_dict
  File "/Users/edgarramirez/Code/sdk/singer_sdk/typing.py", line 347, in type_dict
    raise ValueError(
ValueError: Type dict for <class 'singer_sdk.typing.ArrayType'> is not defined. Try instantiating it with a nested type such as ArrayType(StringType).
>>>

Relevant logs and/or screenshots

tap_workato/tests/test_core.py:7: in <module>
    from tap_workato.tap import TapWorkato
tap_workato/tap.py:8: in <module>
    from tap_workato.streams import (
tap_workato/streams.py:82: in <module>
    class RecipesStream(WorkatoStream):
tap_workato/streams.py:116: in RecipesStream
    th.ArrayType
../../../Library/Caches/pypoetry/virtualenvs/tap-workato-T66zip44-py3.7/lib/python3.7/site-packages/singer_sdk/typing.py:94: in to_dict
    return cast(dict, self.type_dict)
../../../Library/Caches/pypoetry/virtualenvs/tap-workato-T66zip44-py3.7/lib/python3.7/site-packages/singer_sdk/typing.py:374: in type_dict
    merged_props.update(w.to_dict())
../../../Library/Caches/pypoetry/virtualenvs/tap-workato-T66zip44-py3.7/lib/python3.7/site-packages/singer_sdk/typing.py:338: in to_dict
    type_dict = append_type(type_dict, "null")
../../../Library/Caches/pypoetry/virtualenvs/tap-workato-T66zip44-py3.7/lib/python3.7/site-packages/singer_sdk/helpers/_typing.py:38: in append_type
    if "anyOf" in result:
E   TypeError: argument of type 'property' is not iterable

Possible fixes

Add a check in Property.type_dict to see if the wrapped object actually has a type_dict of dict type.