From b6ae7ca91dd0f54f58475463804540ad25eeea7d Mon Sep 17 00:00:00 2001 From: Christophe Bornet Date: Thu, 23 Jan 2025 19:34:47 +0100 Subject: [PATCH] core: Cache RunnableLambda __repr__ (#29199) `RunnableLambda`'s `__repr__` may do costly OS operation by calling `get_lambda_source`. So it's better to cache it. See #29043 --------- Co-authored-by: Chester Curme --- libs/core/langchain_core/runnables/base.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/libs/core/langchain_core/runnables/base.py b/libs/core/langchain_core/runnables/base.py index 9942174103c..bf805c3a4f0 100644 --- a/libs/core/langchain_core/runnables/base.py +++ b/libs/core/langchain_core/runnables/base.py @@ -4347,6 +4347,8 @@ class RunnableLambda(Runnable[Input, Output]): except AttributeError: pass + self._repr: Optional[str] = None + @property @override def InputType(self) -> Any: @@ -4525,14 +4527,18 @@ class RunnableLambda(Runnable[Input, Output]): def __repr__(self) -> str: """A string representation of this Runnable.""" - if hasattr(self, "func") and isinstance(self.func, itemgetter): - return f"RunnableLambda({str(self.func)[len('operator.') :]})" - elif hasattr(self, "func"): - return f"RunnableLambda({get_lambda_source(self.func) or '...'})" - elif hasattr(self, "afunc"): - return f"RunnableLambda(afunc={get_lambda_source(self.afunc) or '...'})" - else: - return "RunnableLambda(...)" + if self._repr is None: + if hasattr(self, "func") and isinstance(self.func, itemgetter): + self._repr = f"RunnableLambda({str(self.func)[len('operator.') :]})" + elif hasattr(self, "func"): + self._repr = f"RunnableLambda({get_lambda_source(self.func) or '...'})" + elif hasattr(self, "afunc"): + self._repr = ( + f"RunnableLambda(afunc={get_lambda_source(self.afunc) or '...'})" + ) + else: + self._repr = "RunnableLambda(...)" + return self._repr def _invoke( self,