Create it’s own option

Generic regexp option: RegexpOption

Use RegexpOption to create custom option is very simple.

You just have to create an object that inherits from RegexpOption and that has the following class attributes:

  • __slots__: with new data members (the values should always be tuple())

  • _type = with a name

  • _display_name: with the display name (for example in error message)

  • _regexp: with a compiled regexp

Here an example to an option that only accept string with on lowercase ASCII vowel characters:

1import re
2from tiramisu import RegexpOption
3
4
5class VowelOption(RegexpOption):
6    __slots__ = tuple()
7    _type = 'vowel'
8    _display_name = "string with vowel"
9    _regexp = re.compile(r"^[aeiouy]*$")

Let’s try our object:

>>> VowelOption('vowel', 'Vowel', 'aae')
<VowelOption object at 0x7feb2779c050>
>>> try:
...     VowelOption('vowel', 'Vowel', 'oooups')
... except ValueError as err:
...     print(err)
...
"oooups" is an invalid string with vowel for "Vowel"

Create you own option

An option always inherits from Option object. This object has the following class attributes:

  • __slots__: with new data members (the values should always be tuple())

  • _type = with a name

  • _display_name: with the display name (for example in error message)

Here an example to an lipogram option:

 1from tiramisu import Option
 2from tiramisu.error import ValueWarning
 3import warnings
 4
 5
 6class LipogramOption(Option):
 7    __slots__ = tuple()
 8    _type = 'lipogram'
 9    _display_name = 'lipogram'
10    def __init__(self,
11                 *args,
12                 min_len=100,
13                 **kwargs):

First of all we want to add a custom parameter to ask the minimum length (min_len) of the value:

1        # store extra parameters
2        extra = {'_min_len': min_len}
3        super().__init__(*args,
4                         extra=extra,
5                         **kwargs)

We have a first validation method. In this method, we verify that the value is a string and that there is no “e” on it:

1    def validate(self,
2                 value):
3        # first, valid that the value is a string
4        if not isinstance(value, str):
5            raise ValueError('invalid string')
6        # and verify that there is any 'e' in the sentense
7        if 'e' in value:
8            raise ValueError('Perec wrote a book without any "e", you could not do it in a simple sentence?')

Even if user set warnings_only attribute, this method will raise.

Finally we add a method to valid the value length. If warnings_only is set to True, a warning will be emit:

 1    def second_level_validation(self,
 2                                value,
 3                                warnings_only):
 4        # retrive parameter in extra
 5        min_len = self.impl_get_extra('_min_len')
 6        # verify the sentense length
 7        if len(value) < min_len:
 8            # raise message, in this case, warning and error message are different
 9            if warnings_only:
10                msg = f'it would be better to have at least {min_len} characters in the sentence'
11            else:
12                msg = f'you must have at least {min_len} characters in the sentence'
13            raise ValueError(msg)

Let’s test it:

  1. the character “e” is in the value:

>>> try:
...    LipogramOption('lipo',
...                   'Lipogram',
...                   'I just want to add a quality string that has no bad characters')
... except ValueError as err:
...    print(err)
...
"I just want to add a quality string that has no bad characters" is an invalid lipogram for "Lipogram", Perec wrote a book without any "e", you could not do it in a simple sentence?
  1. the character “e” is in the value and warnings_only is set to True:

>>> try:
...     LipogramOption('lipo',
...                    'Lipogram',
...                    'I just want to add a quality string that has no bad characters',
...                    warnings_only=True)
... except ValueError as err:
...     print(err)
...
"I just want to add a quality string that has no bad characters" is an invalid lipogram for "Lipogram", Perec wrote a book without any "e", you could not do it in a simple sentence?
  1. the value is too short

>>> try:
...     LipogramOption('lipo',
...                    'Lipogram',
...                    'I just want to add a quality string that has no bad symbols')
... except ValueError as err:
...     print(err)
...
"I just want to add a quality string that has no bad symbols" is an invalid lipogram for "Lipogram", you must have at least 100 characters in the sentence
  1. the value is too short and warnings_only is set to True:

>>> warnings.simplefilter('always', ValueWarning)
>>> with warnings.catch_warnings(record=True) as warn:
...    LipogramOption('lipo',
...                   'Lipogram',
...                   'I just want to add a quality string that has no bad symbols',
...                   warnings_only=True)
...    if warn:
...        print(warn[0].message)
...
attention, "I just want to add a quality string that has no bad symbols" could be an invalid lipogram for "Lipogram", it would be better to have at least 100 characters in the sentence
  1. set minimum length to 50 characters, the value is valid:

>>> LipogramOption('lipo',
...                'Lipogram',
...                'I just want to add a quality string that has no bad symbols',
...                min_len=50)