Deepwalker / trafaret

Ultimate transformation library that supports validation, contexts and aiohttp.
http://trafaret.readthedocs.org/en/latest/
BSD 2-Clause "Simplified" License
177 stars 31 forks source link

`construct(dict)` doesn't convert types #99

Closed imbolc closed 4 years ago

imbolc commented 4 years ago

I'm not sure if it's the intended behavior, but in 0.12 it worked without wrapping into t.Dict:

>>> rule, raw = {"foo": int}, {"foo": "1"}
>>> construct(rule)(raw)
{'foo': '1'}
>>> construct(t.Dict(rule))(raw)
{'foo': 1}
Deepwalker commented 4 years ago

The problem is that construct uses t.Int and not t.ToInt. We changed this in 2.0 that Int will not convert '1' to 1, only ToInt will. And t.Dict(rule) does not need construct call, because construct will just return this t.Dict instance.

>>> c.construct({"foo": int})
<Dict(<Key "foo" <Int>>)>
>>> rule, raw = {"foo": int}, {"foo": "1"}
>>> t.Dict(rule)
<Dict(<Key "foo" <Call(<lambda>)>>)>

I'm not sure if we need change construct behaviour about int, what do you think? since trafaret more about transformation then validation it makes sense to use ToInt here.

imbolc commented 4 years ago

Ah, what I'm trying to do is to replicate the old behavior of construct. It did two things: raise t.DataError and converted value types. The new one raises t.DataError too, but it doesn't convert types. t.Dict converts types, but rises only ValueError. So, for some reason, I assumed I should wrap t.Dict into construct. Anyway, it doesn't actually work, it still raises ValueError, t.Dict().check does the same.

I am personally completely ok with the new syntax. The only question I have now is how to properly check for error with types conversion. Should I sequentially call construct and then, if there are no errors, convert the values with t.Dict? It doesn't feel quite right :)

Deepwalker commented 4 years ago

2.0.2 has fixed behaviour

imbolc commented 4 years ago

It works, thank you :)