dvt-core 0.52.2__cp310-cp310-macosx_10_9_x86_64.whl

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.

Potentially problematic release.


This version of dvt-core might be problematic. Click here for more details.

Files changed (275) hide show
  1. dbt/__init__.py +7 -0
  2. dbt/_pydantic_shim.py +26 -0
  3. dbt/artifacts/__init__.py +0 -0
  4. dbt/artifacts/exceptions/__init__.py +1 -0
  5. dbt/artifacts/exceptions/schemas.py +31 -0
  6. dbt/artifacts/resources/__init__.py +116 -0
  7. dbt/artifacts/resources/base.py +67 -0
  8. dbt/artifacts/resources/types.py +93 -0
  9. dbt/artifacts/resources/v1/analysis.py +10 -0
  10. dbt/artifacts/resources/v1/catalog.py +23 -0
  11. dbt/artifacts/resources/v1/components.py +274 -0
  12. dbt/artifacts/resources/v1/config.py +277 -0
  13. dbt/artifacts/resources/v1/documentation.py +11 -0
  14. dbt/artifacts/resources/v1/exposure.py +51 -0
  15. dbt/artifacts/resources/v1/function.py +52 -0
  16. dbt/artifacts/resources/v1/generic_test.py +31 -0
  17. dbt/artifacts/resources/v1/group.py +21 -0
  18. dbt/artifacts/resources/v1/hook.py +11 -0
  19. dbt/artifacts/resources/v1/macro.py +29 -0
  20. dbt/artifacts/resources/v1/metric.py +172 -0
  21. dbt/artifacts/resources/v1/model.py +145 -0
  22. dbt/artifacts/resources/v1/owner.py +10 -0
  23. dbt/artifacts/resources/v1/saved_query.py +111 -0
  24. dbt/artifacts/resources/v1/seed.py +41 -0
  25. dbt/artifacts/resources/v1/semantic_layer_components.py +72 -0
  26. dbt/artifacts/resources/v1/semantic_model.py +314 -0
  27. dbt/artifacts/resources/v1/singular_test.py +14 -0
  28. dbt/artifacts/resources/v1/snapshot.py +91 -0
  29. dbt/artifacts/resources/v1/source_definition.py +84 -0
  30. dbt/artifacts/resources/v1/sql_operation.py +10 -0
  31. dbt/artifacts/resources/v1/unit_test_definition.py +77 -0
  32. dbt/artifacts/schemas/__init__.py +0 -0
  33. dbt/artifacts/schemas/base.py +191 -0
  34. dbt/artifacts/schemas/batch_results.py +24 -0
  35. dbt/artifacts/schemas/catalog/__init__.py +11 -0
  36. dbt/artifacts/schemas/catalog/v1/__init__.py +0 -0
  37. dbt/artifacts/schemas/catalog/v1/catalog.py +59 -0
  38. dbt/artifacts/schemas/freshness/__init__.py +1 -0
  39. dbt/artifacts/schemas/freshness/v3/__init__.py +0 -0
  40. dbt/artifacts/schemas/freshness/v3/freshness.py +158 -0
  41. dbt/artifacts/schemas/manifest/__init__.py +2 -0
  42. dbt/artifacts/schemas/manifest/v12/__init__.py +0 -0
  43. dbt/artifacts/schemas/manifest/v12/manifest.py +211 -0
  44. dbt/artifacts/schemas/results.py +147 -0
  45. dbt/artifacts/schemas/run/__init__.py +2 -0
  46. dbt/artifacts/schemas/run/v5/__init__.py +0 -0
  47. dbt/artifacts/schemas/run/v5/run.py +184 -0
  48. dbt/artifacts/schemas/upgrades/__init__.py +4 -0
  49. dbt/artifacts/schemas/upgrades/upgrade_manifest.py +174 -0
  50. dbt/artifacts/schemas/upgrades/upgrade_manifest_dbt_version.py +2 -0
  51. dbt/artifacts/utils/validation.py +153 -0
  52. dbt/cli/__init__.py +1 -0
  53. dbt/cli/context.py +17 -0
  54. dbt/cli/exceptions.py +57 -0
  55. dbt/cli/flags.py +560 -0
  56. dbt/cli/main.py +2039 -0
  57. dbt/cli/option_types.py +121 -0
  58. dbt/cli/options.py +80 -0
  59. dbt/cli/params.py +804 -0
  60. dbt/cli/requires.py +490 -0
  61. dbt/cli/resolvers.py +50 -0
  62. dbt/cli/types.py +40 -0
  63. dbt/clients/__init__.py +0 -0
  64. dbt/clients/checked_load.py +83 -0
  65. dbt/clients/git.py +164 -0
  66. dbt/clients/jinja.py +206 -0
  67. dbt/clients/jinja_static.py +245 -0
  68. dbt/clients/registry.py +192 -0
  69. dbt/clients/yaml_helper.py +68 -0
  70. dbt/compilation.py +876 -0
  71. dbt/compute/__init__.py +14 -0
  72. dbt/compute/engines/__init__.py +12 -0
  73. dbt/compute/engines/spark_engine.py +624 -0
  74. dbt/compute/federated_executor.py +837 -0
  75. dbt/compute/filter_pushdown.cpython-310-darwin.so +0 -0
  76. dbt/compute/filter_pushdown.py +273 -0
  77. dbt/compute/jar_provisioning.cpython-310-darwin.so +0 -0
  78. dbt/compute/jar_provisioning.py +255 -0
  79. dbt/compute/java_compat.cpython-310-darwin.so +0 -0
  80. dbt/compute/java_compat.py +689 -0
  81. dbt/compute/jdbc_utils.cpython-310-darwin.so +0 -0
  82. dbt/compute/jdbc_utils.py +678 -0
  83. dbt/compute/smart_selector.cpython-310-darwin.so +0 -0
  84. dbt/compute/smart_selector.py +311 -0
  85. dbt/compute/strategies/__init__.py +54 -0
  86. dbt/compute/strategies/base.py +165 -0
  87. dbt/compute/strategies/dataproc.py +207 -0
  88. dbt/compute/strategies/emr.py +203 -0
  89. dbt/compute/strategies/local.py +364 -0
  90. dbt/compute/strategies/standalone.py +262 -0
  91. dbt/config/__init__.py +4 -0
  92. dbt/config/catalogs.py +94 -0
  93. dbt/config/compute.cpython-310-darwin.so +0 -0
  94. dbt/config/compute.py +547 -0
  95. dbt/config/dvt_profile.cpython-310-darwin.so +0 -0
  96. dbt/config/dvt_profile.py +342 -0
  97. dbt/config/profile.py +422 -0
  98. dbt/config/project.py +873 -0
  99. dbt/config/project_utils.py +28 -0
  100. dbt/config/renderer.py +231 -0
  101. dbt/config/runtime.py +553 -0
  102. dbt/config/selectors.py +208 -0
  103. dbt/config/utils.py +77 -0
  104. dbt/constants.py +28 -0
  105. dbt/context/__init__.py +0 -0
  106. dbt/context/base.py +745 -0
  107. dbt/context/configured.py +135 -0
  108. dbt/context/context_config.py +382 -0
  109. dbt/context/docs.py +82 -0
  110. dbt/context/exceptions_jinja.py +178 -0
  111. dbt/context/macro_resolver.py +195 -0
  112. dbt/context/macros.py +171 -0
  113. dbt/context/manifest.py +72 -0
  114. dbt/context/providers.py +2249 -0
  115. dbt/context/query_header.py +13 -0
  116. dbt/context/secret.py +58 -0
  117. dbt/context/target.py +74 -0
  118. dbt/contracts/__init__.py +0 -0
  119. dbt/contracts/files.py +413 -0
  120. dbt/contracts/graph/__init__.py +0 -0
  121. dbt/contracts/graph/manifest.py +1904 -0
  122. dbt/contracts/graph/metrics.py +97 -0
  123. dbt/contracts/graph/model_config.py +70 -0
  124. dbt/contracts/graph/node_args.py +42 -0
  125. dbt/contracts/graph/nodes.py +1806 -0
  126. dbt/contracts/graph/semantic_manifest.py +232 -0
  127. dbt/contracts/graph/unparsed.py +811 -0
  128. dbt/contracts/project.py +417 -0
  129. dbt/contracts/results.py +53 -0
  130. dbt/contracts/selection.py +23 -0
  131. dbt/contracts/sql.py +85 -0
  132. dbt/contracts/state.py +68 -0
  133. dbt/contracts/util.py +46 -0
  134. dbt/deprecations.py +346 -0
  135. dbt/deps/__init__.py +0 -0
  136. dbt/deps/base.py +152 -0
  137. dbt/deps/git.py +195 -0
  138. dbt/deps/local.py +79 -0
  139. dbt/deps/registry.py +130 -0
  140. dbt/deps/resolver.py +149 -0
  141. dbt/deps/tarball.py +120 -0
  142. dbt/docs/source/_ext/dbt_click.py +119 -0
  143. dbt/docs/source/conf.py +32 -0
  144. dbt/env_vars.py +64 -0
  145. dbt/event_time/event_time.py +40 -0
  146. dbt/event_time/sample_window.py +60 -0
  147. dbt/events/__init__.py +15 -0
  148. dbt/events/base_types.py +36 -0
  149. dbt/events/core_types_pb2.py +2 -0
  150. dbt/events/logging.py +108 -0
  151. dbt/events/types.py +2516 -0
  152. dbt/exceptions.py +1486 -0
  153. dbt/flags.py +89 -0
  154. dbt/graph/__init__.py +11 -0
  155. dbt/graph/cli.py +247 -0
  156. dbt/graph/graph.py +172 -0
  157. dbt/graph/queue.py +214 -0
  158. dbt/graph/selector.py +374 -0
  159. dbt/graph/selector_methods.py +975 -0
  160. dbt/graph/selector_spec.py +222 -0
  161. dbt/graph/thread_pool.py +18 -0
  162. dbt/hooks.py +21 -0
  163. dbt/include/README.md +49 -0
  164. dbt/include/__init__.py +3 -0
  165. dbt/include/starter_project/.gitignore +4 -0
  166. dbt/include/starter_project/README.md +15 -0
  167. dbt/include/starter_project/__init__.py +3 -0
  168. dbt/include/starter_project/analyses/.gitkeep +0 -0
  169. dbt/include/starter_project/dbt_project.yml +36 -0
  170. dbt/include/starter_project/macros/.gitkeep +0 -0
  171. dbt/include/starter_project/models/example/my_first_dbt_model.sql +27 -0
  172. dbt/include/starter_project/models/example/my_second_dbt_model.sql +6 -0
  173. dbt/include/starter_project/models/example/schema.yml +21 -0
  174. dbt/include/starter_project/seeds/.gitkeep +0 -0
  175. dbt/include/starter_project/snapshots/.gitkeep +0 -0
  176. dbt/include/starter_project/tests/.gitkeep +0 -0
  177. dbt/internal_deprecations.py +26 -0
  178. dbt/jsonschemas/__init__.py +3 -0
  179. dbt/jsonschemas/jsonschemas.py +309 -0
  180. dbt/jsonschemas/project/0.0.110.json +4717 -0
  181. dbt/jsonschemas/project/0.0.85.json +2015 -0
  182. dbt/jsonschemas/resources/0.0.110.json +2636 -0
  183. dbt/jsonschemas/resources/0.0.85.json +2536 -0
  184. dbt/jsonschemas/resources/latest.json +6773 -0
  185. dbt/links.py +4 -0
  186. dbt/materializations/__init__.py +0 -0
  187. dbt/materializations/incremental/__init__.py +0 -0
  188. dbt/materializations/incremental/microbatch.py +236 -0
  189. dbt/mp_context.py +8 -0
  190. dbt/node_types.py +37 -0
  191. dbt/parser/__init__.py +23 -0
  192. dbt/parser/analysis.py +21 -0
  193. dbt/parser/base.py +548 -0
  194. dbt/parser/common.py +266 -0
  195. dbt/parser/docs.py +52 -0
  196. dbt/parser/fixtures.py +51 -0
  197. dbt/parser/functions.py +30 -0
  198. dbt/parser/generic_test.py +100 -0
  199. dbt/parser/generic_test_builders.py +333 -0
  200. dbt/parser/hooks.py +118 -0
  201. dbt/parser/macros.py +137 -0
  202. dbt/parser/manifest.py +2204 -0
  203. dbt/parser/models.py +573 -0
  204. dbt/parser/partial.py +1178 -0
  205. dbt/parser/read_files.py +445 -0
  206. dbt/parser/schema_generic_tests.py +422 -0
  207. dbt/parser/schema_renderer.py +111 -0
  208. dbt/parser/schema_yaml_readers.py +935 -0
  209. dbt/parser/schemas.py +1466 -0
  210. dbt/parser/search.py +149 -0
  211. dbt/parser/seeds.py +28 -0
  212. dbt/parser/singular_test.py +20 -0
  213. dbt/parser/snapshots.py +44 -0
  214. dbt/parser/sources.py +558 -0
  215. dbt/parser/sql.py +62 -0
  216. dbt/parser/unit_tests.py +621 -0
  217. dbt/plugins/__init__.py +20 -0
  218. dbt/plugins/contracts.py +9 -0
  219. dbt/plugins/exceptions.py +2 -0
  220. dbt/plugins/manager.py +163 -0
  221. dbt/plugins/manifest.py +21 -0
  222. dbt/profiler.py +20 -0
  223. dbt/py.typed +1 -0
  224. dbt/query_analyzer.cpython-310-darwin.so +0 -0
  225. dbt/query_analyzer.py +410 -0
  226. dbt/runners/__init__.py +2 -0
  227. dbt/runners/exposure_runner.py +7 -0
  228. dbt/runners/no_op_runner.py +45 -0
  229. dbt/runners/saved_query_runner.py +7 -0
  230. dbt/selected_resources.py +8 -0
  231. dbt/task/__init__.py +0 -0
  232. dbt/task/base.py +503 -0
  233. dbt/task/build.py +197 -0
  234. dbt/task/clean.py +56 -0
  235. dbt/task/clone.py +161 -0
  236. dbt/task/compile.py +150 -0
  237. dbt/task/compute.py +454 -0
  238. dbt/task/debug.py +505 -0
  239. dbt/task/deps.py +280 -0
  240. dbt/task/docs/__init__.py +3 -0
  241. dbt/task/docs/generate.py +660 -0
  242. dbt/task/docs/index.html +250 -0
  243. dbt/task/docs/serve.py +29 -0
  244. dbt/task/freshness.py +322 -0
  245. dbt/task/function.py +121 -0
  246. dbt/task/group_lookup.py +46 -0
  247. dbt/task/init.py +553 -0
  248. dbt/task/java.py +316 -0
  249. dbt/task/list.py +236 -0
  250. dbt/task/printer.py +175 -0
  251. dbt/task/retry.py +175 -0
  252. dbt/task/run.py +1306 -0
  253. dbt/task/run_operation.py +141 -0
  254. dbt/task/runnable.py +758 -0
  255. dbt/task/seed.py +103 -0
  256. dbt/task/show.py +149 -0
  257. dbt/task/snapshot.py +56 -0
  258. dbt/task/spark.py +414 -0
  259. dbt/task/sql.py +110 -0
  260. dbt/task/target_sync.py +759 -0
  261. dbt/task/test.py +464 -0
  262. dbt/tests/fixtures/__init__.py +1 -0
  263. dbt/tests/fixtures/project.py +620 -0
  264. dbt/tests/util.py +651 -0
  265. dbt/tracking.py +529 -0
  266. dbt/utils/__init__.py +3 -0
  267. dbt/utils/artifact_upload.py +151 -0
  268. dbt/utils/utils.py +408 -0
  269. dbt/version.py +268 -0
  270. dvt_cli/__init__.py +72 -0
  271. dvt_core-0.52.2.dist-info/METADATA +286 -0
  272. dvt_core-0.52.2.dist-info/RECORD +275 -0
  273. dvt_core-0.52.2.dist-info/WHEEL +5 -0
  274. dvt_core-0.52.2.dist-info/entry_points.txt +2 -0
  275. dvt_core-0.52.2.dist-info/top_level.txt +2 -0
dbt/cli/flags.py ADDED
@@ -0,0 +1,560 @@
1
+ import os
2
+ import sys
3
+ from dataclasses import dataclass
4
+ from datetime import datetime
5
+ from importlib import import_module
6
+ from pathlib import Path
7
+ from pprint import pformat as pf
8
+ from typing import Any, Callable, Dict, List, Optional, Set, Union
9
+
10
+ from click import Context, Parameter, get_current_context
11
+ from click.core import Command as ClickCommand
12
+ from click.core import Group, ParameterSource
13
+
14
+ from dbt.cli.exceptions import DbtUsageException
15
+ from dbt.cli.resolvers import default_log_path, default_project_dir
16
+ from dbt.cli.types import Command as CliCommand
17
+ from dbt.config.project import read_project_flags
18
+ from dbt.config.utils import normalize_warn_error_options
19
+ from dbt.contracts.project import ProjectFlags
20
+ from dbt.deprecations import fire_buffered_deprecations, renamed_env_var, warn
21
+ from dbt.events import ALL_EVENT_NAMES
22
+ from dbt_common import ui
23
+ from dbt_common.clients import jinja
24
+ from dbt_common.events import functions
25
+ from dbt_common.exceptions import DbtInternalError
26
+ from dbt_common.helper_types import WarnErrorOptionsV2
27
+
28
+ if os.name != "nt":
29
+ # https://bugs.python.org/issue41567
30
+ import multiprocessing.popen_spawn_posix # type: ignore # noqa: F401
31
+
32
+ FLAGS_DEFAULTS = {
33
+ "INDIRECT_SELECTION": "eager",
34
+ "TARGET_PATH": None,
35
+ "DEFER_STATE": None, # necessary because of retry construction of flags
36
+ "WARN_ERROR": None,
37
+ # Cli args without project_flags or env var option.
38
+ "FULL_REFRESH": False,
39
+ "STRICT_MODE": False,
40
+ "STORE_FAILURES": False,
41
+ "INTROSPECT": True,
42
+ "STATE_MODIFIED_COMPARE_VARS": False,
43
+ # DVT v0.5.99: CLI override for compute engine
44
+ "TARGET_COMPUTE": None,
45
+ }
46
+
47
+ DEPRECATED_PARAMS = {
48
+ "deprecated_defer": "defer",
49
+ "deprecated_favor_state": "favor_state",
50
+ "deprecated_print": "print",
51
+ "deprecated_state": "state",
52
+ }
53
+
54
+
55
+ DEPRECATED_FLAGS_TO_WARNINGS = {("--models", "--model", "-m"): "model-param-usage-deprecation"}
56
+
57
+ WHICH_KEY = "which"
58
+
59
+
60
+ def convert_config(config_name, config_value):
61
+ """Convert the values from config and original set_from_args to the correct type."""
62
+ ret = config_value
63
+ if config_name.lower() == "warn_error_options" and type(config_value) == dict:
64
+ normalize_warn_error_options(ret)
65
+ ret = WarnErrorOptionsV2(
66
+ error=config_value.get("error", []),
67
+ warn=config_value.get("warn", []),
68
+ silence=config_value.get("silence", []),
69
+ valid_error_names=ALL_EVENT_NAMES,
70
+ )
71
+ return ret
72
+
73
+
74
+ def args_to_context(args: List[str]) -> Context:
75
+ """Convert a list of args to a click context with proper hierarchy for dbt commands"""
76
+ from dbt.cli.main import cli
77
+
78
+ cli_ctx = cli.make_context(cli.name, args)
79
+ # Split args if they're a comma separated string.
80
+ if len(args) == 1 and "," in args[0]:
81
+ args = args[0].split(",")
82
+ sub_command_name, sub_command, args = cli.resolve_command(cli_ctx, args)
83
+ # Handle source and docs group.
84
+ if isinstance(sub_command, Group):
85
+ sub_command_name, sub_command, args = sub_command.resolve_command(cli_ctx, args)
86
+
87
+ assert isinstance(sub_command, ClickCommand)
88
+ sub_command_ctx = sub_command.make_context(sub_command_name, args)
89
+ sub_command_ctx.parent = cli_ctx
90
+ return sub_command_ctx
91
+
92
+
93
+ @dataclass(frozen=True)
94
+ class Flags:
95
+ """Primary configuration artifact for running dbt"""
96
+
97
+ def __init__(
98
+ self, ctx: Optional[Context] = None, project_flags: Optional[ProjectFlags] = None
99
+ ) -> None:
100
+ # Set the default flags.
101
+ for key, value in FLAGS_DEFAULTS.items():
102
+ object.__setattr__(self, key, value)
103
+ # Use to handle duplicate params in _assign_params
104
+ flags_defaults_list = list(FLAGS_DEFAULTS.keys())
105
+
106
+ if ctx is None:
107
+ ctx = get_current_context()
108
+
109
+ def _get_params_by_source(ctx: Context, source_type: ParameterSource):
110
+ """Generates all params of a given source type."""
111
+ yield from [
112
+ name for name, source in ctx._parameter_source.items() if source is source_type
113
+ ]
114
+ if ctx.parent:
115
+ yield from _get_params_by_source(ctx.parent, source_type)
116
+
117
+ # Ensure that any params sourced from the commandline are not present more than once.
118
+ # Click handles this exclusivity, but only at a per-subcommand level.
119
+ seen_params = []
120
+ for param in _get_params_by_source(ctx, ParameterSource.COMMANDLINE):
121
+ if param in seen_params:
122
+ raise DbtUsageException(
123
+ f"{param.lower()} was provided both before and after the subcommand, it can only be set either before or after.",
124
+ )
125
+ seen_params.append(param)
126
+
127
+ def _assign_params(
128
+ ctx: Context,
129
+ params_assigned_from_default: set,
130
+ params_assigned_from_user: set,
131
+ deprecated_env_vars: Dict[str, Callable],
132
+ ):
133
+ """Recursively adds all click params to flag object"""
134
+ for param_name, param_value in ctx.params.items():
135
+ # N.B. You have to use the base MRO method (object.__setattr__) to set attributes
136
+ # when using frozen dataclasses.
137
+ # https://docs.python.org/3/library/dataclasses.html#frozen-instances
138
+
139
+ # Handle deprecated env vars while still respecting old values
140
+ # e.g. DBT_NO_PRINT -> DBT_PRINT if DBT_NO_PRINT is set, it is
141
+ # respected over DBT_PRINT or --print.
142
+ new_name: Union[str, None] = None
143
+ if param_name in DEPRECATED_PARAMS:
144
+ # Deprecated env vars can only be set via env var.
145
+ # We use the deprecated option in click to serialize the value
146
+ # from the env var string.
147
+ param_source = ctx.get_parameter_source(param_name)
148
+ if param_source == ParameterSource.DEFAULT:
149
+ continue
150
+ elif param_source != ParameterSource.ENVIRONMENT:
151
+ raise DbtUsageException(
152
+ "Deprecated parameters can only be set via environment variables",
153
+ )
154
+
155
+ # Rename for clarity.
156
+ dep_name = param_name
157
+ new_name = DEPRECATED_PARAMS.get(dep_name)
158
+ try:
159
+ assert isinstance(new_name, str)
160
+ except AssertionError:
161
+ raise Exception(
162
+ f"No deprecated param name match in DEPRECATED_PARAMS from {dep_name} to {new_name}"
163
+ )
164
+
165
+ # Find param objects for their envvar name.
166
+ try:
167
+ dep_param = [x for x in ctx.command.params if x.name == dep_name][0]
168
+ new_param = [x for x in ctx.command.params if x.name == new_name][0]
169
+ except IndexError:
170
+ raise Exception(
171
+ f"No deprecated param name match in context from {dep_name} to {new_name}"
172
+ )
173
+
174
+ # Remove param from defaulted set since the deprecated
175
+ # value is not set from default, but from an env var.
176
+ if new_name in params_assigned_from_default:
177
+ params_assigned_from_default.remove(new_name)
178
+
179
+ # Add the deprecation warning function to the set.
180
+ assert isinstance(dep_param.envvar, str)
181
+ assert isinstance(new_param.envvar, str)
182
+ deprecated_env_vars[new_name] = renamed_env_var(
183
+ old_name=dep_param.envvar,
184
+ new_name=new_param.envvar,
185
+ )
186
+ # end deprecated_params
187
+
188
+ # Set the flag value.
189
+ is_duplicate = (
190
+ hasattr(self, param_name.upper())
191
+ and param_name.upper() not in flags_defaults_list
192
+ )
193
+ # First time through, set as though FLAGS_DEFAULTS hasn't been set, so not a duplicate.
194
+ # Subsequent pass (to process "parent" params) should be treated as duplicates.
195
+ if param_name.upper() in flags_defaults_list:
196
+ flags_defaults_list.remove(param_name.upper())
197
+ # Note: the following determines whether parameter came from click default,
198
+ # not from FLAGS_DEFAULTS in __init__.
199
+ is_default = ctx.get_parameter_source(param_name) == ParameterSource.DEFAULT
200
+ is_envvar = ctx.get_parameter_source(param_name) == ParameterSource.ENVIRONMENT
201
+
202
+ flag_name = (new_name or param_name).upper()
203
+
204
+ # envvar flags are assigned in either parent or child context if there
205
+ # isn't an overriding cli command flag.
206
+ # If the flag has been encountered as a child cli flag, we don't
207
+ # want to overwrite with parent envvar, since the commandline flag takes precedence.
208
+ if (is_duplicate and not (is_default or is_envvar)) or not is_duplicate:
209
+ object.__setattr__(self, flag_name, param_value)
210
+
211
+ # Track default assigned params.
212
+ # For flags that are accepted at both 'parent' and 'child' levels,
213
+ # we need to track user-provided and default values across both,
214
+ # to support detection of mutually exclusive flags later on.
215
+ if not is_default:
216
+ params_assigned_from_user.add(param_name)
217
+ if param_name in params_assigned_from_default:
218
+ params_assigned_from_default.remove(param_name)
219
+ if is_default and param_name not in params_assigned_from_user:
220
+ params_assigned_from_default.add(param_name)
221
+
222
+ if ctx.parent:
223
+ _assign_params(
224
+ ctx.parent,
225
+ params_assigned_from_default,
226
+ params_assigned_from_user,
227
+ deprecated_env_vars,
228
+ )
229
+
230
+ params_assigned_from_user = set() # type: Set[str]
231
+ params_assigned_from_default = set() # type: Set[str]
232
+ deprecated_env_vars: Dict[str, Callable] = {}
233
+ _assign_params(
234
+ ctx, params_assigned_from_default, params_assigned_from_user, deprecated_env_vars
235
+ )
236
+
237
+ # Set deprecated_env_var_warnings to be fired later after events have been init.
238
+ object.__setattr__(
239
+ self, "deprecated_env_var_warnings", [x for x in deprecated_env_vars.values()]
240
+ )
241
+
242
+ # Get the invoked command flags.
243
+ invoked_subcommand_name = (
244
+ ctx.invoked_subcommand if hasattr(ctx, "invoked_subcommand") else None
245
+ )
246
+ if invoked_subcommand_name is not None:
247
+ invoked_subcommand = getattr(import_module("dbt.cli.main"), invoked_subcommand_name)
248
+ invoked_subcommand.allow_extra_args = True
249
+ invoked_subcommand.ignore_unknown_options = True
250
+ invoked_subcommand_ctx = invoked_subcommand.make_context(None, sys.argv)
251
+ _assign_params(
252
+ invoked_subcommand_ctx,
253
+ params_assigned_from_default,
254
+ params_assigned_from_user,
255
+ deprecated_env_vars,
256
+ )
257
+
258
+ if not project_flags:
259
+ project_dir = getattr(self, "PROJECT_DIR", str(default_project_dir()))
260
+ profiles_dir = getattr(self, "PROFILES_DIR", None)
261
+ if profiles_dir and project_dir:
262
+ project_flags = read_project_flags(project_dir, profiles_dir)
263
+ else:
264
+ project_flags = None
265
+
266
+ # Add entire invocation command to flags
267
+ object.__setattr__(self, "INVOCATION_COMMAND", "dbt " + " ".join(sys.argv[1:]))
268
+
269
+ if project_flags:
270
+ # Overwrite default assignments with project flags if available.
271
+ param_assigned_from_default_copy = params_assigned_from_default.copy()
272
+ for param_assigned_from_default in params_assigned_from_default:
273
+ project_flags_param_value = getattr(
274
+ project_flags, param_assigned_from_default, None
275
+ )
276
+ if project_flags_param_value is not None:
277
+ object.__setattr__(
278
+ self,
279
+ param_assigned_from_default.upper(),
280
+ convert_config(param_assigned_from_default, project_flags_param_value),
281
+ )
282
+ param_assigned_from_default_copy.remove(param_assigned_from_default)
283
+ params_assigned_from_default = param_assigned_from_default_copy
284
+
285
+ # Add project-level flags that are not available as CLI options / env vars
286
+ for (
287
+ project_level_flag_name,
288
+ project_level_flag_value,
289
+ ) in project_flags.project_only_flags.items():
290
+ object.__setattr__(self, project_level_flag_name.upper(), project_level_flag_value)
291
+
292
+ # Set hard coded flags.
293
+ object.__setattr__(self, "WHICH", invoked_subcommand_name or ctx.info_name)
294
+
295
+ # Apply the lead/follow relationship between some parameters.
296
+ self._override_if_set("USE_COLORS", "USE_COLORS_FILE", params_assigned_from_default)
297
+ self._override_if_set("LOG_LEVEL", "LOG_LEVEL_FILE", params_assigned_from_default)
298
+ self._override_if_set("LOG_FORMAT", "LOG_FORMAT_FILE", params_assigned_from_default)
299
+
300
+ # Set default LOG_PATH from PROJECT_DIR, if available.
301
+ # Starting in v1.5, if `log-path` is set in `dbt_project.yml`, it will raise a deprecation warning,
302
+ # with the possibility of removing it in a future release.
303
+ if getattr(self, "LOG_PATH", None) is None:
304
+ project_dir = getattr(self, "PROJECT_DIR", str(default_project_dir()))
305
+ version_check = getattr(self, "VERSION_CHECK", True)
306
+ object.__setattr__(
307
+ self, "LOG_PATH", default_log_path(Path(project_dir), version_check)
308
+ )
309
+
310
+ # Support console DO NOT TRACK initiative.
311
+ if os.getenv("DO_NOT_TRACK", "").lower() in ("1", "t", "true", "y", "yes"):
312
+ object.__setattr__(self, "SEND_ANONYMOUS_USAGE_STATS", False)
313
+
314
+ # Check mutual exclusivity once all flags are set.
315
+ self._assert_mutually_exclusive(
316
+ params_assigned_from_default, ["WARN_ERROR", "WARN_ERROR_OPTIONS"]
317
+ )
318
+
319
+ # Handle arguments mutually exclusive with INLINE
320
+ self._assert_mutually_exclusive(params_assigned_from_default, ["SELECT", "INLINE"])
321
+ self._assert_mutually_exclusive(params_assigned_from_default, ["SELECTOR", "INLINE"])
322
+
323
+ # Check event_time configs for validity
324
+ self._validate_event_time_configs()
325
+
326
+ # Support lower cased access for legacy code.
327
+ params = set(
328
+ x for x in dir(self) if not callable(getattr(self, x)) and not x.startswith("__")
329
+ )
330
+ for param in params:
331
+ object.__setattr__(self, param.lower(), getattr(self, param))
332
+
333
+ self.set_common_global_flags()
334
+
335
+ def __str__(self) -> str:
336
+ return str(pf(self.__dict__))
337
+
338
+ def _override_if_set(self, lead: str, follow: str, defaulted: Set[str]) -> None:
339
+ """If the value of the lead parameter was set explicitly, apply the value to follow, unless follow was also set explicitly."""
340
+ if lead.lower() not in defaulted and follow.lower() in defaulted:
341
+ object.__setattr__(self, follow.upper(), getattr(self, lead.upper(), None))
342
+
343
+ def _assert_mutually_exclusive(
344
+ self, params_assigned_from_default: Set[str], group: List[str]
345
+ ) -> None:
346
+ """
347
+ Ensure no elements from group are simultaneously provided by a user, as inferred from params_assigned_from_default.
348
+ Raises click.UsageError if any two elements from group are simultaneously provided by a user.
349
+ """
350
+ set_flag = None
351
+ for flag in group:
352
+ flag_set_by_user = (
353
+ hasattr(self, flag) and flag.lower() not in params_assigned_from_default
354
+ )
355
+ if flag_set_by_user and set_flag:
356
+ raise DbtUsageException(
357
+ f"{flag.lower()}: not allowed with argument {set_flag.lower()}"
358
+ )
359
+ elif flag_set_by_user:
360
+ set_flag = flag
361
+
362
+ def _validate_event_time_configs(self) -> None:
363
+ event_time_start: datetime = (
364
+ getattr(self, "EVENT_TIME_START") if hasattr(self, "EVENT_TIME_START") else None
365
+ )
366
+ event_time_end: datetime = (
367
+ getattr(self, "EVENT_TIME_END") if hasattr(self, "EVENT_TIME_END") else None
368
+ )
369
+
370
+ # only do validations if at least one of `event_time_start` or `event_time_end` are specified
371
+ if event_time_start is not None or event_time_end is not None:
372
+
373
+ # These `ifs`, combined with the parent `if` make it so that `event_time_start` and
374
+ # `event_time_end` are mutually required
375
+ if event_time_start is None:
376
+ raise DbtUsageException(
377
+ "The flag `--event-time-end` was specified, but `--event-time-start` was not. "
378
+ "When specifying `--event-time-end`, `--event-time-start` must also be present."
379
+ )
380
+ if event_time_end is None:
381
+ raise DbtUsageException(
382
+ "The flag `--event-time-start` was specified, but `--event-time-end` was not. "
383
+ "When specifying `--event-time-start`, `--event-time-end` must also be present."
384
+ )
385
+
386
+ # This `if` just is a sanity check that `event_time_start` is before `event_time_end`
387
+ if event_time_start >= event_time_end:
388
+ raise DbtUsageException(
389
+ "Value for `--event-time-start` must be less than `--event-time-end`"
390
+ )
391
+
392
+ def fire_deprecations(self, ctx: Optional[Context] = None):
393
+ """Fires events for deprecated env_var usage."""
394
+ [dep_fn() for dep_fn in self.deprecated_env_var_warnings]
395
+ # It is necessary to remove this attr from the class so it does
396
+ # not get pickled when written to disk as json.
397
+ object.__delattr__(self, "deprecated_env_var_warnings")
398
+
399
+ fire_buffered_deprecations()
400
+
401
+ # Handle firing deprecations of CLI aliases separately using argv or dbtRunner args
402
+ # because click doesn't make it possible to disambiguite which literal CLI option was used
403
+ # and only preserves the 'canonical' representation.
404
+ original_command_args = (
405
+ ctx.obj["dbt_runner_command_args"]
406
+ if (ctx and ctx.obj and "dbt_runner_command_args" in ctx.obj)
407
+ else sys.argv
408
+ )
409
+ for deprecated_flags, warning in DEPRECATED_FLAGS_TO_WARNINGS.items():
410
+ for deprecated_flag in deprecated_flags:
411
+ if deprecated_flag in original_command_args:
412
+ warn(warning)
413
+
414
+ @classmethod
415
+ def from_dict(cls, command: CliCommand, args_dict: Dict[str, Any]) -> "Flags":
416
+ command_arg_list = command_params(command, args_dict)
417
+ ctx = args_to_context(command_arg_list)
418
+ flags = cls(ctx=ctx)
419
+ flags.fire_deprecations(ctx=ctx)
420
+ return flags
421
+
422
+ def set_common_global_flags(self):
423
+ # Set globals for common.ui
424
+ if getattr(self, "PRINTER_WIDTH", None) is not None:
425
+ ui.PRINTER_WIDTH = getattr(self, "PRINTER_WIDTH")
426
+ if getattr(self, "USE_COLORS", None) is not None:
427
+ ui.USE_COLOR = getattr(self, "USE_COLORS")
428
+
429
+ # Set globals for common.events.functions
430
+ functions.WARN_ERROR = getattr(self, "WARN_ERROR", False)
431
+ if getattr(self, "WARN_ERROR_OPTIONS", None) is not None:
432
+ functions.WARN_ERROR_OPTIONS = getattr(self, "WARN_ERROR_OPTIONS")
433
+
434
+ # Set globals for common.jinja
435
+ if getattr(self, "MACRO_DEBUGGING", None) is not None:
436
+ jinja.MACRO_DEBUGGING = getattr(self, "MACRO_DEBUGGING")
437
+
438
+ # This is here to prevent mypy from complaining about all of the
439
+ # attributes which we added dynamically.
440
+ def __getattr__(self, name: str) -> Any:
441
+ return super().__getattribute__(name) # type: ignore
442
+
443
+
444
+ CommandParams = List[str]
445
+
446
+
447
+ def command_params(command: CliCommand, args_dict: Dict[str, Any]) -> CommandParams:
448
+ """Given a command and a dict, returns a list of strings representing
449
+ the CLI params for that command. The order of this list is consistent with
450
+ which flags are expected at the parent level vs the command level.
451
+
452
+ e.g. fn("run", {"defer": True, "print": False}) -> ["--no-print", "run", "--defer"]
453
+
454
+ The result of this function can be passed in to the args_to_context function
455
+ to produce a click context to instantiate Flags with.
456
+ """
457
+
458
+ cmd_args = set(command_args(command))
459
+ prnt_args = set(parent_args())
460
+ default_args = set([x.lower() for x in FLAGS_DEFAULTS.keys()])
461
+
462
+ res = command.to_list()
463
+ for k, v in args_dict.items():
464
+ k = k.lower()
465
+ # if a "which" value exists in the args dict, it should match the command provided
466
+ if k == WHICH_KEY:
467
+ if v != command.value:
468
+ raise DbtInternalError(
469
+ f"Command '{command.value}' does not match value of which: '{v}'"
470
+ )
471
+ continue
472
+
473
+ # param was assigned from defaults and should not be included
474
+ if k not in (cmd_args | prnt_args) or (
475
+ k in default_args and v == FLAGS_DEFAULTS[k.upper()]
476
+ ):
477
+ continue
478
+
479
+ # if the param is in parent args, it should come before the arg name
480
+ # e.g. ["--print", "run"] vs ["run", "--print"]
481
+ add_fn = res.append
482
+ if k in prnt_args:
483
+
484
+ def add_fn(x):
485
+ res.insert(0, x)
486
+
487
+ spinal_cased = k.replace("_", "-")
488
+
489
+ # MultiOption flags come back as lists, but we want to pass them as space separated strings
490
+ if isinstance(v, list):
491
+ if len(v) > 0:
492
+ v = " ".join(v)
493
+ else:
494
+ continue
495
+
496
+ if k == "macro" and command == CliCommand.RUN_OPERATION:
497
+ add_fn(v)
498
+ # None is a Singleton, False is a Flyweight, only one instance of each.
499
+ elif (v is None or v is False) and k not in (
500
+ # These are None by default but they do not support --no-{flag}
501
+ "defer_state",
502
+ "log_format",
503
+ ):
504
+ add_fn(f"--no-{spinal_cased}")
505
+ elif v is True:
506
+ add_fn(f"--{spinal_cased}")
507
+ else:
508
+ add_fn(f"--{spinal_cased}={v}")
509
+
510
+ return res
511
+
512
+
513
+ ArgsList = List[str]
514
+
515
+
516
+ def parent_args() -> ArgsList:
517
+ """Return a list representing the params the base click command takes."""
518
+ from dbt.cli.main import cli
519
+
520
+ return format_params(cli.params)
521
+
522
+
523
+ def command_args(command: CliCommand) -> ArgsList:
524
+ """Given a command, return a list of strings representing the params
525
+ that command takes. This function only returns params assigned to a
526
+ specific command, not those of its parent command.
527
+
528
+ e.g. fn("run") -> ["defer", "favor_state", "exclude", ...]
529
+ """
530
+ import dbt.cli.main as cli
531
+
532
+ CMD_DICT: Dict[CliCommand, ClickCommand] = {
533
+ CliCommand.BUILD: cli.build,
534
+ CliCommand.CLEAN: cli.clean,
535
+ CliCommand.CLONE: cli.clone,
536
+ CliCommand.COMPILE: cli.compile,
537
+ CliCommand.DOCS_GENERATE: cli.docs_generate,
538
+ CliCommand.DOCS_SERVE: cli.docs_serve,
539
+ CliCommand.DEBUG: cli.debug,
540
+ CliCommand.DEPS: cli.deps,
541
+ CliCommand.INIT: cli.init,
542
+ CliCommand.LIST: cli.list,
543
+ CliCommand.PARSE: cli.parse,
544
+ CliCommand.RUN: cli.run,
545
+ CliCommand.RUN_OPERATION: cli.run_operation,
546
+ CliCommand.SEED: cli.seed,
547
+ CliCommand.SHOW: cli.show,
548
+ CliCommand.SNAPSHOT: cli.snapshot,
549
+ CliCommand.SOURCE_FRESHNESS: cli.freshness,
550
+ CliCommand.TEST: cli.test,
551
+ CliCommand.RETRY: cli.retry,
552
+ }
553
+ click_cmd: Optional[ClickCommand] = CMD_DICT.get(command, None)
554
+ if click_cmd is None:
555
+ raise DbtInternalError(f"No command found for name '{command.name}'")
556
+ return format_params(click_cmd.params)
557
+
558
+
559
+ def format_params(params: List[Parameter]) -> ArgsList:
560
+ return [str(x.name) for x in params if not str(x.name).lower().startswith("deprecated_")]