-
Notifications
You must be signed in to change notification settings - Fork 20.5k
fix(langchain): activate mypy warn-unreachable #34553
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -417,18 +417,15 @@ def _handle_structured_output_error( | |
| return True, STRUCTURED_OUTPUT_ERROR_TEMPLATE.format(error=str(exception)) | ||
| if isinstance(handle_errors, str): | ||
| return True, handle_errors | ||
| if isinstance(handle_errors, type) and issubclass(handle_errors, Exception): | ||
| if isinstance(exception, handle_errors): | ||
| if isinstance(handle_errors, type): | ||
| if issubclass(handle_errors, Exception) and isinstance(exception, handle_errors): | ||
| return True, STRUCTURED_OUTPUT_ERROR_TEMPLATE.format(error=str(exception)) | ||
| return False, "" | ||
| if isinstance(handle_errors, tuple): | ||
| if any(isinstance(exception, exc_type) for exc_type in handle_errors): | ||
| return True, STRUCTURED_OUTPUT_ERROR_TEMPLATE.format(error=str(exception)) | ||
| return False, "" | ||
| if callable(handle_errors): | ||
| # type narrowing not working appropriately w/ callable check, can fix later | ||
| return True, handle_errors(exception) # type: ignore[return-value,call-arg] | ||
| return False, "" | ||
| return True, handle_errors(exception) | ||
|
|
||
|
|
||
| def _chain_tool_call_wrappers( | ||
|
|
@@ -547,7 +544,7 @@ def create_agent( | |
| *, | ||
| system_prompt: str | SystemMessage | None = None, | ||
| middleware: Sequence[AgentMiddleware[StateT_co, ContextT]] = (), | ||
| response_format: ResponseFormat[ResponseT] | type[ResponseT] | None = None, | ||
| response_format: ResponseFormat[ResponseT] | type[ResponseT] | dict[str, Any] | None = None, | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. According to |
||
| state_schema: type[AgentState[ResponseT]] | None = None, | ||
| context_schema: type[ContextT] | None = None, | ||
| checkpointer: Checkpointer | None = None, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,8 +15,10 @@ | |
|
|
||
| try: # pragma: no cover - optional dependency on POSIX platforms | ||
| import resource | ||
|
|
||
| _HAS_RESOURCE = True | ||
| except ImportError: # pragma: no cover - non-POSIX systems | ||
| resource = None # type: ignore[assignment] | ||
| _HAS_RESOURCE = False | ||
|
|
||
|
|
||
| SHELL_TEMP_PREFIX = "langchain-shell-" | ||
|
|
@@ -119,7 +121,7 @@ def __post_init__(self) -> None: | |
| self._limits_requested = any( | ||
| value is not None for value in (self.cpu_time_seconds, self.memory_bytes) | ||
| ) | ||
| if self._limits_requested and resource is None: | ||
| if self._limits_requested and not _HAS_RESOURCE: | ||
| msg = ( | ||
| "HostExecutionPolicy cpu/memory limits require the Python 'resource' module. " | ||
| "Either remove the limits or run on a POSIX platform." | ||
|
|
@@ -163,11 +165,9 @@ def _configure() -> None: # pragma: no cover - depends on OS | |
| def _apply_post_spawn_limits(self, process: subprocess.Popen[str]) -> None: | ||
| if not self._limits_requested or not self._can_use_prlimit(): | ||
| return | ||
| if resource is None: # pragma: no cover - defensive | ||
| if not _HAS_RESOURCE: # pragma: no cover - defensive | ||
| return | ||
| pid = process.pid | ||
| if pid is None: | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| return | ||
| try: | ||
| prlimit = typing.cast("typing.Any", resource).prlimit | ||
| if self.cpu_time_seconds is not None: | ||
|
|
@@ -184,11 +184,7 @@ def _apply_post_spawn_limits(self, process: subprocess.Popen[str]) -> None: | |
|
|
||
| @staticmethod | ||
| def _can_use_prlimit() -> bool: | ||
| return ( | ||
| resource is not None | ||
| and hasattr(resource, "prlimit") | ||
| and sys.platform.startswith("linux") | ||
| ) | ||
| return _HAS_RESOURCE and hasattr(resource, "prlimit") and sys.platform.startswith("linux") | ||
|
|
||
|
|
||
| @dataclass | ||
|
|
@@ -251,9 +247,9 @@ def _determine_platform(self) -> str: | |
| return self.platform | ||
| if sys.platform.startswith("linux"): | ||
| return "linux" | ||
| if sys.platform == "darwin": | ||
| if sys.platform == "darwin": # type: ignore[unreachable, unused-ignore] | ||
| return "macos" | ||
| msg = ( | ||
| msg = ( # type: ignore[unreachable, unused-ignore] | ||
| "Codex sandbox policy could not determine a supported platform; " | ||
| "set 'platform' explicitly." | ||
| ) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -106,7 +106,7 @@ def _parse_with_schema( | |
| class _SchemaSpec(Generic[SchemaT]): | ||
| """Describes a structured output schema.""" | ||
|
|
||
| schema: type[SchemaT] | ||
| schema: type[SchemaT] | dict[str, Any] | ||
| """The schema for the response, can be a Pydantic model, `dataclass`, `TypedDict`, | ||
| or JSON schema dict.""" | ||
|
|
||
|
|
@@ -134,7 +134,7 @@ class _SchemaSpec(Generic[SchemaT]): | |
|
|
||
| def __init__( | ||
| self, | ||
| schema: type[SchemaT], | ||
| schema: type[SchemaT] | dict[str, Any], | ||
| *, | ||
| name: str | None = None, | ||
| description: str | None = None, | ||
|
|
@@ -257,15 +257,15 @@ def _iter_variants(schema: Any) -> Iterable[Any]: | |
| class ProviderStrategy(Generic[SchemaT]): | ||
| """Use the model provider's native structured output method.""" | ||
|
|
||
| schema: type[SchemaT] | ||
| schema: type[SchemaT] | dict[str, Any] | ||
| """Schema for native mode.""" | ||
|
|
||
| schema_spec: _SchemaSpec[SchemaT] | ||
| """Schema spec for native mode.""" | ||
|
|
||
| def __init__( | ||
| self, | ||
| schema: type[SchemaT], | ||
| schema: type[SchemaT] | dict[str, Any], | ||
| *, | ||
| strict: bool | None = None, | ||
| ) -> None: | ||
|
|
@@ -309,7 +309,7 @@ class OutputToolBinding(Generic[SchemaT]): | |
| and the corresponding tool implementation used by the tools strategy. | ||
| """ | ||
|
|
||
| schema: type[SchemaT] | ||
| schema: type[SchemaT] | dict[str, Any] | ||
| """The original schema provided for structured output | ||
| (Pydantic model, dataclass, TypedDict, or JSON schema dict).""" | ||
|
|
||
|
|
@@ -363,7 +363,7 @@ class ProviderStrategyBinding(Generic[SchemaT]): | |
| its type classification, and parsing logic for provider-enforced JSON. | ||
| """ | ||
|
|
||
| schema: type[SchemaT] | ||
| schema: type[SchemaT] | dict[str, Any] | ||
| """The original schema provided for structured output | ||
| (Pydantic model, `dataclass`, `TypedDict`, or JSON schema dict).""" | ||
|
|
||
|
|
@@ -426,29 +426,27 @@ def _extract_text_content_from_message(message: AIMessage) -> str: | |
| content = message.content | ||
| if isinstance(content, str): | ||
| return content | ||
| if isinstance(content, list): | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. BaseMessage.content is either a str or a list. |
||
| parts: list[str] = [] | ||
| for c in content: | ||
| if isinstance(c, dict): | ||
| if c.get("type") == "text" and "text" in c: | ||
| parts.append(str(c["text"])) | ||
| elif "content" in c and isinstance(c["content"], str): | ||
| parts.append(c["content"]) | ||
| else: | ||
| parts.append(str(c)) | ||
| return "".join(parts) | ||
| return str(content) | ||
| parts: list[str] = [] | ||
| for c in content: | ||
| if isinstance(c, dict): | ||
| if c.get("type") == "text" and "text" in c: | ||
| parts.append(str(c["text"])) | ||
| elif "content" in c and isinstance(c["content"], str): | ||
| parts.append(c["content"]) | ||
| else: | ||
| parts.append(str(c)) | ||
| return "".join(parts) | ||
|
|
||
|
|
||
| class AutoStrategy(Generic[SchemaT]): | ||
| """Automatically select the best strategy for structured output.""" | ||
|
|
||
| schema: type[SchemaT] | ||
| schema: type[SchemaT] | dict[str, Any] | ||
| """Schema for automatic mode.""" | ||
|
|
||
| def __init__( | ||
| self, | ||
| schema: type[SchemaT], | ||
| schema: type[SchemaT] | dict[str, Any], | ||
| ) -> None: | ||
| """Initialize AutoStrategy with schema.""" | ||
| self.schema = schema | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
type narrowing now works because
handle_errorscannot be atypeanymore at this stage.Note that
typeiscallable.