Fixed #29244 -- Prevented Paginator.count() from silencing TypeError and AttributeError.
This commit is contained in:
parent
f1bf069ec1
commit
3767c7ff39
|
@ -1,8 +1,10 @@
|
||||||
import collections.abc
|
import collections.abc
|
||||||
|
import inspect
|
||||||
import warnings
|
import warnings
|
||||||
from math import ceil
|
from math import ceil
|
||||||
|
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
|
from django.utils.inspect import method_has_no_args
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
|
@ -83,13 +85,10 @@ class Paginator:
|
||||||
@cached_property
|
@cached_property
|
||||||
def count(self):
|
def count(self):
|
||||||
"""Return the total number of objects, across all pages."""
|
"""Return the total number of objects, across all pages."""
|
||||||
try:
|
c = getattr(self.object_list, 'count', None)
|
||||||
return self.object_list.count()
|
if callable(c) and not inspect.isbuiltin(c) and method_has_no_args(c):
|
||||||
except (AttributeError, TypeError):
|
return c()
|
||||||
# AttributeError if object_list has no count() method.
|
return len(self.object_list)
|
||||||
# TypeError if object_list.count() requires arguments
|
|
||||||
# (i.e. is of type list).
|
|
||||||
return len(self.object_list)
|
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def num_pages(self):
|
def num_pages(self):
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import unittest
|
|
||||||
import warnings
|
import warnings
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
@ -6,13 +5,13 @@ from django.core.paginator import (
|
||||||
EmptyPage, InvalidPage, PageNotAnInteger, Paginator,
|
EmptyPage, InvalidPage, PageNotAnInteger, Paginator,
|
||||||
UnorderedObjectListWarning,
|
UnorderedObjectListWarning,
|
||||||
)
|
)
|
||||||
from django.test import TestCase
|
from django.test import SimpleTestCase, TestCase
|
||||||
|
|
||||||
from .custom import ValidAdjacentNumsPaginator
|
from .custom import ValidAdjacentNumsPaginator
|
||||||
from .models import Article
|
from .models import Article
|
||||||
|
|
||||||
|
|
||||||
class PaginationTests(unittest.TestCase):
|
class PaginationTests(SimpleTestCase):
|
||||||
"""
|
"""
|
||||||
Tests for the Paginator and Page classes.
|
Tests for the Paginator and Page classes.
|
||||||
"""
|
"""
|
||||||
|
@ -151,6 +150,22 @@ class PaginationTests(unittest.TestCase):
|
||||||
self.assertEqual(5, paginator.num_pages)
|
self.assertEqual(5, paginator.num_pages)
|
||||||
self.assertEqual([1, 2, 3, 4, 5], list(paginator.page_range))
|
self.assertEqual([1, 2, 3, 4, 5], list(paginator.page_range))
|
||||||
|
|
||||||
|
def test_count_does_not_silence_attribute_error(self):
|
||||||
|
class AttributeErrorContainer:
|
||||||
|
def count(self):
|
||||||
|
raise AttributeError('abc')
|
||||||
|
|
||||||
|
with self.assertRaisesMessage(AttributeError, 'abc'):
|
||||||
|
Paginator(AttributeErrorContainer(), 10).count()
|
||||||
|
|
||||||
|
def test_count_does_not_silence_type_error(self):
|
||||||
|
class TypeErrorContainer:
|
||||||
|
def count(self):
|
||||||
|
raise TypeError('abc')
|
||||||
|
|
||||||
|
with self.assertRaisesMessage(TypeError, 'abc'):
|
||||||
|
Paginator(TypeErrorContainer(), 10).count()
|
||||||
|
|
||||||
def check_indexes(self, params, page_num, indexes):
|
def check_indexes(self, params, page_num, indexes):
|
||||||
"""
|
"""
|
||||||
Helper method that instantiates a Paginator object from the passed
|
Helper method that instantiates a Paginator object from the passed
|
||||||
|
|
Loading…
Reference in New Issue