Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[1.6 backport] buffer deprecations to respect --quiet and --warn-error-options #10543

Merged
merged 2 commits into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -304,6 +304,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 @@ -791,8 +791,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
Loading