JSONEncoder not handling lists
<p>I have a deeply nested data structure with extensive lists.  I want to count the lists instead of displaying all the contents.</p>

<pre><code>class SummaryJSONEncoder(json.JSONEncoder):
    """
    Simple extension to JSON encoder to handle date or datetime objects
    """
    def default(self, obj):
        func = inspect.currentframe().f_code
        logger.info("%s in %s:%i" % ( 
            func.co_name, 
            func.co_filename, 
            func.co_firstlineno
        ))
        logger.info('default %s', type(obj))
        if isinstance(obj, (datetime.datetime, datetime.date,)):
            return obj.isoformat()
        if isinstance(obj, (list, tuple, set,)):
            return "count(%s)" % len(obj)
        else:
            logger.info('Falling back for %s', type(obj))
            return super(SummaryJSONEncoder, self).default(obj)
    def encode(self, obj):
        func = inspect.currentframe().f_code
        logger.info("%s in %s:%i" % ( 
            func.co_name, 
            func.co_filename, 
            func.co_firstlineno
        ))
        return super(SummaryJSONEncoder, self).encode(obj)
</code></pre>

<p>The sets seem to encode properly, but lists and tuples will not bend to my will.</p>

<pre><code> &gt;&gt;&gt; json.dumps({'hello': set([]), 'world': [1,2,3], 'snot': (1,2,3,), 'time': datetime.datetime.now()}, indent=4, cls=SummaryJSONEncoder)
2016-10-05 14:07:42,786 (9296) __main__ INFO - encode in &lt;pyshell#56&gt;:20
2016-10-05 14:07:42,789 (9296) __main__ INFO - default in &lt;pyshell#56&gt;:5
2016-10-05 14:07:42,792 (9296) __main__ INFO - default &lt;type 'set'&gt;
2016-10-05 14:07:42,793 (9296) __main__ INFO - default in &lt;pyshell#56&gt;:5
2016-10-05 14:07:42,796 (9296) __main__ INFO - default &lt;type 'datetime.datetime'&gt;
'{\n    "world": [\n        1, \n        2, \n        3\n    ], \n    "hello": "count(0)", \n    "snot": [\n        1, \n        2, \n        3\n    ], \n    "time": "2016-10-05T14:07:42.786000"\n}'
&gt;&gt;&gt;
</code></pre>

<p>I cannot tell, but it looks like lists and tuples are handled elsewhere and not passed to the default method.  Has anyone needed to do this before?</p>

<p>This seems to work</p>

<pre><code>class SummaryJSONEncoder(json.JSONEncoder):
"""
Simple extension to JSON encoder to handle date or datetime objects
"""
def default(self, obj):
    if isinstance(obj, (datetime.datetime, datetime.date,)):
        return obj.isoformat()
    if isinstance(obj, (list, tuple, set,)):
        return "count(%s)" % len(obj)
    else:
        return super(SummaryJSONEncoder, self).default(obj)
def _iterencode_list(self, obj, x):
    if isinstance(obj, (list, tuple, set,)):
        return self.default(obj)
    return super(SummaryJSONEncoder, self)._iterencode_list(obj, x)
</code></pre>

<p>The code trace is.</p>

<pre><code>json.dumps({'hello': set([]), 'world': [1,2,3], 'snot': (1,2,3,), 'time': datetime.datetime.now()}, indent=4, cls=SummaryJSONEncoder)
2016-10-05 14:50:10,785 (9296) __main__ INFO - default in &lt;pyshell#73&gt;:5
2016-10-05 14:50:10,788 (9296) __main__ INFO - default &lt;type 'list'&gt;
2016-10-05 14:50:10,792 (9296) __main__ INFO - default in &lt;pyshell#73&gt;:5
2016-10-05 14:50:10,796 (9296) __main__ INFO - default &lt;type 'set'&gt;
2016-10-05 14:50:10,799 (9296) __main__ INFO - default in &lt;pyshell#73&gt;:5
2016-10-05 14:50:10,802 (9296) __main__ INFO - default &lt;type 'tuple'&gt;
2016-10-05 14:50:10,806 (9296) __main__ INFO - default in &lt;pyshell#73&gt;:5
2016-10-05 14:50:10,811 (9296) __main__ INFO - default &lt;type 'datetime.datetime'&gt;
'{\n    "world": count(3), \n    "hello": "count(0)", \n    "snot": count(3), \n    "time": "2016-10-05T14:50:10.785000"\n}'
</code></pre>

<p>I hope this helps someone :-)</p>

python json list set encode