Files
langchain/libs/core/scripts/check_version.py
Mason Daugherty 4108c0738c release(core): 1.4.7 (#38111)
Bumps `langchain-core` to `1.4.7` for the next patch release and updates
downstream minimum `langchain-core` requirements so package locks
resolve against the new core version.

This also refreshes the runnable snapshots that embed `lc_versions`
metadata so the version consistency check continues to validate
checked-in artifacts.

Validated with `python libs/core/scripts/check_version.py`, `uv lock
--check` across package lockfiles, and the core runnable tests that own
the updated snapshots with local LangSmith tracing env disabled.
2026-06-12 14:54:25 -04:00

104 lines
3.9 KiB
Python

"""Check version consistency between package metadata and generated artifacts.
This script validates that the version defined in pyproject.toml matches the `VERSION`
variable in `langchain_core/version.py`. It also checks checked-in snapshots that embed
`langchain-core` version metadata. Intended for use as a pre-commit hook to prevent
version mismatches.
"""
import re
import sys
from pathlib import Path
# Matches the `langchain-core` version embedded in serialized model metadata,
# e.g. `{'versions': {'langchain-core': '1.4.7'}}`. Intentionally broad: every such
# occurrence in a snapshot is expected to track the released version.
SNAPSHOT_VERSION_PATTERN = re.compile(r"langchain-core': '([^']+)'")
def get_pyproject_version(pyproject_path: Path) -> str | None:
"""Extract version from `pyproject.toml`."""
content = pyproject_path.read_text(encoding="utf-8")
match = re.search(r'^version\s*=\s*"([^"]+)"', content, re.MULTILINE)
return match.group(1) if match else None
def get_version_py_version(version_path: Path) -> str | None:
"""Extract `VERSION` from `version.py`."""
content = version_path.read_text(encoding="utf-8")
match = re.search(r'^VERSION\s*=\s*"([^"]+)"', content, re.MULTILINE)
return match.group(1) if match else None
def get_snapshot_version_mismatches(
snapshots_dir: Path, expected_version: str
) -> list[tuple[Path, int, str]]:
"""Find snapshot `langchain-core` version metadata that is out of date."""
mismatches = []
for snapshot_path in sorted(snapshots_dir.rglob("*.ambr")):
# `errors="replace"` keeps a stray non-UTF-8 file from crashing the hook;
# the version strings we match are ASCII, so decoding is unaffected.
content = snapshot_path.read_text(encoding="utf-8", errors="replace")
for match in SNAPSHOT_VERSION_PATTERN.finditer(content):
version = match.group(1)
if version == expected_version:
continue
line_number = content.count("\n", 0, match.start()) + 1
mismatches.append((snapshot_path, line_number, version))
return mismatches
def main() -> int:
"""Validate version consistency."""
script_dir = Path(__file__).parent
package_dir = script_dir.parent
pyproject_path = package_dir / "pyproject.toml"
version_path = package_dir / "langchain_core" / "version.py"
# Scoped to this package's snapshots: only core's own `tests/` tree embeds
# `langchain-core` version metadata today.
snapshots_dir = package_dir / "tests"
if not pyproject_path.exists():
print(f"Error: {pyproject_path} not found")
return 1
if not version_path.exists():
print(f"Error: {version_path} not found")
return 1
pyproject_version = get_pyproject_version(pyproject_path)
version_py_version = get_version_py_version(version_path)
if pyproject_version is None:
print("Error: Could not find version in pyproject.toml")
return 1
if version_py_version is None:
print("Error: Could not find VERSION in langchain_core/version.py")
return 1
if pyproject_version != version_py_version:
print("Error: Version mismatch detected!")
print(f" pyproject.toml: {pyproject_version}")
print(f" langchain_core/version.py: {version_py_version}")
return 1
snapshot_mismatches = get_snapshot_version_mismatches(
snapshots_dir, pyproject_version
)
if snapshot_mismatches:
print("Error: Snapshot version mismatch detected!")
print(f" expected langchain-core version: {pyproject_version}")
for snapshot_path, line_number, snapshot_version in snapshot_mismatches:
relative_path = snapshot_path.relative_to(package_dir)
print(f" {relative_path}:{line_number}: {snapshot_version}")
return 1
print(f"Version check passed: {pyproject_version}")
return 0
if __name__ == "__main__":
sys.exit(main())