Source code for langchain_core.output_parsers.list
"""Parsers for list output."""from__future__importannotationsimportcsvimportrefromabcimportabstractmethodfromcollectionsimportdequefromioimportStringIOfromtypingimportTYPE_CHECKING,TypeVar,Unionfromtyping_extensionsimportoverridefromlangchain_core.messagesimportBaseMessagefromlangchain_core.output_parsers.transformimportBaseTransformOutputParserifTYPE_CHECKING:fromcollections.abcimportAsyncIterator,IteratorT=TypeVar("T")
[docs]defdroplastn(iter:Iterator[T],n:int)->Iterator[T]:"""Drop the last n elements of an iterator. Args: iter: The iterator to drop elements from. n: The number of elements to drop. Yields: The elements of the iterator, except the last n elements. """buffer:deque[T]=deque()foriteminiter:buffer.append(item)iflen(buffer)>n:yieldbuffer.popleft()
[docs]classListOutputParser(BaseTransformOutputParser[list[str]]):"""Parse the output of an LLM call to a list."""@propertydef_type(self)->str:return"list"
[docs]@abstractmethoddefparse(self,text:str)->list[str]:"""Parse the output of an LLM call. Args: text: The output of an LLM call. Returns: A list of strings. """
[docs]defparse_iter(self,text:str)->Iterator[re.Match]:"""Parse the output of an LLM call. Args: text: The output of an LLM call. Yields: A match object for each part of the output. """raiseNotImplementedError
def_transform(self,input:Iterator[Union[str,BaseMessage]])->Iterator[list[str]]:buffer=""forchunkininput:ifisinstance(chunk,BaseMessage):# extract textchunk_content=chunk.contentifnotisinstance(chunk_content,str):continuebuffer+=chunk_contentelse:# add current chunk to bufferbuffer+=chunk# parse buffer into a list of partstry:done_idx=0# yield only complete partsformindroplastn(self.parse_iter(buffer),1):done_idx=m.end()yield[m.group(1)]buffer=buffer[done_idx:]exceptNotImplementedError:parts=self.parse(buffer)# yield only complete partsiflen(parts)>1:forpartinparts[:-1]:yield[part]buffer=parts[-1]# yield the last partforpartinself.parse(buffer):yield[part]asyncdef_atransform(self,input:AsyncIterator[Union[str,BaseMessage]])->AsyncIterator[list[str]]:buffer=""asyncforchunkininput:ifisinstance(chunk,BaseMessage):# extract textchunk_content=chunk.contentifnotisinstance(chunk_content,str):continuebuffer+=chunk_contentelse:# add current chunk to bufferbuffer+=chunk# parse buffer into a list of partstry:done_idx=0# yield only complete partsformindroplastn(self.parse_iter(buffer),1):done_idx=m.end()yield[m.group(1)]buffer=buffer[done_idx:]exceptNotImplementedError:parts=self.parse(buffer)# yield only complete partsiflen(parts)>1:forpartinparts[:-1]:yield[part]buffer=parts[-1]# yield the last partforpartinself.parse(buffer):yield[part]
[docs]classCommaSeparatedListOutputParser(ListOutputParser):"""Parse the output of an LLM call to a comma-separated list."""@classmethoddefis_lc_serializable(cls)->bool:"""Check if the langchain object is serializable. Returns True. """returnTrue@classmethoddefget_lc_namespace(cls)->list[str]:"""Get the namespace of the langchain object. Returns: A list of strings. Default is ["langchain", "output_parsers", "list"]. """return["langchain","output_parsers","list"]
[docs]defget_format_instructions(self)->str:"""Return the format instructions for the comma-separated list output."""return("Your response should be a list of comma separated values, ""eg: `foo, bar, baz` or `foo,bar,baz`")
[docs]defparse(self,text:str)->list[str]:"""Parse the output of an LLM call. Args: text: The output of an LLM call. Returns: A list of strings. """try:reader=csv.reader(StringIO(text),quotechar='"',delimiter=",",skipinitialspace=True)return[itemforsublistinreaderforiteminsublist]exceptcsv.Error:# keep old logic for backupreturn[part.strip()forpartintext.split(",")]
[docs]classNumberedListOutputParser(ListOutputParser):"""Parse a numbered list."""pattern:str=r"\d+\.\s([^\n]+)""""The pattern to match a numbered list item."""
[docs]@overridedefget_format_instructions(self)->str:return("Your response should be a numbered list with each item on a new line. ""For example: \n\n1. foo\n\n2. bar\n\n3. baz")
[docs]defparse(self,text:str)->list[str]:"""Parse the output of an LLM call. Args: text: The output of an LLM call. Returns: A list of strings. """returnre.findall(self.pattern,text)
[docs]defparse_iter(self,text:str)->Iterator[re.Match]:"""Parse the output of an LLM call. Args: text: The output of an LLM call. Yields: A match object for each part of the output. """returnre.finditer(self.pattern,text)
[docs]classMarkdownListOutputParser(ListOutputParser):"""Parse a Markdown list."""pattern:str=r"^\s*[-*]\s([^\n]+)$""""The pattern to match a Markdown list item."""
[docs]defget_format_instructions(self)->str:"""Return the format instructions for the Markdown list output."""return"Your response should be a markdown list, eg: `- foo\n- bar\n- baz`"
[docs]defparse(self,text:str)->list[str]:"""Parse the output of an LLM call. Args: text: The output of an LLM call. Returns: A list of strings. """returnre.findall(self.pattern,text,re.MULTILINE)
[docs]defparse_iter(self,text:str)->Iterator[re.Match]:"""Parse the output of an LLM call. Args: text: The output of an LLM call. Yields: A match object for each part of the output. """returnre.finditer(self.pattern,text,re.MULTILINE)