From 3ccef1d669de942b9f3280a35ad4d4422b0b46d2 Mon Sep 17 00:00:00 2001 From: varunkasyap Date: Thu, 4 Dec 2025 14:06:44 +0530 Subject: [PATCH] Fixed #36768 -- Optimized string concatenation in File.__iter__(). --- django/core/files/base.py | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/django/core/files/base.py b/django/core/files/base.py index b8613ffc5537..461ff8b8732e 100644 --- a/django/core/files/base.py +++ b/django/core/files/base.py @@ -74,30 +74,33 @@ def multiple_chunks(self, chunk_size=None): def __iter__(self): # Iterate over this file-like object by newlines - buffer_ = None + buffer_ = [] for chunk in self.chunks(): for line in chunk.splitlines(True): if buffer_: - if endswith_cr(buffer_) and not equals_lf(line): + if endswith_cr(buffer_[-1]) and not equals_lf(line): # Line split after a \r newline; yield buffer_. - yield buffer_ + yield type(buffer_[0])().join(buffer_) # Continue with line. + buffer_ = [] else: # Line either split without a newline (line # continues after buffer_) or with \r\n # newline (line == b'\n'). - line = buffer_ + line - # buffer_ handled, clear it. - buffer_ = None - - # If this is the end of a \n or \r\n line, yield. - if endswith_lf(line): - yield line - else: - buffer_ = line - - if buffer_ is not None: - yield buffer_ + buffer_.append(line) + + if not buffer_: + # If this is the end of a \n or \r\n line, yield. + if endswith_lf(line): + yield line + else: + buffer_.append(line) + elif endswith_lf(line): + yield type(buffer_[0])().join(buffer_) + buffer_ = [] + + if buffer_: + yield type(buffer_[0])().join(buffer_) def __enter__(self): return self