sqlmesh 0.187.6.dev5__py3-none-any.whl → 0.187.6.dev6__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 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.187.6.dev5'
21
- __version_tuple__ = version_tuple = (0, 187, 6, 'dev5')
20
+ __version__ = version = '0.187.6.dev6'
21
+ __version_tuple__ = version_tuple = (0, 187, 6, 'dev6')
sqlmesh/lsp/main.py CHANGED
@@ -57,8 +57,12 @@ class SQLMeshLanguageServer:
57
57
  self.server = LanguageServer(server_name, version)
58
58
  self.context_class = context_class
59
59
  self.lsp_context: t.Optional[LSPContext] = None
60
- self.lint_cache: t.Dict[URI, t.List[AnnotatedRuleViolation]] = {}
61
60
 
61
+ # Cache stores tuples of (diagnostics, diagnostic_version)
62
+ self.lint_cache: t.Dict[URI, t.Tuple[t.List[AnnotatedRuleViolation], int]] = {}
63
+ self._diagnostic_version_counter: int = 0
64
+
65
+ self.client_supports_pull_diagnostics = False
62
66
  # Register LSP features (e.g., formatting, hover, etc.)
63
67
  self._register_features()
64
68
 
@@ -69,6 +73,18 @@ class SQLMeshLanguageServer:
69
73
  def initialize(ls: LanguageServer, params: types.InitializeParams) -> None:
70
74
  """Initialize the server when the client connects."""
71
75
  try:
76
+ # Check if client supports pull diagnostics
77
+ if params.capabilities and params.capabilities.text_document:
78
+ diagnostics = getattr(params.capabilities.text_document, "diagnostic", None)
79
+ if diagnostics:
80
+ self.client_supports_pull_diagnostics = True
81
+ ls.log_trace("Client supports pull diagnostics")
82
+ else:
83
+ self.client_supports_pull_diagnostics = False
84
+ ls.log_trace("Client does not support pull diagnostics")
85
+ else:
86
+ self.client_supports_pull_diagnostics = False
87
+
72
88
  if params.workspace_folders:
73
89
  # Try to find a SQLMesh config file in any workspace folder (only at the root level)
74
90
  for folder in params.workspace_folders:
@@ -153,61 +169,71 @@ class SQLMeshLanguageServer:
153
169
  def did_open(ls: LanguageServer, params: types.DidOpenTextDocumentParams) -> None:
154
170
  uri = URI(params.text_document.uri)
155
171
  context = self._context_get_or_load(uri)
156
- if self.lint_cache.get(uri) is not None:
172
+ models = context.map[uri.to_path()]
173
+ if models is None or not isinstance(models, ModelTarget):
174
+ return
175
+
176
+ if self.lint_cache.get(uri) is None:
177
+ diagnostics = context.context.lint_models(
178
+ models.names,
179
+ raise_on_error=False,
180
+ )
181
+ self._diagnostic_version_counter += 1
182
+ self.lint_cache[uri] = (diagnostics, self._diagnostic_version_counter)
183
+
184
+ # Only publish diagnostics if client doesn't support pull diagnostics
185
+ if not self.client_supports_pull_diagnostics:
186
+ diagnostics, _ = self.lint_cache[uri]
157
187
  ls.publish_diagnostics(
158
188
  params.text_document.uri,
159
- SQLMeshLanguageServer._diagnostics_to_lsp_diagnostics(self.lint_cache[uri]),
189
+ SQLMeshLanguageServer._diagnostics_to_lsp_diagnostics(diagnostics),
160
190
  )
161
- return
162
- models = context.map[uri.to_path()]
163
- if models is None:
164
- return
165
- if not isinstance(models, ModelTarget):
166
- return
167
- self.lint_cache[uri] = context.context.lint_models(
168
- models.names,
169
- raise_on_error=False,
170
- )
171
- ls.publish_diagnostics(
172
- params.text_document.uri,
173
- SQLMeshLanguageServer._diagnostics_to_lsp_diagnostics(self.lint_cache[uri]),
174
- )
175
191
 
176
192
  @self.server.feature(types.TEXT_DOCUMENT_DID_CHANGE)
177
193
  def did_change(ls: LanguageServer, params: types.DidChangeTextDocumentParams) -> None:
178
194
  uri = URI(params.text_document.uri)
179
195
  context = self._context_get_or_load(uri)
180
196
  models = context.map[uri.to_path()]
181
- if models is None:
197
+ if models is None or not isinstance(models, ModelTarget):
182
198
  return
183
- if not isinstance(models, ModelTarget):
184
- return
185
- self.lint_cache[uri] = context.context.lint_models(
199
+
200
+ # Always update the cache
201
+ diagnostics = context.context.lint_models(
186
202
  models.names,
187
203
  raise_on_error=False,
188
204
  )
189
- ls.publish_diagnostics(
190
- params.text_document.uri,
191
- SQLMeshLanguageServer._diagnostics_to_lsp_diagnostics(self.lint_cache[uri]),
192
- )
205
+ self._diagnostic_version_counter += 1
206
+ self.lint_cache[uri] = (diagnostics, self._diagnostic_version_counter)
207
+
208
+ # Only publish diagnostics if client doesn't support pull diagnostics
209
+ if not self.client_supports_pull_diagnostics:
210
+ ls.publish_diagnostics(
211
+ params.text_document.uri,
212
+ SQLMeshLanguageServer._diagnostics_to_lsp_diagnostics(diagnostics),
213
+ )
193
214
 
194
215
  @self.server.feature(types.TEXT_DOCUMENT_DID_SAVE)
195
216
  def did_save(ls: LanguageServer, params: types.DidSaveTextDocumentParams) -> None:
196
217
  uri = URI(params.text_document.uri)
197
218
  context = self._context_get_or_load(uri)
198
219
  models = context.map[uri.to_path()]
199
- if models is None:
200
- return
201
- if not isinstance(models, ModelTarget):
220
+ if models is None or not isinstance(models, ModelTarget):
202
221
  return
203
- self.lint_cache[uri] = context.context.lint_models(
222
+
223
+ # Always update the cache
224
+ diagnostics = context.context.lint_models(
204
225
  models.names,
205
226
  raise_on_error=False,
206
227
  )
207
- ls.publish_diagnostics(
208
- params.text_document.uri,
209
- SQLMeshLanguageServer._diagnostics_to_lsp_diagnostics(self.lint_cache[uri]),
210
- )
228
+ self._diagnostic_version_counter += 1
229
+ self.lint_cache[uri] = (diagnostics, self._diagnostic_version_counter)
230
+
231
+ # Only publish diagnostics if client doesn't support pull diagnostics
232
+ if not self.client_supports_pull_diagnostics:
233
+ ls.publish_diagnostics(
234
+ params.text_document.uri,
235
+ SQLMeshLanguageServer._diagnostics_to_lsp_diagnostics(diagnostics),
236
+ )
211
237
 
212
238
  @self.server.feature(types.TEXT_DOCUMENT_FORMATTING)
213
239
  def formatting(
@@ -327,6 +353,125 @@ class SQLMeshLanguageServer:
327
353
  ls.show_message(f"Error getting references: {e}", types.MessageType.Error)
328
354
  return []
329
355
 
356
+ @self.server.feature(types.TEXT_DOCUMENT_DIAGNOSTIC)
357
+ def diagnostic(
358
+ ls: LanguageServer, params: types.DocumentDiagnosticParams
359
+ ) -> types.DocumentDiagnosticReport:
360
+ """Handle diagnostic pull requests from the client."""
361
+ try:
362
+ uri = URI(params.text_document.uri)
363
+ diagnostics, result_id = self._get_diagnostics_for_uri(uri)
364
+
365
+ # Check if client provided a previous result ID
366
+ if hasattr(params, "previous_result_id") and params.previous_result_id == result_id:
367
+ # Return unchanged report if diagnostics haven't changed
368
+ return types.RelatedUnchangedDocumentDiagnosticReport(
369
+ kind=types.DocumentDiagnosticReportKind.Unchanged,
370
+ result_id=str(result_id),
371
+ )
372
+
373
+ return types.RelatedFullDocumentDiagnosticReport(
374
+ kind=types.DocumentDiagnosticReportKind.Full,
375
+ items=diagnostics,
376
+ result_id=str(result_id),
377
+ )
378
+ except Exception as e:
379
+ ls.show_message(f"Error getting diagnostics: {e}", types.MessageType.Error)
380
+ return types.RelatedFullDocumentDiagnosticReport(
381
+ kind=types.DocumentDiagnosticReportKind.Full,
382
+ items=[],
383
+ )
384
+
385
+ @self.server.feature(types.WORKSPACE_DIAGNOSTIC)
386
+ def workspace_diagnostic(
387
+ ls: LanguageServer, params: types.WorkspaceDiagnosticParams
388
+ ) -> types.WorkspaceDiagnosticReport:
389
+ """Handle workspace-wide diagnostic pull requests from the client."""
390
+ try:
391
+ if self.lsp_context is None:
392
+ current_path = Path.cwd()
393
+ self._ensure_context_in_folder(current_path)
394
+
395
+ if self.lsp_context is None:
396
+ return types.WorkspaceDiagnosticReport(items=[])
397
+
398
+ items: t.List[
399
+ t.Union[
400
+ types.WorkspaceFullDocumentDiagnosticReport,
401
+ types.WorkspaceUnchangedDocumentDiagnosticReport,
402
+ ]
403
+ ] = []
404
+
405
+ # Get all SQL and Python model files from the context
406
+ for path, target in self.lsp_context.map.items():
407
+ if isinstance(target, ModelTarget):
408
+ uri = URI.from_path(path)
409
+ diagnostics, result_id = self._get_diagnostics_for_uri(uri)
410
+
411
+ # Check if we have a previous result ID for this file
412
+ previous_result_id = None
413
+ if hasattr(params, "previous_result_ids") and params.previous_result_ids:
414
+ for prev in params.previous_result_ids:
415
+ if prev.uri == uri.value:
416
+ previous_result_id = prev.value
417
+ break
418
+
419
+ if previous_result_id and previous_result_id == result_id:
420
+ # File hasn't changed
421
+ items.append(
422
+ types.WorkspaceUnchangedDocumentDiagnosticReport(
423
+ kind=types.DocumentDiagnosticReportKind.Unchanged,
424
+ result_id=str(result_id),
425
+ uri=uri.value,
426
+ )
427
+ )
428
+ else:
429
+ # File has changed or is new
430
+ items.append(
431
+ types.WorkspaceFullDocumentDiagnosticReport(
432
+ kind=types.DocumentDiagnosticReportKind.Full,
433
+ result_id=str(result_id),
434
+ uri=uri.value,
435
+ items=diagnostics,
436
+ )
437
+ )
438
+
439
+ return types.WorkspaceDiagnosticReport(items=items)
440
+
441
+ except Exception as e:
442
+ ls.show_message(
443
+ f"Error getting workspace diagnostics: {e}", types.MessageType.Error
444
+ )
445
+ return types.WorkspaceDiagnosticReport(items=[])
446
+
447
+ def _get_diagnostics_for_uri(self, uri: URI) -> t.Tuple[t.List[types.Diagnostic], int]:
448
+ """Get diagnostics for a specific URI, returning (diagnostics, result_id)."""
449
+ # Check if we have cached diagnostics
450
+ if uri in self.lint_cache:
451
+ diagnostics, result_id = self.lint_cache[uri]
452
+ return SQLMeshLanguageServer._diagnostics_to_lsp_diagnostics(diagnostics), result_id
453
+
454
+ # Try to get diagnostics by loading context and linting
455
+ try:
456
+ context = self._context_get_or_load(uri)
457
+ models = context.map[uri.to_path()]
458
+ if models is None or not isinstance(models, ModelTarget):
459
+ return [], 0
460
+
461
+ # Lint the models and cache the results
462
+ diagnostics = context.context.lint_models(
463
+ models.names,
464
+ raise_on_error=False,
465
+ )
466
+ self._diagnostic_version_counter += 1
467
+ self.lint_cache[uri] = (diagnostics, self._diagnostic_version_counter)
468
+ return SQLMeshLanguageServer._diagnostics_to_lsp_diagnostics(
469
+ diagnostics
470
+ ), self._diagnostic_version_counter
471
+ except Exception:
472
+ # If we can't get diagnostics, return empty list with no result ID
473
+ return [], 0
474
+
330
475
  def _context_get_or_load(self, document_uri: URI) -> LSPContext:
331
476
  if self.lsp_context is None:
332
477
  self._ensure_context_for_document(document_uri)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlmesh
3
- Version: 0.187.6.dev5
3
+ Version: 0.187.6.dev6
4
4
  Summary: Next-generation data transformation framework
5
5
  Author-email: "TobikoData Inc." <engineering@tobikodata.com>
6
6
  License: Apache License
@@ -1,5 +1,5 @@
1
1
  sqlmesh/__init__.py,sha256=69xw6bTmi4cW90M-sl3g6wLDgxVcLHcKg1q8GS3lqyA,7466
2
- sqlmesh/_version.py,sha256=GUi5LwIkoCGfqcPhpacvHW-W-KbtH11PiHTo0Q57fOY,528
2
+ sqlmesh/_version.py,sha256=nwLeHNJZHDMcITzvamR5IDQO8DhPkF3cQ712so8RVsw,528
3
3
  sqlmesh/magics.py,sha256=JHorAZNtezf123jmTyNSoUC9yHmv-08hMP205PJmmIo,39750
4
4
  sqlmesh/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  sqlmesh/cicd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -160,7 +160,7 @@ sqlmesh/lsp/completions.py,sha256=Uo8lUzPBeoB58Eu2642YoAtNI0pgIFWFSvwmuJALTv4,35
160
160
  sqlmesh/lsp/context.py,sha256=nCWg2uVH28-IJC2uDYuCbiXTh1lUFElSpNu4Q-fDWi4,2918
161
161
  sqlmesh/lsp/custom.py,sha256=1YVcQz0y-4cdsvTdOQvlhUQXwOqPBWi3v_u1X2EqQxE,901
162
162
  sqlmesh/lsp/description.py,sha256=4QIGC9ix8IzmWF6DVUNhY4m1Crk3sNQA6hZ1RbyqU78,827
163
- sqlmesh/lsp/main.py,sha256=afQif7TFaaSMlJmuHGTu2g51SwJ9ij8pjic6OQbnP6s,20214
163
+ sqlmesh/lsp/main.py,sha256=Lg_XHxXNScStf0aiOUptijZnBLOIjcmmhsFgM5w2rNo,27405
164
164
  sqlmesh/lsp/reference.py,sha256=v4VXMYQY9rPC8b5w-jzob3i77VdZ1FZ8sA_-sWuPx7M,10502
165
165
  sqlmesh/lsp/uri.py,sha256=mvSLbZGmMTHPpliThOtVWiFcHnfJzp1w39q9l-xD2SI,802
166
166
  sqlmesh/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -270,7 +270,7 @@ sqlmesh/utils/pydantic.py,sha256=I898jAFqa3qU6lG2uPpRebVFncOUo8ZrLWM_R3K3DHU,116
270
270
  sqlmesh/utils/rich.py,sha256=xNZyPCqEc4TAlJlsEthg-5eYUWpaizz0QjBzO7a1Yv4,1509
271
271
  sqlmesh/utils/windows.py,sha256=r7Yin4WEwbvH7sKA3hOJtRsclmscNuBeCklCfVPvtQs,611
272
272
  sqlmesh/utils/yaml.py,sha256=np-WVcwmwsKghCgAj1OBBMsK1SXSRn4wR-H37cGiFr8,2282
273
- sqlmesh-0.187.6.dev5.dist-info/licenses/LICENSE,sha256=OlMefUjgWJdULtf84BLW0AZZcY8DwdgQqb_1j2862j8,11346
273
+ sqlmesh-0.187.6.dev6.dist-info/licenses/LICENSE,sha256=OlMefUjgWJdULtf84BLW0AZZcY8DwdgQqb_1j2862j8,11346
274
274
  web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
275
275
  web/client/dist/index.html,sha256=M50OuwjW63dRCS0Dz40Yecgvw9ecLFqizbTa6gv5Nd4,5472
276
276
  web/client/dist/assets/Audits-BPlxzqeG.js,sha256=TCx1qCjCGgmUSvH6HoPr5t8ztbRXMlOxrcW4o7hRjlA,1041
@@ -388,8 +388,8 @@ web/server/api/endpoints/models.py,sha256=ud-lRwriyI_OYg9tZchrBgeiXELiRTLNEodraf
388
388
  web/server/api/endpoints/modules.py,sha256=8hqqgonGay_mJmpCw0IdbjsPhWlQH2VLdKAqha-myac,468
389
389
  web/server/api/endpoints/plan.py,sha256=OYuQ_4dgbhG9ibTcX1a8mvYgH3ANxw9Fhbb4wg6QWqc,9222
390
390
  web/server/api/endpoints/table_diff.py,sha256=Wd5YxeKbZB7AkrDvqFgvV9ZQlnKYOF1n5W_w2EHE_Zw,2085
391
- sqlmesh-0.187.6.dev5.dist-info/METADATA,sha256=iABynQh3DIRW5aOLpWJEzu8IHH19ycnQEcFAQ_zP-ek,26493
392
- sqlmesh-0.187.6.dev5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
393
- sqlmesh-0.187.6.dev5.dist-info/entry_points.txt,sha256=pIYKtg-u-uO7BK_Y0qrdmfyj0bYrcMc3Xiqr5WE3VFk,121
394
- sqlmesh-0.187.6.dev5.dist-info/top_level.txt,sha256=bspjo5vjELQkuN0qKuTFIbsrUt3Zeo8D2mlKeHG1LdE,12
395
- sqlmesh-0.187.6.dev5.dist-info/RECORD,,
391
+ sqlmesh-0.187.6.dev6.dist-info/METADATA,sha256=LPngDmRnD-PUHYU9VsgtEwdgog70kQ1iUaiS9YlbuUQ,26493
392
+ sqlmesh-0.187.6.dev6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
393
+ sqlmesh-0.187.6.dev6.dist-info/entry_points.txt,sha256=pIYKtg-u-uO7BK_Y0qrdmfyj0bYrcMc3Xiqr5WE3VFk,121
394
+ sqlmesh-0.187.6.dev6.dist-info/top_level.txt,sha256=bspjo5vjELQkuN0qKuTFIbsrUt3Zeo8D2mlKeHG1LdE,12
395
+ sqlmesh-0.187.6.dev6.dist-info/RECORD,,