Skip to content

Commit a375344

Browse files
committed
fix: Relocate custom-option ids to a contiguous block, not by old-id value
create_custom_trees relocated an object's existing custom-option trees to new ids computed as old_id + offset + 1, where offset is one above the store's current maximum id. When the object already held the store's largest id -- the normal case when re-styling the retained result of a previous .opts() call -- the new id was roughly twice the maximum, so the maximum id doubled on every re-customization and grew exponentially. Ids are opaque keys into Store._custom_options; their absolute value carries no meaning. The relocation only needs new ids disjoint from existing keys and a bijection over the object's own id set. Assigning a fresh contiguous block above the offset (indexed by position) satisfies both and keeps the maximum id linear in the number of live customizations, avoiding the unbounded bignum growth and the Python 3.11 4300-digit integer-to-string ValueError it eventually triggered.
1 parent cb93307 commit a375344

1 file changed

Lines changed: 10 additions & 5 deletions

File tree

holoviews/core/options.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1754,18 +1754,23 @@ def create_custom_trees(cls, obj, options, backend=None):
17541754
}
17551755

17561756
custom_options = Store.custom_options(backend=backend)
1757-
for tree_id in obj_ids:
1757+
# Relocate the object's trees to a fresh contiguous block above the
1758+
# offset. Ids are opaque keys into Store._custom_options; the only
1759+
# requirements are that the new ids are disjoint from existing keys
1760+
# (guaranteed by the offset) and that distinct old ids map to distinct
1761+
# new ids. Indexing by position keeps the maximum id linear in the
1762+
# number of live customizations; deriving it from the old id's value
1763+
# (tree_id + offset + 1) doubles the maximum on every re-customization.
1764+
for new_id, tree_id in enumerate(obj_ids, start=offset):
17581765
if tree_id is not None and tree_id in custom_options:
17591766
original = custom_options[tree_id]
17601767
clone = OptionTree(
17611768
items=original.items(), groups=original.groups, backend=original.backend
17621769
)
1763-
clones[tree_id + offset + 1] = clone
1764-
id_mapping.append((tree_id, tree_id + offset + 1))
17651770
else:
17661771
clone = OptionTree(groups=available_options.groups, backend=backend)
1767-
clones[offset] = clone
1768-
id_mapping.append((tree_id, offset))
1772+
clones[new_id] = clone
1773+
id_mapping.append((tree_id, new_id))
17691774

17701775
# Nodes needed to ensure allowed_keywords is respected
17711776
for obj_type, opts in used_options.items():

0 commit comments

Comments
 (0)