Skip to content

Commit

Permalink
Ignore DeprecationWarning from Pandas via cachey (#682)
Browse files Browse the repository at this point in the history
* Ignore Pandas DeprecationWarning from cachey.nbytes()

* Ignore Pandas DeprecationWarning in tests?

* Subclass warnings.catch_warnings for backward compatibility

* Make catch_warning_msg a utility; use specialized instance forPandas block warning
  • Loading branch information
padraic-shafer authored Mar 15, 2024
1 parent 2b7fd88 commit 5aae35a
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 2 deletions.
5 changes: 5 additions & 0 deletions tiled/_tests/test_writing.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
from ..client import Context, from_context, record_history
from ..queries import Key
from ..server.app import build_app

# from ..server.object_cache import WARNING_PANDAS_BLOCKS
from ..structures.core import Spec
from ..structures.data_source import DataSource
from ..structures.sparse import COOStructure
Expand Down Expand Up @@ -111,6 +113,7 @@ def test_write_array_chunked(tree):
assert result.specs == specs


# @pytest.mark.filterwarnings(f"ignore:{WARNING_PANDAS_BLOCKS}:DeprecationWarning")
def test_write_dataframe_full(tree):
with Context.from_app(
build_app(tree, validation_registry=validation_registry)
Expand All @@ -136,6 +139,7 @@ def test_write_dataframe_full(tree):
assert result.specs == specs


# @pytest.mark.filterwarnings(f"ignore:{WARNING_PANDAS_BLOCKS}:DeprecationWarning")
def test_write_dataframe_partitioned(tree):
with Context.from_app(
build_app(tree, validation_registry=validation_registry)
Expand Down Expand Up @@ -389,6 +393,7 @@ async def test_delete_non_empty_node(tree):
client.delete("a")


# @pytest.mark.filterwarnings(f"ignore:{WARNING_PANDAS_BLOCKS}:DeprecationWarning")
@pytest.mark.asyncio
async def test_write_in_container(tree):
"Create a container and write a structure into it."
Expand Down
21 changes: 19 additions & 2 deletions tiled/server/object_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import cachey
from dask.callbacks import Callback

from ..utils import catch_warning_msg

if __debug__:
import logging

Expand All @@ -23,6 +25,19 @@
logger.addHandler(handler)


# See https://github.com/bluesky/tiled/issues/675#issuecomment-1983581882
WARNING_PANDAS_BLOCKS = (
"DataFrame._data is deprecated and will be removed in a future version. "
"Use public APIs instead."
)


def catch_pandas_blocks_warning():
return catch_warning_msg(
action="ignore", message=WARNING_PANDAS_BLOCKS, category=DeprecationWarning
)


class _NO_CACHE_SENTINEL:
def __init__(self):
self.dask_context = contextlib.nullcontext()
Expand Down Expand Up @@ -129,7 +144,8 @@ def put(self, key, value, cost, nbytes=None):
Computed (with best effort) if not provided.
"""
if nbytes is None:
nbytes = self._cache.get_nbytes(value)
with catch_pandas_blocks_warning():
nbytes = self._cache.get_nbytes(value)
logger.debug("Store %r (cost=%.3f, nbytes=%d)", key, cost, nbytes)
self._cache.put(key, value, cost, nbytes=nbytes)

Expand Down Expand Up @@ -196,7 +212,8 @@ def _posttask(self, key, value, dsk, state, id):
if deps:
duration += max(self.durations.get(k, 0) for k in deps)
self.durations[key] = duration
nb = self._nbytes(value)
with catch_pandas_blocks_warning():
nb = self._nbytes(value)
self.cache.put(("dask", *key), value, cost=duration, nbytes=nb)

def _finish(self, dsk, state, errored):
Expand Down
38 changes: 38 additions & 0 deletions tiled/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import collections.abc
import contextlib
import enum
import functools
import importlib
import importlib.util
import inspect
Expand All @@ -12,6 +13,7 @@
import re
import sys
import threading
import warnings
from pathlib import Path
from typing import Any, Callable
from urllib.parse import urlparse, urlunparse
Expand Down Expand Up @@ -709,3 +711,39 @@ def ensure_uri(uri_or_path):
mutable[1] = "localhost"
uri_str = urlunparse(mutable)
return str(uri_str)


class catch_warning_msg(warnings.catch_warnings):
"""Backward compatible version of catch_warnings for python <3.11.
Allows regex matching of warning message, as in filterwarnings().
Note that this context manager is not thread-safe.
https://docs.python.org/3.12/library/warnings.html#warnings.catch_warnings
"""

def __init__(
self,
*,
action="",
message="",
category=Warning,
module="",
lineno=0,
append=False,
record=False,
):
super().__init__(record=record)
self.apply_filter = functools.partial(
warnings.filterwarnings,
action,
message=message,
category=category,
module=module,
lineno=lineno,
append=append,
)

def __enter__(self):
super().__enter__()
self.apply_filter()
return self

0 comments on commit 5aae35a

Please sign in to comment.