sqlmesh 0.206.2.dev6__py3-none-any.whl → 0.206.2.dev8__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.
- sqlmesh/_version.py +2 -2
- sqlmesh/core/console.py +19 -33
- sqlmesh/core/loader.py +6 -1
- sqlmesh/core/test/definition.py +13 -4
- sqlmesh/core/test/result.py +17 -2
- {sqlmesh-0.206.2.dev6.dist-info → sqlmesh-0.206.2.dev8.dist-info}/METADATA +1 -1
- {sqlmesh-0.206.2.dev6.dist-info → sqlmesh-0.206.2.dev8.dist-info}/RECORD +11 -11
- {sqlmesh-0.206.2.dev6.dist-info → sqlmesh-0.206.2.dev8.dist-info}/WHEEL +0 -0
- {sqlmesh-0.206.2.dev6.dist-info → sqlmesh-0.206.2.dev8.dist-info}/entry_points.txt +0 -0
- {sqlmesh-0.206.2.dev6.dist-info → sqlmesh-0.206.2.dev8.dist-info}/licenses/LICENSE +0 -0
- {sqlmesh-0.206.2.dev6.dist-info → sqlmesh-0.206.2.dev8.dist-info}/top_level.txt +0 -0
sqlmesh/_version.py
CHANGED
|
@@ -17,5 +17,5 @@ __version__: str
|
|
|
17
17
|
__version_tuple__: VERSION_TUPLE
|
|
18
18
|
version_tuple: VERSION_TUPLE
|
|
19
19
|
|
|
20
|
-
__version__ = version = '0.206.2.
|
|
21
|
-
__version_tuple__ = version_tuple = (0, 206, 2, '
|
|
20
|
+
__version__ = version = '0.206.2.dev8'
|
|
21
|
+
__version_tuple__ = version_tuple = (0, 206, 2, 'dev8')
|
sqlmesh/core/console.py
CHANGED
|
@@ -2163,13 +2163,12 @@ class TerminalConsole(Console):
|
|
|
2163
2163
|
self._print("-" * divider_length)
|
|
2164
2164
|
self._print("Test Failure Summary", style="red")
|
|
2165
2165
|
self._print("=" * divider_length)
|
|
2166
|
-
|
|
2166
|
+
fail_and_error_tests = result.get_fail_and_error_tests()
|
|
2167
2167
|
self._print(f"{message} \n")
|
|
2168
2168
|
|
|
2169
|
-
self._print(f"Failed tests ({
|
|
2170
|
-
for test
|
|
2171
|
-
|
|
2172
|
-
self._print(f" • {test.path}::{test.test_name}")
|
|
2169
|
+
self._print(f"Failed tests ({len(fail_and_error_tests)}):")
|
|
2170
|
+
for test in fail_and_error_tests:
|
|
2171
|
+
self._print(f" • {test.path}::{test.test_name}")
|
|
2173
2172
|
self._print("=" * divider_length, end="\n\n")
|
|
2174
2173
|
|
|
2175
2174
|
def _captured_unit_test_results(self, result: ModelTextTestResult) -> str:
|
|
@@ -2721,28 +2720,15 @@ class TerminalConsole(Console):
|
|
|
2721
2720
|
Args:
|
|
2722
2721
|
result: The unittest test result that contains metrics like num success, fails, ect.
|
|
2723
2722
|
"""
|
|
2724
|
-
|
|
2725
2723
|
if result.wasSuccessful():
|
|
2726
2724
|
self._print("\n", end="")
|
|
2727
2725
|
return
|
|
2728
2726
|
|
|
2729
|
-
errors = result.errors
|
|
2730
|
-
failures = result.failures
|
|
2731
|
-
skipped = result.skipped
|
|
2732
|
-
|
|
2733
|
-
infos = []
|
|
2734
|
-
if failures:
|
|
2735
|
-
infos.append(f"failures={len(failures)}")
|
|
2736
|
-
if errors:
|
|
2737
|
-
infos.append(f"errors={len(errors)}")
|
|
2738
|
-
if skipped:
|
|
2739
|
-
infos.append(f"skipped={skipped}")
|
|
2740
|
-
|
|
2741
2727
|
if unittest_char_separator:
|
|
2742
2728
|
self._print(f"\n{unittest.TextTestResult.separator1}\n\n", end="")
|
|
2743
2729
|
|
|
2744
2730
|
for (test_case, failure), test_failure_tables in zip_longest( # type: ignore
|
|
2745
|
-
failures, result.failure_tables
|
|
2731
|
+
result.failures, result.failure_tables
|
|
2746
2732
|
):
|
|
2747
2733
|
self._print(unittest.TextTestResult.separator2)
|
|
2748
2734
|
self._print(f"FAIL: {test_case}")
|
|
@@ -2758,7 +2744,7 @@ class TerminalConsole(Console):
|
|
|
2758
2744
|
self._print(failure_table)
|
|
2759
2745
|
self._print("\n", end="")
|
|
2760
2746
|
|
|
2761
|
-
for test_case, error in errors:
|
|
2747
|
+
for test_case, error in result.errors:
|
|
2762
2748
|
self._print(unittest.TextTestResult.separator2)
|
|
2763
2749
|
self._print(f"ERROR: {test_case}")
|
|
2764
2750
|
self._print(f"{unittest.TextTestResult.separator2}")
|
|
@@ -3080,27 +3066,27 @@ class NotebookMagicConsole(TerminalConsole):
|
|
|
3080
3066
|
fail_shared_style = {**shared_style, **fail_color}
|
|
3081
3067
|
header = str(h("span", {"style": fail_shared_style}, "-" * divider_length))
|
|
3082
3068
|
message = str(h("span", {"style": fail_shared_style}, "Test Failure Summary"))
|
|
3069
|
+
fail_and_error_tests = result.get_fail_and_error_tests()
|
|
3083
3070
|
failed_tests = [
|
|
3084
3071
|
str(
|
|
3085
3072
|
h(
|
|
3086
3073
|
"span",
|
|
3087
3074
|
{"style": fail_shared_style},
|
|
3088
|
-
f"Failed tests ({len(
|
|
3075
|
+
f"Failed tests ({len(fail_and_error_tests)}):",
|
|
3089
3076
|
)
|
|
3090
3077
|
)
|
|
3091
3078
|
]
|
|
3092
3079
|
|
|
3093
|
-
for test
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
f" • {test.model.name}::{test.test_name}",
|
|
3101
|
-
)
|
|
3080
|
+
for test in fail_and_error_tests:
|
|
3081
|
+
failed_tests.append(
|
|
3082
|
+
str(
|
|
3083
|
+
h(
|
|
3084
|
+
"span",
|
|
3085
|
+
{"style": fail_shared_style},
|
|
3086
|
+
f" • {test.model.name}::{test.test_name}",
|
|
3102
3087
|
)
|
|
3103
3088
|
)
|
|
3089
|
+
)
|
|
3104
3090
|
failures = "<br>".join(failed_tests)
|
|
3105
3091
|
footer = str(h("span", {"style": fail_shared_style}, "=" * divider_length))
|
|
3106
3092
|
error_output = widgets.Textarea(output, layout={"height": "300px", "width": "100%"})
|
|
@@ -3508,10 +3494,10 @@ class MarkdownConsole(CaptureTerminalConsole):
|
|
|
3508
3494
|
self._log_test_details(result, unittest_char_separator=False)
|
|
3509
3495
|
self._print("```\n\n")
|
|
3510
3496
|
|
|
3511
|
-
|
|
3497
|
+
fail_and_error_tests = result.get_fail_and_error_tests()
|
|
3512
3498
|
self._print(f"**{message}**\n")
|
|
3513
|
-
self._print(f"**Failed tests ({
|
|
3514
|
-
for test
|
|
3499
|
+
self._print(f"**Failed tests ({len(fail_and_error_tests)}):**")
|
|
3500
|
+
for test in fail_and_error_tests:
|
|
3515
3501
|
if isinstance(test, ModelTest):
|
|
3516
3502
|
self._print(f" • `{test.model.name}`::`{test.test_name}`\n\n")
|
|
3517
3503
|
|
sqlmesh/core/loader.py
CHANGED
|
@@ -710,6 +710,8 @@ class SqlMeshLoader(Loader):
|
|
|
710
710
|
def _load_signals(self) -> UniqueKeyDict[str, signal]:
|
|
711
711
|
"""Loads signals for the built-in scheduler."""
|
|
712
712
|
|
|
713
|
+
base_signals = signal.get_registry()
|
|
714
|
+
|
|
713
715
|
signals_max_mtime: t.Optional[float] = None
|
|
714
716
|
|
|
715
717
|
for path in self._glob_paths(
|
|
@@ -729,7 +731,10 @@ class SqlMeshLoader(Loader):
|
|
|
729
731
|
|
|
730
732
|
self._signals_max_mtime = signals_max_mtime
|
|
731
733
|
|
|
732
|
-
|
|
734
|
+
signals = signal.get_registry()
|
|
735
|
+
signal.set_registry(base_signals)
|
|
736
|
+
|
|
737
|
+
return signals
|
|
733
738
|
|
|
734
739
|
def _load_audits(
|
|
735
740
|
self, macros: MacroRegistry, jinja_macros: JinjaMacroRegistry
|
sqlmesh/core/test/definition.py
CHANGED
|
@@ -317,6 +317,13 @@ class ModelTest(unittest.TestCase):
|
|
|
317
317
|
#
|
|
318
318
|
# This is a bit of a hack, but it's a way to get the best of both worlds.
|
|
319
319
|
args: t.List[t.Any] = []
|
|
320
|
+
|
|
321
|
+
failed_subtest = ""
|
|
322
|
+
|
|
323
|
+
if subtest := getattr(self, "_subtest", None):
|
|
324
|
+
if cte := subtest.params.get("cte"):
|
|
325
|
+
failed_subtest = f" (CTE {cte})"
|
|
326
|
+
|
|
320
327
|
if expected.shape != actual.shape:
|
|
321
328
|
_raise_if_unexpected_columns(expected.columns, actual.columns)
|
|
322
329
|
|
|
@@ -325,13 +332,13 @@ class ModelTest(unittest.TestCase):
|
|
|
325
332
|
missing_rows = _row_difference(expected, actual)
|
|
326
333
|
if not missing_rows.empty:
|
|
327
334
|
args[0] += f"\n\nMissing rows:\n\n{missing_rows}"
|
|
328
|
-
args.append(df_to_table("Missing rows", missing_rows))
|
|
335
|
+
args.append(df_to_table(f"Missing rows{failed_subtest}", missing_rows))
|
|
329
336
|
|
|
330
337
|
unexpected_rows = _row_difference(actual, expected)
|
|
331
338
|
|
|
332
339
|
if not unexpected_rows.empty:
|
|
333
340
|
args[0] += f"\n\nUnexpected rows:\n\n{unexpected_rows}"
|
|
334
|
-
args.append(df_to_table("Unexpected rows", unexpected_rows))
|
|
341
|
+
args.append(df_to_table(f"Unexpected rows{failed_subtest}", unexpected_rows))
|
|
335
342
|
|
|
336
343
|
else:
|
|
337
344
|
diff = expected.compare(actual).rename(columns={"self": "exp", "other": "act"})
|
|
@@ -341,7 +348,8 @@ class ModelTest(unittest.TestCase):
|
|
|
341
348
|
diff.rename(columns={"exp": "Expected", "act": "Actual"}, inplace=True)
|
|
342
349
|
if self.verbosity == Verbosity.DEFAULT:
|
|
343
350
|
args.extend(
|
|
344
|
-
df_to_table("Data mismatch", df)
|
|
351
|
+
df_to_table(f"Data mismatch{failed_subtest}", df)
|
|
352
|
+
for df in _split_df_by_column_pairs(diff)
|
|
345
353
|
)
|
|
346
354
|
else:
|
|
347
355
|
from pandas import MultiIndex
|
|
@@ -351,7 +359,8 @@ class ModelTest(unittest.TestCase):
|
|
|
351
359
|
col_diff = diff[col]
|
|
352
360
|
if not col_diff.empty:
|
|
353
361
|
table = df_to_table(
|
|
354
|
-
f"[bold red]Column '{col}' mismatch[/bold red]",
|
|
362
|
+
f"[bold red]Column '{col}' mismatch{failed_subtest}[/bold red]",
|
|
363
|
+
col_diff,
|
|
355
364
|
)
|
|
356
365
|
args.append(table)
|
|
357
366
|
|
sqlmesh/core/test/result.py
CHANGED
|
@@ -4,6 +4,8 @@ import types
|
|
|
4
4
|
import typing as t
|
|
5
5
|
import unittest
|
|
6
6
|
|
|
7
|
+
from sqlmesh.core.test.definition import ModelTest
|
|
8
|
+
|
|
7
9
|
if t.TYPE_CHECKING:
|
|
8
10
|
ErrorType = t.Union[
|
|
9
11
|
t.Tuple[type[BaseException], BaseException, types.TracebackType],
|
|
@@ -42,7 +44,10 @@ class ModelTextTestResult(unittest.TextTestResult):
|
|
|
42
44
|
exctype, value, tb = err
|
|
43
45
|
err = (exctype, value, None) # type: ignore
|
|
44
46
|
|
|
45
|
-
|
|
47
|
+
if err[0] and issubclass(err[0], test.failureException):
|
|
48
|
+
self.addFailure(test, err)
|
|
49
|
+
else:
|
|
50
|
+
self.addError(test, err)
|
|
46
51
|
|
|
47
52
|
def _print_char(self, char: str) -> None:
|
|
48
53
|
from sqlmesh.core.console import TerminalConsole
|
|
@@ -117,4 +122,14 @@ class ModelTextTestResult(unittest.TextTestResult):
|
|
|
117
122
|
skipped_args = other.skipped[0]
|
|
118
123
|
self.addSkip(skipped_args[0], skipped_args[1])
|
|
119
124
|
|
|
120
|
-
self.testsRun +=
|
|
125
|
+
self.testsRun += other.testsRun
|
|
126
|
+
|
|
127
|
+
def get_fail_and_error_tests(self) -> t.List[ModelTest]:
|
|
128
|
+
# If tests contain failed subtests (e.g testing CTE outputs) we don't want
|
|
129
|
+
# to report it as different test failures
|
|
130
|
+
test_name_to_test = {
|
|
131
|
+
test.test_name: test
|
|
132
|
+
for test, _ in self.failures + self.errors
|
|
133
|
+
if isinstance(test, ModelTest)
|
|
134
|
+
}
|
|
135
|
+
return list(test_name_to_test.values())
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
sqlmesh/__init__.py,sha256=QjwaamJIdW7voXoS880yAx7tHm-Im4_mqGA-XJgafos,7631
|
|
2
|
-
sqlmesh/_version.py,sha256=
|
|
2
|
+
sqlmesh/_version.py,sha256=xjRXn5bPwiZFKZ9lkp60TXLTlVjewwJGYmGlX053TQo,528
|
|
3
3
|
sqlmesh/magics.py,sha256=bEzYqXHcM0P3CjyUZ1O9arlmXAdLAhoglKbQ29fD9AE,41842
|
|
4
4
|
sqlmesh/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
sqlmesh/cicd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -11,14 +11,14 @@ sqlmesh/cli/options.py,sha256=8qEGWivk4urGikpEmaU9T8WsyaZtjCpmW4Ed25iQ73I,2543
|
|
|
11
11
|
sqlmesh/cli/project_init.py,sha256=5JmDmUK0WJs39hM-p76uzHYdo1Hnx6fKuJg_pR3Hn5A,16419
|
|
12
12
|
sqlmesh/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
13
|
sqlmesh/core/_typing.py,sha256=e1f7xO2aZCy38M_3VoDy-XI3shyd99-IFctgIFSgXWM,497
|
|
14
|
-
sqlmesh/core/console.py,sha256=
|
|
14
|
+
sqlmesh/core/console.py,sha256=KbIXoxt5hpDENEolY-DpBlPmcWtJ9vzEgF52mjG2jPE,165710
|
|
15
15
|
sqlmesh/core/constants.py,sha256=gUABXWYgH_XOSbaZAJsR5o1dmA61JDCvBDyxqqXX3LM,2630
|
|
16
16
|
sqlmesh/core/context.py,sha256=SkTNrp9TUNx469_mWkemhMk4leGDtmblBIWE7S64sk8,127598
|
|
17
17
|
sqlmesh/core/context_diff.py,sha256=_Ur55fGLJ58Icsp44I4pVhdi7_JHiHq45mWIco9oFzk,21792
|
|
18
18
|
sqlmesh/core/dialect.py,sha256=lJHcE7D6GvYs1tzbexJb1mi4gltsMUzHeOrhN4ObIdo,51343
|
|
19
19
|
sqlmesh/core/environment.py,sha256=odus40R-YzdQdS_IiUq_tFouUXIhnpwmNwo8dE8Aw1k,13041
|
|
20
20
|
sqlmesh/core/lineage.py,sha256=zjB0Zfamo2Fja2r5SSZPMbrEKTXr1WjozZPVqvxdybI,3143
|
|
21
|
-
sqlmesh/core/loader.py,sha256=
|
|
21
|
+
sqlmesh/core/loader.py,sha256=8xQ925fFgcM9k24S3V7LgsRvdX6M2WWLX5mU1UMkfWk,41203
|
|
22
22
|
sqlmesh/core/macros.py,sha256=h99VzqXXjFZYA0t2730HKdq4NP6tYo-VKvcpwipAneQ,62422
|
|
23
23
|
sqlmesh/core/node.py,sha256=3ChBz1PIMJhp-jzed_GLBrtmEF2v_BVDEM5WNe0ssPk,14658
|
|
24
24
|
sqlmesh/core/notification_target.py,sha256=PPGoDrgbRKxr27vJEu03XqNTQLYTw0ZF_b0yAapxGeI,16158
|
|
@@ -119,9 +119,9 @@ sqlmesh/core/state_sync/db/utils.py,sha256=204OpT3ISFPCwWP9Aqq8nr6ETl24sbG5uOyo8
|
|
|
119
119
|
sqlmesh/core/state_sync/db/version.py,sha256=fl5g1tNMYu8O6WTN4J3bciwjGq0c5nZlRDlxxRKGU78,2210
|
|
120
120
|
sqlmesh/core/test/__init__.py,sha256=e83TJPwPRR_rAG29Y0OVbZb-5oWVBzz-_wrcd22Qk10,418
|
|
121
121
|
sqlmesh/core/test/context.py,sha256=9mmskKXpzsIkW_I31uN1n3Ioj8ngvyGAqyL_AZvVHpc,2253
|
|
122
|
-
sqlmesh/core/test/definition.py,sha256=
|
|
122
|
+
sqlmesh/core/test/definition.py,sha256=VvjwvBoyd-y6Ucepf_vLuDm2DxqDLJh0X--D8BzFUng,41868
|
|
123
123
|
sqlmesh/core/test/discovery.py,sha256=WXIwPidLoacAGHoT_3TVFFEKamG89nHNtaMsZ01uGjs,1188
|
|
124
|
-
sqlmesh/core/test/result.py,sha256=
|
|
124
|
+
sqlmesh/core/test/result.py,sha256=6gOKEsERciHhcrw9TedtNr7g1ynTO7UwA5-PPrzvYuM,4564
|
|
125
125
|
sqlmesh/core/test/runner.py,sha256=8I-cL7Q9CggLvET_GPkrXB2YjlyCIHrvbFbbRDnSHRE,6169
|
|
126
126
|
sqlmesh/dbt/__init__.py,sha256=KUv-lW5sG9D2ceXAIzA4MLcjyhzq3E-7qJP4P_PH2EU,144
|
|
127
127
|
sqlmesh/dbt/adapter.py,sha256=pV8b8m_wqK3YJo_6D5b6cZBwgewFAPvAlvLO51UCBl4,16948
|
|
@@ -288,7 +288,7 @@ sqlmesh/utils/pydantic.py,sha256=o_NsXbIpDqNpUA1Uc5xF0ZzoXQYYB0DfHwdRxBwXPNk,120
|
|
|
288
288
|
sqlmesh/utils/rich.py,sha256=cwQ5nJ6sgz64xHtoh6_ec7ReV5YpsOGhMtUJnwoRfEI,3549
|
|
289
289
|
sqlmesh/utils/windows.py,sha256=r7Yin4WEwbvH7sKA3hOJtRsclmscNuBeCklCfVPvtQs,611
|
|
290
290
|
sqlmesh/utils/yaml.py,sha256=hvo5lmybYLcIx4p6CQwufS8X4MbwS60lEBnCmYJCXmU,2336
|
|
291
|
-
sqlmesh-0.206.2.
|
|
291
|
+
sqlmesh-0.206.2.dev8.dist-info/licenses/LICENSE,sha256=OlMefUjgWJdULtf84BLW0AZZcY8DwdgQqb_1j2862j8,11346
|
|
292
292
|
web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
293
293
|
web/client/dist/index.html,sha256=SXykdSRNgrT1k6I2dPZPEfpxPjIsi8-yVFijt-naSA4,5472
|
|
294
294
|
web/client/dist/assets/Audits-Jm353fhk.js,sha256=ry6b5IKT3hLAfD5C3T2BqxulfauEV0n0YZ2vsP4eQ_U,1041
|
|
@@ -406,8 +406,8 @@ web/server/api/endpoints/models.py,sha256=kwj0s7uve3iZSMfmjkoPVMFMeY1sD0peTeyrWf
|
|
|
406
406
|
web/server/api/endpoints/modules.py,sha256=8hqqgonGay_mJmpCw0IdbjsPhWlQH2VLdKAqha-myac,468
|
|
407
407
|
web/server/api/endpoints/plan.py,sha256=bbbY50W_2MsZSTxOHWMKz0tbIm75nsRSlPy8GI2fg9Q,9306
|
|
408
408
|
web/server/api/endpoints/table_diff.py,sha256=SCy3-pr5x6bEEiOaZGCDbiHQhpgxwmnz3Acqa2Ie6jI,2090
|
|
409
|
-
sqlmesh-0.206.2.
|
|
410
|
-
sqlmesh-0.206.2.
|
|
411
|
-
sqlmesh-0.206.2.
|
|
412
|
-
sqlmesh-0.206.2.
|
|
413
|
-
sqlmesh-0.206.2.
|
|
409
|
+
sqlmesh-0.206.2.dev8.dist-info/METADATA,sha256=6yXTgCs4ubiok83fzzYObV7Fs7VF8WbOa5DvfwqolCU,26685
|
|
410
|
+
sqlmesh-0.206.2.dev8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
411
|
+
sqlmesh-0.206.2.dev8.dist-info/entry_points.txt,sha256=pIYKtg-u-uO7BK_Y0qrdmfyj0bYrcMc3Xiqr5WE3VFk,121
|
|
412
|
+
sqlmesh-0.206.2.dev8.dist-info/top_level.txt,sha256=bspjo5vjELQkuN0qKuTFIbsrUt3Zeo8D2mlKeHG1LdE,12
|
|
413
|
+
sqlmesh-0.206.2.dev8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|