Files
langchain/libs/core/tests/unit_tests
Christophe Bornet 62f255980d chore(core): add mypy warn_unreachable (#38109)
Enables mypy's `warn_unreachable` rule for `langchain-core`, bringing it
in line with the other strict libraries in the monorepo. Previously this
rule was intentionally disabled by a code comment, because under mypy
2.x it false-flags intentional defensive runtime checks — most notably
the SSRF / IP-policy guards in `langchain_core/_security/` — as
unreachable.

This PR resolves all of those warnings without deleting or
blanket-ignoring the defensive guards, so contributors get
unreachable-code coverage going forward and accidental dead code is
caught in CI.

The bulk of the change is mechanical: a targeted `# type:
ignore[unreachable]` on each defensive `else`/error branch that mypy
considers unreachable but that we deliberately keep as a runtime guard
against unexpected input. A few changes are more substantive and worth a
closer look:

- **`coro_with_context` (`runnables/utils.py`) — behavior change on
Python < 3.11.** The pre-3.11 path is rewritten to always route through
`context.run(asyncio.create_task, coro)`, so the supplied context is
reliably propagated to the task. Previously, on 3.10 the helper returned
the bare coroutine (run in the caller's context) when
`create_task=False`, and dropped the context entirely when
`create_task=True`. The new behavior matches 3.11+. The `create_task`
parameter is now inert but retained for signature compatibility. All
callers `await` the result, so returning a `Task` rather than a
coroutine is transparent.
- **`_create_template_from_message_type` (`prompts/chat.py`) — signature
widening.** This private helper's `template` parameter now accepts
`bool` inside the list, accurately reflecting the existing `["{var}",
is_optional]` placeholder form. No public-API impact.
- **`PydanticOutputFunctionsParser`
(`output_parsers/openai_functions.py`).** The `pydantic_schema` field is
typed as `TypeBaseModel` (which covers both v1 and v2 model classes,
unlike the prior annotation), and the `args_only` parse path now
dispatches explicitly on `BaseModel` vs `BaseModelV1` rather than
duck-typing via `hasattr`. This also yields clearer errors for
unsupported / dict schemas.
- **`_security/_policy.py`.** Loop variables are renamed so mypy can
narrow their types, which lets the old `# type: ignore[assignment]`
comments be dropped. The IP-blocklist logic is unchanged.

---------

Co-authored-by: Mason Daugherty <mason@langchain.dev>
Co-authored-by: Mason Daugherty <github@mdrxy.com>
2026-06-14 17:05:48 -04:00
..
2025-10-02 18:46:26 -04:00