@@ -195,6 +195,7 @@ def _replace_amp_or_semi(match: re.Match):
195
195
)
196
196
_TOKEN_PATTERN = re .compile (r"{{ .+? }}|{% .+? %}" )
197
197
_LSTRIP_BLOCK_PATTERN = re .compile (r"\n +$" )
198
+ _YIELD_PATTERN = re .compile (r"\n +yield " )
198
199
199
200
200
201
def _find_extends (template : str ):
@@ -233,6 +234,10 @@ def _token_is_on_own_line(text_before_token: str) -> bool:
233
234
return _LSTRIP_BLOCK_PATTERN .search (text_before_token ) is not None
234
235
235
236
237
+ def _contains_any_yield_statement (function_def : str ) -> bool :
238
+ return _YIELD_PATTERN .search (function_def ) is not None
239
+
240
+
236
241
def _exists_and_is_file (path : str ) -> bool :
237
242
try :
238
243
return (os .stat (path )[0 ] & 0b_11110000_00000000 ) == 0b_10000000_00000000
@@ -657,6 +662,10 @@ def indented(fragment: str, end: str = "\n") -> str:
657
662
658
663
function_def += indented (f"yield { repr (text_after_last_token )} " )
659
664
665
+ # Make sure the function definition contains at least one yield statement
666
+ if not _contains_any_yield_statement (function_def ):
667
+ function_def += indented ('yield ""' )
668
+
660
669
# Create and return the template function
661
670
exec (function_def ) # pylint: disable=exec-used
662
671
return locals ()[function_name ]
@@ -669,15 +678,18 @@ def _yield_as_sized_chunks(
669
678
670
679
# Yield chunks with a given size
671
680
chunk = ""
681
+ already_yielded = False
682
+
672
683
for item in generator :
673
684
chunk += item
674
685
675
686
if chunk_size <= len (chunk ):
676
687
yield chunk [:chunk_size ]
677
688
chunk = chunk [chunk_size :]
689
+ already_yielded = True
678
690
679
691
# Yield the last chunk
680
- if chunk :
692
+ if chunk or not already_yielded :
681
693
yield chunk
682
694
683
695
0 commit comments