mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Fixed #29244 -- Prevented Paginator.count() from silencing TypeError and AttributeError.
This commit is contained in:
		
				
					committed by
					
						 Tim Graham
						Tim Graham
					
				
			
			
				
	
			
			
			
						parent
						
							f1bf069ec1
						
					
				
				
					commit
					3767c7ff39
				
			| @@ -1,8 +1,10 @@ | ||||
| import collections.abc | ||||
| import inspect | ||||
| import warnings | ||||
| from math import ceil | ||||
|  | ||||
| from django.utils.functional import cached_property | ||||
| from django.utils.inspect import method_has_no_args | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
|  | ||||
|  | ||||
| @@ -83,13 +85,10 @@ class Paginator: | ||||
|     @cached_property | ||||
|     def count(self): | ||||
|         """Return the total number of objects, across all pages.""" | ||||
|         try: | ||||
|             return self.object_list.count() | ||||
|         except (AttributeError, TypeError): | ||||
|             # AttributeError if object_list has no count() method. | ||||
|             # TypeError if object_list.count() requires arguments | ||||
|             # (i.e. is of type list). | ||||
|             return len(self.object_list) | ||||
|         c = getattr(self.object_list, 'count', None) | ||||
|         if callable(c) and not inspect.isbuiltin(c) and method_has_no_args(c): | ||||
|             return c() | ||||
|         return len(self.object_list) | ||||
|  | ||||
|     @cached_property | ||||
|     def num_pages(self): | ||||
|   | ||||
| @@ -1,4 +1,3 @@ | ||||
| import unittest | ||||
| import warnings | ||||
| from datetime import datetime | ||||
|  | ||||
| @@ -6,13 +5,13 @@ from django.core.paginator import ( | ||||
|     EmptyPage, InvalidPage, PageNotAnInteger, Paginator, | ||||
|     UnorderedObjectListWarning, | ||||
| ) | ||||
| from django.test import TestCase | ||||
| from django.test import SimpleTestCase, TestCase | ||||
|  | ||||
| from .custom import ValidAdjacentNumsPaginator | ||||
| from .models import Article | ||||
|  | ||||
|  | ||||
| class PaginationTests(unittest.TestCase): | ||||
| class PaginationTests(SimpleTestCase): | ||||
|     """ | ||||
|     Tests for the Paginator and Page classes. | ||||
|     """ | ||||
| @@ -151,6 +150,22 @@ class PaginationTests(unittest.TestCase): | ||||
|         self.assertEqual(5, paginator.num_pages) | ||||
|         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): | ||||
|         """ | ||||
|         Helper method that instantiates a Paginator object from the passed | ||||
|   | ||||
		Reference in New Issue
	
	Block a user