sqlakit-lsp 0.1.0__tar.gz → 0.1.2__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlakit-lsp
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: The language server for SQLAKit templates.
5
5
  Keywords: sqlalchemy,sqlakit,lsp,language-server,sql
6
6
  Author: Anton Ruhlov
@@ -18,7 +18,7 @@ Classifier: Programming Language :: Python :: 3.14
18
18
  Classifier: Topic :: Database
19
19
  Classifier: Topic :: Text Editors :: Integrated Development Environments (IDE)
20
20
  Classifier: Typing :: Typed
21
- Requires-Dist: sqlakit>=0.21.0,<0.22
21
+ Requires-Dist: sqlakit>=0.21.0,<0.23
22
22
  Requires-Dist: pygls>=2.1,<3
23
23
  Requires-Python: >=3.11
24
24
  Project-URL: Repository, https://github.com/sqlakit/sqlakit-lsp
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sqlakit-lsp"
3
- version = "0.1.0"
3
+ version = "0.1.2"
4
4
  description = "The language server for SQLAKit templates."
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -27,7 +27,7 @@ classifiers = [
27
27
  ]
28
28
  requires-python = ">=3.11"
29
29
  dependencies = [
30
- "sqlakit>=0.21.0,<0.22",
30
+ "sqlakit>=0.21.0,<0.23",
31
31
  "pygls>=2.1,<3",
32
32
  ]
33
33
 
@@ -131,7 +131,7 @@ dev = [
131
131
  "pytest>=9.1.1",
132
132
  "pytest-cov>=7.1.0",
133
133
  "anyio>=4.14.2",
134
- "ty>=0.0.80",
134
+ "ty>=0.0.84",
135
135
  "ruff>=0.16.6",
136
136
  "poethepoet>=0.48.0",
137
137
  "codespell>=2.4.3",
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sqlakit-lsp"
3
- version = "0.1.0"
3
+ version = "0.1.2"
4
4
  description = "The language server for SQLAKit templates."
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -22,9 +22,7 @@ classifiers = [
22
22
  ]
23
23
  requires-python = ">=3.11"
24
24
  dependencies = [
25
- # The server reads the private modules of `sqlakit`, which a minor version
26
- # may change.
27
- "sqlakit>=0.21.0,<0.22",
25
+ "sqlakit>=0.21.0,<0.23",
28
26
  "pygls>=2.1,<3",
29
27
  ]
30
28
 
@@ -51,7 +49,7 @@ dev = [
51
49
  "pytest>=9.1.1",
52
50
  "pytest-cov>=7.1.0",
53
51
  "anyio>=4.14.2",
54
- "ty>=0.0.80",
52
+ "ty>=0.0.84",
55
53
  "ruff>=0.16.6",
56
54
  "poethepoet>=0.48.0",
57
55
  "codespell>=2.4.3",
@@ -27,12 +27,13 @@ import re
27
27
  import tempfile
28
28
  import uuid
29
29
  from collections import OrderedDict
30
- from dataclasses import dataclass, field
31
- from functools import lru_cache
30
+ from dataclasses import dataclass, field, replace
31
+ from functools import cached_property, lru_cache
32
32
  from importlib.metadata import version
33
33
  from pathlib import Path
34
34
  from typing import TYPE_CHECKING, Any
35
35
 
36
+ import sqlakit
36
37
  import sqlalchemy as sa
37
38
  import sqlalchemy.engine.default
38
39
  import sqlalchemy.exc
@@ -421,6 +422,34 @@ class _Assistant:
421
422
  resolved = path.resolve()
422
423
  return any(resolved in files for files in self._files)
423
424
 
425
+ def _source(self, macro: Macro) -> Target | None:
426
+ """Return where a macro is written, in the project's own `sqlakit`.
427
+
428
+ A server that `uvx` runs imports `sqlakit` from a cache of its own. The
429
+ project holds the same version in `.venv`, which is the file to open.
430
+ """
431
+ target = _source_of(macro)
432
+ if target is None or self._library is None:
433
+ return target
434
+ try:
435
+ inside = target.path.resolve().relative_to(_LIBRARY)
436
+ except ValueError:
437
+ return target
438
+ return replace(target, path=self._library / inside)
439
+
440
+ @cached_property
441
+ def _library(self) -> Path | None:
442
+ """Return the project's `sqlakit` in `.venv`, when it is this version."""
443
+ installed = f"sqlakit-{version('sqlakit')}.dist-info"
444
+ for site in (
445
+ *self._root.glob(".venv/lib/python*/site-packages"),
446
+ self._root / ".venv/Lib/site-packages",
447
+ ):
448
+ library = site / "sqlakit"
449
+ if (site / installed).is_dir() and library.resolve() != _LIBRARY:
450
+ return library
451
+ return None
452
+
424
453
  def owns(self, path: Path) -> bool:
425
454
  """Whether a file is the project's own, where `walk` goes.
426
455
 
@@ -460,7 +489,7 @@ class _Assistant:
460
489
  self._sources = {
461
490
  target.path.resolve()
462
491
  for macro in self.project.templates.macros.values()
463
- if (target := _source_of(macro)) is not None
492
+ if (target := self._source(macro)) is not None
464
493
  }
465
494
  return path.resolve() in self._sources
466
495
 
@@ -688,7 +717,7 @@ class _Assistant:
688
717
  signature_of(macro, namespace),
689
718
  )
690
719
  for macro in self.project.templates.macros.values()
691
- if (target := _source_of(macro)) is not None
720
+ if (target := self._source(macro)) is not None
692
721
  ]
693
722
  everything.extend(
694
723
  (name, "template", Target(path, 0), "")
@@ -942,7 +971,7 @@ class _Assistant:
942
971
  return None if path is None else Target(path, 0)
943
972
  macro = self.project.templates.macros.get(self._macro_at(source, offset) or "")
944
973
  if macro is not None:
945
- return _source_of(macro)
974
+ return self._source(macro)
946
975
  if path is None:
947
976
  return None
948
977
  # The SQL of `@sql_macro("file.sql")` goes to its function.
@@ -963,7 +992,7 @@ class _Assistant:
963
992
  if macro is None or sql is None:
964
993
  return None
965
994
  if Path(sql).resolve() == path.resolve():
966
- return _source_of(macro)
995
+ return self._source(macro)
967
996
  statement = next(
968
997
  (one for one in sql_macros(Path(sql)) if one.name == macro.name), None
969
998
  )
@@ -1271,7 +1300,7 @@ class _Assistant:
1271
1300
  def declaration(self, name: str) -> Reference | None:
1272
1301
  """Return where a macro's name is written, for a list of its references."""
1273
1302
  macro = self.project.templates.macros.get(name)
1274
- if macro is None or (target := _source_of(macro)) is None:
1303
+ if macro is None or (target := self._source(macro)) is None:
1275
1304
  return None
1276
1305
  text = _read(target.path)
1277
1306
  start = _line_span(text, target.line + 1)[0] + target.column
@@ -1300,7 +1329,7 @@ class _Assistant:
1300
1329
  sql = getattr(macro, "sql_path", None)
1301
1330
  if sql is not None and Path(sql).resolve() == path.resolve():
1302
1331
  return word
1303
- target = _source_of(macro)
1332
+ target = self._source(macro)
1304
1333
  if target is None or target.path.resolve() != path.resolve():
1305
1334
  return None
1306
1335
  return word if target.line + 1 == line else None
@@ -1673,6 +1702,9 @@ def _source_of(macro: Macro) -> Target | None:
1673
1702
 
1674
1703
  _DEF = re.compile(r"\s*(?:async\s+)?def\s+(\w+)")
1675
1704
 
1705
+ _LIBRARY = Path(sqlakit.__file__).resolve().parent
1706
+ """The `sqlakit` this server imports."""
1707
+
1676
1708
 
1677
1709
  @dataclass(frozen=True, slots=True)
1678
1710
  class _At:
File without changes
File without changes