Python not decoding JSON because "encoding" is an unexpected argument

Viewed 4981

I have a Django 2.2.23 app, running on Python 3.9.4. I have django-extensions 2.2.9.

I have a model that has a django_extensions.db.fields.json.JSONField attribute (which, AFAIK, is just a text field auto-serialized). I mention this because when the JSON is deserialized, the django-extensions library does it like this:

def loads(txt):
    value = json.loads(
        txt,
        encoding=settings.DEFAULT_CHARSET
    )
    return value

The problem is that the library imported by import json gives me an error when it's called this way:

Python 3.9.4 (default, Apr  5 2021, 01:50:46)
[Clang 12.0.0 (clang-1200.0.32.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import json
>>> json.loads("{}", encoding="UTF-8")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/Cellar/python@3.9/3.9.4/Frameworks/Python.framework/Versions/3.9/lib/python3.9/json/__init__.py", line 359, in loads
    return cls(**kw).decode(s)
TypeError: __init__() got an unexpected keyword argument 'encoding'
>>>

The end result is that I am unable to load any of the records that contain a JSONField from the database because the JSONDecoder can't handle being passed an encoding argument.

I was under the impression that Python's json library was simplejson. But looking at the source for that, it does handle encoding. But if I look at the json library in "/usr/local/Cellar/python@3.9/3.9.4/Frameworks/Python.framework/Versions/3.9/lib/python3.9/json/init.py" (as specified in the error above), this decoder definitely does not.

This is clearly incorrect behavior, but I don't know what I need to upgrade in order to get the right thing to happen.

2 Answers

You are seeing this error because the argument encoding was removed from json.loads in Python 3.9 (it was deprecated since Python 3.1).

django-extensions 2.2.9, the version you are using, was released in March 2020, Python 3.9 was released in October 2020.

This particular issue should be fixed in django-extensions 3.0, but Python 3.9 was only added to the test suite in django-extensions 3.1.1, so I'd suggest updating to the latest version.

Since the encoding argument is deprecated you can try doing :

def loads(txt):
    txt = txt.encode("utf-8")
    value = json.loads(txt)

    return value
Related