Repository: holoviz/panel

Issue:
GridBox ncols not honored when rendering from a callable
#297 ## ALL software version info
```
In [3]: param.__version__                                                                                                                                                                                                                                                                                                                                               
Out[3]: '1.10.0a2'

In [4]: pn.__version__                                                                                                                                                                                                                                                                                                                                                  
Out[4]: '0.10.0a2'
```

#### Description of expected behavior and the observed behavior
When a `GridBox` is first rendered dynamically (from a callable) then it first renders with only one column. After updating then the `ncols` parameter is respected. 

#### Complete, minimal, self-contained example code that reproduces the issue

```
import random
import param
import panel as pn
pn.extension()

class Test(param.Parameterized):
    ncols = param.Integer(default=6)
    
    @param.depends('ncols')
    def grid(self):
        rcolor = lambda: "#%06x" % random.randint(0, 0xFFFFFF)
        return pn.GridBox(*[pn.pane.HTML(background=rcolor(), width=50, height=50) for i in range(24)], ncols=self.ncols)
    
    def panel(self):
        return pn.Column(
            self.param.ncols,
            self.grid,
        )
t = Test()
t.panel()

```
#### Screenshots or screencasts of the bug in action
![GridBox_ncols](https://user-images.githubusercontent.com/6454472/81433463-35790900-912a-11ea-8271-b2eefb53e2cc.gif)






Discussion:

Resolving patch:
diff --git a/panel/layout/base.py b/panel/layout/base.py
--- a/panel/layout/base.py
+++ b/panel/layout/base.py
@@ -247,7 +247,7 @@ def clone(self, *objects, **params):
                              % type(self).__name__)
         p = dict(self.param.get_param_values(), **params)
         del p['objects']
-        return type(self)(*objects, **params)
+        return type(self)(*objects, **p)
 
     def append(self, obj):
         """


Test patch:
diff --git a/panel/tests/layout/test_base.py b/panel/tests/layout/test_base.py
--- a/panel/tests/layout/test_base.py
+++ b/panel/tests/layout/test_base.py
@@ -402,6 +402,46 @@ def test_layout_clone_kwargs(panel):
     assert clone.sizing_mode == 'stretch_height'
 
 
+@pytest.mark.parametrize('panel', [Column, Row])
+def test_layout_clone_no_args_no_kwargs(panel):
+    div1 = Div()
+    div2 = Div()
+    layout = panel(div1, div2, width=400, sizing_mode='stretch_height')
+    clone = layout.clone()
+
+    assert layout.objects[0].object is clone.objects[0].object
+    assert layout.objects[1].object is clone.objects[1].object
+
+    assert clone.width == 400
+    assert clone.sizing_mode == 'stretch_height'
+
+
+@pytest.mark.parametrize('panel', [Column, Row])
+def test_layout_clone_objects_in_kwargs(panel):
+    div1 = Div()
+    div2 = Div()
+    layout = panel(div1, div2)
+    clone = layout.clone(
+        objects=(div2, div1), 
+        width=400, sizing_mode='stretch_height'
+    )
+
+    assert layout.objects[0].object is clone.objects[1].object
+    assert layout.objects[1].object is clone.objects[0].object
+
+    assert clone.width == 400
+    assert clone.sizing_mode == 'stretch_height'
+
+
+@pytest.mark.parametrize('panel', [Column, Row])
+def test_layout_clone_objects_in_args_and_kwargs(panel):
+    div1 = Div()
+    div2 = Div()
+    layout = panel(div1, div2)
+    with pytest.raises(ValueError):
+        layout.clone(div1, objects=div1)
+
+
 def test_widgetbox(document, comm):
     widget_box = WidgetBox("WidgetBox")