From 3276aa3e17c4053eeb4a5734e7641d76ea876412 Mon Sep 17 00:00:00 2001 From: Mark Bell Date: Thu, 2 Nov 2023 17:08:54 -0400 Subject: [PATCH] __getattr__ should rase AttributeError not ImportError on missing attributes (#12801) [The python spec](https://docs.python.org/3/reference/datamodel.html#object.__getattr__) requires that `__getattr__` throw `AttributeError` for missing attributes but there are several places throwing `ImportError` in the current code base. This causes a specific problem with `hasattr` since it calls `__getattr__` then looks only for `AttributeError` exceptions. At present, calling `hasattr` on any of these modules will raise an unexpected exception that most code will not handle as `hasattr` throwing exceptions is not expected. In our case this is triggered by an exception tracker (Airbrake) that attempts to collect the version of all installed modules with code that looks like: `if hasattr(mod, "__version__"):`. With `HEAD` this is causing our exception tracker to fail on all exceptions. I only changed instances of unknown attributes raising `ImportError` and left instances of known attributes raising `ImportError`. It feels a little weird but doesn't seem to break anything. --- libs/langchain/langchain/agents/__init__.py | 2 +- libs/langchain/langchain/agents/agent_toolkits/__init__.py | 2 +- libs/langchain/langchain/agents/agent_toolkits/csv/__init__.py | 2 +- .../langchain/agents/agent_toolkits/pandas/__init__.py | 2 +- .../langchain/agents/agent_toolkits/python/__init__.py | 2 +- .../langchain/langchain/agents/agent_toolkits/spark/__init__.py | 2 +- .../langchain/agents/agent_toolkits/xorbits/__init__.py | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libs/langchain/langchain/agents/__init__.py b/libs/langchain/langchain/agents/__init__.py index 44094bc97..b1329af30 100644 --- a/libs/langchain/langchain/agents/__init__.py +++ b/libs/langchain/langchain/agents/__init__.py @@ -90,7 +90,7 @@ def __getattr__(name: str) -> Any: "for more information.\n" f"Please update your import statement from: `{old_path}` to `{new_path}`." ) - raise ImportError(f"{name} does not exist") + raise AttributeError(f"{name} does not exist") __all__ = [ diff --git a/libs/langchain/langchain/agents/agent_toolkits/__init__.py b/libs/langchain/langchain/agents/agent_toolkits/__init__.py index 154ff2e2b..9008e5825 100644 --- a/libs/langchain/langchain/agents/agent_toolkits/__init__.py +++ b/libs/langchain/langchain/agents/agent_toolkits/__init__.py @@ -78,7 +78,7 @@ def __getattr__(name: str) -> Any: "for more information.\n" f"Please update your import statement from: `{old_path}` to `{new_path}`." ) - raise ImportError(f"{name} does not exist") + raise AttributeError(f"{name} does not exist") __all__ = [ diff --git a/libs/langchain/langchain/agents/agent_toolkits/csv/__init__.py b/libs/langchain/langchain/agents/agent_toolkits/csv/__init__.py index e01dffb97..7af077a8e 100644 --- a/libs/langchain/langchain/agents/agent_toolkits/csv/__init__.py +++ b/libs/langchain/langchain/agents/agent_toolkits/csv/__init__.py @@ -11,7 +11,7 @@ def __getattr__(name: str) -> Any: old_path = "langchain." + here + "." + name new_path = "langchain_experimental." + here + "." + name - raise ImportError( + raise AttributeError( "This agent has been moved to langchain experiment. " "This agent relies on python REPL tool under the hood, so to use it " "safely please sandbox the python REPL. " diff --git a/libs/langchain/langchain/agents/agent_toolkits/pandas/__init__.py b/libs/langchain/langchain/agents/agent_toolkits/pandas/__init__.py index e01dffb97..7af077a8e 100644 --- a/libs/langchain/langchain/agents/agent_toolkits/pandas/__init__.py +++ b/libs/langchain/langchain/agents/agent_toolkits/pandas/__init__.py @@ -11,7 +11,7 @@ def __getattr__(name: str) -> Any: old_path = "langchain." + here + "." + name new_path = "langchain_experimental." + here + "." + name - raise ImportError( + raise AttributeError( "This agent has been moved to langchain experiment. " "This agent relies on python REPL tool under the hood, so to use it " "safely please sandbox the python REPL. " diff --git a/libs/langchain/langchain/agents/agent_toolkits/python/__init__.py b/libs/langchain/langchain/agents/agent_toolkits/python/__init__.py index e01dffb97..7af077a8e 100644 --- a/libs/langchain/langchain/agents/agent_toolkits/python/__init__.py +++ b/libs/langchain/langchain/agents/agent_toolkits/python/__init__.py @@ -11,7 +11,7 @@ def __getattr__(name: str) -> Any: old_path = "langchain." + here + "." + name new_path = "langchain_experimental." + here + "." + name - raise ImportError( + raise AttributeError( "This agent has been moved to langchain experiment. " "This agent relies on python REPL tool under the hood, so to use it " "safely please sandbox the python REPL. " diff --git a/libs/langchain/langchain/agents/agent_toolkits/spark/__init__.py b/libs/langchain/langchain/agents/agent_toolkits/spark/__init__.py index e01dffb97..7af077a8e 100644 --- a/libs/langchain/langchain/agents/agent_toolkits/spark/__init__.py +++ b/libs/langchain/langchain/agents/agent_toolkits/spark/__init__.py @@ -11,7 +11,7 @@ def __getattr__(name: str) -> Any: old_path = "langchain." + here + "." + name new_path = "langchain_experimental." + here + "." + name - raise ImportError( + raise AttributeError( "This agent has been moved to langchain experiment. " "This agent relies on python REPL tool under the hood, so to use it " "safely please sandbox the python REPL. " diff --git a/libs/langchain/langchain/agents/agent_toolkits/xorbits/__init__.py b/libs/langchain/langchain/agents/agent_toolkits/xorbits/__init__.py index e01dffb97..7af077a8e 100644 --- a/libs/langchain/langchain/agents/agent_toolkits/xorbits/__init__.py +++ b/libs/langchain/langchain/agents/agent_toolkits/xorbits/__init__.py @@ -11,7 +11,7 @@ def __getattr__(name: str) -> Any: old_path = "langchain." + here + "." + name new_path = "langchain_experimental." + here + "." + name - raise ImportError( + raise AttributeError( "This agent has been moved to langchain experiment. " "This agent relies on python REPL tool under the hood, so to use it " "safely please sandbox the python REPL. "