Skip to content

Commit b10dc28

Browse files
authored
fix(testing+linting): add nox lint+format directives (googleapis#123)
* fix(testing+linting): add nox lint+format directives This change introduces new nox directives: * blacken: `nox -s blacken` * format: `nox -s format` to apply formatting to files * lint: `nox -s lint` to flag linting issues * integration: to run integration tests * unit: to run unit tests locally which are the basis to enable scalable development and continuous testing as I prepare to bring in Approximate Nearest Neighors (ANN) functionality into this package. * Rebased from main and re-ran nox -s format/lint
1 parent e3ed5c3 commit b10dc28

File tree

8 files changed

+121
-20
lines changed

8 files changed

+121
-20
lines changed

noxfile.py

Lines changed: 105 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,28 @@
2020
import pathlib
2121
import shutil
2222
from pathlib import Path
23-
from typing import Optional
2423

2524
import nox
2625

2726
DEFAULT_PYTHON_VERSION = "3.10"
2827
CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute()
28+
LINT_PATHS = ["src", "tests", "noxfile.py"]
29+
2930

3031
nox.options.sessions = [
31-
"docs",
32+
"blacken",
3233
"docfx",
34+
"docs",
35+
"format",
36+
"lint",
37+
"unit",
3338
]
3439

3540
# Error if a python version is missing
3641
nox.options.error_on_missing_interpreters = True
3742

3843

39-
@nox.session(python="3.10")
44+
@nox.session(python=DEFAULT_PYTHON_VERSION)
4045
def docs(session):
4146
"""Build the docs for this library."""
4247

@@ -71,7 +76,7 @@ def docs(session):
7176
)
7277

7378

74-
@nox.session(python="3.10")
79+
@nox.session(python=DEFAULT_PYTHON_VERSION)
7580
def docfx(session):
7681
"""Build the docfx yaml files for this library."""
7782

@@ -115,3 +120,99 @@ def docfx(session):
115120
os.path.join("docs", ""),
116121
os.path.join("docs", "_build", "html", ""),
117122
)
123+
124+
125+
@nox.session(python=DEFAULT_PYTHON_VERSION)
126+
def lint(session):
127+
"""Run linters.
128+
129+
Returns a failure if the linters find linting errors or
130+
sufficiently serious code quality issues.
131+
"""
132+
session.install(".[lint]")
133+
session.run(
134+
"black",
135+
"--check",
136+
*LINT_PATHS,
137+
)
138+
session.run("flake8", "src", "tests")
139+
140+
141+
@nox.session(python=DEFAULT_PYTHON_VERSION)
142+
def lint_setup_py(session):
143+
"""Verify that setup.py is valid (including an RST check)."""
144+
session.install("docutils", "pygments")
145+
session.run("python", "setup.py", "check", "--restructuredtext", "--strict")
146+
147+
148+
@nox.session(python=DEFAULT_PYTHON_VERSION)
149+
def blacken(session):
150+
session.install(".[lint]")
151+
session.run(
152+
"black",
153+
*LINT_PATHS,
154+
)
155+
156+
157+
@nox.session(python=DEFAULT_PYTHON_VERSION)
158+
def format(session):
159+
session.install(".[lint]")
160+
# Sort imports in strict alphabetical order.
161+
session.run(
162+
"isort",
163+
*LINT_PATHS,
164+
)
165+
session.run(
166+
"black",
167+
*LINT_PATHS,
168+
)
169+
170+
171+
@nox.session(python=DEFAULT_PYTHON_VERSION)
172+
def unit(session):
173+
install_unittest_dependencies(session)
174+
session.run(
175+
"py.test",
176+
"--quiet",
177+
os.path.join("tests", "unit"),
178+
*session.posargs,
179+
)
180+
181+
182+
def install_unittest_dependencies(session, *constraints):
183+
session.install(".[test]")
184+
session.run(
185+
"pip",
186+
"install",
187+
"--no-compile", # To ensure no byte recompliation which is usually super slow
188+
"-q",
189+
"--disable-pip-version-check", # Avoid the slow version check
190+
".",
191+
"-r",
192+
"requirements.txt",
193+
)
194+
195+
196+
@nox.session(python=DEFAULT_PYTHON_VERSION)
197+
def integration(session):
198+
install_integrationtest_dependencies(session)
199+
session.run(
200+
"py.test",
201+
"--quiet",
202+
os.path.join("tests", "integration"),
203+
*session.posargs,
204+
)
205+
206+
207+
def install_integrationtest_dependencies(session):
208+
session.install(".[test]")
209+
session.run(
210+
"pip",
211+
"install",
212+
"--no-compile", # To ensure no byte recompliation which is usually super slow
213+
"-q",
214+
"--disable-pip-version-check", # Avoid the slow version check
215+
".",
216+
"-r",
217+
"requirements.txt",
218+
)

pyproject.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,16 @@ Repository = "https://github.com/googleapis/langchain-google-spanner-python.git"
3535
Changelog = "https://github.com/googleapis/langchain-google-spanner-python/blob/main/CHANGELOG.md"
3636

3737
[project.optional-dependencies]
38+
lint = [
39+
"black[jupyter]==24.8.0",
40+
"flake8==6.1.0",
41+
"isort==5.13.2",
42+
]
43+
3844
test = [
3945
"black[jupyter]==24.8.0",
4046
"bs4==0.0.2",
47+
"flake8==6.1.0",
4148
"isort==5.13.2",
4249
"mypy==1.11.2",
4350
"pytest==8.3.3",

src/langchain_google_spanner/graph_qa.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,6 @@ def _call(
288288
inputs: Dict[str, Any],
289289
run_manager: Optional[CallbackManagerForChainRun] = None,
290290
) -> Dict[str, str]:
291-
292291
intermediate_steps: List = []
293292

294293
"""Generate gql statement, uses it to look up in db and answer question."""

src/langchain_google_spanner/graph_retriever.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,7 @@
1616
from typing import Any, List, Optional
1717

1818
from langchain.schema.retriever import BaseRetriever
19-
from langchain_community.graphs.graph_document import GraphDocument
20-
from langchain_core.callbacks import (
21-
CallbackManagerForChainRun,
22-
CallbackManagerForRetrieverRun,
23-
)
19+
from langchain_core.callbacks import CallbackManagerForRetrieverRun
2420
from langchain_core.documents import Document
2521
from langchain_core.embeddings import Embeddings
2622
from langchain_core.example_selectors import SemanticSimilarityExampleSelector

src/langchain_google_spanner/loader.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
from google.cloud.spanner import Client, KeySet # type: ignore
2121
from google.cloud.spanner_admin_database_v1.types import DatabaseDialect # type: ignore
22-
from google.cloud.spanner_v1.data_types import JsonObject # type: ignore
2322
from langchain_community.document_loaders.base import BaseLoader
2423
from langchain_core.documents import Document
2524

tests/integration/test_spanner_graph_qa.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@ def load_data(graph: SpannerGraphStore):
145145

146146

147147
class TestSpannerGraphQAChain:
148-
149148
@pytest.fixture(scope="module")
150149
def setup_db_load_data(self):
151150
graph = get_spanner_graph()

tests/integration/test_spanner_loader.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import uuid
1717

1818
import pytest
19-
from google.cloud.spanner import Client, KeySet # type: ignore
19+
from google.cloud.spanner import Client # type: ignore
2020
from langchain_core.documents import Document
2121

2222
from langchain_google_spanner.loader import Column, SpannerDocumentSaver, SpannerLoader
@@ -363,7 +363,7 @@ def test_loader_custom_format_error(self, client):
363363
client=client,
364364
format="NOT_A_FORMAT",
365365
)
366-
docs = loader.load()
366+
docs = loader.load() # noqa
367367

368368
def test_loader_custom_content_key_error(self, client):
369369
query = f"SELECT * FROM {table_name}"
@@ -375,7 +375,7 @@ def test_loader_custom_content_key_error(self, client):
375375
client=client,
376376
content_columns=["NOT_A_COLUMN"],
377377
)
378-
docs = loader.load()
378+
docs = loader.load() # noqa
379379

380380
def test_loader_custom_metadata_key_error(self, client):
381381
query = f"SELECT * FROM {table_name}"
@@ -387,7 +387,7 @@ def test_loader_custom_metadata_key_error(self, client):
387387
client=client,
388388
metadata_columns=["NOT_A_COLUMN"],
389389
)
390-
docs = loader.load()
390+
docs = loader.load() # noqa
391391

392392
def test_loader_custom_json_metadata(self, client):
393393
database = client.instance(instance_id).database(google_database)
@@ -792,7 +792,7 @@ def test_loader_custom_content_key_error(self, client):
792792
client=client,
793793
content_columns=["NOT_A_COLUMN"],
794794
)
795-
docs = loader.load()
795+
docs = loader.load() # noqa
796796

797797
def test_loader_custom_metadata_key_error(self, client):
798798
query = f"SELECT * FROM {table_name}"
@@ -804,7 +804,7 @@ def test_loader_custom_metadata_key_error(self, client):
804804
client=client,
805805
metadata_columns=["NOT_A_COLUMN"],
806806
)
807-
docs = loader.load()
807+
docs = loader.load() # noqa
808808

809809
def test_loader_custom_json_metadata(self, client):
810810
database = client.instance(instance_id).database(pg_database)

tests/integration/test_spanner_vector_store.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ def test_spanner_vector_delete_data(self, setup_database):
301301

302302
deleted = db.delete(documents=[docs[0], docs[1]])
303303

304-
assert deleted == True
304+
assert deleted
305305

306306
def test_spanner_vector_search_data1(self, setup_database):
307307
loader, embeddings = setup_database
@@ -483,7 +483,7 @@ def test_spanner_vector_delete_data(self, setup_database):
483483

484484
deleted = db.delete(documents=[docs[0], docs[1]])
485485

486-
assert deleted == True
486+
assert deleted
487487

488488
def test_spanner_vector_search_data1(self, setup_database):
489489
loader, embeddings = setup_database

0 commit comments

Comments
 (0)