dbt-common 1.6.0__tar.gz → 1.8.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. {dbt_common-1.6.0 → dbt_common-1.8.0}/.gitignore +3 -0
  2. {dbt_common-1.6.0 → dbt_common-1.8.0}/PKG-INFO +1 -1
  3. dbt_common-1.8.0/dbt_common/__about__.py +1 -0
  4. dbt_common-1.8.0/dbt_common/behavior_flags.py +125 -0
  5. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/clients/agate_helper.py +2 -2
  6. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/clients/jinja.py +8 -6
  7. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/clients/system.py +27 -1
  8. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/context.py +2 -2
  9. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/contracts/config/base.py +12 -12
  10. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/contracts/util.py +10 -4
  11. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/dataclass_schema.py +4 -5
  12. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/events/contextvars.py +1 -1
  13. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/events/types.proto +16 -0
  14. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/events/types.py +39 -0
  15. dbt_common-1.8.0/dbt_common/events/types_pb2.py +77 -0
  16. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/exceptions/base.py +13 -13
  17. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/exceptions/system.py +2 -2
  18. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/invocation.py +1 -1
  19. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/semver.py +14 -14
  20. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/utils/casting.py +3 -2
  21. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/utils/connection.py +2 -1
  22. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/utils/jinja.py +7 -5
  23. {dbt_common-1.6.0 → dbt_common-1.8.0}/pyproject.toml +4 -2
  24. dbt_common-1.8.0/third-party-stubs/mashumaro/core/meta/helpers.pyi +70 -0
  25. dbt_common-1.6.0/dbt_common/__about__.py +0 -1
  26. dbt_common-1.6.0/dbt_common/events/types_pb2.py +0 -73
  27. dbt_common-1.6.0/third-party-stubs/mashumaro/core/meta/helpers.pyi +0 -58
  28. {dbt_common-1.6.0 → dbt_common-1.8.0}/CHANGELOG.md +0 -0
  29. {dbt_common-1.6.0 → dbt_common-1.8.0}/LICENSE +0 -0
  30. {dbt_common-1.6.0 → dbt_common-1.8.0}/README.md +0 -0
  31. {dbt_common-1.6.0 → dbt_common-1.8.0}/codecov.yml +0 -0
  32. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/__init__.py +0 -0
  33. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/clients/__init__.py +0 -0
  34. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/clients/_jinja_blocks.py +0 -0
  35. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/constants.py +0 -0
  36. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/contracts/__init__.py +0 -0
  37. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/contracts/config/__init__.py +0 -0
  38. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/contracts/config/materialization.py +0 -0
  39. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/contracts/config/metadata.py +0 -0
  40. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/contracts/config/properties.py +0 -0
  41. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/contracts/constraints.py +0 -0
  42. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/contracts/metadata.py +0 -0
  43. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/events/README.md +0 -0
  44. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/events/__init__.py +0 -0
  45. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/events/base_types.py +0 -0
  46. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/events/event_handler.py +0 -0
  47. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/events/event_manager.py +0 -0
  48. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/events/event_manager_client.py +0 -0
  49. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/events/format.py +0 -0
  50. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/events/functions.py +0 -0
  51. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/events/helpers.py +0 -0
  52. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/events/interfaces.py +0 -0
  53. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/events/logger.py +0 -0
  54. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/exceptions/__init__.py +0 -0
  55. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/exceptions/cache.py +0 -0
  56. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/exceptions/connection.py +0 -0
  57. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/exceptions/contracts.py +0 -0
  58. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/exceptions/events.py +0 -0
  59. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/exceptions/jinja.py +0 -0
  60. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/exceptions/macros.py +0 -0
  61. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/helper_types.py +0 -0
  62. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/py.typed +0 -0
  63. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/record.py +0 -0
  64. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/tests.py +0 -0
  65. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/ui.py +0 -0
  66. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/utils/__init__.py +0 -0
  67. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/utils/dict.py +0 -0
  68. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/utils/encoding.py +0 -0
  69. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/utils/executor.py +0 -0
  70. {dbt_common-1.6.0 → dbt_common-1.8.0}/dbt_common/utils/formatting.py +0 -0
  71. {dbt_common-1.6.0 → dbt_common-1.8.0}/docs/README.md +0 -0
  72. {dbt_common-1.6.0 → dbt_common-1.8.0}/docs/arch/adr-0001-build-tooling.md +0 -0
  73. {dbt_common-1.6.0 → dbt_common-1.8.0}/docs/guides/record_replay.md +0 -0
  74. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/agate/__init__.pyi +0 -0
  75. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/agate/data_types.pyi +0 -0
  76. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/colorama/__init__.pyi +0 -0
  77. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/isodate/__init__.pyi +0 -0
  78. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/__init__.pyi +0 -0
  79. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/config.pyi +0 -0
  80. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/core/__init__.pyi +0 -0
  81. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/core/const.pyi +0 -0
  82. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/core/helpers.pyi +0 -0
  83. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/core/meta/__init__.pyi +0 -0
  84. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/core/meta/code/__init__.pyi +0 -0
  85. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/core/meta/code/builder.pyi +0 -0
  86. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/core/meta/code/lines.pyi +0 -0
  87. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/core/meta/mixin.pyi +0 -0
  88. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/core/meta/types/__init__.pyi +0 -0
  89. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/core/meta/types/common.pyi +0 -0
  90. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/core/meta/types/pack.pyi +0 -0
  91. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/core/meta/types/unpack.pyi +0 -0
  92. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/dialect.pyi +0 -0
  93. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/exceptions.pyi +0 -0
  94. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/helper.pyi +0 -0
  95. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/jsonschema/__init__.pyi +0 -0
  96. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/jsonschema/annotations.pyi +0 -0
  97. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/jsonschema/builder.pyi +0 -0
  98. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/jsonschema/dialects.pyi +0 -0
  99. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/jsonschema/models.pyi +0 -0
  100. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/jsonschema/schema.pyi +0 -0
  101. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/mixins/__init__.pyi +0 -0
  102. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/mixins/dict.pyi +0 -0
  103. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/mixins/json.pyi +0 -0
  104. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/mixins/msgpack.pyi +0 -0
  105. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/mixins/orjson.pyi +0 -0
  106. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/mixins/toml.pyi +0 -0
  107. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/mixins/yaml.pyi +0 -0
  108. {dbt_common-1.6.0 → dbt_common-1.8.0}/third-party-stubs/mashumaro/types.pyi +0 -0
@@ -158,3 +158,6 @@ cython_debug/
158
158
  # and can be added to the global gitignore or merged into this file. For a more nuclear
159
159
  # option (not recommended) you can uncomment the following to ignore the entire idea folder.
160
160
  .idea/
161
+
162
+ # VSCode
163
+ .vscode/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: dbt-common
3
- Version: 1.6.0
3
+ Version: 1.8.0
4
4
  Summary: The shared common utilities that dbt-core and adapter implementations use
5
5
  Project-URL: Homepage, https://github.com/dbt-labs/dbt-common
6
6
  Project-URL: Repository, https://github.com/dbt-labs/dbt-common.git
@@ -0,0 +1 @@
1
+ version = "1.8.0"
@@ -0,0 +1,125 @@
1
+ import inspect
2
+ from typing import Any, Dict, List, TypedDict
3
+
4
+ try:
5
+ from typing import NotRequired
6
+ except ImportError:
7
+ # NotRequired was introduced in Python 3.11
8
+ # This is the suggested way to implement a TypedDict with optional arguments
9
+ from typing import Optional as NotRequired
10
+
11
+ from dbt_common.events.functions import fire_event
12
+ from dbt_common.events.types import BehaviorDeprecationEvent
13
+ from dbt_common.exceptions import CompilationError
14
+
15
+
16
+ class BehaviorFlag(TypedDict):
17
+ """
18
+ Configuration used to create a BehaviorFlagRendered instance
19
+
20
+ Args:
21
+ name: the name of the behavior flag
22
+ default: default setting, starts as False, becomes True after a bake-in period
23
+ deprecation_version: the version when the default will change to True
24
+ deprecation_message: an additional message to send when the flag evaluates to False
25
+ docs_url: the url to the relevant docs on docs.getdbt.com
26
+ """
27
+
28
+ name: str
29
+ default: bool
30
+ source: NotRequired[str]
31
+ deprecation_version: NotRequired[str]
32
+ deprecation_message: NotRequired[str]
33
+ docs_url: NotRequired[str]
34
+
35
+
36
+ class BehaviorFlagRendered:
37
+ """
38
+ A rendered behavior flag that gets used throughout dbt packages
39
+
40
+ Args:
41
+ flag: the configuration for the behavior flag
42
+ user_overrides: a set of user settings, one of which may be an override on this behavior flag
43
+ """
44
+
45
+ def __init__(self, flag: BehaviorFlag, user_overrides: Dict[str, Any]) -> None:
46
+ self.name = flag["name"]
47
+ self.setting = user_overrides.get(flag["name"], flag["default"])
48
+ self.deprecation_event = self._deprecation_event(flag)
49
+
50
+ @property
51
+ def setting(self) -> bool:
52
+ if self._setting is False:
53
+ fire_event(self.deprecation_event)
54
+ return self._setting
55
+
56
+ @setting.setter
57
+ def setting(self, value: bool) -> None:
58
+ self._setting = value
59
+
60
+ @property
61
+ def no_warn(self) -> bool:
62
+ return self._setting
63
+
64
+ def _deprecation_event(self, flag: BehaviorFlag) -> BehaviorDeprecationEvent:
65
+ return BehaviorDeprecationEvent(
66
+ flag_name=flag["name"],
67
+ flag_source=flag.get("source", self._default_source()),
68
+ deprecation_version=flag.get("deprecation_version"),
69
+ deprecation_message=flag.get("deprecation_message"),
70
+ docs_url=flag.get("docs_url"),
71
+ )
72
+
73
+ @staticmethod
74
+ def _default_source() -> str:
75
+ """
76
+ If the maintainer did not provide a source, default to the module that called this class.
77
+ For adapters, this will likely be `dbt.adapters.<foo>.impl` for `dbt-foo`.
78
+ """
79
+ for frame in inspect.stack():
80
+ if module := inspect.getmodule(frame[0]):
81
+ if module.__name__ != __name__:
82
+ return module.__name__
83
+ return "Unknown"
84
+
85
+ def __bool__(self) -> bool:
86
+ return self.setting
87
+
88
+
89
+ class Behavior:
90
+ """
91
+ A collection of behavior flags
92
+
93
+ This is effectively a dictionary that supports dot notation for easy reference, e.g.:
94
+ ```python
95
+ if adapter.behavior.my_flag:
96
+ ...
97
+
98
+ if adapter.behavior.my_flag.no_warn: # this will not fire the deprecation event
99
+ ...
100
+ ```
101
+ ```jinja
102
+ {% if adapter.behavior.my_flag %}
103
+ ...
104
+ {% endif %}
105
+
106
+ {% if adapter.behavior.my_flag.no_warn %} {# this will not fire the deprecation event #}
107
+ ...
108
+ {% endif %}
109
+ ```
110
+
111
+ Args:
112
+ flags: a list of configurations, one for each behavior flag
113
+ user_overrides: a set of user settings, which may include overrides on one or more of the behavior flags
114
+ """
115
+
116
+ _flags: List[BehaviorFlagRendered]
117
+
118
+ def __init__(self, flags: List[BehaviorFlag], user_overrides: Dict[str, Any]) -> None:
119
+ self._flags = [BehaviorFlagRendered(flag, user_overrides) for flag in flags]
120
+
121
+ def __getattr__(self, name: str) -> BehaviorFlagRendered:
122
+ for flag in self._flags:
123
+ if flag.name == name:
124
+ return flag
125
+ raise CompilationError(f"The flag {name} has not be registered.")
@@ -1,6 +1,6 @@
1
1
  from codecs import BOM_UTF8
2
2
 
3
- import agate # type: ignore
3
+ import agate
4
4
  import datetime
5
5
  import isodate
6
6
  import json
@@ -149,7 +149,7 @@ def as_matrix(table):
149
149
  return [r.values() for r in table.rows.values()]
150
150
 
151
151
 
152
- def from_csv(abspath, text_columns, delimiter=","):
152
+ def from_csv(abspath, text_columns, delimiter=",") -> agate.Table:
153
153
  type_tester = build_type_tester(text_columns=text_columns)
154
154
  with open(abspath, encoding="utf-8") as fp:
155
155
  if fp.read(1) != BOM:
@@ -9,12 +9,12 @@ from itertools import chain, islice
9
9
  from typing import Any, Callable, Dict, Iterator, List, Mapping, Optional, Union, Set, Type
10
10
  from typing_extensions import Protocol
11
11
 
12
- import jinja2 # type: ignore
13
- import jinja2.ext # type: ignore
14
- import jinja2.nativetypes # type: ignore
15
- import jinja2.nodes # type: ignore
16
- import jinja2.parser # type: ignore
17
- import jinja2.sandbox # type: ignore
12
+ import jinja2
13
+ import jinja2.ext
14
+ import jinja2.nativetypes
15
+ import jinja2.nodes
16
+ import jinja2.parser
17
+ import jinja2.sandbox
18
18
 
19
19
  from dbt_common.tests import test_caching_enabled
20
20
  from dbt_common.utils.jinja import (
@@ -124,6 +124,7 @@ class MacroFuzzTemplate(jinja2.nativetypes.NativeTemplate):
124
124
  "shared or locals parameters."
125
125
  )
126
126
 
127
+ vars = {} if vars is None else vars
127
128
  parent = ChainMap(vars, self.globals) if self.globals else vars
128
129
 
129
130
  return self.environment.context_class(self.environment, parent, self.name, self.blocks)
@@ -544,6 +545,7 @@ _TESTING_BLOCKS_CACHE: Dict[int, List[Union[BlockData, BlockTag]]] = {}
544
545
 
545
546
  def _get_blocks_hash(text: str, allowed_blocks: Optional[Set[str]], collect_raw_data: bool) -> int:
546
547
  """Provides a hash function over the arguments to extract_toplevel_blocks, in order to support caching."""
548
+ allowed_blocks = allowed_blocks or set()
547
549
  allowed_tuple = tuple(sorted(allowed_blocks) or [])
548
550
  return text.__hash__() + allowed_tuple.__hash__() + collect_raw_data.__hash__()
549
551
 
@@ -52,6 +52,7 @@ class FindMatchingParams:
52
52
  root_path: str
53
53
  relative_paths_to_search: List[str]
54
54
  file_pattern: str
55
+
55
56
  # ignore_spec: Optional[PathSpec] = None
56
57
 
57
58
  def __init__(
@@ -608,11 +609,36 @@ def rename(from_path: str, to_path: str, force: bool = False) -> None:
608
609
  shutil.move(from_path, to_path)
609
610
 
610
611
 
612
+ def safe_extract(tarball: tarfile.TarFile, path: str = ".") -> None:
613
+ """
614
+ Fix for CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
615
+ Solution copied from https://github.com/mindsdb/mindsdb/blob/main/mindsdb/utilities/fs.py
616
+ """
617
+
618
+ def _is_within_directory(directory, target):
619
+ abs_directory = os.path.abspath(directory)
620
+ abs_target = os.path.abspath(target)
621
+ prefix = os.path.commonprefix([abs_directory, abs_target])
622
+ return prefix == abs_directory
623
+
624
+ # for py >= 3.12
625
+ if hasattr(tarball, "data_filter"):
626
+ tarball.extractall(path, filter="data")
627
+ else:
628
+ members = tarball.getmembers()
629
+ for member in members:
630
+ member_path = os.path.join(path, member.name)
631
+ if not _is_within_directory(path, member_path):
632
+ raise tarfile.OutsideDestinationError(member, path)
633
+
634
+ tarball.extractall(path, members=members)
635
+
636
+
611
637
  def untar_package(tar_path: str, dest_dir: str, rename_to: Optional[str] = None) -> None:
612
638
  tar_path = convert_path(tar_path)
613
639
  tar_dir_name = None
614
640
  with tarfile.open(tar_path, "r:gz") as tarball:
615
- tarball.extractall(dest_dir)
641
+ safe_extract(tarball, dest_dir)
616
642
  tar_dir_name = os.path.commonprefix(tarball.getnames())
617
643
  if rename_to:
618
644
  downloaded_path = os.path.join(dest_dir, tar_dir_name)
@@ -6,7 +6,7 @@ from dbt_common.constants import PRIVATE_ENV_PREFIX, SECRET_ENV_PREFIX
6
6
  from dbt_common.record import Recorder
7
7
 
8
8
 
9
- class CaseInsensitiveMapping(Mapping):
9
+ class CaseInsensitiveMapping(Mapping[str, str]):
10
10
  def __init__(self, env: Mapping[str, str]):
11
11
  self._env = {k.casefold(): (k, v) for k, v in env.items()}
12
12
 
@@ -65,7 +65,7 @@ _INVOCATION_CONTEXT_VAR: ContextVar[InvocationContext] = ContextVar("DBT_INVOCAT
65
65
 
66
66
 
67
67
  def reliably_get_invocation_var() -> ContextVar[InvocationContext]:
68
- invocation_var: Optional[ContextVar] = next(
68
+ invocation_var: Optional[ContextVar[InvocationContext]] = next(
69
69
  (cv for cv in copy_context() if cv.name == _INVOCATION_CONTEXT_VAR.name), None
70
70
  )
71
71
 
@@ -4,7 +4,7 @@ from __future__ import annotations
4
4
  from dataclasses import dataclass, Field
5
5
 
6
6
  from itertools import chain
7
- from typing import Callable, Dict, Any, List, TypeVar, Type
7
+ from typing import Any, Callable, Dict, Iterator, List, Type, TypeVar
8
8
 
9
9
  from dbt_common.contracts.config.metadata import Metadata
10
10
  from dbt_common.exceptions import CompilationError, DbtInternalError
@@ -17,11 +17,11 @@ T = TypeVar("T", bound="BaseConfig")
17
17
  @dataclass
18
18
  class BaseConfig(AdditionalPropertiesAllowed, Replaceable):
19
19
  # enable syntax like: config['key']
20
- def __getitem__(self, key):
20
+ def __getitem__(self, key: str) -> Any:
21
21
  return self.get(key)
22
22
 
23
23
  # like doing 'get' on a dictionary
24
- def get(self, key, default=None):
24
+ def get(self, key: str, default: Any = None) -> Any:
25
25
  if hasattr(self, key):
26
26
  return getattr(self, key)
27
27
  elif key in self._extra:
@@ -30,13 +30,13 @@ class BaseConfig(AdditionalPropertiesAllowed, Replaceable):
30
30
  return default
31
31
 
32
32
  # enable syntax like: config['key'] = value
33
- def __setitem__(self, key, value):
33
+ def __setitem__(self, key: str, value) -> None:
34
34
  if hasattr(self, key):
35
35
  setattr(self, key, value)
36
36
  else:
37
37
  self._extra[key] = value
38
38
 
39
- def __delitem__(self, key):
39
+ def __delitem__(self, key: str) -> None:
40
40
  if hasattr(self, key):
41
41
  msg = (
42
42
  'Error, tried to delete config key "{}": Cannot delete ' "built-in keys"
@@ -45,7 +45,7 @@ class BaseConfig(AdditionalPropertiesAllowed, Replaceable):
45
45
  else:
46
46
  del self._extra[key]
47
47
 
48
- def _content_iterator(self, include_condition: Callable[[Field], bool]):
48
+ def _content_iterator(self, include_condition: Callable[[Field[Any]], bool]) -> Iterator[str]:
49
49
  seen = set()
50
50
  for fld, _ in self._get_fields():
51
51
  seen.add(fld.name)
@@ -57,10 +57,10 @@ class BaseConfig(AdditionalPropertiesAllowed, Replaceable):
57
57
  seen.add(key)
58
58
  yield key
59
59
 
60
- def __iter__(self):
60
+ def __iter__(self) -> Iterator[str]:
61
61
  yield from self._content_iterator(include_condition=lambda f: True)
62
62
 
63
- def __len__(self):
63
+ def __len__(self) -> int:
64
64
  return len(self._get_fields()) + len(self._extra)
65
65
 
66
66
  @staticmethod
@@ -76,7 +76,7 @@ class BaseConfig(AdditionalPropertiesAllowed, Replaceable):
76
76
  elif key in unrendered and key not in other:
77
77
  return False
78
78
  else:
79
- return unrendered[key] == other[key]
79
+ return bool(unrendered[key] == other[key])
80
80
 
81
81
  @classmethod
82
82
  def same_contents(cls, unrendered: Dict[str, Any], other: Dict[str, Any]) -> bool:
@@ -203,11 +203,11 @@ class CompareBehavior(Metadata):
203
203
  return "compare"
204
204
 
205
205
  @classmethod
206
- def should_include(cls, fld: Field) -> bool:
206
+ def should_include(cls, fld: Field[Any]) -> bool:
207
207
  return cls.from_field(fld) == cls.Include
208
208
 
209
209
 
210
- def _listify(value: Any) -> List:
210
+ def _listify(value: Any) -> List[Any]:
211
211
  if isinstance(value, list):
212
212
  return value[:]
213
213
  else:
@@ -221,7 +221,7 @@ def _merge_field_value(
221
221
  merge_behavior: MergeBehavior,
222
222
  self_value: Any,
223
223
  other_value: Any,
224
- ):
224
+ ) -> Any:
225
225
  if merge_behavior == MergeBehavior.Clobber:
226
226
  return other_value
227
227
  elif merge_behavior == MergeBehavior.Append:
@@ -1,21 +1,27 @@
1
1
  import dataclasses
2
+ from typing import Any, TypeVar
3
+
4
+ _R = TypeVar("_R", bound="Replaceable")
2
5
 
3
6
 
4
7
  # TODO: remove from dbt_common.contracts.util:: Replaceable + references
5
8
  class Replaceable:
6
- def replace(self, **kwargs):
7
- return dataclasses.replace(self, **kwargs)
9
+ def replace(self: _R, **kwargs: Any) -> _R:
10
+ return dataclasses.replace(self, **kwargs) # type: ignore
11
+
12
+
13
+ _M = TypeVar("_M", bound="Mergeable")
8
14
 
9
15
 
10
16
  class Mergeable(Replaceable):
11
- def merged(self, *args):
17
+ def merged(self: _M, *args: Any) -> _M:
12
18
  """Perform a shallow merge, where the last non-None write wins. This is
13
19
  intended to merge dataclasses that are a collection of optional values.
14
20
  """
15
21
  replacements = {}
16
22
  cls = type(self)
17
23
  for arg in args:
18
- for field in dataclasses.fields(cls):
24
+ for field in dataclasses.fields(cls): # type: ignore
19
25
  value = getattr(arg, field.name)
20
26
  if value is not None:
21
27
  replacements[field.name] = value
@@ -1,4 +1,4 @@
1
- from typing import Any, cast, ClassVar, Dict, get_type_hints, List, Optional, Tuple
1
+ from typing import Any, ClassVar, Dict, get_type_hints, List, Optional, Tuple, Union
2
2
  import re
3
3
  import jsonschema
4
4
  from dataclasses import fields, Field
@@ -6,7 +6,6 @@ from enum import Enum
6
6
  from datetime import datetime
7
7
  from dateutil.parser import parse
8
8
 
9
- # type: ignore
10
9
  from mashumaro.config import (
11
10
  TO_DICT_ADD_OMIT_NONE_FLAG,
12
11
  ADD_SERIALIZATION_CONTEXT,
@@ -33,8 +32,8 @@ class DateTimeSerialization(SerializationStrategy):
33
32
  out += "Z"
34
33
  return out
35
34
 
36
- def deserialize(self, value) -> datetime:
37
- return value if isinstance(value, datetime) else parse(cast(str, value))
35
+ def deserialize(self, value: Union[datetime, str]) -> datetime:
36
+ return value if isinstance(value, datetime) else parse(value)
38
37
 
39
38
 
40
39
  class dbtMashConfig(MashBaseConfig):
@@ -92,7 +91,7 @@ class dbtClassMixin(DataClassMessagePackMixin):
92
91
  return json_schema
93
92
 
94
93
  @classmethod
95
- def validate(cls, data):
94
+ def validate(cls, data: Any) -> None:
96
95
  json_schema = cls.json_schema()
97
96
  validator = jsonschema.Draft7Validator(json_schema)
98
97
  error = next(iter(validator.iter_errors(data)), None)
@@ -22,7 +22,7 @@ def get_contextvars(prefix: str) -> Dict[str, Any]:
22
22
  return rv
23
23
 
24
24
 
25
- def get_node_info():
25
+ def get_node_info() -> Dict[str, Any]:
26
26
  cvars = get_contextvars(LOG_PREFIX)
27
27
  if "node_info" in cvars:
28
28
  return cvars["node_info"]
@@ -23,6 +23,22 @@ message GenericMessage {
23
23
  EventInfo info = 1;
24
24
  }
25
25
 
26
+ // D - Deprecations
27
+
28
+ // D018
29
+ message BehaviorDeprecationEvent {
30
+ string flag_name = 1;
31
+ string flag_source = 2;
32
+ string deprecation_version = 3;
33
+ string deprecation_message = 4;
34
+ string docs_url = 5;
35
+ }
36
+
37
+ message BehaviorDeprecationEventMsg {
38
+ EventInfo info = 1;
39
+ BehaviorDeprecationEvent data = 2;
40
+ }
41
+
26
42
  // M - Deps generation
27
43
 
28
44
  // M020
@@ -1,7 +1,11 @@
1
+ from typing import Optional
2
+
1
3
  from dbt_common.events.base_types import (
2
4
  DebugLevel,
3
5
  InfoLevel,
6
+ WarnLevel,
4
7
  )
8
+ from dbt_common.ui import warning_tag
5
9
 
6
10
 
7
11
  # The classes in this file represent the data necessary to describe a
@@ -28,6 +32,41 @@ from dbt_common.events.base_types import (
28
32
  #
29
33
  # The basic idea is that event codes roughly translate to the natural order of running a dbt task
30
34
 
35
+
36
+ # =======================================================
37
+ # D - Deprecations
38
+ # =======================================================
39
+
40
+
41
+ class BehaviorDeprecationEvent(WarnLevel):
42
+ flag_name: str
43
+ flag_source: str
44
+ deprecation_version: Optional[str]
45
+ deprecation_message: Optional[str]
46
+ docs_url: Optional[str]
47
+
48
+ def code(self) -> str:
49
+ return "D018"
50
+
51
+ def message(self) -> str:
52
+ msg = f"The legacy behavior controlled by `{self.flag_name}` is deprecated.\n"
53
+
54
+ if self.deprecation_version:
55
+ msg = (
56
+ f"The legacy behavior is expected to be retired in `{self.deprecation_version}`.\n"
57
+ )
58
+
59
+ msg += f"The new behavior can be turned on by setting `flags.{self.flag_name}` to `True` in `dbt_project.yml`.\n"
60
+
61
+ if self.deprecation_message:
62
+ msg += f"{self.deprecation_message}.\n"
63
+
64
+ docs_url = self.docs_url or f"https://docs.getdbt.com/search?q={self.flag_name}"
65
+ msg += f"Visit {docs_url} for more information."
66
+
67
+ return warning_tag(msg)
68
+
69
+
31
70
  # =======================================================
32
71
  # M - Deps generation
33
72
  # =======================================================
@@ -0,0 +1,77 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: types.proto
4
+ # Protobuf Python Version: 4.25.2
5
+ """Generated protocol buffer code."""
6
+ from google.protobuf import descriptor as _descriptor
7
+ from google.protobuf import descriptor_pool as _descriptor_pool
8
+ from google.protobuf import symbol_database as _symbol_database
9
+ from google.protobuf.internal import builder as _builder
10
+ # @@protoc_insertion_point(imports)
11
+
12
+ _sym_db = _symbol_database.Default()
13
+
14
+
15
+ from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
16
+
17
+
18
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0btypes.proto\x12\x0bproto_types\x1a\x1fgoogle/protobuf/timestamp.proto\"\x91\x02\n\tEventInfo\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04\x63ode\x18\x02 \x01(\t\x12\x0b\n\x03msg\x18\x03 \x01(\t\x12\r\n\x05level\x18\x04 \x01(\t\x12\x15\n\rinvocation_id\x18\x05 \x01(\t\x12\x0b\n\x03pid\x18\x06 \x01(\x05\x12\x0e\n\x06thread\x18\x07 \x01(\t\x12&\n\x02ts\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x30\n\x05\x65xtra\x18\t \x03(\x0b\x32!.proto_types.EventInfo.ExtraEntry\x12\x10\n\x08\x63\x61tegory\x18\n \x01(\t\x1a,\n\nExtraEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"6\n\x0eGenericMessage\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\"\x8e\x01\n\x18\x42\x65haviorDeprecationEvent\x12\x11\n\tflag_name\x18\x01 \x01(\t\x12\x13\n\x0b\x66lag_source\x18\x02 \x01(\t\x12\x1b\n\x13\x64\x65precation_version\x18\x03 \x01(\t\x12\x1b\n\x13\x64\x65precation_message\x18\x04 \x01(\t\x12\x10\n\x08\x64ocs_url\x18\x05 \x01(\t\"x\n\x1b\x42\x65haviorDeprecationEventMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12\x33\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32%.proto_types.BehaviorDeprecationEvent\"1\n\x11RetryExternalCall\x12\x0f\n\x07\x61ttempt\x18\x01 \x01(\x05\x12\x0b\n\x03max\x18\x02 \x01(\x05\"j\n\x14RetryExternalCallMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12,\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x1e.proto_types.RetryExternalCall\"#\n\x14RecordRetryException\x12\x0b\n\x03\x65xc\x18\x01 \x01(\t\"p\n\x17RecordRetryExceptionMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12/\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32!.proto_types.RecordRetryException\"@\n\x13SystemCouldNotWrite\x12\x0c\n\x04path\x18\x01 \x01(\t\x12\x0e\n\x06reason\x18\x02 \x01(\t\x12\x0b\n\x03\x65xc\x18\x03 \x01(\t\"n\n\x16SystemCouldNotWriteMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12.\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32 .proto_types.SystemCouldNotWrite\"!\n\x12SystemExecutingCmd\x12\x0b\n\x03\x63md\x18\x01 \x03(\t\"l\n\x15SystemExecutingCmdMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12-\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x1f.proto_types.SystemExecutingCmd\"\x1c\n\x0cSystemStdOut\x12\x0c\n\x04\x62msg\x18\x01 \x01(\t\"`\n\x0fSystemStdOutMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12\'\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x19.proto_types.SystemStdOut\"\x1c\n\x0cSystemStdErr\x12\x0c\n\x04\x62msg\x18\x01 \x01(\t\"`\n\x0fSystemStdErrMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12\'\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x19.proto_types.SystemStdErr\",\n\x16SystemReportReturnCode\x12\x12\n\nreturncode\x18\x01 \x01(\x05\"t\n\x19SystemReportReturnCodeMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12\x31\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32#.proto_types.SystemReportReturnCode\"\x19\n\nFormatting\x12\x0b\n\x03msg\x18\x01 \x01(\t\"\\\n\rFormattingMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12%\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x17.proto_types.Formatting\"\x13\n\x04Note\x12\x0b\n\x03msg\x18\x01 \x01(\t\"P\n\x07NoteMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12\x1f\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x11.proto_types.Note\"\x19\n\nPrintEvent\x12\x0b\n\x03msg\x18\x01 \x01(\t\"\\\n\rPrintEventMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12%\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x17.proto_types.PrintEventb\x06proto3')
19
+
20
+ _globals = globals()
21
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
22
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'types_pb2', _globals)
23
+ if _descriptor._USE_C_DESCRIPTORS == False:
24
+ DESCRIPTOR._options = None
25
+ _globals['_EVENTINFO_EXTRAENTRY']._options = None
26
+ _globals['_EVENTINFO_EXTRAENTRY']._serialized_options = b'8\001'
27
+ _globals['_EVENTINFO']._serialized_start=62
28
+ _globals['_EVENTINFO']._serialized_end=335
29
+ _globals['_EVENTINFO_EXTRAENTRY']._serialized_start=291
30
+ _globals['_EVENTINFO_EXTRAENTRY']._serialized_end=335
31
+ _globals['_GENERICMESSAGE']._serialized_start=337
32
+ _globals['_GENERICMESSAGE']._serialized_end=391
33
+ _globals['_BEHAVIORDEPRECATIONEVENT']._serialized_start=394
34
+ _globals['_BEHAVIORDEPRECATIONEVENT']._serialized_end=536
35
+ _globals['_BEHAVIORDEPRECATIONEVENTMSG']._serialized_start=538
36
+ _globals['_BEHAVIORDEPRECATIONEVENTMSG']._serialized_end=658
37
+ _globals['_RETRYEXTERNALCALL']._serialized_start=660
38
+ _globals['_RETRYEXTERNALCALL']._serialized_end=709
39
+ _globals['_RETRYEXTERNALCALLMSG']._serialized_start=711
40
+ _globals['_RETRYEXTERNALCALLMSG']._serialized_end=817
41
+ _globals['_RECORDRETRYEXCEPTION']._serialized_start=819
42
+ _globals['_RECORDRETRYEXCEPTION']._serialized_end=854
43
+ _globals['_RECORDRETRYEXCEPTIONMSG']._serialized_start=856
44
+ _globals['_RECORDRETRYEXCEPTIONMSG']._serialized_end=968
45
+ _globals['_SYSTEMCOULDNOTWRITE']._serialized_start=970
46
+ _globals['_SYSTEMCOULDNOTWRITE']._serialized_end=1034
47
+ _globals['_SYSTEMCOULDNOTWRITEMSG']._serialized_start=1036
48
+ _globals['_SYSTEMCOULDNOTWRITEMSG']._serialized_end=1146
49
+ _globals['_SYSTEMEXECUTINGCMD']._serialized_start=1148
50
+ _globals['_SYSTEMEXECUTINGCMD']._serialized_end=1181
51
+ _globals['_SYSTEMEXECUTINGCMDMSG']._serialized_start=1183
52
+ _globals['_SYSTEMEXECUTINGCMDMSG']._serialized_end=1291
53
+ _globals['_SYSTEMSTDOUT']._serialized_start=1293
54
+ _globals['_SYSTEMSTDOUT']._serialized_end=1321
55
+ _globals['_SYSTEMSTDOUTMSG']._serialized_start=1323
56
+ _globals['_SYSTEMSTDOUTMSG']._serialized_end=1419
57
+ _globals['_SYSTEMSTDERR']._serialized_start=1421
58
+ _globals['_SYSTEMSTDERR']._serialized_end=1449
59
+ _globals['_SYSTEMSTDERRMSG']._serialized_start=1451
60
+ _globals['_SYSTEMSTDERRMSG']._serialized_end=1547
61
+ _globals['_SYSTEMREPORTRETURNCODE']._serialized_start=1549
62
+ _globals['_SYSTEMREPORTRETURNCODE']._serialized_end=1593
63
+ _globals['_SYSTEMREPORTRETURNCODEMSG']._serialized_start=1595
64
+ _globals['_SYSTEMREPORTRETURNCODEMSG']._serialized_end=1711
65
+ _globals['_FORMATTING']._serialized_start=1713
66
+ _globals['_FORMATTING']._serialized_end=1738
67
+ _globals['_FORMATTINGMSG']._serialized_start=1740
68
+ _globals['_FORMATTINGMSG']._serialized_end=1832
69
+ _globals['_NOTE']._serialized_start=1834
70
+ _globals['_NOTE']._serialized_end=1853
71
+ _globals['_NOTEMSG']._serialized_start=1855
72
+ _globals['_NOTEMSG']._serialized_end=1935
73
+ _globals['_PRINTEVENT']._serialized_start=1937
74
+ _globals['_PRINTEVENT']._serialized_end=1962
75
+ _globals['_PRINTEVENTMSG']._serialized_start=1964
76
+ _globals['_PRINTEVENTMSG']._serialized_end=2056
77
+ # @@protoc_insertion_point(module_scope)