Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,14 @@ Note that 0.3.3 was never released; 0.3.4 follows 0.3.2.
pattern clears nothing, the prefix-stripped form is still tried and emits a
`DeprecationWarning` if it clears anything. The retry will be removed in
0.4.0. ([#125](https://github.com/allen0099/FastAPI-CacheX/issues/125))

- **The `memcache` extra.** Use `memcached` instead. The old name keeps working
until 0.4.0 removes it; after that, pip and uv only warn about the unknown
extra and install without `pymemcache`.
([#202](https://github.com/allen0099/FastAPI-CacheX/issues/202))
- **`fastapi_cachex.exceptions.CacheError`.** Nothing in the package raises it.
Accessing or importing it emits a `DeprecationWarning`; catch `CacheXError`
instead. It will be removed in 0.4.0.
([#163](https://github.com/allen0099/FastAPI-CacheX/issues/163))

### Fixed

Expand Down
4 changes: 4 additions & 0 deletions docs/api/types.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@
::: fastapi_cachex.types

::: fastapi_cachex.exceptions

`fastapi_cachex.exceptions.CacheError` is deprecated since 0.3.8 and not listed
above. Nothing in the package raises it, and accessing it emits a
`DeprecationWarning`. Catch `CacheXError` instead. It will be removed in 0.4.0.
32 changes: 30 additions & 2 deletions fastapi_cachex/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
"""Custom exception classes for FastAPI-CacheX."""

import warnings
from typing import TYPE_CHECKING


class CacheXError(Exception):
"""Base class for all exceptions in FastAPI-CacheX."""


class CacheError(CacheXError):
"""Exception raised for cache-related errors."""
class _CacheError(CacheXError):
"""Exception raised for cache-related errors.

.. deprecated:: 0.3.8
Never raised by FastAPI-CacheX. Catch :class:`CacheXError` instead.
Will be removed in version 0.4.0.
"""


_CacheError.__name__ = _CacheError.__qualname__ = "CacheError"

if TYPE_CHECKING:
CacheError = _CacheError


class BackendNotFoundError(CacheXError):
Expand All @@ -28,3 +42,17 @@ class RequestNotFoundError(CacheXError):

class LockTimeoutError(CacheXError):
"""Exception raised when acquiring a lock times out."""


def __getattr__(name: str) -> type[CacheXError]:
"""Return the deprecated ``CacheError`` with a ``DeprecationWarning``."""
if name == "CacheError":
warnings.warn(
"CacheError is deprecated and never raised, catch CacheXError instead. "
"Will be removed in version 0.4.0.",
DeprecationWarning,
stacklevel=2,
)
return _CacheError
msg = f"module {__name__!r} has no attribute {name!r}"
raise AttributeError(msg)
35 changes: 35 additions & 0 deletions tests/test_exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""Tests for the package-level exceptions."""

import importlib

import pytest

from fastapi_cachex.exceptions import CacheXError


def test_cache_error_access_warns_and_still_works() -> None:
"""Test accessing the deprecated CacheError warns (#163)."""
exceptions = importlib.import_module("fastapi_cachex.exceptions")

with pytest.warns(DeprecationWarning, match="CacheError is deprecated") as record:
cache_error = exceptions.CacheError

assert record[0].filename == __file__
assert cache_error.__name__ == "CacheError"
assert issubclass(cache_error, CacheXError)
with pytest.raises(CacheXError):
raise cache_error


def test_cache_error_from_import_warns() -> None:
"""Test ``from fastapi_cachex.exceptions import CacheError`` warns (#163)."""
with pytest.warns(DeprecationWarning, match="removed in version 0.4.0"):
from fastapi_cachex.exceptions import CacheError # noqa: F401


def test_unknown_attribute_still_raises_attribute_error() -> None:
"""Test the module ``__getattr__`` only handles CacheError."""
exceptions = importlib.import_module("fastapi_cachex.exceptions")

with pytest.raises(AttributeError, match="has no attribute 'Missing'"):
_ = exceptions.Missing
Loading