﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
33284	JSONFIeld decode error with Python 3.9	Alan D. Snow	nobody	"https://code.djangoproject.com/ticket/31973

Traceback:

{{{
venv/lib/python3.9/site-packages/django/db/models/fields/json.py:83: in from_db_value
    return json.loads(value, cls=self.decoder)

}}}
{{{
    def loads(s, *, cls=None, object_hook=None, parse_float=None,
            parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):
        """"""Deserialize ``s`` (a ``str``, ``bytes`` or ``bytearray`` instance
        containing a JSON document) to a Python object.
    
        ``object_hook`` is an optional function that will be called with the
        result of any object literal decode (a ``dict``). The return value of
        ``object_hook`` will be used instead of the ``dict``. This feature
        can be used to implement custom decoders (e.g. JSON-RPC class hinting).
    
        ``object_pairs_hook`` is an optional function that will be called with the
        result of any object literal decoded with an ordered list of pairs.  The
        return value of ``object_pairs_hook`` will be used instead of the ``dict``.
        This feature can be used to implement custom decoders.  If ``object_hook``
        is also defined, the ``object_pairs_hook`` takes priority.
    
        ``parse_float``, if specified, will be called with the string
        of every JSON float to be decoded. By default this is equivalent to
        float(num_str). This can be used to use another datatype or parser
        for JSON floats (e.g. decimal.Decimal).
    
        ``parse_int``, if specified, will be called with the string
        of every JSON int to be decoded. By default this is equivalent to
        int(num_str). This can be used to use another datatype or parser
        for JSON integers (e.g. float).
    
        ``parse_constant``, if specified, will be called with one of the
        following strings: -Infinity, Infinity, NaN.
        This can be used to raise an exception if invalid JSON numbers
        are encountered.
    
        To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
        kwarg; otherwise ``JSONDecoder`` is used.
        """"""
        if isinstance(s, str):
            if s.startswith('\ufeff'):
                raise JSONDecodeError(""Unexpected UTF-8 BOM (decode using utf-8-sig)"",
                                      s, 0)
        else:
            if not isinstance(s, (bytes, bytearray)):
>               raise TypeError(f'the JSON object must be str, bytes or bytearray, '
                                f'not {s.__class__.__name__}')
E               TypeError: the JSON object must be str, bytes or bytearray, not list

../../miniconda/envs/midas/lib/python3.9/json/__init__.py:339: TypeError
}}}


Suggested fix is to catch `TypeError` as well as `JSONDecodeError` here: https://github.com/django/django/blob/adb4100e58d9ea073ee8caa454bb7c885b6a83ed/django/db/models/fields/json.py#L82-L85

{{{
        try:
            return json.loads(value, cls=self.decoder)
        except (json.JSONDecodeError, TypeError):
            return value
}}}"	Bug	closed	Database layer (models, ORM)	3.2	Normal	needsinfo	python, json		Unreviewed	1	0	0	0	0	0
