Sample InvalidSchemaError output

To give you an idea of the different error messages (all output at once under one umbrella exception), let’s use the following YAML with many problems, indicated by comments:

case_sensitive: 'This should be a boolean'
screen_width: 'This should be an integer'
tabs:
  - # there is no tab_header_input for this tab
    # the other two keys missing is ok, they're optional
    items:
      - item_choice_displayed: choice1
        item_description: descript1
        item_inputs: 
          - # item inputs is an empty list
        item_returns: return1 
  - tab_header_input: a  # this will conflict with an item input in another tab
    items:
      - item_choice_displayed: 1
        item_description: descript1
        item_inputs: 
          - 1  # int is okay, but it will conflict with another input in the same list
        item_returns: None  # must be coerceable to string, can't be None
      - item_choice_displayed: 2
        item_description: descript2
        item_inputs: 
          - 1  # conflicts with previous item
        item_returns: 1
  - tab_header_input: b
    items:
      - item_choice_displayed: a
        item_description: descripta
        item_inputs: 
          - a  # conflicts with the input to switch to another tab
        item_returns: a  
      - item_choice_displayed: foo
        item_description: bar
        item_inputs: 
          - spam  # conflicts with previous item
        # missing item_returns

And here’s what happens when we try to initialize a Menu instance with that config:

>>> from pytabby import Menu
>>> config = Menu.safe_read_yaml('sampleerror.yaml')
>>> menu = Menu(config)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<<path redacted>>pytabby/menu.py", line 58, in __init__
    validators.validate_all(self._config)
  File "<<path redacted>>pytabby/validators.py", line 388, in validate_all
    raise InvalidInputError("\n".join(printed_message))
pytabby.validators.InvalidInputError:
Errors:
1. schema.SchemaError: Key 'case_sensitive' error: 'This should be a boolean' should be instance of 'bool'
2. tab#0: schema.SchemaMissingKeyError: Missing key: 'tab_header_input'
3. tab#0,item#0,valid_entry#0: schema.SchemaError: <lambda>(None) should evaluate to True
4. tab#2,item#1: schema.SchemaMissingKeyError: Missing key: 'item_returns'
5. In tab#1, there are repeated input values including tab selectors: [(1, 2)].
6. In tab#2, there are repeated input values including tab selectors: [('a', 2)].
>>>

As you can see, instead of having to fix the errors one by one, the error message output six errors to fix at once.

It’s a little unpythonic, but foolish consistency is the hobgoblin of bad design, to paraphrase.

Now, it’s possible certain kinds of errors can be ‘swallowed’ by others, so there’s no guarantee that you won’t have to do more than one round of fixes in particularly problematic configs, but this should save you much more than half your time.