Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

experimental: migrate to uv #37

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
28 changes: 28 additions & 0 deletions .github/actions/uv_setup/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# TODO: https://docs.astral.sh/uv/guides/integration/github/#caching

name: uv-install
description: Set up Python and uv

inputs:
python-version:
description: Python version, supporting MAJOR.MINOR only
required: true

env:
UV_VERSION: "0.5.25"

runs:
using: composite
steps:
- uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v5
with:
version: ${{ env.UV_VERSION }}

- uses: actions/setup-python@v5
name: Setup python ${{ inputs.python-version }}
id: setup-python
with:
python-version: ${{ inputs.python-version }}
18 changes: 6 additions & 12 deletions .github/workflows/_compile_integration_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ on:
type: string
description: "From which folder this pipeline executes"

env:
POETRY_VERSION: "1.7.1"

jobs:
build:
defaults:
Expand All @@ -20,29 +17,26 @@ jobs:
strategy:
matrix:
python-version:
- "3.8"
- "3.9"
- "3.10"
- "3.11"
name: "poetry run pytest -m compile tests/integration_tests #${{ matrix.python-version }}"
- "3.12"
name: "uv run pytest -m compile tests/integration_tests #${{ matrix.python-version }}"
steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }} + Poetry ${{ env.POETRY_VERSION }}
uses: "./.github/actions/poetry_setup"
- name: Set up Python ${{ matrix.python-version }} + uv
uses: "./.github/actions/uv_setup"
with:
python-version: ${{ matrix.python-version }}
poetry-version: ${{ env.POETRY_VERSION }}
working-directory: ${{ inputs.working-directory }}
cache-key: compile-integration

- name: Install integration dependencies
shell: bash
run: poetry install --with=test_integration,test
run: uv sync --group test --group test_integration

- name: Check integration tests compile
shell: bash
run: poetry run pytest -m compile tests/integration_tests
run: uv run pytest -m compile tests/integration_tests

- name: Ensure the tests did not create any additional files
shell: bash
Expand Down
47 changes: 6 additions & 41 deletions .github/workflows/_lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ on:
description: "From which folder this pipeline executes"

env:
POETRY_VERSION: "1.7.1"
WORKDIR: ${{ inputs.working-directory == '' && '.' || inputs.working-directory }}

# This env var allows us to get inline annotations when ruff has complaints.
Expand All @@ -29,30 +28,15 @@ jobs:
# Starting new jobs is also relatively slow,
# so linting on fewer versions makes CI faster.
python-version:
- "3.8"
- "3.11"
- "3.9"
- "3.12"
steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }} + Poetry ${{ env.POETRY_VERSION }}
uses: "./.github/actions/poetry_setup"
- name: Set up Python ${{ matrix.python-version }} + uv
uses: "./.github/actions/uv_setup"
with:
python-version: ${{ matrix.python-version }}
poetry-version: ${{ env.POETRY_VERSION }}
working-directory: ${{ inputs.working-directory }}
cache-key: lint-with-extras

- name: Check Poetry File
shell: bash
working-directory: ${{ inputs.working-directory }}
run: |
poetry check

- name: Check lock file
shell: bash
working-directory: ${{ inputs.working-directory }}
run: |
poetry lock --check

- name: Install dependencies
# Also installs dev/lint/test/typing dependencies, to ensure we have
Expand All @@ -65,17 +49,7 @@ jobs:
# It doesn't matter how you change it, any change will cause a cache-bust.
working-directory: ${{ inputs.working-directory }}
run: |
poetry install --with lint,typing

- name: Get .mypy_cache to speed up mypy
uses: actions/cache@v4
env:
SEGMENT_DOWNLOAD_TIMEOUT_MIN: "2"
with:
path: |
${{ env.WORKDIR }}/.mypy_cache
key: mypy-lint-${{ runner.os }}-${{ runner.arch }}-py${{ matrix.python-version }}-${{ inputs.working-directory }}-${{ hashFiles(format('{0}/poetry.lock', inputs.working-directory)) }}

uv sync --group lint --group typing

- name: Analysing the code with our lint
working-directory: ${{ inputs.working-directory }}
Expand All @@ -85,16 +59,7 @@ jobs:
- name: Install unit+integration test dependencies
working-directory: ${{ inputs.working-directory }}
run: |
poetry install --with test,test_integration

- name: Get .mypy_cache_test to speed up mypy
uses: actions/cache@v4
env:
SEGMENT_DOWNLOAD_TIMEOUT_MIN: "2"
with:
path: |
${{ env.WORKDIR }}/.mypy_cache_test
key: mypy-test-${{ runner.os }}-${{ runner.arch }}-py${{ matrix.python-version }}-${{ inputs.working-directory }}-${{ hashFiles(format('{0}/poetry.lock', inputs.working-directory)) }}
uv sync --group test --group test_integration

- name: Analysing the code with our lint
working-directory: ${{ inputs.working-directory }}
Expand Down
14 changes: 4 additions & 10 deletions .github/workflows/_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ on:
type: string
description: "From which folder this pipeline executes"

env:
POETRY_VERSION: "1.7.1"

jobs:
build:
defaults:
Expand All @@ -20,25 +17,22 @@ jobs:
strategy:
matrix:
python-version:
- "3.8"
- "3.9"
- "3.10"
- "3.11"
- "3.12"
name: "make test #${{ matrix.python-version }}"
steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }} + Poetry ${{ env.POETRY_VERSION }}
uses: "./.github/actions/poetry_setup"
- name: Set up Python ${{ matrix.python-version }} + uv
uses: "./.github/actions/uv_setup"
with:
python-version: ${{ matrix.python-version }}
poetry-version: ${{ env.POETRY_VERSION }}
working-directory: ${{ inputs.working-directory }}
cache-key: core

- name: Install dependencies
shell: bash
run: poetry install --with test
run: uv sync --all-extras --dev

- name: Run core tests
shell: bash
Expand Down
3 changes: 0 additions & 3 deletions .github/workflows/check_diffs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
POETRY_VERSION: "1.7.1"

jobs:
build:
runs-on: ubuntu-latest
Expand Down
26 changes: 13 additions & 13 deletions libs/experimental/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,22 @@ all: help
TEST_FILE ?= tests/unit_tests/

test:
poetry run pytest $(TEST_FILE)
uv run --group test pytest $(TEST_FILE)

tests:
poetry run pytest $(TEST_FILE)
uv run -- group test pytest $(TEST_FILE)

test_watch:
poetry run ptw --now . -- tests/unit_tests
uv run --group test ptw --now . -- tests/unit_tests

extended_tests:
poetry run pytest --only-extended tests/unit_tests
uv run --group test pytest --only-extended tests/unit_tests

integration_tests:
poetry run pytest tests/integration_tests
uv run --group test_integration pytest tests/integration_tests

check_imports: $(shell find langchain_experimental -name '*.py')
poetry run python ./scripts/check_imports.py $^
uv run python ./scripts/check_imports.py $^


######################
Expand All @@ -39,19 +39,19 @@ lint_tests: PYTHON_FILES=tests
lint_tests: MYPY_CACHE=.mypy_cache_test

lint lint_diff lint_package lint_tests:
[ "$(PYTHON_FILES)" = "" ] || poetry run ruff check $(PYTHON_FILES)
[ "$(PYTHON_FILES)" = "" ] || poetry run ruff format $(PYTHON_FILES) --diff
[ "$(PYTHON_FILES)" = "" ] || mkdir -p $(MYPY_CACHE) && poetry run mypy $(PYTHON_FILES) --cache-dir $(MYPY_CACHE)
[ "$(PYTHON_FILES)" = "" ] || uv run --all-groups ruff check $(PYTHON_FILES)
[ "$(PYTHON_FILES)" = "" ] || uv run --all-groups ruff format $(PYTHON_FILES) --diff
[ "$(PYTHON_FILES)" = "" ] || mkdir -p $(MYPY_CACHE) && uv run --all-groups mypy $(PYTHON_FILES) --cache-dir $(MYPY_CACHE)

format format_diff:
[ "$(PYTHON_FILES)" = "" ] || poetry run ruff format $(PYTHON_FILES)
[ "$(PYTHON_FILES)" = "" ] || poetry run ruff check --select I --fix $(PYTHON_FILES)
[ "$(PYTHON_FILES)" = "" ] || uv run --all-groups ruff format $(PYTHON_FILES)
[ "$(PYTHON_FILES)" = "" ] || uv run --all-groups ruff check --select I --fix $(PYTHON_FILES)

spell_check:
poetry run codespell --toml pyproject.toml
uv run --all-groups codespell --toml pyproject.toml

spell_fix:
poetry run codespell --toml pyproject.toml -w
uv run --all-groups codespell --toml pyproject.toml -w

######################
# HELP
Expand Down
7 changes: 4 additions & 3 deletions libs/experimental/langchain_experimental/cpal/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from __future__ import annotations

import json
from typing import Any, ClassVar, Dict, List, Optional, Type
from typing import Any, ClassVar, Dict, List, Optional, Type, cast

import pydantic
from langchain.base_language import BaseLanguageModel
Expand Down Expand Up @@ -165,7 +165,8 @@ class CPALChain(_BaseStoryElementChain):
causal_chain: Optional[CausalChain] = None
intervention_chain: Optional[InterventionChain] = None
query_chain: Optional[QueryChain] = None
_story: StoryModel = pydantic.PrivateAttr(default=None) # TODO: change name ?
# TODO: change name of _story?
_story: Optional[StoryModel] = pydantic.PrivateAttr(default=None)

@classmethod
def from_univariate_prompt(
Expand Down Expand Up @@ -300,4 +301,4 @@ def draw(self, **kwargs: Any) -> None:
>>> cpal_chain.draw(path="graph.svg")
>>> SVG('graph.svg')
"""
self._story._networkx_wrapper.draw_graphviz(**kwargs)
cast(StoryModel, self._story)._networkx_wrapper.draw_graphviz(**kwargs)
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ def optional_enum_field(
enum=parsed_enum_values, # type: ignore[call-arg]
description=f"{description}. Available options are {parsed_enum_values}",
**field_kwargs,
)
) # type: ignore[call-overload]
elif enum_values:
return Field(
...,
Expand Down
4 changes: 2 additions & 2 deletions libs/experimental/langchain_experimental/tools/python/tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ class PythonAstREPLTool(BaseTool):
"When using this tool, sometimes output is abbreviated - "
"make sure it does not look abbreviated before using it in your answer."
)
globals: Optional[Dict] = Field(default_factory=dict)
locals: Optional[Dict] = Field(default_factory=dict)
globals: Optional[Dict] = Field(default_factory=dict) # type: ignore[arg-type]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These come from updating Pydantic to 2.10 in CI. There were some breaking changes associated with that version (see updates in other langchain packages here). Issue here is unclear to me + we appear to test the python repl tool.

error: Argument "default_factory" to "Field" has incompatible type "type[dict[Any, Any]]"; expected "Callable[[], Never] | Callable[[dict[str, Any]], Never]" [arg-type]

locals: Optional[Dict] = Field(default_factory=dict) # type: ignore[arg-type]
sanitize_input: bool = True
args_schema: Type[BaseModel] = PythonInputs

Expand Down
4 changes: 2 additions & 2 deletions libs/experimental/langchain_experimental/utilities/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ def warn_once() -> None:
class PythonREPL(BaseModel):
"""Simulates a standalone Python REPL."""

globals: Optional[Dict] = Field(default_factory=dict, alias="_globals")
locals: Optional[Dict] = Field(default_factory=dict, alias="_locals")
globals: Optional[Dict] = Field(default_factory=dict, alias="_globals") # type: ignore[arg-type]
locals: Optional[Dict] = Field(default_factory=dict, alias="_locals") # type: ignore[arg-type]

@staticmethod
def sanitize_input(query: str) -> str:
Expand Down
Loading