Skip to content

Commit

Permalink
Fix macro namespace search packages (#5804)
Browse files Browse the repository at this point in the history
  • Loading branch information
dbeatty10 authored Jun 27, 2023
1 parent b37e5b5 commit 6a1e3a6
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 15 deletions.
7 changes: 7 additions & 0 deletions .changes/unreleased/Fixes-20220909-164413.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
kind: Fixes
body: Raise better error message when dispatching a package that is not installed
time: 2022-09-09T16:44:13.382685-06:00
custom:
Author: "dbeatty10"
Issue: "5801"
PR: "5804"
36 changes: 21 additions & 15 deletions core/dbt/context/providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,25 @@ def _get_adapter_macro_prefixes(self) -> List[str]:
search_prefixes = get_adapter_type_names(self._adapter.type()) + ["default"]
return search_prefixes

def _get_search_packages(self, namespace: Optional[str] = None) -> List[Optional[str]]:
search_packages: List[Optional[str]] = [None]

if namespace is None:
search_packages = [None]
elif isinstance(namespace, str):
macro_search_order = self._adapter.config.get_macro_search_order(namespace)
if macro_search_order:
search_packages = macro_search_order
elif not macro_search_order and namespace in self._adapter.config.dependencies:
search_packages = [self.config.project_name, namespace]
else:
raise CompilationError(
f"In adapter.dispatch, got a {type(namespace)} macro_namespace argument "
f'("{namespace}"), but macro_namespace should be None or a string.'
)

return search_packages

def dispatch(
self,
macro_name: str,
Expand All @@ -154,20 +173,7 @@ def dispatch(
if packages is not None:
raise MacroDispatchArgError(macro_name)

namespace = macro_namespace

if namespace is None:
search_packages = [None]
elif isinstance(namespace, str):
search_packages = self._adapter.config.get_macro_search_order(namespace)
if not search_packages and namespace in self._adapter.config.dependencies:
search_packages = [self.config.project_name, namespace]
else:
# Not a string and not None so must be a list
raise CompilationError(
f"In adapter.dispatch, got a list macro_namespace argument "
f'("{macro_namespace}"), but macro_namespace should be None or a string.'
)
search_packages = self._get_search_packages(macro_namespace)

attempts = []

Expand All @@ -191,7 +197,7 @@ def dispatch(
return macro

searched = ", ".join(repr(a) for a in attempts)
msg = f"In dispatch: No macro named '{macro_name}' found\n Searched for: {searched}"
msg = f"In dispatch: No macro named '{macro_name}' found within namespace: '{macro_namespace}'\n Searched for: {searched}"
raise CompilationError(msg)


Expand Down
25 changes: 25 additions & 0 deletions tests/functional/macros/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,28 @@
{{ adapter_macro('some_macro', arg1, arg2) }}
{%- endmacro %}
"""

macros__incorrect_dispatch = """
{% macro cowsay() %}
{{ return(adapter.dispatch('cowsay', 'farm_utils')()) }}
{%- endmacro %}
{% macro default__cowsay() %}
'moo'
{% endmacro %}
"""

# Note the difference between `test_utils` below and `farm_utils` above
models__incorrect_dispatch = """
select {{ test_utils.cowsay() }} as cowsay
"""

dbt_project__incorrect_dispatch = """
name: 'test_utils'
version: '1.0'
config-version: 2
profile: 'default'
macro-paths: ["macros"]
"""
41 changes: 41 additions & 0 deletions tests/functional/macros/test_macros.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,22 @@
check_relations_equal,
)

from dbt.tests.fixtures.project import write_project_files
from tests.functional.macros.fixtures import (
dbt_project__incorrect_dispatch,
models__dep_macro,
models__with_undefined_macro,
models__local_macro,
models__ref_macro,
models__override_get_columns_macros,
models__deprecated_adapter_macro_model,
models__incorrect_dispatch,
macros__my_macros,
macros__no_default_macros,
macros__override_get_columns_macros,
macros__package_override_get_columns_macros,
macros__deprecated_adapter_macro,
macros__incorrect_dispatch,
)


Expand Down Expand Up @@ -203,6 +207,43 @@ def test_overrides(self, project):
run_dbt()


class TestMisnamedMacroNamespace:
@pytest.fixture(scope="class", autouse=True)
def setUp(self, project_root):
test_utils_files = {
"dbt_project.yml": dbt_project__incorrect_dispatch,
"macros": {
"cowsay.sql": macros__incorrect_dispatch,
},
}
write_project_files(project_root, "test_utils", test_utils_files)

@pytest.fixture(scope="class")
def models(self):
return {
"my_model.sql": models__incorrect_dispatch,
}

@pytest.fixture(scope="class")
def packages(self):
return {
"packages": [
{"local": "test_utils"},
]
}

def test_misnamed_macro_namespace(
self,
project,
):
run_dbt(["deps"])

with pytest.raises(dbt.exceptions.CompilationError) as exc:
run_dbt()

assert "In dispatch: No macro named 'cowsay' found" in str(exc.value)


class TestAdapterMacroDeprecated:
@pytest.fixture(scope="class")
def models(self):
Expand Down

0 comments on commit 6a1e3a6

Please sign in to comment.