From 573422d71bc4962983fb0de9d62b29a0cf751a94 Mon Sep 17 00:00:00 2001 From: libretto Date: Mon, 11 Nov 2024 14:56:22 +0200 Subject: [PATCH] fixup mypy issues --- src/karapace/schema_models.py | 17 ++++- .../test_jsonschema_references.py | 75 +++++++------------ 2 files changed, 42 insertions(+), 50 deletions(-) diff --git a/src/karapace/schema_models.py b/src/karapace/schema_models.py index 99218b47b..4a2ae9c55 100644 --- a/src/karapace/schema_models.py +++ b/src/karapace/schema_models.py @@ -218,9 +218,20 @@ def json_resolver(schema_str: str, dependencies: Mapping[str, Dependency] | None stack.append((dependency.schema.schema_str, dependency.schema.dependencies)) else: schema_json = json_decode(current_schema_str) - schema_store[schema_json["$id"]] = schema_json - - resolver = RefResolver.from_schema(json_decode(schema_str), store=schema_store) + if isinstance(schema_json, dict): + schema_store[schema_json["$id"]] = schema_json + else: + # In the case of schemas with references, we only support schemas with a canonical structure, + # which must include a $id in the reference. + raise InvalidSchema + main_schema_json = json_decode(schema_str) + if not isinstance(main_schema_json, dict): + # In the case of schemas with references, we only support schemas with a canonical structure, which must + # contain an $id tag within the reference. Simple main schemas of types such as bool, int, str, etc., + # are not supported. + raise InvalidSchema + + resolver = RefResolver.from_schema(main_schema_json, store=schema_store) return resolver diff --git a/tests/integration/schema_registry/test_jsonschema_references.py b/tests/integration/schema_registry/test_jsonschema_references.py index 2149218b0..4b39a08b3 100644 --- a/tests/integration/schema_registry/test_jsonschema_references.py +++ b/tests/integration/schema_registry/test_jsonschema_references.py @@ -5,7 +5,6 @@ from karapace.client import Client from karapace.compatibility import CompatibilityModes from karapace.schema_reader import SchemaType -from karapace.typing import SchemaMetadata, SchemaRuleSet from tests.schemas.json_schemas import ( A_DINT_B_DINT_OBJECT_SCHEMA, A_DINT_B_INT_OBJECT_SCHEMA, @@ -19,7 +18,6 @@ A_INT_OBJECT_SCHEMA, A_INT_OPEN_OBJECT_SCHEMA, A_OBJECT_SCHEMA, - ALL_SCHEMAS, ARRAY_OF_INT_SCHEMA, ARRAY_OF_NUMBER_SCHEMA, ARRAY_OF_POSITIVE_INTEGER, @@ -33,7 +31,6 @@ B_NUM_C_INT_OBJECT_SCHEMA, B_NUM_C_INT_OPEN_OBJECT_SCHEMA, BOOLEAN_SCHEMA, - BOOLEAN_SCHEMAS, EMPTY_OBJECT_SCHEMA, EMPTY_SCHEMA, ENUM_AB_SCHEMA, @@ -47,7 +44,6 @@ EXCLUSIVE_MINIMUM_INCREASED_NUMBER_SCHEMA, EXCLUSIVE_MINIMUM_INTEGER_SCHEMA, EXCLUSIVE_MINIMUM_NUMBER_SCHEMA, - FALSE_SCHEMA, INT_SCHEMA, MAX_ITEMS_DECREASED_SCHEMA, MAX_ITEMS_SCHEMA, @@ -71,12 +67,10 @@ MINIMUM_INCREASED_NUMBER_SCHEMA, MINIMUM_INTEGER_SCHEMA, MINIMUM_NUMBER_SCHEMA, - NON_OBJECT_SCHEMAS, NOT_OF_EMPTY_SCHEMA, NOT_OF_TRUE_SCHEMA, NUMBER_SCHEMA, OBJECT_SCHEMA, - OBJECT_SCHEMAS, ONEOF_ARRAY_A_DINT_B_NUM_SCHEMA, ONEOF_ARRAY_B_NUM_C_DINT_OPEN_SCHEMA, ONEOF_ARRAY_B_NUM_C_INT_SCHEMA, @@ -87,7 +81,6 @@ PATTERN_PROPERTY_ASTAR_OBJECT_SCHEMA, PROPERTY_NAMES_ASTAR_OBJECT_SCHEMA, STRING_SCHEMA, - TRUE_SCHEMA, TUPLE_OF_INT_INT_OPEN_SCHEMA, TUPLE_OF_INT_INT_SCHEMA, TUPLE_OF_INT_OPEN_SCHEMA, @@ -99,7 +92,6 @@ from tests.utils import new_random_name import json -import pytest async def debugging_details( @@ -153,10 +145,8 @@ async def not_schemas_are_compatible( "schemaType": SchemaType.JSONSCHEMA.value, }, ) - assert older_dependency_res.status_code == 200, \ - await debugging_details(newer, older, client, f"{subject}_dependency") - assert "id" in older_dependency_res.json(), \ - await debugging_details(newer, older, client, f"{subject}_dependency") + assert older_dependency_res.status_code == 200, await debugging_details(newer, older, client, f"{subject}_dependency") + assert "id" in older_dependency_res.json(), await debugging_details(newer, older, client, f"{subject}_dependency") main_schema = { "$id": "https://example.com/main.schema.json", @@ -175,21 +165,18 @@ async def not_schemas_are_compatible( json={ "schema": json.dumps(main_schema), "schemaType": SchemaType.JSONSCHEMA.value, - "references": [{"name": "dependency.schema.json", "subject": f"{subject}_dependency", "version": 1}] + "references": [{"name": "dependency.schema.json", "subject": f"{subject}_dependency", "version": 1}], }, ) - assert main_res.status_code == 200, \ - await debugging_details(newer, older, client, f"{subject}_dependency") - assert "id" in main_res.json(), \ - await debugging_details(newer, older, client, f"{subject}_dependency") + assert main_res.status_code == 200, await debugging_details(newer, older, client, f"{subject}_dependency") + assert "id" in main_res.json(), await debugging_details(newer, older, client, f"{subject}_dependency") # enforce the target compatibility mode. not using the global setting # because that interfere with parallel runs. subject_config_res = await client.put(f"config/{subject}", json={"compatibility": compatibility_mode.value}) assert subject_config_res.status_code == 200 - subject_config_res = await client.put(f"config/{subject}_dependency", - json={"compatibility": compatibility_mode.value}) + subject_config_res = await client.put(f"config/{subject}_dependency", json={"compatibility": compatibility_mode.value}) assert subject_config_res.status_code == 200 newer_schema = dict(template_schema) @@ -233,10 +220,8 @@ async def schemas_are_compatible( "schemaType": SchemaType.JSONSCHEMA.value, }, ) - assert older_dependency_res.status_code == 200, \ - await debugging_details(newer, older, client, f"{subject}_dependency") - assert "id" in older_dependency_res.json(), \ - await debugging_details(newer, older, client, f"{subject}_dependency") + assert older_dependency_res.status_code == 200, await debugging_details(newer, older, client, f"{subject}_dependency") + assert "id" in older_dependency_res.json(), await debugging_details(newer, older, client, f"{subject}_dependency") main_schema = { "$id": "https://example.com/main.schema.json", @@ -255,21 +240,18 @@ async def schemas_are_compatible( json={ "schema": json.dumps(main_schema), "schemaType": SchemaType.JSONSCHEMA.value, - "references": [{"name": "dependency.schema.json", "subject": f"{subject}_dependency", "version": 1}] + "references": [{"name": "dependency.schema.json", "subject": f"{subject}_dependency", "version": 1}], }, ) - assert main_res.status_code == 200, \ - await debugging_details(newer, older, client, f"{subject}_dependency") - assert "id" in main_res.json(), \ - await debugging_details(newer, older, client, f"{subject}_dependency") + assert main_res.status_code == 200, await debugging_details(newer, older, client, f"{subject}_dependency") + assert "id" in main_res.json(), await debugging_details(newer, older, client, f"{subject}_dependency") # enforce the target compatibility mode. not using the global setting # because that interfere with parallel runs. subject_config_res = await client.put(f"config/{subject}", json={"compatibility": compatibility_mode.value}) assert subject_config_res.status_code == 200 - subject_config_res = await client.put(f"config/{subject}_dependency", - json={"compatibility": compatibility_mode.value}) + subject_config_res = await client.put(f"config/{subject}_dependency", json={"compatibility": compatibility_mode.value}) assert subject_config_res.status_code == 200 newer_schema = dict(template_schema) @@ -284,8 +266,9 @@ async def schemas_are_compatible( assert newer_res.status_code == 200, await debugging_details(newer, older, client, f"{subject}_dependency") # Because the IDs are global, and the same schema is used in multiple # tests, their order is unknown. - assert older_dependency_res.json()["id"] != newer_res.json()["id"], \ - await debugging_details(newer, older, client, f"{subject}_dependency") + assert older_dependency_res.json()["id"] != newer_res.json()["id"], await debugging_details( + newer, older, client, f"{subject}_dependency" + ) await sainty_check(client, subject, compatibility_mode) @@ -332,7 +315,7 @@ async def test_schemaregistry_schemaregistry_extra_optional_field_with_open_mode # reader=TRUE_SCHEMA, # writer=A_INT_OBJECT_SCHEMA, # client=registry_async_client, - #) + # ) await schemas_are_backward_compatible( reader=EMPTY_SCHEMA, writer=A_INT_OBJECT_SCHEMA, @@ -387,11 +370,11 @@ async def test_schemaregistry_schemaregistry_extra_field_with_closed_model_is_in # writ-er=A_INT_OBJECT_SCHEMA, # client=registry_async_client, # ) - # await not_schemas_are_backward_compatible( - # reader=A_INT_OBJECT_SCHEMA, - # writer=FALSE_SCHEMA, - # client=registry_async_client, - # ) + # await not_schemas_are_backward_compatible( + # reader=A_INT_OBJECT_SCHEMA, + # writer=FALSE_SCHEMA, + # client=registry_async_client, + # ) await not_schemas_are_backward_compatible( reader=NOT_OF_TRUE_SCHEMA, writer=A_INT_OBJECT_SCHEMA, @@ -419,8 +402,7 @@ async def test_schemaregistry_schemaregistry_extra_field_with_closed_model_is_in ) -async def test_schemaregistry_schemaregistry_missing_required_field_is_incompatible( - registry_async_client: Client) -> None: +async def test_schemaregistry_schemaregistry_missing_required_field_is_incompatible(registry_async_client: Client) -> None: await not_schemas_are_backward_compatible( reader=A_INT_B_INT_REQUIRED_OBJECT_SCHEMA, writer=A_INT_OBJECT_SCHEMA, @@ -488,12 +470,12 @@ async def test_schemaregistry_giving_a_default_value_for_a_non_required_field_is ) -#async def test_schemaregistry_boolean_schemas_are_backward_compatible(registry_async_client: Client) -> None: - # await not_schemas_are_backward_compatible( - # reader=FALSE_SCHEMA, - # writer=TRUE_SCHEMA, - # client=registry_async_client, - # ) +# async def test_schemaregistry_boolean_schemas_are_backward_compatible(registry_async_client: Client) -> None: +# await not_schemas_are_backward_compatible( +# reader=FALSE_SCHEMA, +# writer=TRUE_SCHEMA, +# client=registry_async_client, +# ) # await schemas_are_backward_compatible( # reader=TRUE_SCHEMA, # writer=FALSE_SCHEMA, @@ -726,7 +708,6 @@ async def test_schemaregistry_type_mismatch_incompabilities(registry_async_clien ) - async def test_schemaregistry_schema_restrict_attributes_is_incompatible(registry_async_client: Client) -> None: await not_schemas_are_backward_compatible( writer=STRING_SCHEMA,