dbt-common 1.4.0__py3-none-any.whl → 1.5.0__py3-none-any.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.
dbt_common/__about__.py CHANGED
@@ -1 +1 @@
1
- version = "1.4.0"
1
+ version = "1.5.0"
@@ -62,7 +62,9 @@ class FindMatchingParams:
62
62
  # Do not record or replay filesystem searches that were performed against
63
63
  # files which are actually part of dbt's implementation.
64
64
  return (
65
- "dbt/include/global_project" not in self.root_path
65
+ "dbt/include"
66
+ not in self.root_path # TODO: This actually obviates the next two checks but is probably too coarse?
67
+ and "dbt/include/global_project" not in self.root_path
66
68
  and "/plugins/postgres/dbt/include/" not in self.root_path
67
69
  )
68
70
 
dbt_common/record.py CHANGED
@@ -2,7 +2,7 @@
2
2
  external systems during a command invocation, so that the command can be re-run
3
3
  later with the recording 'replayed' to dbt.
4
4
 
5
- The rationale for and architecture of this module is described in detail in the
5
+ The rationale for and architecture of this module are described in detail in the
6
6
  docs/guides/record_replay.md document in this repository.
7
7
  """
8
8
  import functools
@@ -12,7 +12,7 @@ import os
12
12
 
13
13
  from deepdiff import DeepDiff # type: ignore
14
14
  from enum import Enum
15
- from typing import Any, Dict, List, Mapping, Optional, Type
15
+ from typing import Any, Callable, Dict, List, Mapping, Optional, Type
16
16
 
17
17
  from dbt_common.context import get_invocation_context
18
18
 
@@ -129,10 +129,11 @@ class Recorder:
129
129
  previous_recording_path: Optional[str] = None,
130
130
  ) -> None:
131
131
  self.mode = mode
132
- self.types = types
132
+ self.recorded_types = types
133
133
  self._records_by_type: Dict[str, List[Record]] = {}
134
+ self._unprocessed_records_by_type: Dict[str, List[Dict[str, Any]]] = {}
134
135
  self._replay_diffs: List["Diff"] = []
135
- self.diff: Diff
136
+ self.diff: Optional[Diff] = None
136
137
  self.previous_recording_path = previous_recording_path
137
138
  self.current_recording_path = current_recording_path
138
139
 
@@ -146,7 +147,7 @@ class Recorder:
146
147
  )
147
148
 
148
149
  if self.mode == RecorderMode.REPLAY:
149
- self._records_by_type = self.load(self.previous_recording_path)
150
+ self._unprocessed_records_by_type = self.load(self.previous_recording_path)
150
151
 
151
152
  @classmethod
152
153
  def register_record_type(cls, rec_type) -> Any:
@@ -161,7 +162,14 @@ class Recorder:
161
162
  self._records_by_type[rec_cls_name].append(record)
162
163
 
163
164
  def pop_matching_record(self, params: Any) -> Optional[Record]:
164
- rec_type_name = self._record_name_by_params_name[type(params).__name__]
165
+ rec_type_name = self._record_name_by_params_name.get(type(params).__name__)
166
+
167
+ if rec_type_name is None:
168
+ raise Exception(
169
+ f"A record of type {type(params).__name__} was requested, but no such type has been registered."
170
+ )
171
+
172
+ self._ensure_records_processed(rec_type_name)
165
173
  records = self._records_by_type[rec_type_name]
166
174
  match: Optional[Record] = None
167
175
  for rec in records:
@@ -186,22 +194,20 @@ class Recorder:
186
194
  return dct
187
195
 
188
196
  @classmethod
189
- def load(cls, file_name: str) -> Dict[str, List[Record]]:
197
+ def load(cls, file_name: str) -> Dict[str, List[Dict[str, Any]]]:
190
198
  with open(file_name) as file:
191
- loaded_dct = json.load(file)
199
+ return json.load(file)
192
200
 
193
- records_by_type: Dict[str, List[Record]] = {}
201
+ def _ensure_records_processed(self, record_type_name: str) -> None:
202
+ if record_type_name in self._records_by_type:
203
+ return
194
204
 
195
- for record_type_name in loaded_dct:
196
- # TODO: this breaks with QueryRecord on replay since it's
197
- # not in common so isn't part of cls._record_cls_by_name yet
198
- record_cls = cls._record_cls_by_name[record_type_name]
199
- rec_list = []
200
- for record_dct in loaded_dct[record_type_name]:
201
- rec = record_cls.from_dict(record_dct)
202
- rec_list.append(rec) # type: ignore
203
- records_by_type[record_type_name] = rec_list
204
- return records_by_type
205
+ rec_list = []
206
+ record_cls = self._record_cls_by_name[record_type_name]
207
+ for record_dct in self._unprocessed_records_by_type[record_type_name]:
208
+ rec = record_cls.from_dict(record_dct)
209
+ rec_list.append(rec) # type: ignore
210
+ self._records_by_type[record_type_name] = rec_list
205
211
 
206
212
  def expect_record(self, params: Any) -> Any:
207
213
  record = self.pop_matching_record(params)
@@ -209,16 +215,19 @@ class Recorder:
209
215
  if record is None:
210
216
  raise Exception()
211
217
 
218
+ if record.result is None:
219
+ return None
220
+
212
221
  result_tuple = dataclasses.astuple(record.result)
213
222
  return result_tuple[0] if len(result_tuple) == 1 else result_tuple
214
223
 
215
224
  def write_diffs(self, diff_file_name) -> None:
216
- json.dump(
217
- self.diff.calculate_diff(),
218
- open(diff_file_name, "w"),
219
- )
225
+ assert self.diff is not None
226
+ with open(diff_file_name, "w") as f:
227
+ json.dump(self.diff.calculate_diff(), f)
220
228
 
221
229
  def print_diffs(self) -> None:
230
+ assert self.diff is not None
222
231
  print(repr(self.diff.calculate_diff()))
223
232
 
224
233
 
@@ -273,7 +282,12 @@ def get_record_types_from_dict(fp: str) -> List:
273
282
  return list(loaded_dct.keys())
274
283
 
275
284
 
276
- def record_function(record_type, method=False, tuple_result=False):
285
+ def record_function(
286
+ record_type,
287
+ method: bool = False,
288
+ tuple_result: bool = False,
289
+ id_field_name: Optional[str] = None,
290
+ ) -> Callable:
277
291
  def record_function_inner(func_to_record):
278
292
  # To avoid runtime overhead and other unpleasantness, we only apply the
279
293
  # record/replay decorator if a relevant env var is set.
@@ -291,12 +305,17 @@ def record_function(record_type, method=False, tuple_result=False):
291
305
  if recorder is None:
292
306
  return func_to_record(*args, **kwargs)
293
307
 
294
- if recorder.types is not None and record_type.__name__ not in recorder.types:
308
+ if (
309
+ recorder.recorded_types is not None
310
+ and record_type.__name__ not in recorder.recorded_types
311
+ ):
295
312
  return func_to_record(*args, **kwargs)
296
313
 
297
314
  # For methods, peel off the 'self' argument before calling the
298
315
  # params constructor.
299
316
  param_args = args[1:] if method else args
317
+ if method and id_field_name is not None:
318
+ param_args = (getattr(args[0], id_field_name),) + param_args
300
319
 
301
320
  params = record_type.params_cls(*param_args, **kwargs)
302
321
 
@@ -313,7 +332,7 @@ def record_function(record_type, method=False, tuple_result=False):
313
332
  r = func_to_record(*args, **kwargs)
314
333
  result = (
315
334
  None
316
- if r is None or record_type.result_cls is None
335
+ if record_type.result_cls is None
317
336
  else record_type.result_cls(*r)
318
337
  if tuple_result
319
338
  else record_type.result_cls(r)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: dbt-common
3
- Version: 1.4.0
3
+ Version: 1.5.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
@@ -1,4 +1,4 @@
1
- dbt_common/__about__.py,sha256=0kccNYBMuNA3PIhlESWmh8xP1TWpNtIEzS0d-x80SC0,18
1
+ dbt_common/__about__.py,sha256=Wgohrh7g_peUNIz0Cro4w7u88rZU94fNypIcm9oMWgQ,18
2
2
  dbt_common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  dbt_common/constants.py,sha256=-Y5DIL1SDPQWtlCNizXRYxFgbx1D7LaLs1ysamvGMRk,278
4
4
  dbt_common/context.py,sha256=BhgT7IgyvpZHEtIdFVVuBBBX5LuU7obXT7NvIPeuD2g,1760
@@ -6,7 +6,7 @@ dbt_common/dataclass_schema.py,sha256=t3HGD0oXTSjitctuCVHv3iyq5BT3jxoSxv_VGkrJlE
6
6
  dbt_common/helper_types.py,sha256=NoxqGFAq9bOjh7rqtz_eepXAxk20n3mmW_gUVpnMyYU,3901
7
7
  dbt_common/invocation.py,sha256=Zw8jRPn75oi2VrUD6qGvaCDtSyIfqm5pJlPpRjs3s1E,202
8
8
  dbt_common/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- dbt_common/record.py,sha256=_P-OZWKQwGmq6nTC4r2oQDyh89gi-VGC2gdok6TywhI,11765
9
+ dbt_common/record.py,sha256=F-FbFt6Js_U4r5b5hXGp8DY-MTEKNb-dLMaBT80UWHw,12415
10
10
  dbt_common/semver.py,sha256=2zoZYCQ7PfswqslT2NHuMGgPGMuMuX-yRThVoqfDWQU,13954
11
11
  dbt_common/tests.py,sha256=6lC_JuRtoYO6cbAF8-R5aTM4HtQiM_EH8X5m_97duGY,315
12
12
  dbt_common/ui.py,sha256=rc2TEM29raBFc_LXcg901pMDD07C2ohwp9qzkE-7pBY,2567
@@ -14,7 +14,7 @@ dbt_common/clients/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuF
14
14
  dbt_common/clients/_jinja_blocks.py,sha256=xoJK9Y0F93U2PKfT_3SJbBopCGYCtl7LiwKuylXnrEE,12947
15
15
  dbt_common/clients/agate_helper.py,sha256=n5Q0_gJPbBhFvjd286NGYGlcTtdEExYmIT3968lppyg,9124
16
16
  dbt_common/clients/jinja.py,sha256=i6VQ94FU4F6ZCQLHTxNSeGHmvyYSIe34nDhNkH6wO08,18502
17
- dbt_common/clients/system.py,sha256=OOhRDWR5t0Ns3OhkqjPTNTtyl_RMRWPDHWCzDoFtgkA,23014
17
+ dbt_common/clients/system.py,sha256=K-b9Lx8ZhgR5tKq1vnqbX8sEVaVRQHqkEkLYQIjFc64,23158
18
18
  dbt_common/contracts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  dbt_common/contracts/constraints.py,sha256=hyqTW2oPB1dfXWW388LWnL-EFdqTpQciKISH3CeLkro,1267
20
20
  dbt_common/contracts/metadata.py,sha256=K_M06Rue0wmrQhFP_mq3uvQszq10CIt93oGiAVgbRfE,1293
@@ -56,7 +56,7 @@ dbt_common/utils/encoding.py,sha256=6_kSY2FvGNYMg7oX7PrbvVioieydih3Kl7Ii802LaHI,
56
56
  dbt_common/utils/executor.py,sha256=Zyzd1wML3aN-iYn9ZG2Gc_jj5vknmvQNyH-c0RaPIpo,2446
57
57
  dbt_common/utils/formatting.py,sha256=JUn5rzJ-uajs9wPCN0-f2iRFY1pOJF5YjTD9dERuLoc,165
58
58
  dbt_common/utils/jinja.py,sha256=XNfZHuZhLM_R_yPmzYojPm6bF7QOoxIjSWrkJRw6wks,965
59
- dbt_common-1.4.0.dist-info/METADATA,sha256=QH1OkqWWMGMTDUDSrqHmEnEvHs0akdlpDU-5asSCUD8,5298
60
- dbt_common-1.4.0.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
61
- dbt_common-1.4.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
62
- dbt_common-1.4.0.dist-info/RECORD,,
59
+ dbt_common-1.5.0.dist-info/METADATA,sha256=phlsK2cVVw1AWNpJa2_uNaM2KG5HroA0RZw4gUsMCFQ,5298
60
+ dbt_common-1.5.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
61
+ dbt_common-1.5.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
62
+ dbt_common-1.5.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.24.2
2
+ Generator: hatchling 1.25.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any