# 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: ```python import re from tiramisu import RegexpOption class VowelOption(RegexpOption): __slots__ = tuple() _type = 'vowel' _display_name = "string with vowel" _regexp = re.compile(r"^[aeiouy]*$") ``` Let's try our object: ```python VowelOption('vowel', 'Vowel', 'aae') ``` ```python try: VowelOption('vowel', 'Vowel', 'oooups') except ValueError as err: print(err) ``` returns: ```python "oooups" is an invalid string with vowel for "Vowel" ``` ## Create a custom option An option always inherits from "Option" object. This object has the following class attributes: - \_\_slots\_\_: a tuple with new data members (by default you should set "tuple()") - \_type = with a name - \_display_name: with the display name (for example in error message) Here an example to an lipogram option: ```python from tiramisu import Option from tiramisu.error import ValueWarning import warnings class LipogramOption(Option): __slots__ = tuple() _type = 'lipogram' _display_name = 'lipogram' # # First of all we want to add a custom parameter to ask the minimum length (min_len) of the value: def __init__(self, *args, min_len=100, **kwargs): # store extra parameters extra = {'_min_len': min_len} super().__init__(*args, extra=extra, **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: # Even if user set warnings_only attribute, this method will raise. def validate(self, value): # first, valid that the value is a string if not isinstance(value, str): raise ValueError('invalid string') # and verify that there is any 'e' in the sentense if 'e' in value: raise ValueError('Perec wrote a book without any "e", you could not do it in a simple sentence?') # # Finally we add a method to valid the value length. # If "warnings_only" is set to True, a warning will be emit: def second_level_validation(self, value, warnings_only): # retrive parameter in extra min_len = self.impl_get_extra('_min_len') # verify the sentense length if len(value) < min_len: # raise message, in this case, warning and error message are different if warnings_only: msg = f'it would be better to have at least {min_len} characters in the sentence' else: msg = f'you must have at least {min_len} characters in the sentence' raise ValueError(msg) ``` Let's test it: 1. the character "e" is in the value: ```python try: LipogramOption('lipo', 'Lipogram', 'I just want to add a quality string that has no bad characters') except ValueError as err: print(err) ``` returns: ``` "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? ``` 2. the character "e" is in the value and warnings_only is set to True: ```python 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? ``` 3. the value is too short ```python try: LipogramOption('lipo', 'Lipogram', 'I just want to add a quality string that has no bad symbols') except ValueError as err: print(err) ``` returns: ``` "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 ``` 4. the value is too short and warnings_only is set to True: ```python 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) ``` returns: ``` 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 ``` 5. set minimum length to 50 characters, the value is valid: ```python LipogramOption('lipo', 'Lipogram', 'I just want to add a quality string that has no bad symbols', min_len=50) ```