msrest-for-python icon indicating copy to clipboard operation
msrest-for-python copied to clipboard

Model validation doesn't check enum values

Open bmc-msft opened this issue 5 years ago • 3 comments

Example:

from enum import Enum
from msrest.serialization import Model

class A(Enum):
    b = "b"

class C(Model):
    _attribute_map = {"a": {"key": "a", "type": "A"}}

assert C(a=A.b).validate() == []
assert C(a="d").validate() != []

I would expect validation of the above to fail.

Note, the value is checked when serialized.

>>> C(a='d').serialize()
ValueError: 'd' is not a valid A

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
# ...(trimmed)...
    raise ValueError("%r is not a valid %s" % (value, cls.__name__))
ValueError: 'd' is not a valid A

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
# ...(trimmed)...
    raise SerializationError(error.format(attr, enum_obj))
msrest.exceptions.SerializationError: 'd' is not valid value for enum <enum 'A'>
>>>

Note, if you deserialize an invalid value, something is logged, but there is no way to check it without reserialization.

>>> C.deserialize({'a': 'd'})
Deserializer is not able to find d as valid enum in <enum 'A'>
<__main__.C object at 0x7f8ed9c8ff50>
>>>

I would expect this error to be checkable from validation, not just as a warning during deserialization.

bmc-msft avatar May 14 '20 16:05 bmc-msft

We don't do hard checking of enum nowadays, since RestAPI tends to had values and not checking is making SDK more resistent. For isntance, autorest (our main code generator) generates serialization type as string nowadays (not enum). We don't validate anymore nor on serialization or deserialization.

lmazuel avatar May 16 '20 00:05 lmazuel

Please readdress this. 'validate()' should actually validate the data.

The validation should be enough to know that it's invalid, not generating an error on serialization.

from enum import Enum
from msrest.serialization import Model

class A(Enum):
    b = "b"

class C(Model):
    _attribute_map = {"a": {"key": "a", "type": "A"}}

x = C(a='d')
x.validate()
x.serialize()

bmc-msft avatar Jun 09 '20 17:06 bmc-msft

That code generates the error:

msrest.exceptions.SerializationError: 'd' is not valid value for enum <enum 'A'>

bmc-msft avatar Jun 09 '20 17:06 bmc-msft