Mpf object not serializable, despite it not being an mpf object

Warning: This may be more of a Python question than a bokeh one?

I am creating a complex plot with multiple data sources created from DataFrames and dictionaries, using bokeh server. At runtime, I get the following error:

 message: Message 'PULL-DOC-REQ' content: {}
 error: TypeError("Object of type 'mpf' is not JSON serializable",)
Traceback (most recent call last):
  File "/home/agilly/.local/lib/python3.6/site-packages/bokeh/server/protocol_handler.py", line 90, in handle
    work = await handler(message, connection)
  File "/home/agilly/.local/lib/python3.6/site-packages/bokeh/server/session.py", line 67, in _needs_document_lock_wrapper
    result = func(self, *args, **kwargs)
  File "/home/agilly/.local/lib/python3.6/site-packages/bokeh/server/session.py", line 232, in _handle_pull
    return connection.protocol.create('PULL-DOC-REPLY', message.header['msgid'], self.document)
  File "/home/agilly/.local/lib/python3.6/site-packages/bokeh/protocol/__init__.py", line 85, in create
    return self._messages[msgtype].create(*args, **kwargs)
  File "/home/agilly/.local/lib/python3.6/site-packages/bokeh/protocol/messages/pull_doc_reply.py", line 74, in create
    content = { 'doc' : document.to_json() }
  File "/home/agilly/.local/lib/python3.6/site-packages/bokeh/document/document.py", line 882, in to_json
    doc_json = self.to_json_string()
  File "/home/agilly/.local/lib/python3.6/site-packages/bokeh/document/document.py", line 911, in to_json_string
    return serialize_json(json, indent=indent)
  File "/home/agilly/.local/lib/python3.6/site-packages/bokeh/core/json_encoder.py", line 166, in serialize_json
    return json.dumps(obj, cls=BokehJSONEncoder, allow_nan=False, indent=indent, separators=separators, sort_keys=True, **kwargs)
  File "/usr/lib/python3.6/json/__init__.py", line 238, in dumps
    **kw).encode(obj)
  File "/usr/lib/python3.6/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python3.6/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/home/agilly/.local/lib/python3.6/site-packages/bokeh/core/json_encoder.py", line 261, in default
    return self.transform_python_types(obj)
  File "/home/agilly/.local/lib/python3.6/site-packages/bokeh/core/json_encoder.py", line 228, in transform_python_types
    return super().default(obj)
  File "/usr/lib/python3.6/json/encoder.py", line 180, in default
    o.__class__.__name__)
TypeError: Object of type 'mpf' is not JSON serializable

I understand that this happens when bokeh encounters a type it doesn’t support for serialization in one of the data sources. However, the only place where I use mpf from the mpmath library is here:

sp["logp"]=[-1*float(str(log10(mpf(x)))) for x in sp["P-value"]]

The logp column gets used later on:

cohdat[i]=dict(logsp=sp.logp, ...)
source = ColumnDataSource(cohdat[0])
p1=figure(x_range=[start, end], tools="box_zoom,lasso_select,tap,xwheel_zoom,reset,save", y_range=[-0.5, maxlogp+0.5], width=1500)
mainplot_points=p1.circle(y='logsp', ..., source=source)

However, given the type conversion, I am completely puzzled as to where the mpf type is coming from at the bokeh stage. The column should not retain the mpf type since it goes through float(str()). The code was np.float() before, I added an extra string conversion to be sure to strip the type for good but it still doesn’t seem to work. Am I missing something?

Please provide a minimal reproducible example.

Found it. It had indeed nothing to do with bokeh. I had a log10 somewhere in the code, and it was overloaded by a mpmath method:

from mpmath import *
from numpy import log10, append, nan
type(-1*log10(0.001))

returns:

numpy.float64

whereas:

from numpy import log10, append, nan
from mpmath import *
type(-1*log10(0.001))

returns

mpmath.ctx_mp_python.mpf

which, indeed, is not serializable.

Ah, right. That’s exactly why import * is not recommended in the first place. :slight_smile: