Repository: meltano/sdk
Pull request #1526 (2023-03-24 04:33:43)

fix: Handle missing `type` value when checking JSON schema types
Uncovered in https://github.com/MeltanoLabs/tap-dbt/pull/119


<!-- readthedocs-preview meltano-sdk start -->
----
:books: Documentation preview :books:: https://meltano-sdk--1526.org.readthedocs.build/en/1526/

<!-- readthedocs-preview meltano-sdk end -->

codecov[bot]: ## [Codecov](https://codecov.io/gh/meltano/sdk/pull/1526?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meltano) Report
> Merging [#1526](https://codecov.io/gh/meltano/sdk/pull/1526?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meltano) (e53f47c) into [main](https://codecov.io/gh/meltano/sdk/commit/7ff1bebbe63c09c5643d1da3e57f1f0115c3d923?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meltano) (7ff1beb) will **not change** coverage.
> The diff coverage is `100.00%`.

```diff
@@           Coverage Diff           @@
##             main    #1526   +/-   ##
=======================================
  Coverage   85.50%   85.50%           
=======================================
  Files          57       57           
  Lines        4692     4692           
  Branches      802      802           
=======================================
  Hits         4012     4012           
  Misses        489      489           
  Partials      191      191           
```


| [Impacted Files](https://codecov.io/gh/meltano/sdk/pull/1526?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meltano) | Coverage Δ | |
|---|---|---|
| [singer\_sdk/helpers/\_typing.py](https://codecov.io/gh/meltano/sdk/pull/1526?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meltano#diff-c2luZ2VyX3Nkay9oZWxwZXJzL190eXBpbmcucHk=) | `74.19% <100.00%> (ø)` | |

:mega: We’re building smart automated test selection to slash your CI/CD build times. [Learn more](https://about.codecov.io/iterative-testing/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=meltano)

mjsqu: Looks good, in the case we found in `tap-dbt`, this would loop over the `"anyOf"` list and skip past `"enum"` without returning anything but output `True` when encountering the `"type"` key. The test looks exactly like the case in `tap-dbt`. Great work @edgarrmondragon 👍 

Patch:
diff --git a/singer_sdk/helpers/_typing.py b/singer_sdk/helpers/_typing.py
index 673a58de..1fe89dc3 100644
--- a/singer_sdk/helpers/_typing.py
+++ b/singer_sdk/helpers/_typing.py
@@ -252,7 +252,7 @@ def is_boolean_type(property_schema: dict) -> bool | None:
         return None  # Could not detect data type
     for property_type in property_schema.get("anyOf", [property_schema.get("type")]):
         if isinstance(property_type, dict):
-            property_type = property_type.get("type")
+            property_type = property_type.get("type", [])
         if "boolean" in property_type or property_type == "boolean":
             return True
     return False
@@ -264,7 +264,7 @@ def is_integer_type(property_schema: dict) -> bool | None:
         return None  # Could not detect data type
     for property_type in property_schema.get("anyOf", [property_schema.get("type")]):
         if isinstance(property_type, dict):
-            property_type = property_type.get("type")
+            property_type = property_type.get("type", [])
         if "integer" in property_type or property_type == "integer":
             return True
     return False
@@ -276,7 +276,7 @@ def is_string_type(property_schema: dict) -> bool | None:
         return None  # Could not detect data type
     for property_type in property_schema.get("anyOf", [property_schema.get("type")]):
         if isinstance(property_type, dict):
-            property_type = property_type.get("type")
+            property_type = property_type.get("type", [])
         if "string" in property_type or property_type == "string":
             return True
     return False
@@ -288,7 +288,7 @@ def is_null_type(property_schema: dict) -> bool | None:
         return None  # Could not detect data type
     for property_type in property_schema.get("anyOf", [property_schema.get("type")]):
         if isinstance(property_type, dict):
-            property_type = property_type.get("type")
+            property_type = property_type.get("type", [])
         if "null" in property_type or property_type == "null":
             return True
     return False
@@ -300,7 +300,7 @@ def is_number_type(property_schema: dict) -> bool | None:
         return None  # Could not detect data type
     for property_type in property_schema.get("anyOf", [property_schema.get("type")]):
         if isinstance(property_type, dict):
-            property_type = property_type.get("type")
+            property_type = property_type.get("type", [])
         if "number" in property_type or property_type == "number":
             return True
     return False


Test patch:
diff --git a/tests/core/test_jsonschema_helpers.py b/tests/core/test_jsonschema_helpers.py
index 6a4ef0ba..f670a6cf 100644
--- a/tests/core/test_jsonschema_helpers.py
+++ b/tests/core/test_jsonschema_helpers.py
@@ -751,6 +751,18 @@ def test_custom_type():
             [is_number_type],
             [True],
         ),
+        (
+            [
+                {
+                    "anyOf": [
+                        {"enum": ["developer", "team", "enterprise"]},
+                        {"type": "string"},
+                    ],
+                },
+            ],
+            [is_string_type],
+            [True],
+        ),
     ],
 )
 def test_type_check_variations(property_schemas, type_check_functions, results):