Skip to content

Commit

Permalink
backport: buffer deprecations to respect --quiet and --warn-error-opt…
Browse files Browse the repository at this point in the history
…ions (#10541)
  • Loading branch information
MichelleArk authored Aug 7, 2024
1 parent 4f50172 commit 60315b6
Show file tree
Hide file tree
Showing 7 changed files with 120 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"
7 changes: 5 additions & 2 deletions core/dbt/cli/flags.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@
from dbt.cli.types import Command as CliCommand
from dbt.config.project import read_project_flags
from dbt.contracts.project import ProjectFlags
from dbt.deprecations import fire_buffered_deprecations, renamed_env_var
from dbt.events import ALL_EVENT_NAMES
from dbt_common import ui
from dbt_common.events import functions
from dbt_common.exceptions import DbtInternalError
from dbt_common.clients import jinja
from dbt.deprecations import renamed_env_var
from dbt_common.helper_types import WarnErrorOptions
from dbt.events import ALL_EVENT_NAMES


if os.name != "nt":
# https://bugs.python.org/issue41567
Expand Down Expand Up @@ -347,6 +348,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 @@ -832,8 +832,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
27 changes: 16 additions & 11 deletions core/dbt/deprecations.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import abc
from typing import Optional, Set, List, Dict, ClassVar
from typing import Callable, ClassVar, Dict, List, Optional, Set

import dbt.tracking

from dbt.events import types as core_types
from dbt_common.events.functions import warn_or_error, fire_event
from dbt_common.events.functions import warn_or_error


class DBTDeprecation:
Expand Down Expand Up @@ -108,15 +108,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.
fire_event(event)
self.track_deprecation_warn()
active_deprecations.add(self.name)


class PackageMaterializationOverrideDeprecation(DBTDeprecation):
_name = "package-materialization-override"
Expand Down Expand Up @@ -156,6 +147,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 @@ -179,6 +177,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()
48 changes: 44 additions & 4 deletions tests/functional/deprecations/test_deprecations.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
import dbt_common

from dbt import deprecations
from dbt.tests.util import run_dbt, run_dbt_and_capture, write_file
from dbt_common.exceptions import EventCompilationError
from tests.functional.deprecations.fixtures import (
models_trivial__model_sql,
bad_name_yaml,
)
from dbt.tests.util import run_dbt, write_file
import yaml


Expand Down Expand Up @@ -143,6 +144,45 @@ 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(EventCompilationError):
run_dbt(["--warn-error-options", "{'include': 'all'}", "parse"])

with pytest.raises(EventCompilationError):
run_dbt(
["--warn-error-options", "{'include': ['ProjectFlagsMovedDeprecation']}", "parse"]
)

_, logs = run_dbt_and_capture(
["--warn-error-options", "{'silence': ['ProjectFlagsMovedDeprecation']}", "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
)
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 60315b6

Please sign in to comment.