Skip to content

Commit

Permalink
Add invocation_args_dict to ProviderContext (#5782)
Browse files Browse the repository at this point in the history
* Add invocation_args_to_dict to ProviderContext

* Change invocation_args_to_dict contextproperty to invocation_args_dict

* Fix invocation_args_dict builtin test

* Add CHANGELOG entry

* Fix formatting
  • Loading branch information
jared-rimmer authored Sep 8, 2022
1 parent c994717 commit 82c8d6a
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 1 deletion.
7 changes: 7 additions & 0 deletions .changes/unreleased/Features-20220908-081315.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
kind: Features
body: Add invocation args dict to ProviderContext class
time: 2022-09-08T08:13:15.17337+01:00
custom:
Author: jared-rimmer
Issue: "5524"
PR: "5782"
6 changes: 5 additions & 1 deletion core/dbt/context/providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
from dbt.config import IsFQNResource
from dbt.node_types import NodeType, ModelLanguage

from dbt.utils import merge, AttrDict, MultiDict
from dbt.utils import merge, AttrDict, MultiDict, args_to_dict

from dbt import selected_resources

Expand Down Expand Up @@ -710,6 +710,10 @@ def _get_namespace_builder(self):
self.model,
)

@contextproperty
def invocation_args_dict(self):
return args_to_dict(self.config.args)

@contextproperty
def _sql_results(self) -> Dict[str, AttrDict]:
return self.sql_results
Expand Down
17 changes: 17 additions & 0 deletions test/unit/test_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ def assert_has_keys(required_keys: Set[str], maybe_keys: Set[str], ctx: Dict[str
"sql_now",
"adapter_macro",
"selected_resources",
"invocation_args_dict",
}
REQUIRED_MODEL_KEYS = REQUIRED_MACRO_KEYS | {"this", "compiled_code",}
MAYBE_KEYS = frozenset({"debug"})
Expand Down Expand Up @@ -417,6 +418,22 @@ def test_macro_runtime_context(config_postgres, manifest_fx, get_adapter, get_in
)
assert_has_keys(REQUIRED_MACRO_KEYS, MAYBE_KEYS, ctx)

def test_invocation_args_to_dict_in_macro_runtime_context(
config_postgres, manifest_fx, get_adapter, get_include_paths
):
ctx = providers.generate_runtime_macro_context(
macro=manifest_fx.macros["macro.root.macro_a"],
config=config_postgres,
manifest=manifest_fx,
package_name="root",
)

# Comes from dbt/flags.py as they are the only values set that aren't None at default
assert ctx["invocation_args_dict"]["event_buffer_size"] == 100000
assert ctx["invocation_args_dict"]["printer_width"] == 80

# Comes from unit/utils.py config_from_parts_or_dicts method
assert ctx["invocation_args_dict"]["profile_dir"] == "/dev/null"

def test_model_parse_context(config_postgres, manifest_fx, get_adapter, get_include_paths):
ctx = providers.generate_parser_model_context(
Expand Down
48 changes: 48 additions & 0 deletions tests/functional/context_methods/test_builtin_functions.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pytest
import json

from dbt.tests.util import run_dbt, run_dbt_and_capture, write_file
from dbt.exceptions import CompilationException
Expand All @@ -23,6 +24,12 @@
{% endmacro %}
"""

macros__validate_invocation_sql = """
{% macro validate_invocation(my_variable) %}
{{ log("invocation_result: "~ invocation_args_dict) }}
{% endmacro %}
"""

models__set_exception_sql = """
{% set set_strict_result = set_strict(1) %}
"""
Expand All @@ -38,6 +45,7 @@ def macros(self):
return {
"validate_set.sql": macros__validate_set_sql,
"validate_zip.sql": macros__validate_zip_sql,
"validate_invocation.sql": macros__validate_invocation_sql,
}

def test_builtin_set_function(self, project):
Expand All @@ -55,6 +63,46 @@ def test_builtin_zip_function(self, project):
assert f"zip_result: {expected_zip}" in log_output
assert f"zip_strict_result: {expected_zip}" in log_output

def test_builtin_invocation_args_dict_function(self, project):
_, log_output = run_dbt_and_capture(
[
"--debug",
"--log-format=json",
"run-operation",
"validate_invocation",
"--args",
"{my_variable: test_variable}",
]
)

parsed_logs = []
for line in log_output.split("\n"):
try:
log = json.loads(line)
except ValueError:
continue

parsed_logs.append(log)

# Value of msg is a string
result = next(
(
item
for item in parsed_logs
if "invocation_result" in item["data"].get("msg", "msg")
),
False,
)

assert result

# Result is checked in two parts because profiles_dir is unique each test run
expected = "invocation_result: {'debug': True, 'log_format': 'json', 'write_json': True, 'use_colors': True, 'printer_width': 80, 'version_check': True, 'partial_parse': True, 'static_parser': True, 'profiles_dir': "
assert expected in str(result)

expected = "'send_anonymous_usage_stats': False, 'event_buffer_size': 100000, 'quiet': False, 'no_print': False, 'macro': 'validate_invocation', 'args': '{my_variable: test_variable}', 'which': 'run-operation', 'rpc_method': 'run-operation', 'indirect_selection': 'eager'}"
assert expected in str(result)


class TestContextBuiltinExceptions:
# Assert compilation errors are raised with _strict equivalents
Expand Down

0 comments on commit 82c8d6a

Please sign in to comment.