Skip to content

Commit ee4c251

Browse files
authored
feat: port various nit changes from wip-v0.4 (#32506)
Lots of work that wasn't directly related to core improvements/messages/testing functionality
1 parent 7db9e60 commit ee4c251

File tree

63 files changed

+2238
-2887
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+2238
-2887
lines changed

.github/workflows/api_doc_build.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ jobs:
5252
run: |
5353
# Get unique repositories
5454
REPOS=$(echo "$REPOS_UNSORTED" | sort -u)
55-
5655
# Checkout each unique repository
5756
for repo in $REPOS; do
5857
# Validate repository format (allow any org with proper format)
@@ -68,7 +67,6 @@ jobs:
6867
echo "Error: Invalid repository name: $REPO_NAME"
6968
exit 1
7069
fi
71-
7270
echo "Checking out $repo to $REPO_NAME"
7371
git clone --depth 1 https://github.com/$repo.git $REPO_NAME
7472
done

.github/workflows/check_diffs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ jobs:
3030
build:
3131
name: 'Detect Changes & Set Matrix'
3232
runs-on: ubuntu-latest
33+
if: ${{ !contains(github.event.pull_request.labels.*.name, 'ci-ignore') }}
3334
steps:
3435
- name: '📋 Checkout Code'
3536
uses: actions/checkout@v4

.github/workflows/codspeed.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ jobs:
2020
codspeed:
2121
name: 'Benchmark'
2222
runs-on: ubuntu-latest
23+
if: ${{ !contains(github.event.pull_request.labels.*.name, 'codspeed-ignore') }}
2324
strategy:
2425
matrix:
2526
include:

.vscode/settings.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"[python]": {
2222
"editor.formatOnSave": true,
2323
"editor.codeActionsOnSave": {
24-
"source.organizeImports": "explicit",
24+
"source.organizeImports.ruff": "explicit",
2525
"source.fixAll": "explicit"
2626
},
2727
"editor.defaultFormatter": "charliermarsh.ruff"
@@ -77,4 +77,6 @@
7777
"editor.tabSize": 2,
7878
"editor.insertSpaces": true
7979
},
80+
"python.terminal.activateEnvironment": false,
81+
"python.defaultInterpreterPath": "./.venv/bin/python"
8082
}

docs/api_reference/create_api_rst.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ def _load_module_members(module_path: str, namespace: str) -> ModuleMembers:
9797
if type(type_) is typing_extensions._TypedDictMeta: # type: ignore
9898
kind: ClassKind = "TypedDict"
9999
elif type(type_) is typing._TypedDictMeta: # type: ignore
100-
kind: ClassKind = "TypedDict"
100+
kind = "TypedDict"
101101
elif (
102102
issubclass(type_, Runnable)
103103
and issubclass(type_, BaseModel)
@@ -189,7 +189,7 @@ def _load_package_modules(
189189
if isinstance(package_directory, str)
190190
else package_directory
191191
)
192-
modules_by_namespace = {}
192+
modules_by_namespace: Dict[str, ModuleMembers] = {}
193193

194194
# Get the high level package name
195195
package_name = package_path.name
@@ -283,7 +283,7 @@ def _construct_doc(
283283
.. toctree::
284284
:hidden:
285285
:maxdepth: 2
286-
286+
287287
"""
288288
index_autosummary = """
289289
"""
@@ -365,9 +365,9 @@ def _construct_doc(
365365

366366
module_doc += f"""\
367367
:template: {template}
368-
368+
369369
{class_["qualified_name"]}
370-
370+
371371
"""
372372
index_autosummary += f"""
373373
{class_["qualified_name"]}
@@ -550,8 +550,8 @@ def _build_index(dirs: List[str]) -> None:
550550
integrations = sorted(dir_ for dir_ in dirs if dir_ not in main_)
551551
doc = """# LangChain Python API Reference
552552
553-
Welcome to the LangChain Python API reference. This is a reference for all
554-
`langchain-x` packages.
553+
Welcome to the LangChain Python API reference. This is a reference for all
554+
`langchain-x` packages.
555555
556556
For user guides see [https://python.langchain.com](https://python.langchain.com).
557557

docs/docs/contributing/how_to/testing.mdx

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,47 @@ start "" htmlcov/index.html || open htmlcov/index.html
124124

125125
```
126126

127+
## Snapshot Testing
128+
129+
Some tests use [syrupy](https://github.com/tophat/syrupy) for snapshot testing, which captures the output of functions and compares them to stored snapshots. This is particularly useful for testing JSON schema generation and other structured outputs.
130+
131+
### Updating Snapshots
132+
133+
To update snapshots when the expected output has legitimately changed:
134+
135+
```bash
136+
uv run --group test pytest path/to/test.py --snapshot-update
137+
```
138+
139+
### Pydantic Version Compatibility Issues
140+
141+
Pydantic generates different JSON schemas across versions, which can cause snapshot test failures in CI when tests run with different Pydantic versions than what was used to generate the snapshots.
142+
143+
**Symptoms:**
144+
- CI fails with snapshot mismatches showing differences like missing or extra fields.
145+
- Tests pass locally but fail in CI with different Pydantic versions
146+
147+
**Solution:**
148+
Locally update snapshots using the same Pydantic version that CI uses:
149+
150+
1. **Identify the failing Pydantic version** from CI logs (e.g., `2.7.0`, `2.8.0`, `2.9.0`)
151+
152+
2. **Update snapshots with that version:**
153+
```bash
154+
uv run --with "pydantic==2.9.0" --group test pytest tests/unit_tests/path/to/test.py::test_name --snapshot-update
155+
```
156+
157+
3. **Verify compatibility across supported versions:**
158+
```bash
159+
# Test with the version you used to update
160+
uv run --with "pydantic==2.9.0" --group test pytest tests/unit_tests/path/to/test.py::test_name
161+
162+
# Test with other supported versions
163+
uv run --with "pydantic==2.8.0" --group test pytest tests/unit_tests/path/to/test.py::test_name
164+
```
165+
166+
**Note:** Some tests use `@pytest.mark.skipif` decorators to only run with specific Pydantic version ranges (e.g., `PYDANTIC_VERSION_AT_LEAST_210`). Make sure to understand these constraints when updating snapshots.
167+
127168
## Coverage
128169

129170
Code coverage (i.e. the amount of code that is covered by unit tests) helps identify areas of the code that are potentially more or less brittle.

libs/core/langchain_core/_api/beta_decorator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ def warn_if_direct_instance(
144144
obj.__init__ = functools.wraps(obj.__init__)( # type: ignore[misc]
145145
warn_if_direct_instance
146146
)
147-
return cast("T", obj)
147+
return obj
148148

149149
elif isinstance(obj, property):
150150
if not _obj_type:

libs/core/langchain_core/_api/deprecation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ def warn_if_direct_instance(
225225
obj.__init__ = functools.wraps(obj.__init__)( # type: ignore[misc]
226226
warn_if_direct_instance
227227
)
228-
return cast("T", obj)
228+
return obj
229229

230230
elif isinstance(obj, FieldInfoV1):
231231
wrapped = None

libs/core/langchain_core/messages/modifier.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class RemoveMessage(BaseMessage):
1313

1414
def __init__(
1515
self,
16-
id: str, # noqa: A002
16+
id: str,
1717
**kwargs: Any,
1818
) -> None:
1919
"""Create a RemoveMessage.

libs/core/langchain_core/messages/tool.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ def tool_call(
212212
*,
213213
name: str,
214214
args: dict[str, Any],
215-
id: Optional[str], # noqa: A002
215+
id: Optional[str],
216216
) -> ToolCall:
217217
"""Create a tool call.
218218
@@ -260,7 +260,7 @@ def tool_call_chunk(
260260
*,
261261
name: Optional[str] = None,
262262
args: Optional[str] = None,
263-
id: Optional[str] = None, # noqa: A002
263+
id: Optional[str] = None,
264264
index: Optional[int] = None,
265265
) -> ToolCallChunk:
266266
"""Create a tool call chunk.
@@ -298,7 +298,7 @@ def invalid_tool_call(
298298
*,
299299
name: Optional[str] = None,
300300
args: Optional[str] = None,
301-
id: Optional[str] = None, # noqa: A002
301+
id: Optional[str] = None,
302302
error: Optional[str] = None,
303303
) -> InvalidToolCall:
304304
"""Create an invalid tool call.

0 commit comments

Comments
 (0)