From 1b5721c999c9fc310cefec383666f43c80ec9620 Mon Sep 17 00:00:00 2001 From: Zander Chase <130414180+vowelparrot@users.noreply.github.com> Date: Thu, 27 Apr 2023 11:39:01 -0700 Subject: [PATCH] Remove Pexpect Dependency (#3667) Resolves #3664 Next PR will be to clean up CI to catch this earlier. Triaging this, it looks like it wasn't caught because pexpect is a `poetry` dependency. --------- Co-authored-by: Eugene Yurtsev --- langchain/utilities/bash.py | 26 ++++++++++++++++++++++++-- pyproject.toml | 3 ++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/langchain/utilities/bash.py b/langchain/utilities/bash.py index 2a37f1e7..8900d557 100644 --- a/langchain/utilities/bash.py +++ b/langchain/utilities/bash.py @@ -1,10 +1,29 @@ """Wrapper around subprocess to run commands.""" +from __future__ import annotations + +import platform import re import subprocess -from typing import List, Union +from typing import TYPE_CHECKING, List, Union from uuid import uuid4 -import pexpect +if TYPE_CHECKING: + import pexpect + + +def _lazy_import_pexpect() -> pexpect: + """Import pexpect only when needed.""" + if platform.system() == "Windows": + raise ValueError("Persistent bash processes are not yet supported on Windows.") + try: + import pexpect + + except ImportError: + raise ImportError( + "pexpect required for persistent bash processes." + " To install, run `pip install pexpect`." + ) + return pexpect class BashProcess: @@ -28,6 +47,8 @@ class BashProcess: @staticmethod def _initialize_persistent_process(prompt: str) -> pexpect.spawn: # Start bash in a clean environment + # Doesn't work on windows + pexpect = _lazy_import_pexpect() process = pexpect.spawn( "env", ["-i", "bash", "--norc", "--noprofile"], encoding="utf-8" ) @@ -75,6 +96,7 @@ class BashProcess: def _run_persistent(self, command: str) -> str: """Run commands and return final output.""" + pexpect = _lazy_import_pexpect() if self.process is None: raise ValueError("Process not initialized") self.process.sendline(command) diff --git a/pyproject.toml b/pyproject.toml index 52122aee..3e7a1067 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,6 +73,7 @@ duckduckgo-search = {version="^2.8.6", optional=true} azure-cosmos = {version="^4.4.0b1", optional=true} lark = {version="^1.1.5", optional=true} lancedb = {version = "^0.1", optional = true} +pexpect = {version = "^4.8.0", optional = true} [tool.poetry.group.docs.dependencies] autodoc_pydantic = "^1.8.0" @@ -150,7 +151,7 @@ openai = ["openai"] cohere = ["cohere"] embeddings = ["sentence-transformers"] azure = ["azure-identity", "azure-cosmos", "openai", "azure-core"] -all = ["anthropic", "cohere", "openai", "nlpcloud", "huggingface_hub", "jina", "manifest-ml", "elasticsearch", "opensearch-py", "google-search-results", "faiss-cpu", "sentence-transformers", "transformers", "spacy", "nltk", "wikipedia", "beautifulsoup4", "tiktoken", "torch", "jinja2", "pinecone-client", "pinecone-text", "weaviate-client", "redis", "google-api-python-client", "wolframalpha", "qdrant-client", "tensorflow-text", "pypdf", "networkx", "nomic", "aleph-alpha-client", "deeplake", "pgvector", "psycopg2-binary", "boto3", "pyowm", "pytesseract", "html2text", "atlassian-python-api", "gptcache", "duckduckgo-search", "arxiv", "azure-identity", "clickhouse-connect", "azure-cosmos", "lancedb", "lark"] +all = ["anthropic", "cohere", "openai", "nlpcloud", "huggingface_hub", "jina", "manifest-ml", "elasticsearch", "opensearch-py", "google-search-results", "faiss-cpu", "sentence-transformers", "transformers", "spacy", "nltk", "wikipedia", "beautifulsoup4", "tiktoken", "torch", "jinja2", "pinecone-client", "pinecone-text", "weaviate-client", "redis", "google-api-python-client", "wolframalpha", "qdrant-client", "tensorflow-text", "pypdf", "networkx", "nomic", "aleph-alpha-client", "deeplake", "pgvector", "psycopg2-binary", "boto3", "pyowm", "pytesseract", "html2text", "atlassian-python-api", "gptcache", "duckduckgo-search", "arxiv", "azure-identity", "clickhouse-connect", "azure-cosmos", "lancedb", "lark", "pexpect"] [tool.ruff] select = [