Skip to content

Commit dad0eb8

Browse files
committed
fix!: pass macros to the last audit in load_multiple_audits
The final load_audit call in load_multiple_audits did not pass module_path, macros or jinja_macros, so the last (or only) AUDIT in a file was loaded with an empty python_env and no project jinja macros. Rendering a standalone audit that used a project macro then failed with "MacroEvalError: Macro '<name>' does not exist." Affected standalone audits now include the macros they reference, which changes their metadata hash and fingerprint. Fixes #6119 Signed-off-by: Markus Sagen <markus@studio555.io>
1 parent 849d6ed commit dad0eb8

2 files changed

Lines changed: 100 additions & 0 deletions

File tree

‎sqlmesh/core/audit/definition.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,9 @@ def load_multiple_audits(
528528
yield load_audit(
529529
expressions=audit_block,
530530
path=path,
531+
module_path=module_path,
532+
macros=macros,
533+
jinja_macros=jinja_macros,
531534
dialect=dialect,
532535
default_catalog=default_catalog,
533536
variables=variables,

‎tests/core/test_audit.py‎

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,103 @@ def test_load_standalone_with_macros(assert_exp_eq):
221221
assert "extra_macro" not in audit.python_env
222222

223223

224+
def test_load_multiple_single_standalone_with_macros():
225+
# Regression test for https://github.com/SQLMesh/sqlmesh/issues/6119
226+
# A standalone audit that is the *last* (and in this case only) AUDIT in its
227+
# file must still have access to project python macros passed into
228+
# `load_multiple_audits`.
229+
expressions = parse(
230+
"""
231+
AUDIT (
232+
name only_allowed,
233+
standalone true,
234+
);
235+
236+
SELECT 1 FROM some_table WHERE name NOT IN @allowed()
237+
"""
238+
)
239+
240+
macros = {
241+
"allowed": Executable(payload="def allowed(evaluator):\n return ['a']"),
242+
}
243+
244+
(audit,) = load_multiple_audits(expressions, path="/path/to/audit", macros=macros)
245+
246+
assert "allowed" in audit.python_env
247+
248+
249+
def test_load_multiple_last_standalone_with_macros():
250+
# Same as above, but for the last audit of a *multi*-audit file, to make sure
251+
# the fix doesn't just special-case single-audit files.
252+
expressions = parse(
253+
"""
254+
AUDIT (
255+
name first_audit,
256+
standalone true,
257+
);
258+
259+
SELECT 1 FROM some_table WHERE col1 IS NULL;
260+
261+
AUDIT (
262+
name second_audit,
263+
standalone true,
264+
);
265+
266+
SELECT 1 FROM some_table WHERE name NOT IN @allowed()
267+
"""
268+
)
269+
270+
macros = {
271+
"allowed": Executable(payload="def allowed(evaluator):\n return ['a']"),
272+
}
273+
274+
first_audit, second_audit = load_multiple_audits(
275+
expressions, path="/path/to/audit", macros=macros
276+
)
277+
278+
assert "allowed" not in first_audit.python_env
279+
assert "allowed" in second_audit.python_env
280+
281+
282+
def test_load_multiple_last_standalone_with_jinja_macros():
283+
# Regression test for https://github.com/SQLMesh/sqlmesh/issues/6119
284+
# Same as test_load_multiple_single_standalone_with_macros, but for jinja macros:
285+
# a standalone audit that is the last (and in this case only) AUDIT in its file
286+
# must still have access to project jinja macros passed into `load_multiple_audits`.
287+
expressions = parse(
288+
"""
289+
AUDIT (
290+
name only_allowed,
291+
standalone true,
292+
);
293+
294+
JINJA_QUERY_BEGIN;
295+
SELECT
296+
*,
297+
{{ test_macro(1) }},
298+
FROM
299+
db.table t1
300+
WHERE
301+
col IS NULL
302+
JINJA_QUERY_END;
303+
"""
304+
)
305+
306+
macros = """
307+
{% macro test_macro(v) %}{{ v }}{% endmacro %}
308+
309+
{% macro extra_macro(v) %}{{ v + 1 }}{% endmacro %}
310+
"""
311+
312+
jinja_macros = JinjaMacroRegistry()
313+
jinja_macros.add_macros(MacroExtractor().extract(macros))
314+
315+
(audit,) = load_multiple_audits(expressions, path="/path/to/audit", jinja_macros=jinja_macros)
316+
317+
assert "test_macro" in audit.jinja_macros.root_macros
318+
assert "extra_macro" not in audit.jinja_macros.root_macros
319+
320+
224321
def test_load_standalone_with_jinja_macros(assert_exp_eq):
225322
expressions = parse(
226323
"""

0 commit comments

Comments
 (0)