Skip to content

Commit

Permalink
Merge pull request #948 from ioam/parser_fixes
Browse files Browse the repository at this point in the history
Parser fixes
  • Loading branch information
jlstevens authored Oct 27, 2016
2 parents e0d94a8 + ca72def commit b64b6c5
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 2 deletions.
20 changes: 18 additions & 2 deletions holoviews/ipython/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,19 @@ def _strip_commas(cls, kw):
kw = kw[:-1] if kw[-1]==',' else kw
return kw[1:] if kw[0]==',' else kw

@classmethod
def recurse_token(cls, token, inner):
recursed = []
for tok in token:
if isinstance(tok, list):
new_tok = [s for t in tok for s in
(cls.recurse_token(t, inner)
if isinstance(t, list) else [t])]
recursed.append((inner % ''.join(new_tok)))
else:
recursed.append(tok)
return inner % ''.join(recursed)

@classmethod
def collect_tokens(cls, parseresult, mode):
"""
Expand All @@ -53,7 +66,8 @@ def collect_tokens(cls, parseresult, mode):
for token in parseresult.asList():
# If value is a tuple, the token will be a list
if isinstance(token, list):
tokens[-1] = tokens[-1] + (inner % ''.join(token))
token = cls.recurse_token(token, inner)
tokens[-1] = tokens[-1] + token
else:
if token.strip() == ',': continue
tokens.append(cls._strip_commas(token))
Expand Down Expand Up @@ -86,7 +100,9 @@ def todict(cls, parseresult, mode='parens', ns={}):
for keyword in grouped:
# Tuple ('a', 3) becomes (,'a',3) and '(,' is never valid
# Same for some of the other joining errors corrected here
for (fst,snd) in [('(,', '('), ('{,', '{'), ('=,','='), (',:',':')]:
for (fst,snd) in [('(,', '('), ('{,', '{'), ('=,','='),
(',:',':'), (':,', ':'), (',,', ','),
(',.', '.')]:
keyword = keyword.replace(fst, snd)
try:
kwargs.update(eval('dict(%s)' % keyword,
Expand Down
46 changes: 46 additions & 0 deletions tests/testparsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,20 @@ def test_plot_opts_with_space_explicit(self):
Options(title_format='foo bar', fig_inches=(3, 3))}}
self.assertEqual(OptsSpec.parse(line), expected)

def test_plot_opts_dict_with_space(self):
line = "Curve [fontsize={'xlabel': 10, 'title': 20}]"
expected = {'Curve': {'plot': Options(fontsize={'xlabel': 10, 'title': 20})}}
self.assertEqual(OptsSpec.parse(line), expected)

def test_plot_opts_dict_without_space(self):
line = "Curve [fontsize=dict(xlabel=10,title=20)]"
expected = {'Curve': {'plot': Options(fontsize={'xlabel': 10, 'title': 20})}}
self.assertEqual(OptsSpec.parse(line), expected)

def test_plot_opts_nested_brackets(self):
line = "Curve [title_format=', '.join(('A', 'B'))]"
expected = {'Curve': {'plot': Options(title_format='A, B')}}
self.assertEqual(OptsSpec.parse(line), expected)


class OptsSpecStyleOptionsTests(ComparisonTestCase):
Expand Down Expand Up @@ -90,6 +104,38 @@ def test_style_opts_advanced(self):
color=Cycle(values=[1,2]))}}
self.assertEqual(OptsSpec.parse(line), expected)

def test_style_opts_dict_with_space(self):
line = "Curve (fontsize={'xlabel': 10, 'title': 20})"
expected = {'Curve': {'style': Options(fontsize={'xlabel': 10, 'title': 20})}}
self.assertEqual(OptsSpec.parse(line), expected)

def test_style_opts_dict_without_space(self):
line = "Curve (fontsize={'xlabel': 10,'title': 20})"
expected = {'Curve': {'style': Options(fontsize={'xlabel': 10, 'title': 20})}}
self.assertEqual(OptsSpec.parse(line), expected)

def test_style_opts_cycle_function(self):
# Explicitly compare because list of arrays do not compare correctly
import numpy as np
np.random.seed(42)
line = "Curve (color=Cycle(values=list(np.random.rand(3,3))))"
options = OptsSpec.parse(line, {'np': np, 'Cycle': Cycle})
self.assertTrue('Curve' in options)
self.assertTrue('style' in options['Curve'])
self.assertTrue('color' in options['Curve']['style'].kwargs)
self.assertTrue(isinstance(options['Curve']['style'].kwargs['color'], Cycle))
values = np.array([[ 0.37454012, 0.95071431, 0.73199394],
[ 0.59865848, 0.15601864, 0.15599452],
[ 0.05808361, 0.86617615, 0.60111501]])
expected = {'Curve': {'style': Options(color=Cycle(values=list(values)))}}
self.assertEqual(np.array(options['Curve']['style'].kwargs['color'].values),
values)

def test_style_opts_cycle_list(self):
line = "Curve (color=Cycle(values=['r', 'g', 'b']))"
expected = {'Curve': {'style': Options(color=Cycle(values=['r', 'g', 'b']))}}
self.assertEqual(OptsSpec.parse(line, {'Cycle': Cycle}), expected)



class OptsNormPlotOptionsTests(ComparisonTestCase):
Expand Down

0 comments on commit b64b6c5

Please sign in to comment.