From d1d4ca53cd905af2a8ad084b3abe4a458600c355 Mon Sep 17 00:00:00 2001 From: Duncan Dewhurst Date: Thu, 6 Jul 2023 12:46:52 +1200 Subject: [PATCH 1/3] Add support for $defs keyword --- docs/changelog.rst | 14 ++++++++++++++ jscc/schema.py | 4 ++-- jscc/testing/checks.py | 10 +++++----- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index fab7914..a58e17b 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,6 +1,20 @@ Changelog ========= +0.2.3 (2023-07-06) +------------------ + +Changed +~~~~~~~ + +- Add support for `$defs` keyword in: + - :meth:`~jscc.testing.checks.validate_letter_case` + - :meth:`~jscc.testing.checks.validate_metadata_presence` + - :meth:`~jscc.testing.checks.validate_null_types` + - :meth:`~jscc.testing.checks.validate_deep_properties` + - :meth:`~jscc.schema.is_json_schema` + - :meth:`~jscc.schema.is_json_merge_patch` + 0.2.2 (2023-06-14) ------------------ diff --git a/jscc/schema.py b/jscc/schema.py index 8f3824f..94eab5c 100644 --- a/jscc/schema.py +++ b/jscc/schema.py @@ -26,7 +26,7 @@ def is_json_schema(data): :returns: whether the JSON data is a JSON Schema :rtype: bool """ - return '$schema' in data or 'definitions' in data or 'properties' in data + return '$schema' in data or 'definitions' in data or '$defs' in data or 'properties' in data def is_json_merge_patch(data): @@ -35,7 +35,7 @@ def is_json_merge_patch(data): :returns: whether the JSON data is a JSON Merge Patch :rtype: bool """ - return '$schema' not in data and ('definitions' in data or 'properties' in data) + return '$schema' not in data and ('definitions' in data or '$defs' in data or 'properties' in data) def is_array_of_objects(field): diff --git a/jscc/testing/checks.py b/jscc/testing/checks.py index 8bdc9d2..95209d6 100644 --- a/jscc/testing/checks.py +++ b/jscc/testing/checks.py @@ -252,7 +252,7 @@ def block(path, data, pointer): if not re.search(r'^[a-z][A-Za-z]+$', key) and key not in property_exceptions: errors += 1 warn(f"{path}: {pointer}/{key} field isn't lowerCamelCase ASCII letters", LetterCaseWarning) - elif parent == 'definitions': + elif parent in ['definitions', '$defs']: for key in data.keys(): if not re.search(r'^[A-Z][A-Za-z]+$', key) and key not in definition_exceptions: errors += 1 @@ -276,7 +276,7 @@ def validate_metadata_presence(*args, allow_missing=_false): :returns: the number of errors :rtype: int """ # noqa: E501 - schema_fields = {'definitions', 'deprecated', 'items', 'patternProperties', 'properties'} + schema_fields = {'definitions', '$defs', 'deprecated', 'items', 'patternProperties', 'properties'} schema_sections = {'patternProperties'} required_properties = {'title', 'description'} @@ -363,7 +363,7 @@ def validate_null_type(path, data, pointer='', no_null=False, expect_null=True, required = data.get('required', []) for key, value in data.items(): - if key in ('properties', 'definitions'): + if key in ('properties', 'definitions', '$defs'): for k, v in data[key].items(): expect_null = key == 'properties' and k not in required errors += validate_null_type(path, v, pointer=f'{pointer}/{key}/{k}', **kwargs, no_null=no_null, @@ -528,7 +528,7 @@ def validate_deep_properties(*args, allow_deep=()): """ Warns and returns the number of errors relating to deep objects. - The schema must use "definitions" instead of nesting "properties". + The schema must use "definitions" or "$defs" instead of nesting "properties". :param allow_deep: JSON Pointers of fields to ignore :type allow_deep: list, tuple or set @@ -544,7 +544,7 @@ def block(path, data, pointer): else: grandparent = None - if pointer and grandparent != 'definitions' and 'properties' in data and pointer not in allow_deep: + if pointer and grandparent not in ['definitions', '$defs'] and 'properties' in data and pointer not in allow_deep: errors += 1 warn(f'{path} has "properties" within "properties" at {pointer}', DeepPropertiesWarning) From e7b3e1f0b6563997e57ebfebe51c56145754703c Mon Sep 17 00:00:00 2001 From: Duncan Dewhurst Date: Thu, 6 Jul 2023 12:57:07 +1200 Subject: [PATCH 2/3] jscc/testing/checks.py: Fix lint error --- jscc/testing/checks.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/jscc/testing/checks.py b/jscc/testing/checks.py index 95209d6..c2f68ef 100644 --- a/jscc/testing/checks.py +++ b/jscc/testing/checks.py @@ -544,7 +544,12 @@ def block(path, data, pointer): else: grandparent = None - if pointer and grandparent not in ['definitions', '$defs'] and 'properties' in data and pointer not in allow_deep: + if ( + pointer and + grandparent not in ['definitions', '$defs'] and + 'properties' in data and + pointer not in allow_deep + ): errors += 1 warn(f'{path} has "properties" within "properties" at {pointer}', DeepPropertiesWarning) From 55714689fe56796410609d0eb56b620b425d42cc Mon Sep 17 00:00:00 2001 From: James McKinney <26463+jpmckinney@users.noreply.github.com> Date: Thu, 6 Jul 2023 11:31:49 -0400 Subject: [PATCH 3/3] chore(style): Use tuples instead of lists in conditions --- docs/changelog.rst | 13 +++++++------ jscc/testing/checks.py | 12 ++++++------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index a58e17b..8671753 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -8,12 +8,13 @@ Changed ~~~~~~~ - Add support for `$defs` keyword in: - - :meth:`~jscc.testing.checks.validate_letter_case` - - :meth:`~jscc.testing.checks.validate_metadata_presence` - - :meth:`~jscc.testing.checks.validate_null_types` - - :meth:`~jscc.testing.checks.validate_deep_properties` - - :meth:`~jscc.schema.is_json_schema` - - :meth:`~jscc.schema.is_json_merge_patch` + + - :meth:`jscc.testing.checks.validate_letter_case` + - :meth:`jscc.testing.checks.validate_metadata_presence` + - :meth:`jscc.testing.checks.validate_null_types` + - :meth:`jscc.testing.checks.validate_deep_properties` + - :meth:`jscc.schema.is_json_schema` + - :meth:`jscc.schema.is_json_merge_patch` 0.2.2 (2023-06-14) ------------------ diff --git a/jscc/testing/checks.py b/jscc/testing/checks.py index c2f68ef..3a5048f 100644 --- a/jscc/testing/checks.py +++ b/jscc/testing/checks.py @@ -252,7 +252,7 @@ def block(path, data, pointer): if not re.search(r'^[a-z][A-Za-z]+$', key) and key not in property_exceptions: errors += 1 warn(f"{path}: {pointer}/{key} field isn't lowerCamelCase ASCII letters", LetterCaseWarning) - elif parent in ['definitions', '$defs']: + elif parent in ('definitions', '$defs'): for key in data.keys(): if not re.search(r'^[A-Z][A-Za-z]+$', key) and key not in definition_exceptions: errors += 1 @@ -545,11 +545,11 @@ def block(path, data, pointer): grandparent = None if ( - pointer and - grandparent not in ['definitions', '$defs'] and - 'properties' in data and - pointer not in allow_deep - ): + pointer + and grandparent not in ('definitions', '$defs') + and 'properties' in data + and pointer not in allow_deep + ): errors += 1 warn(f'{path} has "properties" within "properties" at {pointer}', DeepPropertiesWarning)