Skip to content

Commit 152f413

Browse files
Merge branch 'main' into fix/sanitize-unused-manifest-fields
2 parents 9c05988 + b0ad844 commit 152f413

7 files changed

Lines changed: 105 additions & 8 deletions

File tree

.bumpversion.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[bumpversion]
2-
current_version = 0.2.3
2+
current_version = 0.3.2
33
commit = True
44
tag = True
55

CHANGELOG.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22
Changelog
33
=========
44

5+
0.3.1 (2026-07-01)
6+
------------------
7+
8+
* Relax ``mcp`` dependency pin from ``~=1.9.0`` to ``>=1.9.0,<2.0.0`` so
9+
downstream consumers can use newer ``mcp`` releases. Only the stable
10+
client API (``ClientSession``, ``StdioServerParameters``, ``stdio_client``)
11+
is used, which is unchanged across ``mcp`` 1.x.
12+
513
0.0.0 (2024-01-25)
614
------------------
715

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
year = "2024"
1616
author = "Altimate Inc."
1717
copyright = f"{year}, {author}"
18-
version = release = "0.2.3"
18+
version = release = "0.3.2"
1919

2020
pygments_style = "trac"
2121
templates_path = ["."]

setup.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def read(*names, **kwargs):
1313

1414
setup(
1515
name="altimate-datapilot-cli",
16-
version="0.2.3",
16+
version="0.3.2",
1717
license="MIT",
1818
description="Assistant for Data Teams",
1919
long_description="{}\n{}".format(
@@ -67,8 +67,8 @@ def read(*names, **kwargs):
6767
"ruamel.yaml~=0.18.6",
6868
"tabulate~=0.9.0",
6969
"requests>=2.31",
70-
"sqlglot~=25.30.0",
71-
"mcp~=1.9.0",
70+
"sqlglot[c]==30.7.0",
71+
"mcp>=1.9.0,<2.0.0",
7272
"pyperclip~=1.8.2",
7373
"python-dotenv~=1.0.0",
7474
],

src/datapilot/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.2.3"
1+
__version__ = "0.3.2"

src/vendor/dbt_artifacts_parser/parsers/run_results/run_results_v6.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,23 @@ class Metadata(BaseParserModel):
2525
env: Optional[dict[str, str]] = None
2626

2727

28-
class Status(Enum):
28+
class Status(str, Enum):
2929
success = "success"
3030
error = "error"
3131
skipped = "skipped"
3232
partial_success = "partial success"
33+
reused = "reused"
34+
35+
@classmethod
36+
def _missing_(cls, value):
37+
# Forward-compatibility: dbt periodically introduces new run statuses
38+
# (e.g. "reused" in dbt 2.0). Surface unknown values as real members so
39+
# downstream `.value` access keeps working instead of failing validation
40+
# and silently dropping the entire run_results.json.
41+
member = str.__new__(cls, value)
42+
member._name_ = str(value)
43+
member._value_ = value
44+
return member
3345

3446

3547
class Status1(Enum):
@@ -74,7 +86,7 @@ class Result(BaseParserModel):
7486
model_config = ConfigDict(
7587
extra="allow",
7688
)
77-
status: Union[Status, Status1, Status2]
89+
status: Union[Status1, Status2, Status]
7890
timing: list[TimingItem]
7991
thread_id: str
8092
execution_time: float
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
"""Tests for run_results v6 parser, specifically the resilient run `Status` enum.
2+
3+
Regression coverage for dbt 2.0 emitting ``status="reused"`` (and future unknown
4+
statuses), which previously raised a ``ValidationError`` and caused the entire
5+
run_results.json to be silently dropped during ingestion.
6+
"""
7+
from vendor.dbt_artifacts_parser.parser import parse_run_results
8+
from vendor.dbt_artifacts_parser.parsers.run_results.run_results_v6 import Result
9+
from vendor.dbt_artifacts_parser.parsers.run_results.run_results_v6 import Status
10+
11+
V6_SCHEMA = "https://schemas.getdbt.com/dbt/run-results/v6.json"
12+
13+
14+
def _result(status: str, unique_id: str) -> dict:
15+
return {
16+
"status": status,
17+
"timing": [],
18+
"thread_id": "Thread-1",
19+
"execution_time": 0.1,
20+
"adapter_response": {},
21+
"unique_id": unique_id,
22+
}
23+
24+
25+
def _run_results(*statuses: str) -> dict:
26+
return {
27+
"metadata": {
28+
"dbt_schema_version": V6_SCHEMA,
29+
"dbt_version": "2.0.0",
30+
"invocation_id": "test-invocation-123",
31+
},
32+
"elapsed_time": 1.5,
33+
"args": {},
34+
"results": [_result(s, f"model.proj.m{i}") for i, s in enumerate(statuses)],
35+
}
36+
37+
38+
class TestRunResultStatus:
39+
"""The run `Status` enum must accept new/unknown dbt statuses without failing."""
40+
41+
def test_reused_status_parses(self):
42+
"""dbt 2.0 emits `reused` for unchanged models; it must not fail validation."""
43+
result = Result(**_result("reused", "model.proj.a"))
44+
assert result.status.value == "reused"
45+
assert result.status is Status.reused
46+
47+
def test_known_statuses_preserve_value(self):
48+
"""Known run statuses still resolve with the correct `.value`."""
49+
for status in ("success", "error", "skipped", "partial success"):
50+
assert Result(**_result(status, "model.proj.a")).status.value == status
51+
52+
def test_unknown_future_status_parses(self):
53+
"""Forward-compat: a status dbt has not shipped yet still parses via `_missing_`."""
54+
result = Result(**_result("some_future_status", "model.proj.a"))
55+
assert result.status.value == "some_future_status"
56+
57+
def test_test_and_freshness_statuses_keep_their_value(self):
58+
"""Test/freshness statuses must keep their `.value` (resolved via Status1/Status2)."""
59+
for status in ("pass", "fail", "warn", "runtime error"):
60+
assert Result(**_result(status, "test.proj.t")).status.value == status
61+
62+
63+
class TestParseRunResultsEntryPoint:
64+
"""The public `parse_run_results` must parse a full file containing `reused`."""
65+
66+
def test_file_with_reused_result_parses_fully(self):
67+
run_results = parse_run_results(_run_results("success", "reused", "skipped", "pass", "error", "no-op"))
68+
# Previously this whole file was dropped because of the single `reused` row.
69+
assert len(run_results.results) == 6
70+
assert {r.status.value for r in run_results.results} == {
71+
"success",
72+
"reused",
73+
"skipped",
74+
"pass",
75+
"error",
76+
"no-op",
77+
}

0 commit comments

Comments
 (0)