Skip to content

Commit

Permalink
[1.7 backport] buffer deprecations to respect --quiet and --warn-erro…
Browse files Browse the repository at this point in the history
…r-options (#10542)
  • Loading branch information
MichelleArk committed Aug 7, 2024
1 parent 9264ea9 commit abf7ff0
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 30 deletions.
6 changes: 6 additions & 0 deletions .changes/unreleased/Fixes-20240806-194843.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Fixes
body: respect --quiet and --warn-error-options for flag deprecations
time: 2024-08-06T19:48:43.399453-04:00
custom:
Author: michelleark
Issue: "10105"
4 changes: 3 additions & 1 deletion core/dbt/cli/flags.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from dbt.config.project import read_project_flags
from dbt.contracts.project import ProjectFlags
from dbt.exceptions import DbtInternalError
from dbt.deprecations import renamed_env_var
from dbt.deprecations import fire_buffered_deprecations, renamed_env_var
from dbt.helper_types import WarnErrorOptions

if os.name != "nt":
Expand Down Expand Up @@ -302,6 +302,8 @@ def fire_deprecations(self):
# not get pickled when written to disk as json.
object.__delattr__(self, "deprecated_env_var_warnings")

fire_buffered_deprecations()

@classmethod
def from_dict(cls, command: CliCommand, args_dict: Dict[str, Any]) -> "Flags":
command_arg_list = command_params(command, args_dict)
Expand Down
4 changes: 2 additions & 2 deletions core/dbt/config/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -819,8 +819,8 @@ def read_project_flags(project_dir: str, profiles_dir: str) -> ProjectFlags:

if profile_project_flags:
# This can't use WARN_ERROR or WARN_ERROR_OPTIONS because they're in
# the config that we're loading. Uses special "warn" method.
deprecations.warn("project-flags-moved")
# the config that we're loading. Uses special "buffer" method and fired after flags are initialized in preflight.
deprecations.buffer("project-flags-moved")
project_flags = profile_project_flags

if project_flags is not None:
Expand Down
28 changes: 17 additions & 11 deletions core/dbt/deprecations.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import abc
from typing import Optional, Set, List, Dict, ClassVar
from typing import Callable, ClassVar, Dict, List, Optional, Set

import dbt.exceptions

import dbt.tracking
from dbt.events.functions import warn_or_error


class DBTDeprecation:
Expand Down Expand Up @@ -36,7 +37,7 @@ def event(self) -> abc.ABCMeta:
def show(self, *args, **kwargs) -> None:
if self.name not in active_deprecations:
event = self.event(**kwargs)
dbt.events.functions.warn_or_error(event)
warn_or_error(event)
self.track_deprecation_warn()
active_deprecations.add(self.name)

Expand Down Expand Up @@ -100,15 +101,6 @@ class ProjectFlagsMovedDeprecation(DBTDeprecation):
_name = "project-flags-moved"
_event = "ProjectFlagsMovedDeprecation"

def show(self, *args, **kwargs) -> None:
if self.name not in active_deprecations:
event = self.event(**kwargs)
# We can't do warn_or_error because the ProjectFlags
# is where that is set up and we're just reading it.
dbt.events.functions.fire_event(event)
self.track_deprecation_warn()
active_deprecations.add(self.name)


class PackageMaterializationOverrideDeprecation(DBTDeprecation):
_name = "package-materialization-override"
Expand Down Expand Up @@ -138,6 +130,13 @@ def warn(name, *args, **kwargs):
deprecations[name].show(*args, **kwargs)


def buffer(name: str, *args, **kwargs):
def show_callback():
deprecations[name].show(*args, **kwargs)

buffered_deprecations.append(show_callback)


# these are globally available
# since modules are only imported once, active_deprecations is a singleton

Expand All @@ -159,6 +158,13 @@ def warn(name, *args, **kwargs):

deprecations: Dict[str, DBTDeprecation] = {d.name: d for d in deprecations_list}

buffered_deprecations: List[Callable] = []


def reset_deprecations():
active_deprecations.clear()


def fire_buffered_deprecations():
[dep_fn() for dep_fn in buffered_deprecations]
buffered_deprecations.clear()
41 changes: 36 additions & 5 deletions tests/functional/deprecations/test_deprecations.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from dbt import deprecations
import dbt.exceptions
from dbt.tests.util import run_dbt, write_file
from dbt.tests.util import run_dbt, run_dbt_and_capture, write_file
import yaml


Expand Down Expand Up @@ -160,7 +160,7 @@ def test_exposure_name_fail(self, project):
assert expected_msg in exc_str


class TestPrjectFlagsMovedDeprecation:
class TestProjectFlagsMovedDeprecation:
@pytest.fixture(scope="class")
def profiles_config_update(self):
return {
Expand All @@ -183,6 +183,37 @@ def models(self):
def test_profile_config_deprecation(self, project):
deprecations.reset_deprecations()
assert deprecations.active_deprecations == set()
run_dbt(["parse"])
expected = {"project-flags-moved"}
assert expected == deprecations.active_deprecations

_, logs = run_dbt_and_capture(["parse"])

assert (
"User config should be moved from the 'config' key in profiles.yml to the 'flags' key in dbt_project.yml."
in logs
)
assert deprecations.active_deprecations == {"project-flags-moved"}


class TestProjectFlagsMovedDeprecationQuiet(TestProjectFlagsMovedDeprecation):
def test_profile_config_deprecation(self, project):
deprecations.reset_deprecations()
assert deprecations.active_deprecations == set()

_, logs = run_dbt_and_capture(["--quiet", "parse"])

assert (
"User config should be moved from the 'config' key in profiles.yml to the 'flags' key in dbt_project.yml."
not in logs
)
assert deprecations.active_deprecations == {"project-flags-moved"}


class TestProjectFlagsMovedDeprecationWarnErrorOptions(TestProjectFlagsMovedDeprecation):
def test_profile_config_deprecation(self, project):
deprecations.reset_deprecations()
with pytest.raises(dbt.exceptions.EventCompilationError):
run_dbt(["--warn-error-options", "{'include': 'all'}", "parse"])

with pytest.raises(dbt.exceptions.EventCompilationError):
run_dbt(
["--warn-error-options", "{'include': ['ProjectFlagsMovedDeprecation']}", "parse"]
)
43 changes: 32 additions & 11 deletions tests/unit/test_deprecations.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,36 @@
from dbt.internal_deprecations import deprecated
from dbt.flags import set_from_args
from argparse import Namespace
import pytest

import dbt.deprecations as deprecations

@deprecated(reason="just because", version="1.23.0", suggested_action="Make some updates")
def to_be_decorated():
return 5

@pytest.fixture(scope="function")
def active_deprecations():
assert not deprecations.active_deprecations

# simple test that the return value is not modified
def test_deprecated_func():
set_from_args(Namespace(WARN_ERROR=False), None)
assert hasattr(to_be_decorated, "__wrapped__")
assert to_be_decorated() == 5
yield deprecations.active_deprecations

deprecations.reset_deprecations()


@pytest.fixture(scope="function")
def buffered_deprecations():
assert not deprecations.buffered_deprecations

yield deprecations.buffered_deprecations

deprecations.buffered_deprecations.clear()


def test_buffer_deprecation(active_deprecations, buffered_deprecations):
deprecations.buffer("project-flags-moved")

assert active_deprecations == set()
assert len(buffered_deprecations) == 1


def test_fire_buffered_deprecations(active_deprecations, buffered_deprecations):
deprecations.buffer("project-flags-moved")
deprecations.fire_buffered_deprecations()

assert active_deprecations == set(["project-flags-moved"])
assert len(buffered_deprecations) == 0
15 changes: 15 additions & 0 deletions tests/unit/test_internal_deprecations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from dbt.internal_deprecations import deprecated
from dbt.flags import set_from_args
from argparse import Namespace


@deprecated(reason="just because", version="1.23.0", suggested_action="Make some updates")
def to_be_decorated():
return 5


# simple test that the return value is not modified
def test_deprecated_func():
set_from_args(Namespace(WARN_ERROR=False), None)
assert hasattr(to_be_decorated, "__wrapped__")
assert to_be_decorated() == 5

0 comments on commit abf7ff0

Please sign in to comment.