Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 33 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,13 @@ permissions:

jobs:
test:
name: Test (Python 3.12)
name: Test (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# Both ends of `requires-python`, and every version between.
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

Expand All @@ -24,10 +29,35 @@ jobs:
enable-cache: true

- name: Set up Python
run: uv python install 3.12
run: uv python install ${{ matrix.python-version }}

- name: Install dependencies
run: uv sync --locked
run: uv sync --locked --python ${{ matrix.python-version }}

- name: Test
run: uv run pytest -v

checks:
name: Lint and types
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

- uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v6
with:
enable-cache: true

- name: Set up Python
run: uv python install 3.12

- name: Install dependencies
run: uv sync --locked --python 3.12

- name: Lint
run: uv run ruff check .

- name: Format
run: uv run ruff format --check .

- name: Types
run: uv run mypy
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
about. `SearchableColumn` and `verify_searchable_columns` are exported for callers assembling
descriptions themselves.

- **The whole supported Python range is now tested, and lint and types are gated.** CI ran
`pytest` on 3.12 alone while `requires-python` claimed `>=3.10`, so neither end of the range
was exercised; it now runs the suite on 3.10 through 3.14 and fails the build on `ruff check`,
`ruff format --check`, or `mypy` in strict mode. The suite passes on every version. One test is
skipped on 3.10 only, where `tomllib` is not in the standard library.

### Fixed

- **The SQL tool no longer claims the registered column is the *only* indexed one.** It said
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -776,3 +776,12 @@ question with a stock LangChain retrieval chain over `HotdataVectorStore`.
uv sync --locked
uv run pytest
```

CI runs the suite on Python 3.10 through 3.14, and gates three more checks that a change has
to pass:

```bash
uv run ruff check .
uv run ruff format --check .
uv run mypy
```
7 changes: 4 additions & 3 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from pathlib import Path
from types import SimpleNamespace
from unittest.mock import MagicMock, patch
from urllib.request import Request

import pyarrow as pa
import pyarrow.parquet as pq
Expand Down Expand Up @@ -33,9 +34,9 @@ class FakeOpener:
def __init__(self, payload: bytes, headers: dict[str, str]) -> None:
self._payload = payload
self._headers = headers
self.requests: list[object] = []
self.requests: list[Request] = []

def open(self, request: object, timeout: float | None = None) -> FakeResponse:
def open(self, request: Request, timeout: float | None = None) -> FakeResponse:
self.requests.append(request)
return FakeResponse(self._payload, self._headers)

Expand Down Expand Up @@ -196,7 +197,7 @@ def search_result() -> QueryResult:


@pytest.fixture
def mock_client(sample_result: QueryResult):
def mock_client(sample_result: QueryResult) -> MagicMock:
client = MagicMock()
client.workspace_id = "ws_test"
client.execute_sql = MagicMock(return_value=sample_result)
Expand Down
8 changes: 4 additions & 4 deletions tests/test_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,21 @@
_LANGCHAIN_IMPORT = re.compile(r"(?m)^\s*(?:from|import)\s+langchain(?=[.\s,]|$)")


def test_version_is_pep440_core():
def test_version_is_pep440_core() -> None:
assert re.fullmatch(r"\d+\.\d+\.\d+(\+.*)?", hl.__version__)


def test_version_matches_distribution_metadata():
def test_version_matches_distribution_metadata() -> None:
assert dist_version("hotdata-langchain") == hl.__version__


@pytest.mark.parametrize("name", hl.__all__)
def test_public_export_is_importable(name: str):
def test_public_export_is_importable(name: str) -> None:
assert hasattr(hl, name), f"missing export: {name}"
assert getattr(hl, name) is not None


def test_source_uses_hotdata_framework_root_imports():
def test_source_uses_hotdata_framework_root_imports() -> None:
violations: list[str] = []
for path in SOURCE_ROOT.rglob("*.py"):
if _RUNTIME_SUBMODULE.search(path.read_text(encoding="utf-8")):
Expand Down
6 changes: 5 additions & 1 deletion tests/test_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,11 @@ def test_vector_distance_sql_never_projects_the_vector_column() -> None:
def test_vector_distance_sql_rejects_a_metric_it_has_no_function_for() -> None:
with pytest.raises(ValueError, match="metric must be one of"):
vector_distance_sql(
table=SEMANTIC_TABLE, column="embedding", vector=[0.1], columns=["id"], metric="jaccard"
table=SEMANTIC_TABLE,
column="embedding",
vector=[0.1],
columns=["id"],
metric="jaccard", # type: ignore[arg-type]
)


Expand Down
Loading
Loading