Compare commits

...

1 Commits

Author SHA1 Message Date
Gerda Shank
ed8c07632a Add better error messages for yaml selectors 2020-09-21 15:28:39 -04:00
3 changed files with 94 additions and 5 deletions

View File

@@ -1,5 +1,6 @@
from pathlib import Path
from typing import Dict, Any, Optional
import yaml
from hologram import ValidationError
@@ -33,7 +34,17 @@ class SelectorConfig(Dict[str, SelectionSpec]):
try:
selector_file = SelectorFile.from_dict(data)
selectors = parse_from_selectors_definition(selector_file)
except (ValidationError, RuntimeException) as exc:
except ValidationError as exc:
yaml_sel_cfg = yaml.dump(exc.instance)
raise DbtSelectorsError(
f"Could not parse selector file data: \n{yaml_sel_cfg}\n"
f"Valid selector description definitions: "
f"union, intersection, string, dictionary. No lists. "
f"\nhttps://docs.getdbt.com/reference/node-selection/"
f"yaml-selectors",
result_type='invalid_selector'
) from exc
except RuntimeException as exc:
raise DbtSelectorsError(
f'Could not read selector file data: {exc}',
result_type='invalid_selector',

View File

@@ -1,5 +1,6 @@
# special support for CLI argument parsing.
import itertools
import yaml
from typing import (
Dict, List, Optional, Tuple, Any, Union
@@ -165,9 +166,10 @@ def _parse_include_exclude_subdefs(
if isinstance(definition, dict) and 'exclude' in definition:
# do not allow multiple exclude: defs at the same level
if diff_arg is not None:
yaml_sel_cfg = yaml.dump(definitions)
raise ValidationException(
f'Got multiple exclusion definitions in definition list '
f'{definitions}'
f"You cannot provide multiple exclude arguments to the "
f"same selector set operator:\n{yaml_sel_cfg}"
)
diff_arg = _parse_exclusions(definition)
else:
@@ -251,10 +253,15 @@ def parse_from_definition(definition: RawDefinition) -> SelectionSpec:
return parse_intersection_definition(definition)
elif isinstance(definition, dict):
return parse_dict_definition(definition)
elif isinstance(definition, list):
raise ValidationException(
f'Selector definition root level list not allowed. Use Union to '
f'contain list. {definition}'
)
else:
raise ValidationException(
f'Expected to find str or dict, instead found '
f'{type(definition)}: {definition}'
f'Expected to find union, intersection, str or dict, instead '
f'found {type(definition)}: {definition}'
)

View File

@@ -0,0 +1,71 @@
from dbt.graph import cli
import dbt.exceptions
import textwrap
import yaml
import unittest
from pprint import pprint
from dbt.config.selectors import (
selector_config_from_data
)
from dbt.contracts.selection import SelectorFile
def get_selector_dict(txt: str) -> dict:
txt = textwrap.dedent(txt)
dct = yaml.safe_load(txt)
return dct
class SelectorUnitTest(unittest.TestCase):
def test_parse_multiple_excludes(self):
dct = get_selector_dict('''\
selectors:
- name: mult_excl
definition:
union:
- method: tag
value: nightly
- exclude:
- method: tag
value: hourly
- exclude:
- method: tag
value: daily
''')
with self.assertRaises(dbt.exceptions.DbtSelectorsError):
selectors = selector_config_from_data(dct)
def test_parse_set_op_plus(self):
dct = get_selector_dict('''\
selectors:
- name: union_plus
definition:
- union:
- method: tag
value: nightly
- exclude:
- method: tag
value: hourly
- method: tag
value: foo
''')
with self.assertRaises(dbt.exceptions.DbtSelectorsError):
selectors = selector_config_from_data(dct)
def test_parse_multiple_methods(self):
dct = get_selector_dict('''\
selectors:
- name: mult_methods
definition:
- tag:hourly
- tag:nightly
- fqn:start
''')
with self.assertRaises(dbt.exceptions.DbtSelectorsError):
selectors = selector_config_from_data(dct)