Repository: holoviz/panel

Issue:
param types vs panel widgets
The docs (https://panel.pyviz.org/user_guide/Param.html) tell us that
> internally Panel maintains a mapping between parameter types and widget types.

I think it would be helpful if we could explicitly list this mapping in the docs, i.e. which widget a given param type is translated to. 


Discussion:
Sounds like a good idea.  Rather than list the actual mapping, which would probably quickly go out of date, we should probably just explain how to list what the mapping is.  E.g. this would currently work from the command line:

```
python -c 'from panel.param import Param ; print(Param._mapping)'
```

But that's accessing a private class attribute, so maybe we should provide a public method for showing the current mapping.
Hi!
I believe that it'd be indeed useful to have access to this private mapping and to document how to access it. I've had to dig the code a few times to try to understand why I was getting such that widget for that type of parameter.

Could it be as simple as ``panel.param.mapping()`` returning ``_mapping`` ?
Yeah, making `panel.Param.mapping` public is fine with me.
Just fyi. When i have a package of material widgets i would really like to be able to also Update the mapping.

I think that would be a future use case.



Resolving patch:
diff --git a/panel/param.py b/panel/param.py
--- a/panel/param.py
+++ b/panel/param.py
@@ -22,8 +22,8 @@
 from .layout import Column, Panel, Row, Spacer, Tabs
 from .pane.base import PaneBase, ReplacementPane
 from .util import (
-    abbreviated_repr, full_groupby, get_method_owner, is_parameterized,
-    param_name, recursive_parameterized
+    abbreviated_repr, classproperty, full_groupby, get_method_owner,
+    is_parameterized, param_name, recursive_parameterized
 )
 from .reactive import Reactive
 from .viewable import Layoutable, Viewable
@@ -150,11 +150,7 @@ class Param(PaneBase):
         Dictionary of widget overrides, mapping from parameter name
         to widget class.""")
 
-    priority = 0.1
-
-    _unpack = True
-
-    _mapping = {
+    mapping = {
         param.Action:            Button,
         param.Boolean:           Checkbox,
         param.CalendarDate:      DatePicker,
@@ -180,7 +176,11 @@ class Param(PaneBase):
     }
 
     if hasattr(param, 'Event'):
-        _mapping[param.Event] = Button
+        mapping[param.Event] = Button
+
+    priority = 0.1
+
+    _unpack = True
 
     _rerender_params = []
 
@@ -227,6 +227,14 @@ def __init__(self, object=None, **params):
             'hide_constant'])
         self._update_widgets()
 
+    @classproperty
+    def _mapping(cls):
+        cls.param.warning(
+            "Param._mapping is now deprecated in favor of the public "
+            "Param.mapping attribute. Update your code accordingly."
+        )
+        return cls.mapping
+
     def __repr__(self, depth=0):
         cls = type(self).__name__
         obj_cls = type(self.object).__name__
@@ -422,7 +430,7 @@ def widget(self, p_name):
             if bounds[1] is not None:
                 kw['end'] = bounds[1]
             if ('start' not in kw or 'end' not in kw):
-                # Do not change widget class if _mapping was overridden
+                # Do not change widget class if mapping was overridden
                 if not widget_class_overridden:
                     if (isinstance(p_obj, param.Number) and
                         not isinstance(p_obj, (param.Date, param.CalendarDate))):
@@ -657,10 +665,12 @@ def applies(cls, obj):
     def widget_type(cls, pobj):
         ptype = type(pobj)
         for t in classlist(ptype)[::-1]:
-            if t in cls._mapping:
-                if isinstance(cls._mapping[t], types.FunctionType):
-                    return cls._mapping[t](pobj)
-                return cls._mapping[t]
+            if t not in cls.mapping:
+                continue
+            wtype = cls.mapping[t]
+            if isinstance(wtype, types.FunctionType):
+                return wtype(pobj)
+            return wtype
 
     def select(self, selector=None):
         """


Test patch: