jsonify does not support integer keys
theiosif opened this issue · 1 comments
theiosif commented
The snippets below are self-descriptive and reflect the problem mentioned in the title.
Expected behavior: jsonify builds a response irrespective of the key/value data types (at least for basic types like int and str)
Actual behavior: keys of type int
break jsonify
Personal suggestion: just typecast to str, but issue a warning
Minimal code to reproduce the issue:
from flask import Flask, jsonify
import json
d={32: "aa", "something":"else"}
print(json.dumps(d)) # works # <-------
app = Flask('app')
# app.config['JSON_SORT_KEYS'] = False #<-- makes no difference
with app.app_context():
print(jsonify(d)) # b0rks # <-------
Error log:
TypeError Traceback (most recent call last)
<ipython-input-12-d8fbf48063d9> in <module>
1 with app.app_context():
----> 2 jsonify(d)
3
~/.local/lib/python3.10/site-packages/flask/json/__init__.py in jsonify(*args, **kwargs)
168 .. versionadded:: 0.2
169 """
--> 170 return current_app.json.response(*args, **kwargs)
~/.local/lib/python3.10/site-packages/flask/json/provider.py in response(self, *args, **kwargs)
213
214 return self._app.response_class(
--> 215 f"{self.dumps(obj, **dump_args)}\n", mimetype=self.mimetype
216 )
~/.local/lib/python3.10/site-packages/flask/json/provider.py in dumps(self, obj, **kwargs)
178 kwargs.setdefault("ensure_ascii", self.ensure_ascii)
179 kwargs.setdefault("sort_keys", self.sort_keys)
--> 180 return json.dumps(obj, **kwargs)
181
182 def loads(self, s: str | bytes, **kwargs: t.Any) -> t.Any:
/usr/lib/python3.10/json/__init__.py in dumps(obj, skipkeys, ensure_ascii, check_circular, allow_nan, cls, indent, separators, default, sort_keys, **kw)
236 check_circular=check_circular, allow_nan=allow_nan, indent=indent,
237 separators=separators, default=default, sort_keys=sort_keys,
--> 238 **kw).encode(obj)
239
240
/usr/lib/python3.10/json/encoder.py in encode(self, o)
197 # exceptions aren't as detailed. The list call should be roughly
198 # equivalent to the PySequence_Fast that ''.join() would do.
--> 199 chunks = self.iterencode(o, _one_shot=True)
200 if not isinstance(chunks, (list, tuple)):
201 chunks = list(chunks)
/usr/lib/python3.10/json/encoder.py in iterencode(self, o, _one_shot)
255 self.key_separator, self.item_separator, self.sort_keys,
256 self.skipkeys, _one_shot)
--> 257 return _iterencode(o, 0)
258
259 def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
TypeError: '<' not supported between instances of 'str' and 'int'
- Python version: Python 3.10.12
- Flask version: Flask 2.3.3
- Werkzeug 2.3.7
davidism commented
If you have data that is not serializable to JSON, you'll need to process that data first. Libraries like Marshmallow, attrs/cattrs, Pydantic, and others, are available that can do that.