classification
Title: Subclasses of JSONEncoder should not be insturcted to call JSONEncoder.decode
Type: enhancement Stage: resolved
Components: Documentation Versions: Python 3.2, Python 3.3, Python 3.4, Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: docs@python Nosy List: Justin.Lebar, docs@python, ezio.melotti, kushal.das, petri.lehtinen, python-dev, r.david.murray
Priority: normal Keywords: needs review, patch

Created on 2012-09-26 21:40 by Justin.Lebar, last changed 2013-03-18 02:40 by r.david.murray. This issue is now closed.

Files
File name Uploaded Description Edit
explicit_json_doc_update_for_encoder_default.patch kushal.das, 2012-10-04 05:42 Patch to update docstring and documentation with explicit saying that calling JSONEncoder.default raises a TypeError review
Messages (8)
msg171363 - (view) Author: Justin Lebar (Justin.Lebar) Date: 2012-09-26 21:40
The JSONEncoder documentation says we can implement our own encoder as:

  >>> class ComplexEncoder(json.JSONEncoder):
  ...     def default(self, obj):
  ...         if isinstance(obj, complex):
  ...             return [obj.real, obj.imag]
  ...         return json.JSONEncoder.default(self, obj)

Later on, we give the following example of how to implement the default method in a subclass of json.JSONEncoder:

  def default(self, o):
  try:
      iterable = iter(o)
  except TypeError:
      pass
  else:
      return list(iterable)
  return JSONEncoder.default(self, o)

These are both incorrect, as a quick reading of the source will reveal.  JSONEncoder.default() throws for all input values.  We should s/JSONEncoder.default/JSONEncoder.encode/ here, I think.
msg171518 - (view) Author: Kushal Das (kushal.das) * (Python committer) Date: 2012-09-28 18:36
The implementation clearly says that default method should return a serializable object or calls the base implementation to raise TypeError. So I don't think any of the examples is a bug.
msg171541 - (view) Author: Justin Lebar (Justin.Lebar) Date: 2012-09-28 20:23
Ah, I see.  The examples do what you think they should do, but not for the reason you think they should do it -- the JSON encoding logic calls the encoder's encode() method before calling its default() method.

I still think the examples could be improved, perhaps by adding a comment to the effect of 

  # Raises a TypeError.

before the call to JSONEncoder.default().  Explicit is better than implicit, after all.  :)

Thanks for looking at this.
msg171542 - (view) Author: Kushal Das (kushal.das) * (Python committer) Date: 2012-09-28 20:29
Ok, I will submit a patch.
msg171920 - (view) Author: Kushal Das (kushal.das) * (Python committer) Date: 2012-10-04 05:42
Patch to update docstring and documentation with explicit saying that calling JSONEncoder.default raises a TypeError
msg171921 - (view) Author: Kushal Das (kushal.das) * (Python committer) Date: 2012-10-04 05:43
The previous patch should be back committed to all 3.x and 2.7 branch.
msg184413 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2013-03-18 02:06
New changeset 5d56e1214e95 by R David Murray in branch '3.2':
#16057: Clarify why the base method default is called in custom encoders.
http://hg.python.org/cpython/rev/5d56e1214e95

New changeset 5f76e7db97ac by R David Murray in branch '3.3':
Merge #16057: Clarify why the base method default is called in custom encoders.
http://hg.python.org/cpython/rev/5f76e7db97ac

New changeset 406c6fd7e753 by R David Murray in branch 'default':
Merge #16057: Clarify why the base method default is called in custom encoders.
http://hg.python.org/cpython/rev/406c6fd7e753

New changeset ef8ea052bcc4 by R David Murray in branch '2.7':
#16057: Clarify why the base method default is called in custom encoders.
http://hg.python.org/cpython/rev/ef8ea052bcc4
msg184414 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2013-03-18 02:40
Thanks Kushal.
History
Date User Action Args
2013-03-18 02:40:12r.david.murraysetstatus: open -> closed

nosy: + r.david.murray
messages: + msg184414

resolution: fixed
stage: patch review -> resolved
2013-03-18 02:06:40python-devsetnosy: + python-dev
messages: + msg184413
2013-03-16 01:27:37eric.araujosetkeywords: + needs review
stage: needs patch -> patch review
versions: + Python 3.2, Python 3.3, Python 3.4
2012-10-04 05:43:31kushal.dassetmessages: + msg171921
2012-10-04 05:42:11kushal.dassetfiles: + explicit_json_doc_update_for_encoder_default.patch
keywords: + patch
messages: + msg171920
2012-09-28 20:29:57kushal.dassetmessages: + msg171542
2012-09-28 20:23:01Justin.Lebarsetmessages: + msg171541
2012-09-28 18:36:03kushal.dassetnosy: + kushal.das
messages: + msg171518
2012-09-27 18:57:21ezio.melottisetnosy: + ezio.melotti, petri.lehtinen

type: enhancement
stage: needs patch
2012-09-26 21:40:42Justin.Lebarcreate