Skip to content

Commit

Permalink
config: support comma in config ListAttribute item
Browse files Browse the repository at this point in the history
This is a first step towards completing sopel-irc#1455, since, as @dgw mentioned,
to do so would require accepting commas in a single entry of ListAttribute.

Items entered through the wizard do not need to be escaped manaully. Items
configured in the `.cfg` file manually require an escaped command, like '\,'.
The prompt has also been changed so that the items are now surrounded by quotes
so that one can differentiate items that may contains commas.

The following scenarios were tested (using the `url.py` module, specifically the
`exclude` setting):

1. Wizard, setting items when there is no default (pre-existing items); mix of w/ commas
and w/o commas
2. Wizard, replacing existing items when a default exists; mix of w/ commas and w/o commas
3. Wizard, extending the current default list; mix of w/ commas and w/o commas
4. Manual edit, setting items; w/ commas (manually escaped) and w/o commas
5. Wizard, setting items w/o default; no commas
  • Loading branch information
HumorBaby committed Jan 27, 2019
1 parent 8febccd commit a8e2e46
Showing 1 changed file with 16 additions and 10 deletions.
26 changes: 16 additions & 10 deletions sopel/config/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from __future__ import unicode_literals, absolute_import, print_function, division

import os.path
import re
import sys
from sopel.tools import get_input

Expand Down Expand Up @@ -218,16 +219,18 @@ def __init__(self, name, strip=True, default=None):
self.strip = strip

def parse(self, value):
value = list(filter(None, value.split(',')))
value = list(filter(None, re.split(r'(?<!\\),', value)))
items = map(lambda x: x.replace(r'\,', ','), value)
if self.strip:
return [v.strip() for v in value]
return [v.strip() for v in items]
else:
return value
return items

def serialize(self, value):
if not isinstance(value, (list, set)):
raise ValueError('ListAttribute value must be a list.')
return ','.join(value)
items = map(lambda x: x.replace(',', r'\,'), value)
return ','.join(items)

def configure(self, prompt, default, parent, section_name):
each_prompt = '?'
Expand All @@ -236,17 +239,20 @@ def configure(self, prompt, default, parent, section_name):
prompt = prompt[0]

if default is not NO_DEFAULT:
default = ','.join(default)
prompt = '{} [{}]'.format(prompt, default)
default_value = self.serialize(default)
prompt = '{} [{}]'.format(prompt, ",".join(map(lambda x: '"{}"'.format(x), default)))
else:
default = ''
default_value = ''
print(prompt)
values = []
value = get_input(each_prompt + ' ') or default
value = get_input(each_prompt + ' ') or default_value
while value:
values.append(value)
if value == default_value:
values.extend(self.parse(default_value))
else:
values.append(value)
value = get_input(each_prompt + ' ')
return self.parse(','.join(values))
return self.parse(self.serialize(values))


class ChoiceAttribute(BaseValidated):
Expand Down

0 comments on commit a8e2e46

Please sign in to comment.