Skip to content

Commit

Permalink
Merge branch 'main' into dbeatty/fix-10421
Browse files Browse the repository at this point in the history
  • Loading branch information
dbeatty10 authored Sep 20, 2024
2 parents 8d30e2a + e1d77b6 commit e87dd64
Show file tree
Hide file tree
Showing 46 changed files with 1,073 additions and 326 deletions.
6 changes: 6 additions & 0 deletions .changes/unreleased/Features-20240716-102457.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Features
body: Add to and to_columns to ColumnLevelConstraint and ModelLevelConstraint contracts
time: 2024-07-16T10:24:57.11251-04:00
custom:
Author: michelleark
Issue: "168"
6 changes: 6 additions & 0 deletions .changes/unreleased/Features-20240808-194933.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Features
body: Add Behavior Flag Framework
time: 2024-08-08T19:49:33.738569-04:00
custom:
Author: mikealfare
Issue: "178"
6 changes: 6 additions & 0 deletions .changes/unreleased/Features-20240918-114903.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Features
body: Add MergeBehavior.Object for snapshot column feature
time: 2024-09-18T11:49:03.257411-04:00
custom:
Author: gshank
Issue: "191"
6 changes: 6 additions & 0 deletions .changes/unreleased/Fixes-20240715-205355.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Fixes
body: Fix case-insensitive env vars for Windows
time: 2024-07-15T20:53:55.946355+01:00
custom:
Author: peterallenwebb aranke
Issue: "166"
6 changes: 6 additions & 0 deletions .changes/unreleased/Security-20240808-154439.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Security
body: Fix arbitrary file write during tarfile extraction
time: 2024-08-08T15:44:39.601346-05:00
custom:
Author: aranke
PR: "182"
6 changes: 6 additions & 0 deletions .changes/unreleased/Under the Hood-20240716-125753.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Under the Hood
body: Add record grouping mechanism to record/replay.
time: 2024-07-16T12:57:53.434099-04:00
custom:
Author: peterallenwebb
Issue: "169"
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,6 @@ cython_debug/
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
.idea/

# VSCode
.vscode/
2 changes: 1 addition & 1 deletion dbt_common/__about__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version = "1.5.0"
version = "1.9.0"
139 changes: 139 additions & 0 deletions dbt_common/behavior_flags.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import inspect
from typing import Any, Dict, List, TypedDict

try:
from typing import NotRequired
except ImportError:
# NotRequired was introduced in Python 3.11
# This is the suggested way to implement a TypedDict with optional arguments
from typing import Optional as NotRequired

from dbt_common.events.functions import fire_event
from dbt_common.events.types import BehaviorChangeEvent
from dbt_common.exceptions import CompilationError, DbtInternalError


class BehaviorFlag(TypedDict):
"""
Configuration used to create a BehaviorFlagRendered instance
Args:
name: the name of the behavior flag
default: default setting, starts as False, becomes True after a bake-in period
description: an additional message to send when the flag evaluates to False
docs_url: the url to the relevant docs on docs.getdbt.com
*Note*:
While `description` and `docs_url` are both listed as `NotRequired`, at least one of them is required.
This is validated when the flag is rendered in `BehaviorFlagRendered` below.
The goal of this restriction is to provide the end user with context so they can make an informed decision
about if, and when, to enable the behavior flag.
"""

name: str
default: bool
source: NotRequired[str]
description: NotRequired[str]
docs_url: NotRequired[str]


class BehaviorFlagRendered:
"""
A rendered behavior flag that gets used throughout dbt packages
Args:
flag: the configuration for the behavior flag
user_overrides: a set of user settings, one of which may be an override on this behavior flag
"""

def __init__(self, flag: BehaviorFlag, user_overrides: Dict[str, Any]) -> None:
self._validate(flag)

self.name = flag["name"]
self.setting = user_overrides.get(flag["name"], flag["default"])

default_description = (
f"""The behavior controlled by `{flag["name"]}` is currently turned off.\n"""
)
default_docs_url = "https://docs.getdbt.com/reference/global-configs/behavior-changes"
self._behavior_change_event = BehaviorChangeEvent(
flag_name=flag["name"],
flag_source=flag.get("source", self._default_source()),
description=flag.get("description", default_description),
docs_url=flag.get("docs_url", default_docs_url),
)

@staticmethod
def _validate(flag: BehaviorFlag) -> None:
if flag.get("description") is None and flag.get("docs_url") is None:
raise DbtInternalError(
"Behavior change flags require at least one of `description` and `docs_url`."
)

@property
def setting(self) -> bool:
if self._setting is False:
fire_event(self._behavior_change_event)
return self._setting

@setting.setter
def setting(self, value: bool) -> None:
self._setting = value

@property
def no_warn(self) -> bool:
return self._setting

@staticmethod
def _default_source() -> str:
"""
If the maintainer did not provide a source, default to the module that called this class.
For adapters, this will likely be `dbt.adapters.<foo>.impl` for `dbt-foo`.
"""
for frame in inspect.stack():
if module := inspect.getmodule(frame[0]):
if module.__name__ != __name__:
return module.__name__
return "Unknown"

def __bool__(self) -> bool:
return self.setting


class Behavior:
"""
A collection of behavior flags
This is effectively a dictionary that supports dot notation for easy reference, e.g.:
```python
if adapter.behavior.my_flag:
...
if adapter.behavior.my_flag.no_warn: # this will not fire the behavior change event
...
```
```jinja
{% if adapter.behavior.my_flag %}
...
{% endif %}
{% if adapter.behavior.my_flag.no_warn %} {# this will not fire the behavior change event #}
...
{% endif %}
```
Args:
flags: a list of configurations, one for each behavior flag
user_overrides: a set of user settings, which may include overrides on one or more of the behavior flags
"""

_flags: List[BehaviorFlagRendered]

def __init__(self, flags: List[BehaviorFlag], user_overrides: Dict[str, Any]) -> None:
self._flags = [BehaviorFlagRendered(flag, user_overrides) for flag in flags]

def __getattr__(self, name: str) -> BehaviorFlagRendered:
for flag in self._flags:
if flag.name == name:
return flag
raise CompilationError(f"The flag {name} has not be registered.")
4 changes: 2 additions & 2 deletions dbt_common/clients/agate_helper.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from codecs import BOM_UTF8

import agate # type: ignore
import agate
import datetime
import isodate
import json
Expand Down Expand Up @@ -149,7 +149,7 @@ def as_matrix(table):
return [r.values() for r in table.rows.values()]


def from_csv(abspath, text_columns, delimiter=","):
def from_csv(abspath, text_columns, delimiter=",") -> agate.Table:
type_tester = build_type_tester(text_columns=text_columns)
with open(abspath, encoding="utf-8") as fp:
if fp.read(1) != BOM:
Expand Down
Loading

0 comments on commit e87dd64

Please sign in to comment.