Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/source/whatsnew/v1.5.2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Fixed regressions
Bug fixes
~~~~~~~~~
- Bug in the Copy-on-Write implementation losing track of views in certain chained indexing cases (:issue:`48996`)
-
- Memory leak has been fixed in class CSSToExcelConverter (:issue:`48855`)

.. ---------------------------------------------------------------------------
.. _whatsnew_152.other:
Expand Down
10 changes: 9 additions & 1 deletion pandas/io/formats/excel.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,10 +170,13 @@ def __init__(self, inherited: str | None = None) -> None:
self.inherited = self.compute_css(inherited)
else:
self.inherited = None
# We should avoid lru_cache on the __call__ method.
# Otherwise once the method __call__ has been called
# garbage collection no longer deletes the instance.
self._call_cached = lru_cache(maxsize=None)(self._call_uncached)

compute_css = CSSResolver()

@lru_cache(maxsize=None)
def __call__(
self, declarations: str | frozenset[tuple[str, str]]
) -> dict[str, dict[str, str]]:
Expand All @@ -193,6 +196,11 @@ def __call__(
A style as interpreted by ExcelWriter when found in
ExcelCell.style.
"""
return self._call_cached(declarations)

def _call_uncached(
self, declarations: str | frozenset[tuple[str, str]]
) -> dict[str, dict[str, str]]:
properties = self.compute_css(declarations, self.inherited)
return self.build_xlstyle(properties)

Expand Down
10 changes: 5 additions & 5 deletions pandas/tests/io/formats/test_to_excel.py
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ def test_css_excel_cell_precedence(styles, expected):
"""It applies favors latter declarations over former declarations"""
# See GH 47371
converter = CSSToExcelConverter()
converter.__call__.cache_clear()
converter._call_cached.cache_clear()
css_styles = {(0, 0): styles}
cell = CssExcelCell(
row=0,
Expand All @@ -369,7 +369,7 @@ def test_css_excel_cell_precedence(styles, expected):
css_col=0,
css_converter=converter,
)
converter.__call__.cache_clear()
converter._call_cached.cache_clear()

assert cell.style == converter(expected)

Expand Down Expand Up @@ -410,7 +410,7 @@ def test_css_excel_cell_cache(styles, cache_hits, cache_misses):
"""It caches unique cell styles"""
# See GH 47371
converter = CSSToExcelConverter()
converter.__call__.cache_clear()
converter._call_cached.cache_clear()

css_styles = {(0, i): _style for i, _style in enumerate(styles)}
for css_row, css_col in css_styles:
Expand All @@ -424,8 +424,8 @@ def test_css_excel_cell_cache(styles, cache_hits, cache_misses):
css_col=css_col,
css_converter=converter,
)
cache_info = converter.__call__.cache_info()
converter.__call__.cache_clear()
cache_info = converter._call_cached.cache_info()
converter._call_cached.cache_clear()

assert cache_info.hits == cache_hits
assert cache_info.misses == cache_misses
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ disable = [
"invalid-envvar-default",
"invalid-overridden-method",
"keyword-arg-before-vararg",
"method-cache-max-size-none",
Copy link
Member

@mroeschke mroeschke Nov 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MarcoGorelli have we been using pylint before releasing 1.5? Not sure if this change will cause a merge conflict if backported, and I don't think it's worth backporting pylint configurations to 1.5.x

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree about not backporting the configuration, I'd just backport the fix itself - I'd expect to get a merge conflict, I'll sort this out there

"non-parent-init-called",
"overridden-final-method",
"pointless-statement",
Expand Down