Azure / msrest-for-python

The runtime library "msrest" for AutoRest generated Python clients.
MIT License
41 stars 64 forks source link

Model validation doesn't check enum values #203

Open bmc-msft opened 4 years ago

bmc-msft commented 4 years ago

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.

lmazuel commented 4 years ago

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.

bmc-msft commented 4 years ago

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 commented 4 years ago

That code generates the error:

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