Skip to content
This repository has been archived by the owner on Nov 29, 2019. It is now read-only.

Fix param.Action (#9). #32

Merged
merged 5 commits into from
Dec 19, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ jobs:
env: PYTHON_VERSION="2.7"
install:
- source ./etc/travis-miniconda.sh
- conda create -n test-environment python=$PYTHON_VERSION
- conda create -q -n test-environment python=$PYTHON_VERSION
- source activate test-environment
- conda install param
- conda install -c bokeh "bokeh>=0.12.10"
- conda install -q param
- conda install -q -c bokeh "bokeh>=0.12.10"
# dependencies for testing
- pip install pytest pytest-nbsmoke
- conda install -c ioam "holoviews>=1.9.0"
- conda install pandas notebook flake8 pyparsing
- conda install -q -c ioam "holoviews>=1.9.0"
- conda install -q pandas notebook flake8 pyparsing
- python setup.py develop --no-deps
- conda env export
- conda list
Expand All @@ -50,13 +50,13 @@ jobs:
# TODO: could (build and) use conda package; to be cleaned up
# once auto versioning/package building is finalized
- source ./etc/travis-miniconda.sh
- conda create -n test-environment python=$PYTHON_VERSION
- conda create -q -n test-environment python=$PYTHON_VERSION
- source activate test-environment
- conda install param
- conda install pandas
- conda install -c bokeh "bokeh>=0.12.10"
- conda install -c ioam "holoviews>=1.9.0"
- conda install -c conda-forge notebook ipython sphinx beautifulsoup4 graphviz selenium phantomjs
- conda install -q param
- conda install -q pandas
- conda install -q -c bokeh "bokeh>=0.12.10"
- conda install -q -c ioam "holoviews>=1.9.0"
- conda install -q -c conda-forge notebook ipython sphinx beautifulsoup4 graphviz selenium phantomjs
- pip install nbsite sphinx_ioam_theme
- pip install -e .
script:
Expand Down Expand Up @@ -87,8 +87,8 @@ jobs:
install:
- source ./etc/travis-miniconda.sh
# for building and uploading packages
- conda install conda-build=3.0.25
- conda install anaconda-client
- conda install -q conda-build=3.0.25
- conda install -q anaconda-client
script:
- conda build conda.recipe
- anaconda -t $CONDA_UPLOAD_TOKEN upload --force -u cball $HOME/miniconda/conda-bld/noarch/parambokeh*.tar.bz2
8 changes: 4 additions & 4 deletions examples/user_guide/Bokeh_App.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,11 @@
"\n",
"import param\n",
"import datetime as dt\n",
"\n",
"def hello(x, **kwargs):\n",
" print(\"Hello %s\" % x)\n",
" \n",
"class Example(param.Parameterized):\n",
" \"\"\"An example Parameterized class\"\"\"\n",
" timestamps = []\n",
" \n",
" x = param.Parameter(default=3.14,doc=\"X position\")\n",
" y = param.Parameter(default=\"Not editable\",constant=True)\n",
" string_value = param.String(default=\"str\",doc=\"A string\")\n",
Expand All @@ -46,7 +45,8 @@
" int_list = param.ListSelector(default=[3,5], objects=[1,3,5,7,9],precedence=0.5)\n",
" single_file = param.FileSelector(path='../../*/*.py*',precedence=0.5)\n",
" multiple_files = param.MultiFileSelector(path='../../*/*.py?',precedence=0.5)\n",
" #msg = param.Action(hello, doc=\"\"\"Print a message.\"\"\",precedence=0.7)\n"
" record_timestamp = param.Action(lambda x: x.timestamps.append(dt.datetime.now()), \n",
" doc=\"\"\"Record timestamp.\"\"\",precedence=0.7)\n"
]
},
{
Expand Down
24 changes: 20 additions & 4 deletions examples/user_guide/Introduction.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@
"import param\n",
"import datetime as dt\n",
"\n",
"def hello(x, **kwargs):\n",
" print(\"Hello %s\" % x)\n",
" \n",
"class BaseClass(param.Parameterized):\n",
" x = param.Parameter(default=3.14,doc=\"X position\")\n",
" y = param.Parameter(default=\"Not editable\",constant=True)\n",
Expand All @@ -39,6 +36,8 @@
" \n",
"class Example(BaseClass):\n",
" \"\"\"An example Parameterized class\"\"\"\n",
" timestamps = []\n",
"\n",
" boolean = param.Boolean(True, doc=\"A sample Boolean parameter\")\n",
" color = param.Color(default='#FFFFFF')\n",
" date = param.Date(dt.datetime(2017, 1, 1),\n",
Expand All @@ -48,7 +47,8 @@
" int_list = param.ListSelector(default=[3,5], objects=[1,3,5,7,9],precedence=0.5)\n",
" single_file = param.FileSelector(path='../../*/*.py*',precedence=0.5)\n",
" multiple_files = param.MultiFileSelector(path='../../*/*.py?',precedence=0.5)\n",
" #msg = param.Action(hello, doc=\"\"\"Print a message.\"\"\",precedence=0.7)\n",
" record_timestamp = param.Action(lambda x: x.timestamps.append(dt.datetime.now()), \n",
" doc=\"\"\"Record timestamp.\"\"\",precedence=0.7)\n",
" \n",
"Example.num_int"
]
Expand Down Expand Up @@ -124,6 +124,22 @@
"Example.num_int"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Example.timestamps records the times you pressed the \"record timestamp\" button."
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good example, thanks.

]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Example.timestamps"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand Down
14 changes: 9 additions & 5 deletions parambokeh/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ def __call__(self, parameterized, doc=None, plots=[], **params):
def on_msg(self, msg):
p_name = msg['p_name']
p_obj = self.parameterized.params(p_name)
if isinstance(p_obj, param.Action):
getattr(self.parameterized, p_name)(self.parameterized)
return
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other widgets won't be refreshed - is that a problem? What if the callback alters another parameter value? (I decided not to get into this now, deferring it to 'dependencies between parameters and code'...)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deferring it to 'dependencies between parameters and code'

+1

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds fine.

w = self._widgets[p_name]
self._queue.append((w, p_obj, p_name, None, None, msg['value']))
self.change_event()
Expand Down Expand Up @@ -258,10 +261,6 @@ def _make_widget(self, p_name):
value = getattr(self.parameterized, p_name)

kw = dict(value=value)
if isinstance(p_obj, param.Action):
def action_cb(button):
getattr(self.parameterized, p_name)(self.parameterized)
kw['value'] = action_cb

kw['title'] = p_name

Expand Down Expand Up @@ -289,12 +288,17 @@ def action_cb(button):

if hasattr(p_obj, 'callbacks'):
p_obj.callbacks[id(self.parameterized)] = functools.partial(self._update_trait, p_name)
elif isinstance(w, (Button, Toggle)):
elif isinstance(w, Toggle):
if self.p.mode in ['server', 'raw']:
w.on_change('active', functools.partial(self.on_change, w, p_obj, p_name))
else:
js_callback = self._get_customjs('active', p_name)
w.js_on_change('active', js_callback)
elif isinstance(w, Button):
if self.p.mode in ['server', 'raw']:
w.on_click(functools.partial(value,self.parameterized))
else:
w.js_on_click(self._get_customjs('active', p_name))
elif not p_obj.constant:
if self.p.mode in ['server', 'raw']:
cb = functools.partial(self.on_change, w, p_obj, p_name)
Expand Down
4 changes: 4 additions & 0 deletions parambokeh/comms.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,10 @@ def _handle_msg(self, msg):
with StandardOutput() as stdout:
self._on_msg(msg)
except Exception as e:
# TODO: isn't this cutting out info needed to understand what's gone wrong?
# Since it's only going to the js console, maybe we could just show everything
# (error = traceback.format_exc() or something like that)? Separately we do need a mechanism
# to report reasonable messages to users, though.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All true, if we can find a way to make tracebacks readable on the JS console I'd be very happy to change this (and port the change back to holoviews).

frame =traceback.extract_tb(sys.exc_info()[2])[-2]
fname,lineno,fn,text = frame
error_kwargs = dict(type=type(e).__name__, fn=fn, fname=fname,
Expand Down
6 changes: 2 additions & 4 deletions parambokeh/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,8 @@ def ToggleWidget(*args, **kw):

def ButtonWidget(*args, **kw):
kw['label'] = kw.pop('title')
cb = kw.pop('value')
button = Button(*args, **kw)
button.on_click(cb)
return button
kw.pop('value') # button doesn't have value (value attached as click callback)
return Button(*args, **kw)

# TODO: make a composite box/slider widget; slider only appears if
# there's a range.
Expand Down