Почему oneOf не работает на моей схеме в jsonschema? - PullRequest
0 голосов
/ 18 марта 2020

Мой логин имеет разные полезные данные, один из которых:

{
   "username": "",
   "pass": ""
}

И один из других:

{
  "username": "",
  "pass": "",
  "facebook": true
}

И последний:

{
  "username": "",
  "pass": "",
  "google": true
}

Мой схема выглядит следующим образом:

login_schema = {
    "title": "UserLogin",
    "description": "User login with facebook, google or regular login.",
    "type": "object",
    "properties": {
        "username": {
            "type": "string"
        },
        "pass": {
            "type": "string"
        },
        "facebook": {
            "type": "string"
        },
        "google": {
            "type": "string"
        }
    },
    "oneOf": [
        {
            "required": [
                "username",
                "pass"
            ],
            "additionalProperties": False,
        },
        {
            "required": [
                "username",
                "pass"
                "google"
            ]
        },
        {
            "required": [
                "username",
                "pass",
                "facebook"
            ]
        }
    ],
    "minProperties": 2,
    "additionalProperties": False,
}

В приведенном ниже примере должна выдаваться ошибка:

{
  "username": "",
  "pass": "",
  "google": "",
  "facebook": ""
}

Но она успешно проверяет схему! Что я сделал неправильно в приведенной выше схеме?

РЕДАКТИРОВАТЬ-1:

pip3 show jsonschema
Name: jsonschema
Version: 3.0.2
Summary: An implementation of JSON Schema validation for Python
Home-page: https://github.com/Julian/jsonschema
Author: Julian Berman
Author-email: Julian@GrayVines.com
License: UNKNOWN
Location: /usr/local/lib/python3.7/site-packages
Requires: setuptools, six, attrs, pyrsistent

РЕДАКТИРОВАТЬ-2:

Что я получаю как ошибку:

jsonschema.exceptions.ValidationError: {'username': '', 'pass': '', 'google': '12'} is valid under each of {'required': ['username', 'pass', 'google']}, {'required': ['username', 'pass']}

Демо-версия ошибки: https://jsonschema.dev/s/mXg5X

1 Ответ

0 голосов
/ 23 марта 2020

Ваше решение действительно близко. Вам просто нужно изменить /oneOf/0 на

{
  "properties": {
    "username": true,
    "pass": true
  },
  "required": ["username", "pass"],
  "additionalProperties": false
}

Проблема в том, что additionalProperties не учитывает ключевое слово required при определении того, какие свойства считаются «дополнительными». Он считает только properties и patternProperties. Когда просто используется required, additionalProperties считает все свойства «дополнительными», и единственное допустимое значение - {}.

Однако я предлагаю другой подход. Ключевое слово dependencies полезно в таких ситуациях.

{
  "type": "object",
  "properties": {
    "username": { "type": "string" },
    "pass": { "type": "string" },
    "facebook": { "type": "boolean" },
    "google": { "type": "boolean" }
  },
  "required": ["username", "pass"],
  "dependencies": {
    "facebook": { "not": { "required": ["google"] } },
    "google": { "not": { "required": ["facebook"] } }
  },
  "additionalProperties": false
}
...