recce-nightly 1.3.0.20250507__py3-none-any.whl → 1.4.0.20250515__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.

Potentially problematic release.


This version of recce-nightly might be problematic. Click here for more details.

Files changed (93) hide show
  1. recce/VERSION +1 -1
  2. recce/__init__.py +22 -22
  3. recce/adapter/base.py +11 -14
  4. recce/adapter/dbt_adapter/__init__.py +355 -316
  5. recce/adapter/dbt_adapter/dbt_version.py +3 -0
  6. recce/adapter/sqlmesh_adapter.py +24 -35
  7. recce/apis/check_api.py +39 -28
  8. recce/apis/check_func.py +33 -27
  9. recce/apis/run_api.py +25 -19
  10. recce/apis/run_func.py +29 -23
  11. recce/artifact.py +44 -49
  12. recce/cli.py +484 -285
  13. recce/config.py +42 -33
  14. recce/core.py +52 -44
  15. recce/data/404.html +1 -1
  16. recce/data/_next/static/chunks/{368-7587b306577df275.js → 778-aef312bffb4c0312.js} +15 -15
  17. recce/data/_next/static/chunks/8d700b6a.ed11a130057c7a47.js +1 -0
  18. recce/data/_next/static/chunks/app/layout-c713a2829d3279e4.js +1 -0
  19. recce/data/_next/static/chunks/app/page-7086764277331fcb.js +1 -0
  20. recce/data/_next/static/chunks/{cd9f8d63-cf0d5a7b0f7a92e8.js → cd9f8d63-e020f408095ed77c.js} +3 -3
  21. recce/data/_next/static/chunks/webpack-b787cb1a4f2293de.js +1 -0
  22. recce/data/_next/static/css/88b8abc134cfd59a.css +3 -0
  23. recce/data/index.html +2 -2
  24. recce/data/index.txt +2 -2
  25. recce/diff.py +6 -12
  26. recce/event/__init__.py +74 -72
  27. recce/event/collector.py +27 -20
  28. recce/event/track.py +39 -27
  29. recce/exceptions.py +1 -1
  30. recce/git.py +7 -7
  31. recce/github.py +57 -53
  32. recce/models/__init__.py +1 -1
  33. recce/models/check.py +6 -7
  34. recce/models/run.py +1 -0
  35. recce/models/types.py +27 -27
  36. recce/pull_request.py +26 -24
  37. recce/run.py +148 -111
  38. recce/server.py +103 -89
  39. recce/state.py +209 -177
  40. recce/summary.py +168 -143
  41. recce/tasks/__init__.py +3 -3
  42. recce/tasks/core.py +11 -13
  43. recce/tasks/dataframe.py +19 -17
  44. recce/tasks/histogram.py +69 -34
  45. recce/tasks/lineage.py +2 -2
  46. recce/tasks/profile.py +147 -86
  47. recce/tasks/query.py +139 -87
  48. recce/tasks/rowcount.py +33 -30
  49. recce/tasks/schema.py +14 -14
  50. recce/tasks/top_k.py +35 -35
  51. recce/tasks/valuediff.py +216 -152
  52. recce/util/breaking.py +77 -84
  53. recce/util/cll.py +55 -51
  54. recce/util/io.py +19 -17
  55. recce/util/logger.py +1 -1
  56. recce/util/recce_cloud.py +70 -72
  57. recce/util/singleton.py +4 -4
  58. recce/yaml/__init__.py +7 -10
  59. {recce_nightly-1.3.0.20250507.dist-info → recce_nightly-1.4.0.20250515.dist-info}/METADATA +5 -2
  60. recce_nightly-1.4.0.20250515.dist-info/RECORD +143 -0
  61. {recce_nightly-1.3.0.20250507.dist-info → recce_nightly-1.4.0.20250515.dist-info}/WHEEL +1 -1
  62. tests/adapter/dbt_adapter/conftest.py +1 -0
  63. tests/adapter/dbt_adapter/dbt_test_helper.py +28 -18
  64. tests/adapter/dbt_adapter/test_dbt_adapter.py +0 -15
  65. tests/adapter/dbt_adapter/test_dbt_cll.py +39 -32
  66. tests/adapter/dbt_adapter/test_selector.py +22 -21
  67. tests/tasks/test_histogram.py +58 -66
  68. tests/tasks/test_lineage.py +36 -23
  69. tests/tasks/test_preset_checks.py +45 -31
  70. tests/tasks/test_profile.py +340 -15
  71. tests/tasks/test_query.py +40 -40
  72. tests/tasks/test_row_count.py +65 -46
  73. tests/tasks/test_schema.py +65 -42
  74. tests/tasks/test_top_k.py +22 -18
  75. tests/tasks/test_valuediff.py +43 -32
  76. tests/test_cli.py +71 -58
  77. tests/test_config.py +7 -9
  78. tests/test_core.py +5 -3
  79. tests/test_dbt.py +7 -7
  80. tests/test_pull_request.py +1 -1
  81. tests/test_server.py +19 -13
  82. tests/test_state.py +40 -27
  83. tests/test_summary.py +18 -14
  84. recce/data/_next/static/chunks/8d700b6a-f0b1f6b9e0d97ce2.js +0 -1
  85. recce/data/_next/static/chunks/app/layout-9102e22cb73f74d6.js +0 -1
  86. recce/data/_next/static/chunks/app/page-92f13c8fad9fae3d.js +0 -1
  87. recce/data/_next/static/chunks/webpack-567d72f0bc0820d5.js +0 -1
  88. recce_nightly-1.3.0.20250507.dist-info/RECORD +0 -142
  89. /recce/data/_next/static/{K5iKlCYhdcpq8Ea6ck9J_ → q0Xsc9Sd6PDuo1lshYpLu}/_buildManifest.js +0 -0
  90. /recce/data/_next/static/{K5iKlCYhdcpq8Ea6ck9J_ → q0Xsc9Sd6PDuo1lshYpLu}/_ssgManifest.js +0 -0
  91. {recce_nightly-1.3.0.20250507.dist-info → recce_nightly-1.4.0.20250515.dist-info}/entry_points.txt +0 -0
  92. {recce_nightly-1.3.0.20250507.dist-info → recce_nightly-1.4.0.20250515.dist-info}/licenses/LICENSE +0 -0
  93. {recce_nightly-1.3.0.20250507.dist-info → recce_nightly-1.4.0.20250515.dist-info}/top_level.txt +0 -0
recce/util/io.py CHANGED
@@ -1,14 +1,14 @@
1
1
  import gzip
2
2
  import os
3
3
  import tempfile
4
- from abc import ABCMeta, abstractmethod, ABC
4
+ from abc import ABC, ABCMeta, abstractmethod
5
5
  from enum import Enum
6
6
 
7
7
 
8
8
  class SupportedFileTypes(Enum):
9
- FILE = 'file'
10
- GZIP = 'gzip'
11
- ZIP = 'zip'
9
+ FILE = "file"
10
+ GZIP = "gzip"
11
+ ZIP = "zip"
12
12
 
13
13
 
14
14
  def file_io_factory(file_type: SupportedFileTypes):
@@ -19,7 +19,7 @@ def file_io_factory(file_type: SupportedFileTypes):
19
19
  elif file_type == SupportedFileTypes.ZIP:
20
20
  return ZipFileIO
21
21
  else:
22
- raise ValueError(f'Unsupported file type: {file_type}')
22
+ raise ValueError(f"Unsupported file type: {file_type}")
23
23
 
24
24
 
25
25
  class AbstractFileIO(metaclass=ABCMeta):
@@ -37,24 +37,24 @@ class AbstractFileIO(metaclass=ABCMeta):
37
37
  class FileIO(AbstractFileIO, ABC):
38
38
  @staticmethod
39
39
  def write(path: str, data: str, **kwargs):
40
- with open(path, 'w') as f:
40
+ with open(path, "w") as f:
41
41
  f.write(data)
42
42
 
43
43
  @staticmethod
44
44
  def read(path: str, **kwargs) -> str:
45
- with open(path, 'r') as f:
45
+ with open(path, "r") as f:
46
46
  return f.read()
47
47
 
48
48
 
49
49
  class GzipFileIO(AbstractFileIO, ABC):
50
50
  @staticmethod
51
51
  def write(path: str, data: str, **kwargs):
52
- with gzip.open(path, 'wt') as f:
52
+ with gzip.open(path, "wt") as f:
53
53
  f.write(data)
54
54
 
55
55
  @staticmethod
56
56
  def read(path: str, **kwargs) -> str:
57
- with gzip.open(path, 'rt') as f:
57
+ with gzip.open(path, "rt") as f:
58
58
  return f.read()
59
59
 
60
60
  @staticmethod
@@ -69,17 +69,18 @@ class ZipFileIO(AbstractFileIO, ABC):
69
69
  try:
70
70
  import pyminizip
71
71
  except ImportError:
72
- raise ImportError('pyminizip is not installed. Please install it using `pip install pyminizip`')
72
+ raise ImportError("pyminizip is not installed. Please install it using `pip install pyminizip`")
73
73
 
74
74
  @staticmethod
75
75
  def read(path: str, **kwargs) -> str:
76
76
  ZipFileIO._is_pyminizip_installed()
77
77
  import pyminizip
78
+
78
79
  cwd = os.getcwd()
79
- password = kwargs.get('password')
80
- zip_dir_name = kwargs.get('zip_dir_name')
80
+ password = kwargs.get("password")
81
+ zip_dir_name = kwargs.get("zip_dir_name")
81
82
  if zip_dir_name is None:
82
- raise ValueError('zip_dir_name is required for zipping')
83
+ raise ValueError("zip_dir_name is required for zipping")
83
84
 
84
85
  try:
85
86
  with tempfile.TemporaryDirectory() as tmp_dir:
@@ -88,7 +89,7 @@ class ZipFileIO(AbstractFileIO, ABC):
88
89
  content = FileIO.read(tmp_file)
89
90
  except Exception as e:
90
91
  error_msg = str(e)
91
- if '-3' in error_msg:
92
+ if "-3" in error_msg:
92
93
  raise Exception("Invalid password to uncompress state file.")
93
94
  raise Exception(f"Failed to uncompress state file: {error_msg}")
94
95
  finally:
@@ -100,11 +101,12 @@ class ZipFileIO(AbstractFileIO, ABC):
100
101
  def write(path: str, data: str, **kwargs):
101
102
  ZipFileIO._is_pyminizip_installed()
102
103
  import pyminizip
104
+
103
105
  cwd = os.getcwd()
104
- password = kwargs.get('password')
105
- zip_dir_name = kwargs.get('zip_dir_name')
106
+ password = kwargs.get("password")
107
+ zip_dir_name = kwargs.get("zip_dir_name")
106
108
  if zip_dir_name is None:
107
- raise ValueError('zip_dir_name is required for zipping')
109
+ raise ValueError("zip_dir_name is required for zipping")
108
110
 
109
111
  try:
110
112
  with tempfile.TemporaryDirectory() as tmp_dir:
recce/util/logger.py CHANGED
@@ -16,7 +16,7 @@ class CustomFormatter(logging.Formatter):
16
16
  logging.INFO: green + format + reset,
17
17
  logging.WARNING: yellow + format + reset,
18
18
  logging.ERROR: red + format + reset,
19
- logging.CRITICAL: bold_red + format + reset
19
+ logging.CRITICAL: bold_red + format + reset,
20
20
  }
21
21
 
22
22
  def format(self, record):
recce/util/recce_cloud.py CHANGED
@@ -1,20 +1,20 @@
1
1
  import json
2
2
  import logging
3
3
  import os
4
- from typing import Dict, IO
4
+ from typing import IO, Dict
5
5
 
6
6
  import requests
7
7
 
8
8
  from recce.pull_request import PullRequestInfo
9
9
 
10
- RECCE_CLOUD_API_HOST = os.environ.get('RECCE_CLOUD_API_HOST', 'https://cloud.datarecce.io')
10
+ RECCE_CLOUD_API_HOST = os.environ.get("RECCE_CLOUD_API_HOST", "https://cloud.datarecce.io")
11
11
 
12
- logger = logging.getLogger('uvicorn')
12
+ logger = logging.getLogger("uvicorn")
13
13
 
14
14
 
15
15
  class PresignedUrlMethod:
16
- UPLOAD = 'upload'
17
- DOWNLOAD = 'download'
16
+ UPLOAD = "upload"
17
+ DOWNLOAD = "download"
18
18
 
19
19
 
20
20
  class RecceCloudException(Exception):
@@ -23,7 +23,7 @@ class RecceCloudException(Exception):
23
23
  self.status_code = status_code
24
24
 
25
25
  try:
26
- reason = json.loads(reason).get('detail', '')
26
+ reason = json.loads(reason).get("detail", "")
27
27
  except json.JSONDecodeError:
28
28
  pass
29
29
  self.reason = reason
@@ -32,134 +32,132 @@ class RecceCloudException(Exception):
32
32
  class RecceCloud:
33
33
  def __init__(self, token: str):
34
34
  self.token = token
35
- self.base_url = f'{RECCE_CLOUD_API_HOST}/api/v1'
35
+ self.base_url = f"{RECCE_CLOUD_API_HOST}/api/v1"
36
36
 
37
37
  def _request(self, method, url, **kwargs):
38
- headers = {
39
- 'Authorization': f'Bearer {self.token}'
40
- }
38
+ headers = {"Authorization": f"Bearer {self.token}"}
41
39
  return requests.request(method, url, headers=headers, **kwargs)
42
40
 
43
- def get_presigned_url(self,
44
- method: PresignedUrlMethod,
45
- repository: str,
46
- artifact_name: str,
47
- metadata: dict = None,
48
- pr_id: int = None,
49
- branch: str = None) -> str:
41
+ def get_presigned_url(
42
+ self,
43
+ method: PresignedUrlMethod,
44
+ repository: str,
45
+ artifact_name: str,
46
+ metadata: dict = None,
47
+ pr_id: int = None,
48
+ branch: str = None,
49
+ ) -> str:
50
50
  response = self._fetch_presigned_url(method, repository, artifact_name, metadata, pr_id, branch)
51
- return response.get('presigned_url')
51
+ return response.get("presigned_url")
52
52
 
53
- def get_download_presigned_url_with_tags(self,
54
- repository: str,
55
- artifact_name: str,
56
- branch: str = None) -> (str, dict):
53
+ def get_download_presigned_url_with_tags(
54
+ self, repository: str, artifact_name: str, branch: str = None
55
+ ) -> (str, dict):
57
56
  response = self._fetch_presigned_url(PresignedUrlMethod.DOWNLOAD, repository, artifact_name, branch=branch)
58
- return response.get('presigned_url'), response.get('tags', {})
59
-
60
- def _fetch_presigned_url(self,
61
- method: PresignedUrlMethod,
62
- repository: str,
63
- artifact_name: str,
64
- metadata: dict = None,
65
- pr_id: int = None,
66
- branch: str = None) -> str:
57
+ return response.get("presigned_url"), response.get("tags", {})
58
+
59
+ def _fetch_presigned_url(
60
+ self,
61
+ method: PresignedUrlMethod,
62
+ repository: str,
63
+ artifact_name: str,
64
+ metadata: dict = None,
65
+ pr_id: int = None,
66
+ branch: str = None,
67
+ ) -> str:
67
68
  if pr_id is not None:
68
- api_url = f'{self.base_url}/{repository}/pulls/{pr_id}/artifacts/{method}?artifact_name={artifact_name}&enable_ssec=true'
69
+ api_url = f"{self.base_url}/{repository}/pulls/{pr_id}/artifacts/{method}?artifact_name={artifact_name}&enable_ssec=true"
69
70
  elif branch is not None:
70
- api_url = f'{self.base_url}/{repository}/commits/{branch}/artifacts/{method}?artifact_name={artifact_name}&enable_ssec=true'
71
+ api_url = f"{self.base_url}/{repository}/commits/{branch}/artifacts/{method}?artifact_name={artifact_name}&enable_ssec=true"
71
72
  else:
72
- raise ValueError('Either pr_id or sha must be provided.')
73
- response = self._request('POST', api_url, json=metadata)
73
+ raise ValueError("Either pr_id or sha must be provided.")
74
+ response = self._request("POST", api_url, json=metadata)
74
75
  if response.status_code != 200:
75
76
  raise RecceCloudException(
76
- message='Failed to {method} artifact {preposition} Recce Cloud.'.format(
77
- method=method,
78
- preposition='from' if method == PresignedUrlMethod.DOWNLOAD else 'to'
77
+ message="Failed to {method} artifact {preposition} Recce Cloud.".format(
78
+ method=method, preposition="from" if method == PresignedUrlMethod.DOWNLOAD else "to"
79
79
  ),
80
80
  reason=response.text,
81
- status_code=response.status_code
81
+ status_code=response.status_code,
82
82
  )
83
83
  return response.json()
84
84
 
85
85
  def get_artifact_metadata(self, pr_info: PullRequestInfo) -> dict:
86
- api_url = f'{self.base_url}/{pr_info.repository}/pulls/{pr_info.id}/metadata'
87
- response = self._request('GET', api_url)
86
+ api_url = f"{self.base_url}/{pr_info.repository}/pulls/{pr_info.id}/metadata"
87
+ response = self._request("GET", api_url)
88
88
  if response.status_code == 204:
89
89
  return None
90
90
  if response.status_code != 200:
91
91
  raise RecceCloudException(
92
- message='Failed to get artifact metadata from Recce Cloud.',
92
+ message="Failed to get artifact metadata from Recce Cloud.",
93
93
  reason=response.text,
94
- status_code=response.status_code
94
+ status_code=response.status_code,
95
95
  )
96
96
  return response.json()
97
97
 
98
98
  def purge_artifacts(self, pr_info: PullRequestInfo):
99
- api_url = f'{self.base_url}/{pr_info.repository}/pulls/{pr_info.id}/artifacts'
100
- response = self._request('DELETE', api_url)
99
+ api_url = f"{self.base_url}/{pr_info.repository}/pulls/{pr_info.id}/artifacts"
100
+ response = self._request("DELETE", api_url)
101
101
  if response.status_code != 204:
102
102
  raise RecceCloudException(
103
- message='Failed to purge artifacts from Recce Cloud.',
103
+ message="Failed to purge artifacts from Recce Cloud.",
104
104
  reason=response.text,
105
- status_code=response.status_code
105
+ status_code=response.status_code,
106
106
  )
107
107
 
108
108
  def check_artifacts_exists(self, pr_info: PullRequestInfo) -> bool:
109
- api_url = f'{self.base_url}/{pr_info.repository}/pulls/{pr_info.id}/metadata'
110
- response = self._request('GET', api_url)
109
+ api_url = f"{self.base_url}/{pr_info.repository}/pulls/{pr_info.id}/metadata"
110
+ response = self._request("GET", api_url)
111
111
  if response.status_code == 200:
112
112
  return True
113
113
  elif response.status_code == 204:
114
114
  return False
115
115
  else:
116
116
  raise RecceCloudException(
117
- message='Failed to check if artifacts exist in Recce Cloud.',
117
+ message="Failed to check if artifacts exist in Recce Cloud.",
118
118
  reason=response.text,
119
- status_code=response.status_code
119
+ status_code=response.status_code,
120
120
  )
121
121
 
122
122
  def share_state(self, file_name: str, file_io: IO):
123
- api_url = f'{self.base_url}/recce-state/upload'
124
- files = {'file': (file_name, file_io, 'application/json')}
125
- response = self._request('POST', api_url, files=files)
123
+ api_url = f"{self.base_url}/recce-state/upload"
124
+ files = {"file": (file_name, file_io, "application/json")}
125
+ response = self._request("POST", api_url, files=files)
126
126
  if response.status_code == 403:
127
- return {'status': 'error', 'message': response.json().get('detail')}
127
+ return {"status": "error", "message": response.json().get("detail")}
128
128
  if response.status_code != 200:
129
129
  raise RecceCloudException(
130
- message='Failed to share Recce state.',
131
- reason=response.text,
132
- status_code=response.status_code
130
+ message="Failed to share Recce state.", reason=response.text, status_code=response.status_code
133
131
  )
134
132
  return response.json()
135
133
 
136
134
  def update_github_pull_request_check(self, pr_info: PullRequestInfo, metadata: dict = None):
137
- api_url = f'{self.base_url}/{pr_info.repository}/pulls/{pr_info.id}/github/checks'
135
+ api_url = f"{self.base_url}/{pr_info.repository}/pulls/{pr_info.id}/github/checks"
138
136
  try:
139
- self._request('POST', api_url, json=metadata)
137
+ self._request("POST", api_url, json=metadata)
140
138
  except Exception as e:
141
139
  # We don't care the response of this request, so we don't need to raise any exception.
142
- logger.debug(f'Failed to update the GitHub PR check. Reason: {str(e)}')
140
+ logger.debug(f"Failed to update the GitHub PR check. Reason: {str(e)}")
143
141
 
144
142
  def get_user_info(self) -> Dict:
145
- api_url = f'{self.base_url}/users'
146
- response = self._request('GET', api_url)
143
+ api_url = f"{self.base_url}/users"
144
+ response = self._request("GET", api_url)
147
145
  if response.status_code != 200:
148
146
  raise RecceCloudException(
149
- message='Failed to get user info from Recce Cloud.',
147
+ message="Failed to get user info from Recce Cloud.",
150
148
  reason=response.text,
151
- status_code=response.status_code
149
+ status_code=response.status_code,
152
150
  )
153
- return response.json().get('user')
151
+ return response.json().get("user")
154
152
 
155
153
  def set_onboarding_state(self, state: str):
156
- api_url = f'{self.base_url}/users/onboarding-state'
157
- response = self._request('PUT', api_url, json={'state': state})
154
+ api_url = f"{self.base_url}/users/onboarding-state"
155
+ response = self._request("PUT", api_url, json={"state": state})
158
156
  if response.status_code != 200:
159
157
  raise RecceCloudException(
160
- message='Failed to update onboarding state in Recce Cloud.',
158
+ message="Failed to update onboarding state in Recce Cloud.",
161
159
  reason=response.text,
162
- status_code=response.status_code
160
+ status_code=response.status_code,
163
161
  )
164
162
 
165
163
 
@@ -168,10 +166,10 @@ def get_recce_cloud_onboarding_state(token: str) -> str:
168
166
  recce_cloud = RecceCloud(token)
169
167
  user_info = recce_cloud.get_user_info()
170
168
  if user_info:
171
- return user_info.get('onboarding_state')
169
+ return user_info.get("onboarding_state")
172
170
  except Exception as e:
173
171
  logger.debug(str(e))
174
- return 'undefined'
172
+ return "undefined"
175
173
 
176
174
 
177
175
  def set_recce_cloud_onboarding_state(token: str, new_state: str):
recce/util/singleton.py CHANGED
@@ -1,9 +1,9 @@
1
1
  class SingletonMeta(type):
2
2
  """
3
- The Singleton class can be implemented in different ways in Python. Some
4
- possible methods include: base class, decorator, metaclass. We will use the
5
- metaclass because it is best suited for this purpose.
6
- """
3
+ The Singleton class can be implemented in different ways in Python. Some
4
+ possible methods include: base class, decorator, metaclass. We will use the
5
+ metaclass because it is best suited for this purpose.
6
+ """
7
7
 
8
8
  _instances = {}
9
9
 
recce/yaml/__init__.py CHANGED
@@ -1,10 +1,11 @@
1
1
  from typing import Any, Callable
2
2
 
3
3
  from ruamel import yaml
4
- from ruamel.yaml import CommentedMap as _cm, CommentedSeq as _cs
4
+ from ruamel.yaml import CommentedMap as _cm
5
+ from ruamel.yaml import CommentedSeq as _cs
5
6
 
6
7
  _yaml = yaml.YAML()
7
- _safe_yaml = yaml.YAML(typ='safe')
8
+ _safe_yaml = yaml.YAML(typ="safe")
8
9
 
9
10
  CommentedMap = _cm
10
11
  CommentedSeq = _cs
@@ -27,15 +28,13 @@ def safe_load(stream, version=None) -> Any:
27
28
  return _safe_yaml.load(stream)
28
29
 
29
30
 
30
- def dump(
31
- data, stream: Any = None, *, transform: Any = None
32
- ) -> Any:
31
+ def dump(data, stream: Any = None, *, transform: Any = None) -> Any:
33
32
  return _yaml.dump(data, stream, transform=transform)
34
33
 
35
34
 
36
35
  def safe_load_yaml(file_path):
37
36
  try:
38
- with open(file_path, 'r') as f:
37
+ with open(file_path, "r") as f:
39
38
  payload = safe_load(f)
40
39
  except yaml.YAMLError as e:
41
40
  print(e)
@@ -46,7 +45,7 @@ def safe_load_yaml(file_path):
46
45
 
47
46
 
48
47
  def round_trip_load_yaml(file_path):
49
- with open(file_path, 'r') as f:
48
+ with open(file_path, "r") as f:
50
49
  try:
51
50
  payload = load(f)
52
51
  except yaml.YAMLError as e:
@@ -55,7 +54,5 @@ def round_trip_load_yaml(file_path):
55
54
  return payload
56
55
 
57
56
 
58
- def round_trip_dump(
59
- data: Any,
60
- stream=None):
57
+ def round_trip_dump(data: Any, stream=None):
61
58
  return yaml.round_trip_dump(data, stream)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: recce-nightly
3
- Version: 1.3.0.20250507
3
+ Version: 1.4.0.20250515
4
4
  Summary: Environment diff tool for dbt
5
5
  Home-page: https://github.com/InfuseAI/recce
6
6
  Author: InfuseAI Dev Team
@@ -40,7 +40,10 @@ Requires-Dist: sqlglot
40
40
  Provides-Extra: dev
41
41
  Requires-Dist: pytest>=4.6; extra == "dev"
42
42
  Requires-Dist: pytest-flake8; extra == "dev"
43
- Requires-Dist: flake8==3.9.2; extra == "dev"
43
+ Requires-Dist: black>=25.1.0; extra == "dev"
44
+ Requires-Dist: isort>=6.0.1; extra == "dev"
45
+ Requires-Dist: flake8>=7.2.0; extra == "dev"
46
+ Requires-Dist: pre-commit>=4.2.0; extra == "dev"
44
47
  Requires-Dist: pytest-mypy; extra == "dev"
45
48
  Requires-Dist: pytest-cov; extra == "dev"
46
49
  Requires-Dist: twine; extra == "dev"
@@ -0,0 +1,143 @@
1
+ recce/VERSION,sha256=nGRCfSUGtOUR2H065Ol9AKtkESwDZbAUmawJRgvqOSo,15
2
+ recce/__init__.py,sha256=yNb0QT-yoStex0VZALNJvUwtPLommoVCStcow31guqo,2392
3
+ recce/artifact.py,sha256=tKQAHSrLRjiR3ppOI4sym8SxYiiLTuD3DPMYh4DWQdA,6506
4
+ recce/cli.py,sha256=OqIUMkQSm1XgpGawm_j1XURAMK9ijlBQrWTuakPP6S0,35388
5
+ recce/config.py,sha256=fs22mpFj8CFIxftGbhFAV5xIsPLX2xNTwWSer3UYn5k,4658
6
+ recce/core.py,sha256=C7RooEojAi5PIlbJuvB0Cj8F0HVktyn8bNRZE-TuzHQ,10726
7
+ recce/diff.py,sha256=L2_bzQ3__PO-0aeir8PHF8FvSOUmQ8WcDXgML1-mHdY,748
8
+ recce/exceptions.py,sha256=SclQ678GrHGjw7p_ZFJ3vZaL_yMU5xABeIAm2u_W2bk,592
9
+ recce/git.py,sha256=8Eg-6NzL-KjA3rT-ibbAyaCwGlzV0JqH3yGikrJNMDA,2344
10
+ recce/github.py,sha256=PEpM6ZRiinsPbXSWj4aJCKbZrN1jUXzpzAfJq_CGah4,7420
11
+ recce/pull_request.py,sha256=aW0B1NE2LUKTam1S4TQ7smXB9KLE1DV8GnyBqNXA6j8,3832
12
+ recce/run.py,sha256=LAjbWUF8loZ9cL25d_maQELwROHHmfaFn7iqFRy5O1o,13567
13
+ recce/server.py,sha256=X7WDMlujxfzc8yk-GWuSyVIWee9kUEcjplGP1vD0r1w,20301
14
+ recce/state.py,sha256=VPzKyEdmyBeZ45BQArB587QN5C3Sfr7O5Oh_JRBcKrc,30616
15
+ recce/summary.py,sha256=Mbxvxr9KazR5o9icqhhjiGHsoAiWxQU4PdN7HytBJ1c,19154
16
+ recce/adapter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
+ recce/adapter/base.py,sha256=T_JNeLHgiHSaegw-DbrvHOaYjMyZcjj2Qtg5cWh_fco,3548
18
+ recce/adapter/sqlmesh_adapter.py,sha256=IU3N-F6ToDoO7_bV5vsG8pmTuDcbFtewTIuCxedTaRM,5046
19
+ recce/adapter/dbt_adapter/__init__.py,sha256=21FBwx6ovGO-oOxLcsZWVejlD35NT_r2v3vtApnWfTU,54384
20
+ recce/adapter/dbt_adapter/dbt_version.py,sha256=M7aedZIWslXnJsryK8Ki4OL_t2oAKxy4uE2pRwfWIkk,1228
21
+ recce/apis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ recce/apis/check_api.py,sha256=KMCXSMl1qqzx2jQgRqCrD4j_cY3EHBbM3H2-t-6saAU,6227
23
+ recce/apis/check_func.py,sha256=gktbCcyk3WGvWRJJ-wDnwv7NrIny2nTHWLl1-kdiVRo,4183
24
+ recce/apis/run_api.py,sha256=eOaxOxXDkH59uqGCd4blld7edavUx7JU_DCd2WAYrL8,3416
25
+ recce/apis/run_func.py,sha256=6wC8TDU-h7TLr2VZH7HNsWaUVlQ9HBN5N_dwqfi4lMY,7440
26
+ recce/data/404.html,sha256=W3YNH2KBL0VOtKeQkkAzmG62yZsYqTuZ7FyeENz9-oo,6554
27
+ recce/data/favicon.ico,sha256=B2mBumUOnzvUrXrqNkrc5QfdDXjzEXRcWkWur0fJ6sM,2565
28
+ recce/data/index.html,sha256=Y-h_1XMrE4fFEju84LTO5In4_KfC9AEFDUsTHLMvFOA,40259
29
+ recce/data/index.txt,sha256=4a-9GDo_4rgW83ToVwVRHeZrcxIduqyC6wUs3SqIOSk,3514
30
+ recce/data/_next/static/chunks/1f229bf6-d9fe92e56db8d93b.js,sha256=NvhILR-yLwIu-WlvwD9Hkr2H_I7ZK64vwYvR6c84wC0,172836
31
+ recce/data/_next/static/chunks/29e3cc0d-8c150e37dff9631b.js,sha256=4ZQR-OYMhGWnYPNwUjG5FpsTVzVTPEAf6T0v0E5g-4o,700
32
+ recce/data/_next/static/chunks/36e1c10d-bb0210cbd6573a8d.js,sha256=SkfIoUJXsrjEoql4hRRcWKtW2vMfHOAHUm4NE6eaho4,7797
33
+ recce/data/_next/static/chunks/3998a672-eaad84bdd88cc73e.js,sha256=7FRm86VFsyXQL6M4J0qFq7e4cvhs48uKJF2Qp0tYraM,9024
34
+ recce/data/_next/static/chunks/3a92ee20-3b5d922d4157af5e.js,sha256=Ou-yjvdFB0Zy_Im93w9LrR2LyB_aRnaNn1Sz1EB18mI,177688
35
+ recce/data/_next/static/chunks/450c323b-1bb5db526e54435a.js,sha256=3M8dU9CapPo-oey7uyaRBaSrnwoPHUQb671T-_Nv7bs,2205
36
+ recce/data/_next/static/chunks/47d8844f-79a1b53c66a7d7ec.js,sha256=WwhEczkWeoHd3z0pTrh4u_XwBoUxePZ7rjEMPjajmx8,697
37
+ recce/data/_next/static/chunks/6dc81886-c94b9b91bc2c3caf.js,sha256=xIxqOzAWk07uQb5pgQGMv0O4CHereLF86Fwm2wX0Mmo,69733
38
+ recce/data/_next/static/chunks/6ef81909-694dc38134099299.js,sha256=KiPoS30Exnv9fi1X2HvxnydUFJnWfY-ZeifdexVAEXA,49001
39
+ recce/data/_next/static/chunks/700-3b65fc3666820d00.js,sha256=JokVG7hi66aCWFukVWlzc2vIBKa7EFW7JrSGW9F_2tU,124133
40
+ recce/data/_next/static/chunks/778-aef312bffb4c0312.js,sha256=0r8zj3JFDP8_0FxXPE8b_4aeW2nmwYi8wh5GiWBY5VM,1361523
41
+ recce/data/_next/static/chunks/7a8a3e83-d7fa409d97b38b2b.js,sha256=MmsF3qQgQXqSPGhUHQbIqAtVz7Maa_O3rWErEq0N3gY,1649
42
+ recce/data/_next/static/chunks/7f27ae6c-413f6b869a04183a.js,sha256=8Hs6bhtsCfZiOFrX3_IBxLZKPsdqhkLzikrACS1Pe0M,779
43
+ recce/data/_next/static/chunks/8d700b6a.ed11a130057c7a47.js,sha256=ObDzyvm0pCB9K8yFyj5vin5cVzTr5IqVO4XD-KHtXmo,119972
44
+ recce/data/_next/static/chunks/9746af58-d74bef4d03eea6ab.js,sha256=9MwsjNv8XMd92eUpXYeA32Ahk8ORP_oWMXnpTYOQQ-c,4177
45
+ recce/data/_next/static/chunks/a30376cd-7d806e1602f2dc3a.js,sha256=cvkpSEaZn5Johnsf3DT_x-hKNlNIhYFb6CZcMqpXpTE,797
46
+ recce/data/_next/static/chunks/b63b1b3f-7395c74e11a14e95.js,sha256=g2ArwRSeMZ-o6dODDGh3orC0iRkyxjXTk4NgyVk1nBw,572
47
+ recce/data/_next/static/chunks/c132bf7d-8102037f9ccf372a.js,sha256=CSRe9MSZI7ohCFzU6umTdDDkw2aBiLhA0HLurQwrjUY,198537
48
+ recce/data/_next/static/chunks/c1ceaa8b-a1e442154d23515e.js,sha256=mL85IeBYKB6YBgKlDs2n5lA7iLaxU8nTEtE8jduhGRI,81302
49
+ recce/data/_next/static/chunks/cd9f8d63-e020f408095ed77c.js,sha256=GeYFrOTA_N2zLZhmnWoJJOzgo_Jc9hk8svIHuTysdUg,82989
50
+ recce/data/_next/static/chunks/ce84277d-f42c2c58049cea2d.js,sha256=4FzO_5dSRNQKZHQ2EmZW0iau4yBguMBJ324J0e70UXQ,2562
51
+ recce/data/_next/static/chunks/e24bf851-0f8cbc99656833e7.js,sha256=aaPLADhg4KN7KoE09dpPiE831gBYqepVrIJj6Qh2amk,154153
52
+ recce/data/_next/static/chunks/fee69bc6-f17d36c080742e74.js,sha256=r51nWC424b7AoD-Y68JLMXDDpS_n-IUL3zcJNStzOLA,483
53
+ recce/data/_next/static/chunks/framework-ded83d71b51ce901.js,sha256=0Xsxxnmw5fjRHz8ni6vlaF9tQjfjNGZcZv2oMy7A_T4,140000
54
+ recce/data/_next/static/chunks/main-a0859f1f36d0aa6c.js,sha256=nTSd5jisBq_nX5_3Yf1JMakSk9Rq5IQEhtzeFU0VRyY,111204
55
+ recce/data/_next/static/chunks/main-app-0225a2255968e566.js,sha256=zVNui79GYFi-pNlmSB_zwxzps-uRW9L1-HZXXBUFj-Y,471
56
+ recce/data/_next/static/chunks/polyfills-42372ed130431b0a.js,sha256=CXPB1kyIrcjjyVBBDLWLKI9yEY1ZZbeASUON648vloM,112594
57
+ recce/data/_next/static/chunks/webpack-b787cb1a4f2293de.js,sha256=JMFnMBlHCoK4ti0UmBLCfdf5Vb1lgvJm7C3nzW8KbbQ,3899
58
+ recce/data/_next/static/chunks/app/layout-c713a2829d3279e4.js,sha256=Y0QZ74X1tmZrRQBM1HhnrmFyKgQx4aKRPE4KL6KSh3I,233
59
+ recce/data/_next/static/chunks/app/page-7086764277331fcb.js,sha256=y_cRY7_yvMXI-PsE1gLWRz6rd07RP5H5zUVvrID-2fY,225920
60
+ recce/data/_next/static/chunks/app/_not-found/page-8a886fa0855c3105.js,sha256=T5MBvLNarbZQll8vwvggCZWFzcNwqe6LlL0hGI9YPXA,1751
61
+ recce/data/_next/static/chunks/pages/_app-d5672bf3d8b6371b.js,sha256=UcYdHJMmCNfuMevCyY_iFfFwMGbxcEkLGRbBnEx_cCU,284
62
+ recce/data/_next/static/chunks/pages/_error-ed75be3f25588548.js,sha256=o_MwN3cYfszhI-hy_wkB0XAyTgcEcXt43rrzk-oKIe0,250
63
+ recce/data/_next/static/css/88b8abc134cfd59a.css,sha256=Tb97QjWxV5rOawZojbeD9SSETGsG2p9iaOrENjzAjYM,7235
64
+ recce/data/_next/static/css/c9ecb46a4b21c126.css,sha256=JbGypR8aDNuZavNvH6dhPtSbMVSCsy0ycPrz_6XkiVc,21925
65
+ recce/data/_next/static/media/montserrat-cyrillic-800-normal.22628180.woff2,sha256=P5Sx5PNkdTlDYzAdulW_OPRfMokDLi6XTpmS8KJSRoI,11148
66
+ recce/data/_next/static/media/montserrat-cyrillic-800-normal.31d693bb.woff,sha256=ITxULbMzWscxwUi_v3GpzTSYVWlwq_z9fpEvAkEvHJw,11020
67
+ recce/data/_next/static/media/montserrat-cyrillic-ext-800-normal.7e2c1e62.woff,sha256=6J3PqBk_hOFVM8PpfZeSfwZQumQd6LTPPjnaVha2KQ0,12672
68
+ recce/data/_next/static/media/montserrat-cyrillic-ext-800-normal.94a63aea.woff2,sha256=qHQDcPj9VkK-6sE5nxIKvejtNLo5RwBULzyH9nZsEwo,12052
69
+ recce/data/_next/static/media/montserrat-latin-800-normal.6f8fa298.woff2,sha256=Tyiv8SvOCaTmT_S2FaOZ5FuZz52F1aVV9hzIfrI7sEI,19036
70
+ recce/data/_next/static/media/montserrat-latin-800-normal.97e20d5e.woff,sha256=O3hUbMaqKvL7tlGscLIlvxQbLpHgOmCRLfwQ6RjJvE0,20784
71
+ recce/data/_next/static/media/montserrat-latin-ext-800-normal.013b84f9.woff2,sha256=tOnyR2cgiUm1cKtlrN9CY6FzD2yAMBe90slHKC0cBms,33776
72
+ recce/data/_next/static/media/montserrat-latin-ext-800-normal.aff52ab0.woff,sha256=IaGLu1tg0bPED9SLQjsK_VdkG3_RCq82GBmSP56xNFU,41956
73
+ recce/data/_next/static/media/montserrat-vietnamese-800-normal.5f21869b.woff,sha256=9ke3AivSl-ihV218s2s9NyJS8t0ETKDdqIK4rJWiPl0,7544
74
+ recce/data/_next/static/media/montserrat-vietnamese-800-normal.c0035377.woff2,sha256=bnmP7vEVe-4gLSDBsmKqD-SATv6-Pg-pxnTpSj7BCeI,7948
75
+ recce/data/_next/static/q0Xsc9Sd6PDuo1lshYpLu/_buildManifest.js,sha256=gZrGHi2LPMw1gkjYWs13MYkJyb5aOtihBRSJ1w0E6QA,224
76
+ recce/data/_next/static/q0Xsc9Sd6PDuo1lshYpLu/_ssgManifest.js,sha256=Z49s4suAsf5y_GfnQSvm4qtq2ggxEbZPfEDTXjy6XgA,80
77
+ recce/data/imgs/feedback/thumbs-down.png,sha256=q9KVIbaZku1TWkYHuleYlO-b6HsTApYh3St5xNHMGMg,10695
78
+ recce/data/imgs/feedback/thumbs-up.png,sha256=VF3BH8bmYEqcSsMDJO57xMqW4t6crCXUXaMlOPgI_OE,10556
79
+ recce/data/logo/recce-logo-white.png,sha256=y3re8iEucJnMUkAkRS2CjWHTlOydyvgWdWjuQKcXDbk,46923
80
+ recce/event/CONFIG,sha256=w8_AVcNu_JF-t8lNmjOqtsXbeOawMzpEhkISaMlm-iU,48
81
+ recce/event/SENTRY_DNS,sha256=nWXZevLC4qDScvNtjs329X13oxqvtFI_Kiu6cfCDOBA,83
82
+ recce/event/__init__.py,sha256=5yUqhpRUPejLbaQb7kRUXYtXUwqGYzm8ewga-PYmssQ,8387
83
+ recce/event/collector.py,sha256=1Y02A77CkMMrRv-5F1KUAMGebG7m3wXhsvcPdXM2Ugg,5661
84
+ recce/event/track.py,sha256=xDyDWblhR6mp0tezEYhkA0aOyZLqXBpJyHZwhI2xhU8,4803
85
+ recce/models/__init__.py,sha256=2ai4y8o0HfV358-qjSBBEC0KxqBwsdrbAdG2kT12mIo,104
86
+ recce/models/check.py,sha256=jjR1SGyczjrqyK-0Zas6ikLIGSgVp54lvfcQA19AniI,1588
87
+ recce/models/run.py,sha256=QK2gvOWvko9YYhd2NLs3BPt5l4MSCZGwpzTAiqx9zJw,1161
88
+ recce/models/types.py,sha256=leifP8zMuUcsK4nmtBlcI-Lz1mvDhGYg__POrR_hODg,3130
89
+ recce/tasks/__init__.py,sha256=qtOCHacoGndJ3MunCXe8HtYXpy8b-6jOl5ZCI5IuM2M,316
90
+ recce/tasks/core.py,sha256=JFYa1CfgOiRPQ7KVTwMuxJjhMB-pvCwB-xezVt-h3RU,4080
91
+ recce/tasks/dataframe.py,sha256=03UBWwt0DFTXlaEOtnV5i_mxdRKD7UbRayewEL2Ub48,3650
92
+ recce/tasks/histogram.py,sha256=SMdSznzrBdAFvAbhsoUGAK9o0QUMYy00IVbamUVTpBk,13601
93
+ recce/tasks/lineage.py,sha256=_PbY0ZkDr620U8V2olqoX_T9XA0-G8ILt_6m1Q5TfBs,541
94
+ recce/tasks/profile.py,sha256=gMgms9qvdDsihh2aSC6LvCm9ggah4Oq3xjvmCh_exrU,11352
95
+ recce/tasks/query.py,sha256=k3y_IK1_3D2j4Scw-70ccDjVMa-Oe9jqxlDyLHfjagw,12790
96
+ recce/tasks/rowcount.py,sha256=DIC17VUKtGhEHz6lW4VFLHyD6F4e4QV0i_Dsz4HAv1w,9750
97
+ recce/tasks/schema.py,sha256=HHrSvhd_ZJdrNj2QKi9W8vmig0NuYci5cgsKFvp2bu4,2274
98
+ recce/tasks/top_k.py,sha256=vY3VCBmg61E8I4V-9-hJOv5RCYCmhxl6sHiKR9Zv7eE,5521
99
+ recce/tasks/valuediff.py,sha256=XJWkA307B5qTerT87fJRhJxPCqjmXn5eILYCXDfPtSQ,16439
100
+ recce/util/__init__.py,sha256=0lcJectK7Z7k9h0EaYCcv4Bgw2PN03OdJoxb3tbV5j8,37
101
+ recce/util/breaking.py,sha256=_63SJhEqYVIsIp7SqXA9Muh2fDcvgjm9RhfZ3nTNJFQ,12593
102
+ recce/util/cache.py,sha256=QB6wzxe0M3jNTwP0M27Ys8F2hF-oda4-LyXXG9THuZQ,646
103
+ recce/util/cll.py,sha256=eg32KNz4Ec-FkOLSgMwP8TrW_TTUydI7xTb_UAbt-oI,12164
104
+ recce/util/io.py,sha256=53s4uDFT6ftpI-12MBxfv-RiBkWvPXMvdxPO9lJrjJM,3374
105
+ recce/util/lineage.py,sha256=C-jNqRARgwAEQoicO5t7D0XGBkcVs6SyxLzfzCAqkPQ,707
106
+ recce/util/logger.py,sha256=6UgLFkRiur9jJfu2ZRdo4LUvMw4f75V-l-1HT1-sgKo,747
107
+ recce/util/pydantic_model.py,sha256=KumKuyCjbTzEMsKLE4-b-eZfp0gLhYDdmVtw1-hxiJw,587
108
+ recce/util/recce_cloud.py,sha256=F9Y4zqUVqQAzbLrWnccJdSjGPHzhGCVBfN4mOGVwpL8,6822
109
+ recce/util/singleton.py,sha256=1cU99I0f9tjuMQLMJyLsK1oK3fZJMsO5-TbRHAMXqds,627
110
+ recce/yaml/__init__.py,sha256=EgXYlFeJZchatUClRDXbIC5Oqb2_nBvB2NqItYVihio,1292
111
+ recce_nightly-1.4.0.20250515.dist-info/licenses/LICENSE,sha256=CQjjMy9aYPhfe8xG_bcpIfKtNkdxLZ5IOb8oPygtUhY,11343
112
+ tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
113
+ tests/test_cli.py,sha256=f0n15QNVAyCqkygwIUp2aaoNAQau1zZp-nXpK4yyf1E,5444
114
+ tests/test_config.py,sha256=ODDFe_XF6gphmSmmc422dGLBaCCmG-IjDzTkD5SJsJE,1557
115
+ tests/test_core.py,sha256=oDaZz1nrMxoi-3GwA7sRwCJjk99M6C7dyBqGiJmB62A,785
116
+ tests/test_dbt.py,sha256=n3-Y3NaJI8ewdBKGoOldsWpTedwzCZM4Cp_6UYaURo8,1323
117
+ tests/test_pull_request.py,sha256=HmZo5MoDaoKSgPwbLxJ3Ur3ajZ7IxhkzJxaOmhg6bwE,3562
118
+ tests/test_server.py,sha256=7MYAr3ZvLIeFQ_DlvUW9sgV7wBr0gDMJchEC97zup8M,3383
119
+ tests/test_state.py,sha256=p6rIwEh78GBBocqv98elX14WzqrpXNpnfd4uWI8u1bI,5022
120
+ tests/test_summary.py,sha256=D0WvAkdO-vzGcvholH2rfS1wTxUXjVHwWm59fWy45eA,2876
121
+ tests/adapter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
122
+ tests/adapter/dbt_adapter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
123
+ tests/adapter/dbt_adapter/conftest.py,sha256=bLPgVhwLZpHsYm1bf7CrjNwqu3XZQuzc7CJDjbu8qZk,272
124
+ tests/adapter/dbt_adapter/dbt_test_helper.py,sha256=6yvz8UXzzFyNaL2uUHjJm1zPlhe2PUEpnkH737iRTjQ,9957
125
+ tests/adapter/dbt_adapter/test_dbt_adapter.py,sha256=Y5TSlqkXGjJC6hC7YYs45bnRht5aou_KLjPMjpAGxNM,830
126
+ tests/adapter/dbt_adapter/test_dbt_cll.py,sha256=J_jZ3am8czzSWDxW08Fw1gSggziPBH0pl8bJmz7uFQE,4109
127
+ tests/adapter/dbt_adapter/test_selector.py,sha256=uKFm0QxrxG-xyUEXGobCMueCRUssgnZMyo-S1Nlk3_s,6856
128
+ tests/tasks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
129
+ tests/tasks/conftest.py,sha256=UefgbNfJufLOmgHLiEFXIjOVmu8-58GbS6m5-NcEu20,143
130
+ tests/tasks/test_histogram.py,sha256=g69R2Ljvcd8RQTnq7EMZEa93_1vVWNe4ZLg990rWuyA,4088
131
+ tests/tasks/test_lineage.py,sha256=HODSP2_uSu98e4jV-t9TIOSrln_5mXd-6baKv9aEmws,1095
132
+ tests/tasks/test_preset_checks.py,sha256=fAro5kAv67YiXgRFj7hDAgZEd8fVSHW_VTapVDq4G04,1457
133
+ tests/tasks/test_profile.py,sha256=c26igXN1r6sw-iDf79Skis3B-q2o3VPRamQCuZ43GfY,10262
134
+ tests/tasks/test_query.py,sha256=_Lnew7hVEaFtZs3hWcTgF67YFtgE7AkDVdWyLr9oF5E,4253
135
+ tests/tasks/test_row_count.py,sha256=21PaP2aq-x8-pqwzWHRT1sixhQ8g3CQNRWOZTTmbK0s,3151
136
+ tests/tasks/test_schema.py,sha256=7ds4Vx8ixaiIWDR49Lvjem4xlPkRP1cXazDRY3roUak,3121
137
+ tests/tasks/test_top_k.py,sha256=YR_GS__DJsbDlQVaEEdJvNQ3fh1VmV5Nb3G7lb0r6YM,1779
138
+ tests/tasks/test_valuediff.py,sha256=_xQJGgxsXoy2NYk_Z6Hsw2FlVh6zk2nN_iUueyRN1e8,2046
139
+ recce_nightly-1.4.0.20250515.dist-info/METADATA,sha256=yvc1PBCH3YHHuuZ-8MDlYaBuMES4j4bYTh_P4UyjwJU,9299
140
+ recce_nightly-1.4.0.20250515.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
141
+ recce_nightly-1.4.0.20250515.dist-info/entry_points.txt,sha256=oqoY_IiwIqXbgrIsPnlqUqao2eiIeP2dprowkOlmeyg,40
142
+ recce_nightly-1.4.0.20250515.dist-info/top_level.txt,sha256=6PKGVpf75idP0C6KEaldDzzZUauIxNu1ZDstau1pI4I,12
143
+ recce_nightly-1.4.0.20250515.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.3.1)
2
+ Generator: setuptools (80.7.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,6 +1,7 @@
1
1
  import pytest
2
2
 
3
3
  from recce.core import set_default_context
4
+
4
5
  from .dbt_test_helper import DbtTestHelper
5
6
 
6
7