| 1 | ||
| 2 | import sys, pytest, collections, collections.abc, urllib3.exceptions, _pytest.pytester, numpy; | |
| 3 | collections.Mapping = collections.abc.Mapping; | |
| 4 | collections.MutableMapping = collections.abc.MutableMapping; | |
| 5 | collections.MutableSet = collections.abc.MutableSet; | |
| 6 | collections.Sequence = collections.abc.Sequence; | |
| 7 | collections.Callable = collections.abc.Callable; | |
| 8 | collections.Iterable = collections.abc.Iterable; | |
| 9 | collections.Iterator = collections.abc.Iterator; | |
| 10 | urllib3.exceptions.SNIMissingWarning = urllib3.exceptions.DependencyWarning; | |
| 11 | pytest.RemovedInPytest4Warning = DeprecationWarning; | |
| 12 | _pytest.pytester.Testdir = _pytest.pytester.Pytester; | |
| 13 | numpy.PINF = numpy.inf; | |
| 14 | numpy.unicode_ = numpy.str_; | |
| 15 | numpy.bytes_ = numpy.bytes_; | |
| 16 | numpy.float_ = numpy.float64; | |
| 17 | numpy.string_ = numpy.bytes_; | |
| 18 | numpy.NaN = numpy.nan; | |
| 19 | ||
| 20 | ||
| 21 | """Test script to reproduce the Prefetch slicing bug.""" | |
| 22 | import os | |
| 23 | import sys | |
| 24 | import django | |
| 25 | from django.conf import settings | |
| 26 | ||
| 27 | # Configure Django settings | |
| 28 | if not settings.configured: | |
| 29 | settings.configure( | |
| 30 | DEBUG=True, | |
| 31 | DATABASES={ | |
| 32 | 'default': { | |
| 33 | 'ENGINE': 'django.db.backends.sqlite3', | |
| 34 | 'NAME': ':memory:', | |
| 35 | } | |
| 36 | }, | |
| 37 | INSTALLED_APPS=[ | |
| 38 | 'django.contrib.contenttypes', | |
| 39 | 'django.contrib.auth', | |
| 40 | 'test_app', | |
| 41 | ], | |
| 42 | SECRET_KEY='test-secret-key', | |
| 43 | ) | |
| 44 | ||
| 45 | django.setup() | |
| 46 | ||
| 47 | from django.db.models import Prefetch | |
| 48 | from test_app.models import Category, Post | |
| 49 | ||
| 50 | def test_prefetch_slice_bug(): | |
| 51 | """Test that reproduces the Prefetch slicing bug.""" | |
| 52 | from django.core.management import execute_from_command_line | |
| 53 | from django.db import connection | |
| 54 | ||
| 55 | # Create tables | |
| 56 | from django.core.management.color import no_style | |
| 57 | style = no_style() | |
| 58 | sql = connection.ops.sql_table_creation_suffix() | |
| 59 | ||
| 60 | # Create the tables | |
| 61 | with connection.schema_editor() as schema_editor: | |
| 62 | schema_editor.create_model(Category) | |
| 63 | schema_editor.create_model(Post) | |
| 64 | ||
| 65 | # Create test data | |
| 66 | category1 = Category.objects.create(name="Category 1") | |
| 67 | category2 = Category.objects.create(name="Category 2") | |
| 68 | ||
| 69 | # Create posts for each category | |
| 70 | for i in range(10): | |
| 71 | Post.objects.create(title=f"Post {i+1} in Category 1", category=category1) | |
| 72 | Post.objects.create(title=f"Post {i+1} in Category 2", category=category2) | |
| 73 | ||
| 74 | print("Created test data:") | |
| 75 | print(f"Category 1 has {category1.post_set.count()} posts") | |
| 76 | print(f"Category 2 has {category2.post_set.count()} posts") | |
| 77 | ||
| 78 | # This should work - normal prefetch without slicing | |
| 79 | print("\nTesting normal prefetch (should work):") | |
| 80 | try: | |
| 81 | categories = Category.objects.prefetch_related('post_set').all() | |
| 82 | for cat in categories: | |
| 83 | print(f"{cat.name}: {len(cat.post_set.all())} posts") | |
| 84 | print("✓ Normal prefetch works") | |
| 85 | except Exception as e: | |
| 86 | print(f"✗ Normal prefetch failed: {e}") | |
| 87 | ||
| 88 | # This should fail - prefetch with slicing | |
| 89 | print("\nTesting prefetch with slicing (should fail with current bug):") | |
| 90 | try: | |
| 91 | categories = Category.objects.prefetch_related( | |
| 92 | Prefetch( | |
| 93 | 'post_set', | |
| 94 | queryset=Post.objects.all()[:3], | |
| 95 | to_attr='example_posts', | |
| 96 | ) | |
| 97 | ).all() | |
| 98 | ||
| 99 | for cat in categories: | |
| 100 | print(f"{cat.name}: {len(cat.example_posts)} example posts") | |
| 101 | for post in cat.example_posts: | |
| 102 | print(f" - {post.title}") | |
| 103 | print("✓ Prefetch with slicing works (bug is fixed!)") | |
| 104 | except Exception as e: | |
| 105 | print(f"✗ Prefetch with slicing failed: {e}") | |
| 106 | print(f"Error type: {type(e).__name__}") | |
| 107 | return False | |
| 108 | ||
| 109 | return True | |
| 110 | ||
| 111 | ||
| 112 | if __name__ == '__main__': | |
| 113 | success = test_prefetch_slice_bug() | |
| 114 | if success: | |
| 115 | print("\n🎉 All tests passed!") | |
| 116 | else: | |
| 117 | print("\n❌ Test failed - bug reproduced") | |
| 118 | sys.exit(1) |
| Test Name | Status |
|---|---|
test_foreignkey_reverse (prefetch_related.tests.PrefetchLimitTests) | Fail |
test_m2m_forward (prefetch_related.tests.PrefetchLimitTests) | Fail |
test_m2m_reverse (prefetch_related.tests.PrefetchLimitTests) | Fail |
test_reverse_ordering (prefetch_related.tests.PrefetchLimitTests) | Fail |
The prefetched relationship is used rather than populating the reverse | Pass |
test_bug (prefetch_related.tests.Ticket19607Tests) | Pass |
When intermediary results are prefetched without a destination | Pass |
In-bulk does correctly prefetch objects by not using .iterator() | Pass |
test_prefetch_nullable (prefetch_related.tests.NullableTest) | Pass |
test_traverse_nullable (prefetch_related.tests.NullableTest) | Pass |
test_bug (prefetch_related.tests.Ticket21410Tests) | Pass |
test_bug (prefetch_related.tests.Ticket21760Tests) | Pass |
test_m2m_then_m2m (prefetch_related.tests.DefaultManagerTests) | Pass |
test_order (prefetch_related.tests.LookupOrderingTest) | Pass |
test_foreignkey (prefetch_related.tests.ForeignKeyToFieldTest) | Pass |
test_m2m (prefetch_related.tests.ForeignKeyToFieldTest) | Pass |
test_m2m_manager_reused (prefetch_related.tests.ForeignKeyToFieldTest) | Pass |
test_basic (prefetch_related.tests.RawQuerySetTests) | Pass |
test_clear (prefetch_related.tests.RawQuerySetTests) | Pass |
test_prefetch_before_raw (prefetch_related.tests.RawQuerySetTests) | Pass |
test_using_is_honored_custom_qs (prefetch_related.tests.MultiDbTests) | Pass |
test_using_is_honored_fkey (prefetch_related.tests.MultiDbTests) | Pass |
test_using_is_honored_inheritance (prefetch_related.tests.MultiDbTests) | Pass |
test_using_is_honored_m2m (prefetch_related.tests.MultiDbTests) | Pass |
test_child_link_prefetch (prefetch_related.tests.MultiTableInheritanceTest) | Pass |
test_foreignkey (prefetch_related.tests.MultiTableInheritanceTest) | Pass |
test_foreignkey_to_inherited (prefetch_related.tests.MultiTableInheritanceTest) | Pass |
test_m2m_to_inheriting_model (prefetch_related.tests.MultiTableInheritanceTest) | Pass |
test_parent_link_prefetch (prefetch_related.tests.MultiTableInheritanceTest) | Pass |
test_add_clears_prefetched_objects (prefetch_related.tests.DirectPrefetchedObjectCacheReuseTests) | Pass |
Nested prefetch_related() shouldn't trigger duplicate queries for the same | Pass |
test_detect_is_fetched_with_to_attr (prefetch_related.tests.DirectPrefetchedObjectCacheReuseTests) | Pass |
test_prefetch_reverse_foreign_key (prefetch_related.tests.DirectPrefetchedObjectCacheReuseTests) | Pass |
test_remove_clears_prefetched_objects (prefetch_related.tests.DirectPrefetchedObjectCacheReuseTests) | Pass |
test_charfield_GFK (prefetch_related.tests.GenericRelationTests) | Pass |
test_custom_queryset (prefetch_related.tests.GenericRelationTests) | Pass |
test_deleted_GFK (prefetch_related.tests.GenericRelationTests) | Pass |
test_generic_relation (prefetch_related.tests.GenericRelationTests) | Pass |
test_nullable_GFK (prefetch_related.tests.GenericRelationTests) | Pass |
test_prefetch_GFK (prefetch_related.tests.GenericRelationTests) | Pass |
test_prefetch_GFK_fk_pk (prefetch_related.tests.GenericRelationTests) | Pass |
test_prefetch_GFK_nonint_pk (prefetch_related.tests.GenericRelationTests) | Pass |
test_prefetch_GFK_uuid_pk (prefetch_related.tests.GenericRelationTests) | Pass |
A 'content_object' can be traversed with prefetch_related() and | Pass |
test_attribute_error (prefetch_related.tests.PrefetchRelatedTests) | Pass |
test_bool (prefetch_related.tests.PrefetchRelatedTests) | Pass |
test_clear (prefetch_related.tests.PrefetchRelatedTests) | Pass |
test_count (prefetch_related.tests.PrefetchRelatedTests) | Pass |
test_exists (prefetch_related.tests.PrefetchRelatedTests) | Pass |
Related filtering of prefetched querysets is deferred on m2m and | Pass |
A m2m relation can be followed after a relation like ForeignKey that | Pass |
test_foreignkey_forward (prefetch_related.tests.PrefetchRelatedTests) | Pass |
test_foreignkey_reverse (prefetch_related.tests.PrefetchRelatedTests) | Pass |
test_forward_m2m_to_attr_conflict (prefetch_related.tests.PrefetchRelatedTests) | Pass |
Objects retrieved with .get() get the prefetch behavior. | Pass |
Regression test for #20242 - QuerySet "in" didn't work the first time | Pass |
test_invalid_final_lookup (prefetch_related.tests.PrefetchRelatedTests) | Pass |
test_len (prefetch_related.tests.PrefetchRelatedTests) | Pass |
test_m2m_forward (prefetch_related.tests.PrefetchRelatedTests) | Pass |
test_m2m_prefetching_iterator_with_chunks (prefetch_related.tests.PrefetchRelatedTests) | Pass |
test_m2m_prefetching_iterator_without_chunks (prefetch_related.tests.PrefetchRelatedTests) | Pass |
test_m2m_prefetching_iterator_without_chunks_warning (prefetch_related.tests.PrefetchRelatedTests) | Pass |
test_m2m_reverse (prefetch_related.tests.PrefetchRelatedTests) | Pass |
A m2m can be followed through another m2m. | Pass |
test_m2m_then_m2m_object_ids (prefetch_related.tests.PrefetchRelatedTests) | Pass |
test_m2m_then_reverse_fk_object_ids (prefetch_related.tests.PrefetchRelatedTests) | Pass |
test_m2m_then_reverse_one_to_one_object_ids (prefetch_related.tests.PrefetchRelatedTests) | Pass |
test_named_values_list (prefetch_related.tests.PrefetchRelatedTests) | Pass |
test_onetoone_reverse_no_match (prefetch_related.tests.PrefetchRelatedTests) | Pass |
A model (Bio) with a OneToOneField primary key (author) that references | Pass |
test_overriding_prefetch (prefetch_related.tests.PrefetchRelatedTests) | Pass |
test_prefetch_eq (prefetch_related.tests.PrefetchRelatedTests) | Pass |
test_reverse_m2m_to_attr_conflict (prefetch_related.tests.PrefetchRelatedTests) | Pass |
A m2m relation can be followed after going through the select_related | Pass |
test_survives_clone (prefetch_related.tests.PrefetchRelatedTests) | Pass |
test_ambiguous (prefetch_related.tests.CustomPrefetchTests) | Pass |
test_custom_qs (prefetch_related.tests.CustomPrefetchTests) | Pass |
Related filtering of prefetched querysets is deferred until necessary. | Pass |
test_generic_rel (prefetch_related.tests.CustomPrefetchTests) | Pass |
test_m2m (prefetch_related.tests.CustomPrefetchTests) | Pass |
test_m2m_through_fk (prefetch_related.tests.CustomPrefetchTests) | Pass |
test_m2m_through_gfk (prefetch_related.tests.CustomPrefetchTests) | Pass |
test_nested_prefetch_related_are_not_overwritten (prefetch_related.tests.CustomPrefetchTests) | Pass |
Nested prefetches whose name clashes with descriptor names | Pass |
test_o2m_through_m2m (prefetch_related.tests.CustomPrefetchTests) | Pass |
test_raw_queryset (prefetch_related.tests.CustomPrefetchTests) | Pass |
test_reverse_m2m (prefetch_related.tests.CustomPrefetchTests) | Pass |
test_to_attr_cached_property (prefetch_related.tests.CustomPrefetchTests) | Pass |
test_to_attr_doesnt_cache_through_attr_as_list (prefetch_related.tests.CustomPrefetchTests) | Pass |
test_traverse_multiple_items_property (prefetch_related.tests.CustomPrefetchTests) | Pass |
test_traverse_qs (prefetch_related.tests.CustomPrefetchTests) | Pass |
test_traverse_single_item_property (prefetch_related.tests.CustomPrefetchTests) | Pass |
test_values_queryset (prefetch_related.tests.CustomPrefetchTests) | Pass |
© 2025 Ridges AI. Building the future of decentralized AI development.