Skip to content

Commit de159c4

Browse files
committed
Fix memory leak during large csv error handling
- Delay exception raising until context manager `with open()` has finished. - _render_grid now returns a four element tuple (sheets, size, nbr_rows, nbr_cols), where the first two for success and the last two for the `TableTooLargeError`.
1 parent eb9cccf commit de159c4

File tree

1 file changed

+29
-11
lines changed

1 file changed

+29
-11
lines changed

mfr/extensions/tabular/render.py

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
import gc
23
import logging
34
import os
45

@@ -30,14 +31,23 @@ def render(self):
3031
)
3132

3233
with open(self.file_path, errors='replace') as fp:
33-
sheets, size = self._render_grid(fp, self.metadata.ext)
34-
return self.TEMPLATE.render(
35-
base=self.assets_url,
36-
width=settings.TABLE_WIDTH,
37-
height=settings.TABLE_HEIGHT,
38-
sheets=json.dumps(sheets),
39-
options=json.dumps(size),
40-
)
34+
sheets, size, nbr_rows, nbr_cols = self._render_grid(fp, self.metadata.ext)
35+
# gc.collect()
36+
if sheets and size:
37+
return self.TEMPLATE.render(
38+
base=self.assets_url,
39+
width=settings.TABLE_WIDTH,
40+
height=settings.TABLE_HEIGHT,
41+
sheets=json.dumps(sheets),
42+
options=json.dumps(size),
43+
)
44+
# gc.collect()
45+
raise exceptions.TableTooBigError(
46+
'Table is too large to render.',
47+
extension=self.metadata.ext,
48+
nbr_cols=nbr_cols,
49+
nbr_rows=nbr_rows
50+
)
4151

4252
@property
4353
def file_required(self):
@@ -59,6 +69,11 @@ def _render_grid(self, fp, ext, *args, **kwargs):
5969
size = settings.SMALL_TABLE
6070
self._renderer_tabular_metrics['size'] = 'small'
6171
self._renderer_tabular_metrics['nbr_sheets'] = len(sheets)
72+
73+
table_too_big = False
74+
nbr_cols = 0
75+
nbr_rows = 0
76+
6277
for sheet_title in sheets:
6378
sheet = sheets[sheet_title]
6479

@@ -74,10 +89,13 @@ def _render_grid(self, fp, ext, *args, **kwargs):
7489

7590
nbr_rows = len(sheet[1])
7691
if nbr_cols > settings.MAX_SIZE or nbr_rows > settings.MAX_SIZE:
77-
raise exceptions.TableTooBigError('Table is too large to render.', extension=ext,
78-
nbr_cols=nbr_cols, nbr_rows=nbr_rows)
92+
table_too_big = True
93+
break
94+
95+
if table_too_big:
96+
return None, None, nbr_rows, nbr_cols
7997

80-
return sheets, size
98+
return sheets, size, None, None
8199

82100
def _populate_data(self, fp, ext):
83101
"""Determine the appropriate library and use it to populate rows and columns

0 commit comments

Comments
 (0)