☰Read-only archive⌕
Looking for help with Bokeh?

This is a read-only archive. Ask questions and join the conversation on GitHub.

Visit Community Support on GitHub →
Archived discussions · Captured October 28, 2026

DataSource.patch triggering TypeError: 'tuple' object does not support item assignment

Community Support
andrew.waites
andrew.waites

I have working code old older Bokeh/Python versions and am trying to update using Bokeh 2.2.3 and Python 3.8.

When I try to patch a DataSource i get the error:

TypeError: ‘tuple’ object does not support item assignment

Please see sample below…

ceokey = ‘CTX:David Reeves’
print(type(ds))
idx = sectorsource.data[‘ceo’].index(ceokey)

patches = {‘color’ : }
save_colour = sectorsource.data[‘color’][idx]

patches[‘color’].append((idx, ‘#471568’))
print(‘Patches:’,patches[‘color’])

ds.patch(patches)

This trips as follows:…

TypeError Traceback (most recent call last)
in
9 print(‘Patches:’,patches[‘color’])
10
—> 11 ds.patch(patches)

~/opt/anaconda3/lib/python3.8/site-packages/bokeh/models/sources.py in patch(self, patches, setter)
682 raise ValueError(“Invalid patch index: %s” % ind)
683
→ 684 self.data._patch(self.document, self, patches, setter)
685
686 class CDSView(Model):

~/opt/anaconda3/lib/python3.8/site-packages/bokeh/core/property/wrappers.py in _patch(self, doc, source, patches, setter)
461 for ind, value in patch:
462 if isinstance(ind, (int, slice)):
→ 463 self[name][ind] = value
464 else:
465 shape = self[name][ind[0]][tuple(ind[1:])].shape

TypeError: ‘tuple’ object does not support item assignment

Has anyone else seen this?

⌁   Link to post
andrew.waites
andrew.waites

Just for giggles I made the following (very clunky) change to wrapper.py at line 462:

            if isinstance(ind, (int, slice)):
                as_list = list(self[name])
                #self[name][ind] = value
                as_list[ind] = value
                self[name] = tuple(as_list)

which seemed to fix the problem - I appreciate this may a very bad thing but just putting it out there…

⌁   Link to post
Bryan
Bryan

The purpose of patch is to efficiently update without copying. If you want to patch, then your columns must be mutable (i.e. an array or list, not a tuple) If it ever worked with a tuple in the past, that was a bug.

⌁   Link to post
andrew.waites
andrew.waites

Bryan,

The ColumnDataSournce is based ona dictionary of lists…

grp_list = [x for x in df['ceokey'].unique()]
xs = [df.loc[df['ceokey'] == i].Years for i in grp_list]
ys = [df.loc[df['ceokey'] == i].Relative for i in grp_list]
    
source = ColumnDataSource(data=dict(
    x = xs,
    y = ys,
    color = viridis(len(grp_list)),
    ceo = grp_list
    ))

Pretty standard stuff. The tach list is a single tuple (index, value) but that is used to do the patch and complies with the docs - am puzzled why it is now deemed to be updating a tuple rather than a lit item.

⌁   Link to post
andrew.waites
andrew.waites

Bryan

I suspect I upgraded from older version of Bokeh along the way - viridis used to return a list, now returns a tuple.

If I listify the returned tuple before loading into the ColumnDataSource that should be fine.

⌁   Link to post
Bryan
Bryan

@andrew.waites all the palettes were indeed converted to be tuples, in order to be able to discard a bunch of hacky code that mutable palettes had necessitated. I’d say it’s pretty unusual to set a palette as a CDS column value (palettes are usually inputs to colormappers) so listifying is the appropriate solution on he user side in those rare cases.

⌁   Link to post

End of archived discussion · Replies are disabled