marshmallow-code / marshmallow-code/marshmallow
Can't json encode some validation errors, "unorderable types: str() < int()"
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 7.2k
- Forks
- 738
- Avg merge
- 1d 23h
- Merged PRs (30d)
- 7
Description
I'm using marshmallow with flask, which has a jsonify() function that sorts keys, and i'm using that to return the validation errors to the client. In some situations, the dicts with validation errors returned by marshmallow combine int and str keys, which results in a TypeError while attempting to serialize them.
Here's a somewhat minimized test case:
``` python
import json
import marshmallow as ma
class RoleSchema(ma.Schema):
name = ma.fields.Str()
class UserSchema(ma.Schema):
roles = ma.fields.Nested(RoleSchema, many=True)
user, errors = UserSchema().load({'roles':['name']})
print(errors)
print(json.dumps(errors))
print(json.dumps(errors, sort_keys=True))
```
Output:
```
{'roles': {0: {}, '_schema': ['Invalid input type.']}}
{"roles": {"0": {}, "_schema": ["Invalid input type."]}}
Traceback (most recent call last):
File "asd.py", line 13, in
print(json.dumps(errors, sort_keys=True))
File "/usr/lib64/python3.5/json/__init__.py", line 237, in dumps
**kw).encode(obj)
File "/usr/lib64/python3.5/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/lib64/python3.5/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
TypeError: unorderable types: str() < int()
```
I think the relevant function is `ErrorStore.get_errors(index=0)`
https://github.com/marshmallow-code/marshmallow/blob/2.9.0/marshmallow/marshalling.py#L46
Stringifying the indexes in that function fixes it for me. Not sure if this is the best way to fix it though.
``` diff
--- a/marshalling.py
+++ b/marshalling.py
@@ -45,6 +45,7 @@
def get_errors(self, index=None):
if index is not None:
+ index = str(index)
errors = self.errors.get(index, {})
self.errors[index] = errors
else:
```
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the minimized Python example and inspect ErrorStore.get_errors(index=0) in marshmallow/marshalling.py, the entry point identified in the issue. Reproduce the failure with json.dumps(errors, sort_keys=True), then determine and test the intended representation of indexed validation errors so mixed int and str keys no longer break sorted JSON encoding.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100