Repository: holoviz/holoviews

Issue:
Can't mix pn.bind with streams in DynamicMaps anymore
HoloViews 1.18.1
Param 2.0.1
Panel 1.3.4

#### Description of expected behavior and the observed behavior
I used to be able to wrap a `pn.bind` within a DynamicMap and add a `streams` argument like the following:
`dmap = hv.DynamicMap(pn.bind(function, arg=some_widget), streams=[some_stream])`

This is useful for plots driven both by widgets and streams.

But now this causes an error where expected inputs are missing, maybe related to the new Param version.

#### MRE

In a panel server

```python
import holoviews as hv
import panel as pn

pn.extension()


def make_plot(z, x_range, y_range):
    print(z)
    print(x_range, y_range)
    return hv.Curve([1, 2, 3, 4])


slider = pn.widgets.IntSlider(name='Slider', start=0, end=10)
range_xy = hv.streams.RangeXY()
dmap = hv.DynamicMap(pn.bind(make_plot, z=slider), streams=[range_xy])

pn.Column(slider, dmap).servable()
```

#### Stack traceback and/or browser JavaScript console output
```python
return eval_fn()(*combined_args, **combined_kwargs) Traceback (most recent call last):
  File "/home/mathurin/miniconda3/envs/hv/lib/python3.12/site-packages/bokeh/application/handlers/code_runner.py", line 229, in run
    exec(self._code, module.__dict__)
  File "/home/mathurin/PycharmProjects/test/toast.py", line 18, in <module>
    pn.Column(slider, dmap).servable()
  File "/home/mathurin/miniconda3/envs/hv/lib/python3.12/site-packages/panel/viewable.py", line 394, in servable
    self.server_doc(title=title, location=location) # type: ignore
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mathurin/miniconda3/envs/hv/lib/python3.12/site-packages/panel/viewable.py", line 1023, in server_doc
    model = self.get_root(doc)
            ^^^^^^^^^^^^^^^^^^
  File "/home/mathurin/miniconda3/envs/hv/lib/python3.12/site-packages/panel/layout/base.py", line 309, in get_root
    root = super().get_root(doc, comm, preprocess)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mathurin/miniconda3/envs/hv/lib/python3.12/site-packages/panel/viewable.py", line 670, in get_root
    root = self._get_model(doc, comm=comm)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mathurin/miniconda3/envs/hv/lib/python3.12/site-packages/panel/layout/base.py", line 177, in _get_model
    objects, _ = self._get_objects(model, [], doc, root, comm)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mathurin/miniconda3/envs/hv/lib/python3.12/site-packages/panel/layout/base.py", line 159, in _get_objects
    child = pane._get_model(doc, root, model, comm)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mathurin/miniconda3/envs/hv/lib/python3.12/site-packages/panel/pane/holoviews.py", line 414, in _get_model
    plot = self._render(doc, comm, root)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mathurin/miniconda3/envs/hv/lib/python3.12/site-packages/panel/pane/holoviews.py", line 509, in _render
    return renderer.get_plot(self.object, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mathurin/miniconda3/envs/hv/lib/python3.12/site-packages/holoviews/plotting/bokeh/renderer.py", line 68, in get_plot
    plot = super().get_plot(obj, doc, renderer, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mathurin/miniconda3/envs/hv/lib/python3.12/site-packages/holoviews/plotting/renderer.py", line 217, in get_plot
    initialize_dynamic(obj)
  File "/home/mathurin/miniconda3/envs/hv/lib/python3.12/site-packages/holoviews/plotting/util.py", line 270, in initialize_dynamic
    dmap[dmap._initial_key()]
    ~~~~^^^^^^^^^^^^^^^^^^^^^
  File "/home/mathurin/miniconda3/envs/hv/lib/python3.12/site-packages/holoviews/core/spaces.py", line 1216, in __getitem__
    val = self._execute_callback(*tuple_key)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mathurin/miniconda3/envs/hv/lib/python3.12/site-packages/holoviews/core/spaces.py", line 983, in _execute_callback
    retval = self.callback(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mathurin/miniconda3/envs/hv/lib/python3.12/site-packages/holoviews/core/spaces.py", line 550, in __call__
    return self.callable.rx.value
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mathurin/miniconda3/envs/hv/lib/python3.12/site-packages/param/reactive.py", line 253, in value
    return self._reactive()
           ^^^^^^^^^^^^^^^^
  File "/home/mathurin/miniconda3/envs/hv/lib/python3.12/site-packages/param/depends.py", line 41, in _depends
    return func(*args, **kw)
           ^^^^^^^^^^^^^^^^^
  File "/home/mathurin/miniconda3/envs/hv/lib/python3.12/site-packages/param/reactive.py", line 431, in wrapped
    return eval_fn()(*combined_args, **combined_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: make_plot() missing 2 required positional arguments: 'x_range' and 'y_range'
```


Discussion:
Likely a consequence of the param 2.0 upgrade. As a workaround this should work:

``` python
import holoviews as hv
import panel as pn

pn.extension()


def make_plot(value, x_range, y_range):
    print(value)
    print(x_range, y_range)
    return hv.Curve([1, 2, 3, 4])


slider = pn.widgets.IntSlider(name='Slider', start=0, end=10)
range_xy = hv.streams.RangeXY()
dmap = hv.DynamicMap(make_plot, streams=[slider.param.value, range_xy])

pn.Column(slider, dmap).servable()
```

Resolving patch:
diff --git a/holoviews/core/spaces.py b/holoviews/core/spaces.py
--- a/holoviews/core/spaces.py
+++ b/holoviews/core/spaces.py
@@ -1,7 +1,7 @@
 import itertools
 import types
 from collections import defaultdict
-from contextlib import contextmanager
+from contextlib import contextmanager, suppress
 from functools import partial
 from itertools import groupby
 from numbers import Number
@@ -547,7 +547,10 @@ def __call__(self, *args, **kwargs):
         kwarg_hash = kwargs.pop('_memoization_hash_', ())
         (self.args, self.kwargs) = (args, kwargs)
         if hasattr(self.callable, 'rx'):
-            return self.callable.rx.value
+            with suppress(TypeError):
+                # If param.bind is used and not all arguments are set
+                # it will raise TypeError
+                return self.callable.rx.value
         if not args and not kwargs and not any(kwarg_hash): return self.callable()
         inputs = [i for i in self.inputs if isinstance(i, DynamicMap)]
         streams = []


Test patch:
diff --git a/holoviews/tests/test_streams.py b/holoviews/tests/test_streams.py
--- a/holoviews/tests/test_streams.py
+++ b/holoviews/tests/test_streams.py
@@ -6,8 +6,10 @@
 
 import pandas as pd
 import param
+import pytest
 from panel.widgets import IntSlider
 
+import holoviews as hv
 from holoviews.core.spaces import DynamicMap
 from holoviews.core.util import Version
 from holoviews.element import Curve, Histogram, Points, Polygons, Scatter
@@ -595,6 +597,24 @@ def subscriber_y(**kwargs):
         self.assertEqual(values_y, [{}])
 
 
+@pytest.mark.usefixtures("bokeh_backend")
+def test_dynamicmap_partial_bind_and_streams():
+    # Ref: https://github.com/holoviz/holoviews/issues/6008
+
+    def make_plot(z, x_range, y_range):
+        return Curve([1, 2, 3, 4, z])
+
+    slider = IntSlider(name='Slider', start=0, end=10)
+    range_xy = RangeXY()
+
+    dmap = DynamicMap(param.bind(make_plot, z=slider), streams=[range_xy])
+
+    bk_figure = hv.render(dmap)
+
+    assert bk_figure.renderers[0].data_source.data["y"][-1] == 0
+    assert range_xy.x_range == (0, 4)
+    assert range_xy.y_range == (-0.4, 4.4)
+
 
 class TestSubscribers(ComparisonTestCase):