Skip to content

Commit

Permalink
Fix breaking change of DoesNotExist (#1650)
Browse files Browse the repository at this point in the history
* Support str argument for DoesNotExist

* make style
  • Loading branch information
waketzheng committed Jun 14, 2024
1 parent d1e4be0 commit 3c36151
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 15 deletions.
16 changes: 16 additions & 0 deletions tests/test_queryset.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import Type

from tests.testmodels import (
Event,
IntFields,
Expand All @@ -16,6 +18,7 @@
IntegrityError,
MultipleObjectsReturned,
ParamsError,
NotExistOrMultiple,
)
from tortoise.expressions import F, RawSQL, Subquery

Expand Down Expand Up @@ -673,3 +676,16 @@ async def test_annotation_field_priorior_to_model_field(self):
t1 = await Tournament.create(name="1")
ret = await Tournament.filter(pk=t1.pk).annotate(id=RawSQL("id + 1")).values("id")
self.assertEqual(ret, [{"id": t1.pk + 1}])


class TestNotExist(test.TestCase):
exp_cls: Type[NotExistOrMultiple] = DoesNotExist

@test.requireCapability(dialect="sqlite")
def test_does_not_exist(self):
assert str(self.exp_cls("old format")) == "old format"
assert str(self.exp_cls(Tournament)) == self.exp_cls.TEMPLATE.format(Tournament.__name__)


class TestMultiple(TestNotExist):
exp_cls = MultipleObjectsReturned
37 changes: 22 additions & 15 deletions tortoise/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import TYPE_CHECKING, Any
from typing import TYPE_CHECKING, Any, Union, Optional

if TYPE_CHECKING:
from tortoise import Model, Type
Expand Down Expand Up @@ -52,18 +52,30 @@ class NoValuesFetched(OperationalError):
"""


class MultipleObjectsReturned(OperationalError):
class NotExistOrMultiple(OperationalError):
TEMPLATE = ""

def __init__(self, model: "Union[Type[Model], str]", *args) -> None:
self.model: "Optional[Type[Model]]" = None
if isinstance(model, str):
args = (model,) + args
else:
self.model = model
super().__init__(*args)

def __str__(self) -> str:
if self.model is None:
return super().__str__()
return self.TEMPLATE.format(self.model.__name__)


class MultipleObjectsReturned(NotExistOrMultiple):
"""
The MultipleObjectsReturned exception is raised when doing a ``.get()`` operation,
and more than one object is returned.
"""

def __init__(self, model: "Type[Model]", *args):
self.model: "Type[Model]" = model
super().__init__(*args)

def __str__(self):
return f'Multiple objects returned for "{self.model.__name__}", expected exactly one'
TEMPLATE = 'Multiple objects returned for "{}", expected exactly one'


class ObjectDoesNotExistError(OperationalError, KeyError):
Expand All @@ -80,17 +92,12 @@ def __str__(self):
return f"{self.model.__name__} has no object with {self.pk_name}={self.pk_val}"


class DoesNotExist(OperationalError):
class DoesNotExist(NotExistOrMultiple):
"""
The DoesNotExist exception is raised when expecting data, such as a ``.get()`` operation.
"""

def __init__(self, model: "Type[Model]", *args):
self.model: "Type[Model]" = model
super().__init__(*args)

def __str__(self):
return f'Object "{self.model.__name__}" does not exist'
TEMPLATE = 'Object "{}" does not exist'


class IncompleteInstanceError(OperationalError):
Expand Down

0 comments on commit 3c36151

Please sign in to comment.