dbt-common 1.17.0__tar.gz → 1.19__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 (107) hide show
  1. {dbt_common-1.17.0 → dbt_common-1.19}/CHANGELOG.md +22 -2
  2. {dbt_common-1.17.0 → dbt_common-1.19}/PKG-INFO +2 -1
  3. dbt_common-1.19/dbt_common/__about__.py +1 -0
  4. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/clients/_jinja_blocks.py +19 -2
  5. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/clients/jinja.py +11 -2
  6. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/events/event_manager_client.py +0 -3
  7. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/events/helpers.py +2 -2
  8. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/events/logger.py +2 -2
  9. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/events/types.proto +10 -0
  10. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/events/types.py +11 -1
  11. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/events/types_pb2.py +5 -1
  12. dbt_common-1.19/dbt_common/helper_types.py +270 -0
  13. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/record.py +7 -0
  14. {dbt_common-1.17.0 → dbt_common-1.19}/pyproject.toml +1 -0
  15. dbt_common-1.17.0/dbt_common/__about__.py +0 -1
  16. dbt_common-1.17.0/dbt_common/helper_types.py +0 -134
  17. {dbt_common-1.17.0 → dbt_common-1.19}/.gitignore +0 -0
  18. {dbt_common-1.17.0 → dbt_common-1.19}/LICENSE +0 -0
  19. {dbt_common-1.17.0 → dbt_common-1.19}/README.md +0 -0
  20. {dbt_common-1.17.0 → dbt_common-1.19}/codecov.yml +0 -0
  21. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/__init__.py +0 -0
  22. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/behavior_flags.py +0 -0
  23. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/clients/__init__.py +0 -0
  24. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/clients/agate_helper.py +0 -0
  25. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/clients/system.py +0 -0
  26. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/constants.py +0 -0
  27. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/context.py +0 -0
  28. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/contracts/__init__.py +0 -0
  29. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/contracts/config/__init__.py +0 -0
  30. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/contracts/config/base.py +0 -0
  31. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/contracts/config/materialization.py +0 -0
  32. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/contracts/config/metadata.py +0 -0
  33. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/contracts/config/properties.py +0 -0
  34. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/contracts/constraints.py +0 -0
  35. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/contracts/metadata.py +0 -0
  36. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/contracts/util.py +0 -0
  37. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/dataclass_schema.py +0 -0
  38. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/events/README.md +0 -0
  39. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/events/__init__.py +0 -0
  40. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/events/base_types.py +0 -0
  41. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/events/contextvars.py +0 -0
  42. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/events/event_handler.py +0 -0
  43. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/events/event_manager.py +0 -0
  44. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/events/format.py +0 -0
  45. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/events/functions.py +0 -0
  46. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/events/interfaces.py +0 -0
  47. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/exceptions/__init__.py +0 -0
  48. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/exceptions/base.py +0 -0
  49. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/exceptions/cache.py +0 -0
  50. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/exceptions/connection.py +0 -0
  51. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/exceptions/contracts.py +0 -0
  52. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/exceptions/events.py +0 -0
  53. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/exceptions/jinja.py +0 -0
  54. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/exceptions/macros.py +0 -0
  55. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/exceptions/system.py +0 -0
  56. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/invocation.py +0 -0
  57. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/py.typed +0 -0
  58. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/semver.py +0 -0
  59. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/tests.py +0 -0
  60. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/ui.py +0 -0
  61. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/utils/__init__.py +0 -0
  62. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/utils/casting.py +0 -0
  63. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/utils/connection.py +0 -0
  64. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/utils/dict.py +0 -0
  65. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/utils/encoding.py +0 -0
  66. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/utils/executor.py +0 -0
  67. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/utils/formatting.py +0 -0
  68. {dbt_common-1.17.0 → dbt_common-1.19}/dbt_common/utils/jinja.py +0 -0
  69. {dbt_common-1.17.0 → dbt_common-1.19}/docs/README.md +0 -0
  70. {dbt_common-1.17.0 → dbt_common-1.19}/docs/arch/adr-0001-build-tooling.md +0 -0
  71. {dbt_common-1.17.0 → dbt_common-1.19}/docs/guides/record_replay.md +0 -0
  72. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/agate/__init__.pyi +0 -0
  73. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/agate/data_types.pyi +0 -0
  74. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/colorama/__init__.pyi +0 -0
  75. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/isodate/__init__.pyi +0 -0
  76. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/__init__.pyi +0 -0
  77. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/config.pyi +0 -0
  78. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/core/__init__.pyi +0 -0
  79. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/core/const.pyi +0 -0
  80. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/core/helpers.pyi +0 -0
  81. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/core/meta/__init__.pyi +0 -0
  82. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/core/meta/code/__init__.pyi +0 -0
  83. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/core/meta/code/builder.pyi +0 -0
  84. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/core/meta/code/lines.pyi +0 -0
  85. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/core/meta/helpers.pyi +0 -0
  86. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/core/meta/mixin.pyi +0 -0
  87. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/core/meta/types/__init__.pyi +0 -0
  88. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/core/meta/types/common.pyi +0 -0
  89. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/core/meta/types/pack.pyi +0 -0
  90. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/core/meta/types/unpack.pyi +0 -0
  91. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/dialect.pyi +0 -0
  92. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/exceptions.pyi +0 -0
  93. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/helper.pyi +0 -0
  94. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/jsonschema/__init__.pyi +0 -0
  95. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/jsonschema/annotations.pyi +0 -0
  96. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/jsonschema/builder.pyi +0 -0
  97. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/jsonschema/dialects.pyi +0 -0
  98. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/jsonschema/models.pyi +0 -0
  99. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/jsonschema/schema.pyi +0 -0
  100. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/mixins/__init__.pyi +0 -0
  101. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/mixins/dict.pyi +0 -0
  102. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/mixins/json.pyi +0 -0
  103. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/mixins/msgpack.pyi +0 -0
  104. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/mixins/orjson.pyi +0 -0
  105. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/mixins/toml.pyi +0 -0
  106. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/mixins/yaml.pyi +0 -0
  107. {dbt_common-1.17.0 → dbt_common-1.19}/third-party-stubs/mashumaro/types.pyi +0 -0
@@ -5,6 +5,28 @@
5
5
  - "Breaking changes" listed under a version may require action from end users or external maintainers when upgrading to that version.
6
6
  - Do not edit this file directly. This file is auto-generated using [changie](https://github.com/miniscruff/changie). For details on how to document a change, see [the contributing guide](https://github.com/dbt-labs/dbt-common/blob/main/CONTRIBUTING.md#adding-changelog-entry)
7
7
 
8
+ ## dbt-common 1.19 - April 16, 2025
9
+
10
+
11
+
12
+ ## dbt-common 1.18 - April 14, 2025
13
+
14
+ ### Features
15
+
16
+ - Ability to specify 'Deprecations' in `WarnErrorOptions` ([#265](https://github.com/dbt-labs/dbt-common/issues/265))
17
+
18
+ ### Fixes
19
+
20
+ - Replace depricated datetime.datetime.utcnow() for datetime.datetime.now(timezone.utc) to reduce stdout spam. ([#238](https://github.com/dbt-labs/dbt-common/issues/238), [#99](https://github.com/dbt-labs/dbt-common/issues/99))
21
+
22
+ ### Under the Hood
23
+
24
+ - Add support for Python 3.13 ([#263](https://github.com/dbt-labs/dbt-common/issues/263))
25
+ - Add new event to signal issues during record/replay ([#268](https://github.com/dbt-labs/dbt-common/issues/268))
26
+
27
+ ### Contributors
28
+ - [@cfernhout](https://github.com/cfernhout) ([#238](https://github.com/dbt-labs/dbt-common/issues/238), [#99](https://github.com/dbt-labs/dbt-common/issues/99))
29
+
8
30
  ## dbt-common 1.17.0 - March 31, 2025
9
31
 
10
32
  ### Breaking Changes
@@ -15,8 +37,6 @@
15
37
 
16
38
  - Stream recorded events to disk rather than storing them in memory. ([#260](https://github.com/dbt-labs/dbt-common/issues/260))
17
39
 
18
-
19
-
20
40
  ## dbt-common 1.16.0 - March 18, 2025
21
41
 
22
42
  ### Features
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dbt-common
3
- Version: 1.17.0
3
+ Version: 1.19
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
@@ -20,6 +20,7 @@ Classifier: Programming Language :: Python :: 3.9
20
20
  Classifier: Programming Language :: Python :: 3.10
21
21
  Classifier: Programming Language :: Python :: 3.11
22
22
  Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
23
24
  Classifier: Programming Language :: Python :: Implementation :: CPython
24
25
  Classifier: Programming Language :: Python :: Implementation :: PyPy
25
26
  Requires-Python: >=3.9
@@ -0,0 +1 @@
1
+ version = "1.19"
@@ -1,7 +1,7 @@
1
1
  import dataclasses
2
2
  import re
3
3
  from collections import namedtuple
4
- from typing import Dict, Iterator, List, Optional, Set, Union
4
+ from typing import Callable, Dict, Iterator, List, Optional, Set, Union
5
5
 
6
6
  from dbt_common.exceptions import (
7
7
  BlockDefinitionNotAtTopError,
@@ -115,6 +115,12 @@ class PositionedMatch:
115
115
  match: Optional[re.Match]
116
116
 
117
117
 
118
+ @dataclasses.dataclass
119
+ class ExtractWarning:
120
+ warning_type: str
121
+ msg: str
122
+
123
+
118
124
  class TagIterator:
119
125
  def __init__(self, text: str) -> None:
120
126
  self.text: str = text
@@ -326,8 +332,13 @@ _CONTROL_FLOW_END_TAGS = {v: k for k, v in _CONTROL_FLOW_TAGS.items()}
326
332
 
327
333
 
328
334
  class BlockIterator:
329
- def __init__(self, tag_iterator: TagIterator) -> None:
335
+ def __init__(
336
+ self,
337
+ tag_iterator: TagIterator,
338
+ warning_callback: Optional[Callable[[ExtractWarning], None]] = None,
339
+ ) -> None:
330
340
  self.tag_parser = tag_iterator
341
+ self.warning_callback = warning_callback
331
342
  self.current: Optional[Tag] = None
332
343
  self.stack: List[str] = []
333
344
  self.last_position: int = 0
@@ -393,6 +404,12 @@ class BlockIterator:
393
404
  full_block=self.data[self.current.start : tag.end],
394
405
  )
395
406
  self.current = None
407
+ elif self.warning_callback:
408
+ self.warning_callback(
409
+ ExtractWarning(
410
+ "unexpected_block", f"Found unexpected '{tag.block_type_name}' block tag."
411
+ )
412
+ )
396
413
 
397
414
  if self.current:
398
415
  linecount = self.data[: self.current.end].count("\n") + 1
@@ -38,7 +38,13 @@ from dbt_common.utils.jinja import (
38
38
  get_materialization_macro_name,
39
39
  get_test_macro_name,
40
40
  )
41
- from dbt_common.clients._jinja_blocks import BlockIterator, BlockData, BlockTag, TagIterator
41
+ from dbt_common.clients._jinja_blocks import (
42
+ BlockIterator,
43
+ BlockData,
44
+ BlockTag,
45
+ TagIterator,
46
+ ExtractWarning,
47
+ )
42
48
 
43
49
  from dbt_common.exceptions import (
44
50
  CompilationError,
@@ -659,6 +665,7 @@ def extract_toplevel_blocks(
659
665
  text: str,
660
666
  allowed_blocks: Optional[Set[str]] = None,
661
667
  collect_raw_data: bool = True,
668
+ warning_callback: Optional[Callable[[ExtractWarning], None]] = None,
662
669
  ) -> List[Union[BlockData, BlockTag]]:
663
670
  """Extract the top-level blocks with matching block types from a jinja file.
664
671
 
@@ -672,6 +679,8 @@ def extract_toplevel_blocks(
672
679
  be part of the results, as `BlockData` objects. They have a
673
680
  `block_type_name` field of `'__dbt_data'` and will never have a
674
681
  `block_name`.
682
+ :param warning_callback: An optional callback that will be called if there
683
+ are recoverable issues detected in the template.
675
684
  :return: A list of `BlockTag`s matching the allowed block types and (if
676
685
  `collect_raw_data` is `True`) `BlockData` objects.
677
686
  """
@@ -682,7 +691,7 @@ def extract_toplevel_blocks(
682
691
  return _TESTING_BLOCKS_CACHE[hash]
683
692
 
684
693
  tag_iterator = TagIterator(text)
685
- blocks = BlockIterator(tag_iterator).lex_for_blocks(
694
+ blocks = BlockIterator(tag_iterator, warning_callback).lex_for_blocks(
686
695
  allowed_blocks=allowed_blocks, collect_raw_data=collect_raw_data
687
696
  )
688
697
 
@@ -8,17 +8,14 @@ _EVENT_MANAGER: IEventManager = EventManager()
8
8
 
9
9
 
10
10
  def get_event_manager() -> IEventManager:
11
- global _EVENT_MANAGER
12
11
  return _EVENT_MANAGER
13
12
 
14
13
 
15
14
  def add_logger_to_manager(logger) -> None:
16
- global _EVENT_MANAGER
17
15
  _EVENT_MANAGER.add_logger(logger)
18
16
 
19
17
 
20
18
  def add_callback_to_manager(callback: TCallback) -> None:
21
- global _EVENT_MANAGER
22
19
  _EVENT_MANAGER.add_callback(callback)
23
20
 
24
21
 
@@ -1,4 +1,4 @@
1
- from datetime import datetime
1
+ from datetime import datetime, timezone
2
2
 
3
3
 
4
4
  # This converts a datetime to a json format datetime string which
@@ -9,6 +9,6 @@ def datetime_to_json_string(dt: datetime) -> str:
9
9
 
10
10
  # preformatted time stamp
11
11
  def get_json_string_utcnow() -> str:
12
- ts = datetime.utcnow()
12
+ ts = datetime.now(timezone.utc).replace(tzinfo=None)
13
13
  ts_rfc3339 = datetime_to_json_string(ts)
14
14
  return ts_rfc3339
@@ -2,7 +2,7 @@ import json
2
2
  import logging
3
3
  import threading
4
4
  from dataclasses import dataclass
5
- from datetime import datetime
5
+ from datetime import datetime, timezone
6
6
  from enum import Enum
7
7
  from logging.handlers import RotatingFileHandler
8
8
  from typing import Optional, TextIO, Any, Callable
@@ -156,7 +156,7 @@ class _TextLogger(_Logger):
156
156
  if _is_print_event(msg):
157
157
  # PrintEvent is a special case, we don't want to add a timestamp
158
158
  return scrubbed_msg
159
- ts: str = datetime.utcnow().strftime("%H:%M:%S")
159
+ ts: str = datetime.now(timezone.utc).replace(tzinfo=None).strftime("%H:%M:%S")
160
160
  return f"{self._get_color_tag()}{ts} {scrubbed_msg}"
161
161
 
162
162
  def create_debug_line(self, msg: EventMsg) -> str:
@@ -144,3 +144,13 @@ message PrintEventMsg {
144
144
  EventInfo info = 1;
145
145
  PrintEvent data = 2;
146
146
  }
147
+
148
+ // Z053
149
+ message RecordReplayIssue {
150
+ string msg = 1;
151
+ }
152
+
153
+ message RecordReplayIssueMsg {
154
+ EventInfo info = 1;
155
+ RecordReplayIssue data = 2;
156
+ }
@@ -118,7 +118,7 @@ class SystemReportReturnCode(DebugLevel):
118
118
 
119
119
 
120
120
  # We use events to create console output, but also think of them as a sequence of important and
121
- # meaningful occurrences to be used for debugging and monitoring. The Formatting event helps eases
121
+ # meaningful occurrences to be used for debugging and monitoring. The Formatting event eases
122
122
  # the tension between these two goals by allowing empty lines, heading separators, and other
123
123
  # formatting to be written to the console, while they can be ignored for other purposes. For
124
124
  # general information that isn't simple formatting, the Note event should be used instead.
@@ -156,3 +156,13 @@ class PrintEvent(InfoLevel):
156
156
 
157
157
  def message(self) -> str:
158
158
  return self.msg
159
+
160
+
161
+ class RecordReplayIssue(InfoLevel):
162
+ """General event for reporting record/replay issues at runtime."""
163
+
164
+ def code(self) -> str:
165
+ return "Z053"
166
+
167
+ def message(self) -> str:
168
+ return self.msg
@@ -25,7 +25,7 @@ _sym_db = _symbol_database.Default()
25
25
  from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
26
26
 
27
27
 
28
- 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\"d\n\x13\x42\x65haviorChangeEvent\x12\x11\n\tflag_name\x18\x01 \x01(\t\x12\x13\n\x0b\x66lag_source\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12\x10\n\x08\x64ocs_url\x18\x04 \x01(\t\"n\n\x16\x42\x65haviorChangeEventMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12.\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32 .proto_types.BehaviorChangeEvent\"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')
28
+ 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\"d\n\x13\x42\x65haviorChangeEvent\x12\x11\n\tflag_name\x18\x01 \x01(\t\x12\x13\n\x0b\x66lag_source\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12\x10\n\x08\x64ocs_url\x18\x04 \x01(\t\"n\n\x16\x42\x65haviorChangeEventMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12.\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32 .proto_types.BehaviorChangeEvent\"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.PrintEvent\" \n\x11RecordReplayIssue\x12\x0b\n\x03msg\x18\x01 \x01(\t\"j\n\x14RecordReplayIssueMsg\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.RecordReplayIssueb\x06proto3')
29
29
 
30
30
  _globals = globals()
31
31
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -84,4 +84,8 @@ if not _descriptor._USE_C_DESCRIPTORS:
84
84
  _globals['_PRINTEVENT']._serialized_end=1909
85
85
  _globals['_PRINTEVENTMSG']._serialized_start=1911
86
86
  _globals['_PRINTEVENTMSG']._serialized_end=2003
87
+ _globals['_RECORDREPLAYISSUE']._serialized_start=2005
88
+ _globals['_RECORDREPLAYISSUE']._serialized_end=2037
89
+ _globals['_RECORDREPLAYISSUEMSG']._serialized_start=2039
90
+ _globals['_RECORDREPLAYISSUEMSG']._serialized_end=2145
87
91
  # @@protoc_insertion_point(module_scope)
@@ -0,0 +1,270 @@
1
+ # never name this package "types", or mypy will crash in ugly ways
2
+
3
+ # necessary for annotating constructors
4
+ from __future__ import annotations
5
+
6
+ from dataclasses import dataclass, field
7
+ from typing import Tuple, AbstractSet, Union
8
+ from typing import Callable, cast, Generic, Optional, TypeVar, List, NewType, Set
9
+
10
+ from dbt_common.dataclass_schema import (
11
+ dbtClassMixin,
12
+ ValidationError,
13
+ StrEnum,
14
+ )
15
+ from dbt_common.events.base_types import BaseEvent
16
+
17
+ Port = NewType("Port", int)
18
+
19
+
20
+ class NVEnum(StrEnum):
21
+ novalue = "novalue"
22
+
23
+ def __eq__(self, other) -> bool:
24
+ return isinstance(other, NVEnum)
25
+
26
+
27
+ @dataclass
28
+ class NoValue(dbtClassMixin):
29
+ """Sometimes, you want a way to say none that isn't None!"""
30
+
31
+ novalue: NVEnum = field(default_factory=lambda: NVEnum.novalue)
32
+
33
+
34
+ @dataclass
35
+ class IncludeExclude(dbtClassMixin):
36
+ INCLUDE_ALL = ("all", "*")
37
+
38
+ include: Union[str, List[str]]
39
+ exclude: List[str] = field(default_factory=list)
40
+
41
+ def __post_init__(self):
42
+ if isinstance(self.include, str) and self.include not in self.INCLUDE_ALL:
43
+ raise ValidationError(
44
+ f"include must be one of {self.INCLUDE_ALL} or a list of strings"
45
+ )
46
+
47
+ if self.exclude and self.include not in self.INCLUDE_ALL:
48
+ raise ValidationError(
49
+ f"exclude can only be specified if include is one of {self.INCLUDE_ALL}"
50
+ )
51
+
52
+ if isinstance(self.include, list):
53
+ self._validate_items(self.include)
54
+
55
+ if isinstance(self.exclude, list):
56
+ self._validate_items(self.exclude)
57
+
58
+ def includes(self, item_name: str) -> bool:
59
+ return (
60
+ item_name in self.include or self.include in self.INCLUDE_ALL
61
+ ) and item_name not in self.exclude
62
+
63
+ def _validate_items(self, items: List[str]) -> None:
64
+ pass
65
+
66
+
67
+ class WarnErrorOptions(IncludeExclude):
68
+ """
69
+ This class is used to configure the behavior of the warn_error feature (now part of fire_event).
70
+
71
+ include: "all", "*", or a list of event names.
72
+ exclude: a list of event names.
73
+ silence: a list of event names.
74
+ valid_error_names: a set of event names that can be named in include, exclude, and silence.
75
+
76
+ In a hierarchy of configuration, the following rules apply:
77
+ 1. named > Deprecations > "all"/"*"
78
+ 2. silence > exclude > include
79
+ 3. (1) > (2)
80
+ """
81
+
82
+ DEPRECATIONS = "Deprecations"
83
+
84
+ def __init__(
85
+ self,
86
+ include: Union[str, List[str]],
87
+ exclude: Optional[List[str]] = None,
88
+ valid_error_names: Optional[Set[str]] = None,
89
+ silence: Optional[List[str]] = None,
90
+ ):
91
+ self.silence = silence or []
92
+ self._valid_error_names: Set[str] = valid_error_names or set()
93
+ self._valid_error_names.add(self.DEPRECATIONS)
94
+ super().__init__(include=include, exclude=(exclude or []))
95
+
96
+ def __post_init__(self):
97
+ if isinstance(self.include, str) and self.include not in self.INCLUDE_ALL:
98
+ raise ValidationError(
99
+ f"include must be one of {self.INCLUDE_ALL} or a list of strings"
100
+ )
101
+
102
+ # To specify exclude, either `include` must be "all" or "deprecations" must be
103
+ # in `include` or `silence`.
104
+ if self.exclude and not (
105
+ self.include in self.INCLUDE_ALL
106
+ or self.DEPRECATIONS in self.include
107
+ or self.DEPRECATIONS in self.silence
108
+ ):
109
+ raise ValidationError(
110
+ f"exclude can only be specified if include is one of {self.INCLUDE_ALL} or "
111
+ f"{self.DEPRECATIONS} is in include or silence."
112
+ )
113
+
114
+ if isinstance(self.include, list):
115
+ self._validate_items(self.include)
116
+
117
+ if isinstance(self.exclude, list):
118
+ self._validate_items(self.exclude)
119
+
120
+ if isinstance(self.silence, list):
121
+ self._validate_items(self.silence)
122
+
123
+ def _includes_all(self) -> bool:
124
+ """Is `*` or `all` set as include?"""
125
+ return self.include in self.INCLUDE_ALL
126
+
127
+ def _named_inclusion(self, item_name: str) -> bool:
128
+ """Is the item_name named in the include list?"""
129
+ return item_name in self.include
130
+
131
+ def _named_exclusion(self, item_name: str) -> bool:
132
+ """Is the item_name named in the exclude list?"""
133
+ return item_name in self.exclude
134
+
135
+ def _named_silence(self, item_name: str) -> bool:
136
+ """Is the item_name named in the silence list?"""
137
+ return item_name in self.silence
138
+
139
+ def _include_as_deprecation(self, event: Optional[BaseEvent]) -> bool:
140
+ """Is event included as a deprecation?"""
141
+ return (
142
+ event is not None
143
+ and event.code().startswith("D")
144
+ and self.DEPRECATIONS in self.include
145
+ )
146
+
147
+ def _exclude_as_deprecation(self, event: Optional[BaseEvent]) -> bool:
148
+ """Is event excluded as a deprecation?"""
149
+ return (
150
+ event is not None
151
+ and event.code().startswith("D")
152
+ and self.DEPRECATIONS in self.exclude
153
+ )
154
+
155
+ def _silence_as_deprecation(self, event: Optional[BaseEvent]) -> bool:
156
+ """Is event silenced as a deprecation?"""
157
+ return (
158
+ event is not None
159
+ and event.code().startswith("D")
160
+ and self.DEPRECATIONS in self.silence
161
+ )
162
+
163
+ def includes(self, item_name: Union[str, BaseEvent]) -> bool:
164
+ """Is the event included?
165
+
166
+ An event included if any of the following are true:
167
+ - The event is named in `include` and not named in `exclude` or `silence`
168
+ - "*" or "all" is specified for `include`, and the event is not named in `exclude` or `silence`
169
+ - The event is a deprecation, "deprecations" is in `include`, and the event is not named in `exclude` or `silence`
170
+ nor is "deprecations" in `exclude` or `silence`
171
+ """
172
+ # Setup based on item_name type
173
+ if isinstance(item_name, str):
174
+ event_name = item_name
175
+ event = None
176
+ else:
177
+ event_name = type(item_name).__name__
178
+ event = item_name
179
+
180
+ # Pre-compute checks that will be used multiple times
181
+ named_elsewhere = self._named_exclusion(event_name) or self._named_silence(event_name)
182
+ deprecation_elsewhere = self._exclude_as_deprecation(
183
+ event
184
+ ) or self._silence_as_deprecation(event)
185
+
186
+ # Calculate result
187
+ if self._named_inclusion(event_name) and not named_elsewhere:
188
+ return True
189
+ elif self._include_as_deprecation(event) and not (
190
+ named_elsewhere or deprecation_elsewhere
191
+ ):
192
+ return True
193
+ elif self._includes_all() and not (named_elsewhere or deprecation_elsewhere):
194
+ return True
195
+ else:
196
+ return False
197
+
198
+ def silenced(self, item_name: Union[str, BaseEvent]) -> bool:
199
+ """Is the event silenced?
200
+
201
+ An event silenced if any of the following are true:
202
+ - The event is named in `silence`
203
+ - "Deprecations" is in `silence` and the event is not named in `include` or `exclude`
204
+ """
205
+ # Setup based on item_name type
206
+ if isinstance(item_name, str):
207
+ event_name = item_name
208
+ event = None
209
+ else:
210
+ event_name = type(item_name).__name__
211
+ event = item_name
212
+
213
+ # Pre-compute checks that will be used multiple times
214
+ named_elsewhere = self._named_inclusion(event_name) or self._named_exclusion(event_name)
215
+
216
+ # Calculate result
217
+ if self._named_silence(event_name):
218
+ return True
219
+ elif self._silence_as_deprecation(event) and not named_elsewhere:
220
+ return True
221
+ else:
222
+ return False
223
+
224
+ def _validate_items(self, items: List[str]):
225
+ for item in items:
226
+ if item not in self._valid_error_names:
227
+ raise ValidationError(f"{item} is not a valid dbt error name.")
228
+
229
+
230
+ FQNPath = Tuple[str, ...]
231
+ PathSet = AbstractSet[FQNPath]
232
+
233
+ T = TypeVar("T")
234
+
235
+
236
+ # A data type for representing lazily evaluated values.
237
+ #
238
+ # usage:
239
+ # x = Lazy.defer(lambda: expensive_fn())
240
+ # y = x.force()
241
+ #
242
+ # inspired by the purescript data type
243
+ # https://pursuit.purescript.org/packages/purescript-lazy/5.0.0/docs/Data.Lazy
244
+ @dataclass
245
+ class Lazy(Generic[T]):
246
+ _f: Callable[[], T]
247
+ memo: Optional[T] = None
248
+
249
+ # constructor for lazy values
250
+ @classmethod
251
+ def defer(cls, f: Callable[[], T]) -> Lazy[T]:
252
+ return Lazy(f)
253
+
254
+ # workaround for open mypy issue:
255
+ # https://github.com/python/mypy/issues/6910
256
+ def _typed_eval_f(self) -> T:
257
+ return cast(Callable[[], T], getattr(self, "_f"))()
258
+
259
+ # evaluates the function if the value has not been memoized already
260
+ def force(self) -> T:
261
+ if self.memo is None:
262
+ self.memo = self._typed_eval_f()
263
+ return self.memo
264
+
265
+
266
+ # This class is used in to_target_dict, so that accesses to missing keys
267
+ # will return an empty string instead of Undefined
268
+ class DictDefaultEmptyStr(dict):
269
+ def __getitem__(self, key):
270
+ return dict.get(self, key, "")
@@ -457,6 +457,13 @@ def _record_function_inner(
457
457
  index_on_thread_id,
458
458
  func_to_record,
459
459
  ):
460
+ recorded_types = get_record_types_from_env()
461
+ if recorded_types is not None and not (
462
+ getattr(record_type, "__name__", record_type) in recorded_types
463
+ or getattr(record_type, "group", group) in recorded_types
464
+ ):
465
+ return func_to_record
466
+
460
467
  if isinstance(record_type, str):
461
468
  return_type = inspect.signature(func_to_record).return_annotation
462
469
  fields = _get_arg_fields(inspect.getfullargspec(func_to_record), method)
@@ -23,6 +23,7 @@ classifiers = [
23
23
  "Programming Language :: Python :: 3.10",
24
24
  "Programming Language :: Python :: 3.11",
25
25
  "Programming Language :: Python :: 3.12",
26
+ "Programming Language :: Python :: 3.13",
26
27
  "Programming Language :: Python :: Implementation :: CPython",
27
28
  "Programming Language :: Python :: Implementation :: PyPy",
28
29
  ]
@@ -1 +0,0 @@
1
- version = "1.17.0"
@@ -1,134 +0,0 @@
1
- # never name this package "types", or mypy will crash in ugly ways
2
-
3
- # necessary for annotating constructors
4
- from __future__ import annotations
5
-
6
- from dataclasses import dataclass, field
7
- from typing import Tuple, AbstractSet, Union
8
- from typing import Callable, cast, Generic, Optional, TypeVar, List, NewType, Set
9
-
10
- from dbt_common.dataclass_schema import (
11
- dbtClassMixin,
12
- ValidationError,
13
- StrEnum,
14
- )
15
-
16
- Port = NewType("Port", int)
17
-
18
-
19
- class NVEnum(StrEnum):
20
- novalue = "novalue"
21
-
22
- def __eq__(self, other) -> bool:
23
- return isinstance(other, NVEnum)
24
-
25
-
26
- @dataclass
27
- class NoValue(dbtClassMixin):
28
- """Sometimes, you want a way to say none that isn't None!"""
29
-
30
- novalue: NVEnum = field(default_factory=lambda: NVEnum.novalue)
31
-
32
-
33
- @dataclass
34
- class IncludeExclude(dbtClassMixin):
35
- INCLUDE_ALL = ("all", "*")
36
-
37
- include: Union[str, List[str]]
38
- exclude: List[str] = field(default_factory=list)
39
-
40
- def __post_init__(self):
41
- if isinstance(self.include, str) and self.include not in self.INCLUDE_ALL:
42
- raise ValidationError(
43
- f"include must be one of {self.INCLUDE_ALL} or a list of strings"
44
- )
45
-
46
- if self.exclude and self.include not in self.INCLUDE_ALL:
47
- raise ValidationError(
48
- f"exclude can only be specified if include is one of {self.INCLUDE_ALL}"
49
- )
50
-
51
- if isinstance(self.include, list):
52
- self._validate_items(self.include)
53
-
54
- if isinstance(self.exclude, list):
55
- self._validate_items(self.exclude)
56
-
57
- def includes(self, item_name: str) -> bool:
58
- return (
59
- item_name in self.include or self.include in self.INCLUDE_ALL
60
- ) and item_name not in self.exclude
61
-
62
- def _validate_items(self, items: List[str]) -> None:
63
- pass
64
-
65
-
66
- class WarnErrorOptions(IncludeExclude):
67
- def __init__(
68
- self,
69
- include: Union[str, List[str]],
70
- exclude: Optional[List[str]] = None,
71
- valid_error_names: Optional[Set[str]] = None,
72
- silence: Optional[List[str]] = None,
73
- ):
74
- self.silence = silence or []
75
- self._valid_error_names: Set[str] = valid_error_names or set()
76
- super().__init__(include=include, exclude=(exclude or []))
77
-
78
- def __post_init__(self):
79
- super().__post_init__()
80
- self._validate_items(self.silence)
81
-
82
- def includes(self, item_name: str) -> bool:
83
- return super().includes(item_name) and not self.silenced(item_name)
84
-
85
- def silenced(self, item_name: str) -> bool:
86
- return item_name in self.silence
87
-
88
- def _validate_items(self, items: List[str]):
89
- for item in items:
90
- if item not in self._valid_error_names:
91
- raise ValidationError(f"{item} is not a valid dbt error name.")
92
-
93
-
94
- FQNPath = Tuple[str, ...]
95
- PathSet = AbstractSet[FQNPath]
96
-
97
- T = TypeVar("T")
98
-
99
-
100
- # A data type for representing lazily evaluated values.
101
- #
102
- # usage:
103
- # x = Lazy.defer(lambda: expensive_fn())
104
- # y = x.force()
105
- #
106
- # inspired by the purescript data type
107
- # https://pursuit.purescript.org/packages/purescript-lazy/5.0.0/docs/Data.Lazy
108
- @dataclass
109
- class Lazy(Generic[T]):
110
- _f: Callable[[], T]
111
- memo: Optional[T] = None
112
-
113
- # constructor for lazy values
114
- @classmethod
115
- def defer(cls, f: Callable[[], T]) -> Lazy[T]:
116
- return Lazy(f)
117
-
118
- # workaround for open mypy issue:
119
- # https://github.com/python/mypy/issues/6910
120
- def _typed_eval_f(self) -> T:
121
- return cast(Callable[[], T], getattr(self, "_f"))()
122
-
123
- # evaluates the function if the value has not been memoized already
124
- def force(self) -> T:
125
- if self.memo is None:
126
- self.memo = self._typed_eval_f()
127
- return self.memo
128
-
129
-
130
- # This class is used in to_target_dict, so that accesses to missing keys
131
- # will return an empty string instead of Undefined
132
- class DictDefaultEmptyStr(dict):
133
- def __getitem__(self, key):
134
- return dict.get(self, key, "")
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes