cwacek/python-jsonschema-objects

Improper tuple validation

ahulist opened this issue · 1 comments

Describe the bug
tuple validation on array is not working as expected. ValidationError/TypeError pop up even though they should not.

Example Schema and code
1)

import python_jsonschema_objects as pjs

schema = {
    "title": "Base",
    "type": "object",
    "properties": {
        "name": {
            "additionalItems": False,
            "type": "array",
            "items": [
                {
                    "enum": [
                        "A",
                        "B"
                    ]
                },
                {
                    "type": "string"
                }
            ]
        },
    }
}

builder = pjs.ObjectBuilder(schema)
klasses = builder.build_classes()
a = klasses.Base()
a.name = ['A', 'X']


ValidationError                           Traceback (most recent call last)
<ipython-input-97-7965663f677d> in <module>
----> 1 a.name = ['A', 'X']

~/.conda/envs/py37/lib/python3.7/site-packages/python_jsonschema_objects/classbuilder.py in __setattr__(self, name, val)
    226             # it directly. XXX Heinous.
    227             prop = getattr(self.__class__, self.__prop_names__[name])
--> 228             prop.__set__(self, val)
    229         else:
    230             # This is an additional property of some kind

~/.conda/envs/py37/lib/python3.7/site-packages/python_jsonschema_objects/descriptors.py in __set__(self, obj, val)
     83                 errstr = "\n".join(errors)
     84                 raise validators.ValidationError(
---> 85                     "Object must be one of {0}: \n{1}".format(info["type"], errstr)
     86                 )
     87 

>>> ValidationError: Object must be one of [<class 'python_jsonschema_objects.classbuilder.base/name/<anonymous_0>'>, <class 'python_jsonschema_objects.classbuilder.base/name/<anonymous_1>'>]: 
>>> Failed to coerce to '<class 'python_jsonschema_objects.classbuilder.base/name/<anonymous_0>'>': ['A', 'X'] is not one of ['A', 'B']
>>> Failed to coerce to '<class 'python_jsonschema_objects.classbuilder.base/name/<anonymous_1>'>': ['A', 'X'] is not a string

2)

import python_jsonschema_objects as pjs

s = {
    "title": "Base",
    "type": "object",
    "properties": {
        "name": {
            "additionalItems": False,
            "type": "array",
            "items": [
                {
                    "enum": [
                        "A",
                        "B"
                    ]
                },
                {
                    "type": ["string", "null"]
                }
            ]
        },
    }
}

builder = pjs.ObjectBuilder(s)
klasses = builder.build_classes()
a = klasses.Base()

a.name = ['A', None]


TypeError                                 Traceback (most recent call last)
<ipython-input-95-4295b0f2ae77> in <module>
----> 1 a.name = ['A', None]

~/.conda/envs/py37/lib/python3.7/site-packages/python_jsonschema_objects/classbuilder.py in __setattr__(self, name, val)
    226             # it directly. XXX Heinous.
    227             prop = getattr(self.__class__, self.__prop_names__[name])
--> 228             prop.__set__(self, val)
    229         else:
    230             # This is an additional property of some kind

~/.conda/envs/py37/lib/python3.7/site-packages/python_jsonschema_objects/descriptors.py in __set__(self, obj, val)
     45 
     46             for typ in type_checks:
---> 47                 if isinstance(val, typ):
     48                     ok = True
     49                     break

>>> TypeError: isinstance() arg 2 must be a type or tuple of types

Expected behavior
AFAIK in both cases positional validation should allow array to have two elements:

  1. [either 'A' or 'B', any string]
  2. [either 'A' or 'B', any string or None]

Right now they seem to work more like anyOf (especially #⁠1 where ['A', 'X'] is not one of ['A', 'B']) even though Specs state that:

When this attribute value is an array of schemas and the instance
value is an array, each position in the instance array MUST conform
to the schema in the corresponding position for this array. This
called tuple typing.

Stale issue message