Browse Source

Fixed #28249 -- Removed unnecessary dict.keys() calls.

iter(dict) is equivalent to iter(dict.keys()).
Jon Dufresne 7 years ago
parent
commit
21046e7773
43 changed files with 84 additions and 85 deletions
  1. 1 1
      django/contrib/admin/options.py
  2. 1 1
      django/contrib/auth/forms.py
  3. 1 1
      django/contrib/postgres/validators.py
  4. 2 2
      django/contrib/staticfiles/storage.py
  5. 2 2
      django/core/management/__init__.py
  6. 1 1
      django/core/management/commands/loaddata.py
  7. 1 1
      django/core/validators.py
  8. 1 1
      django/db/backends/oracle/base.py
  9. 1 2
      django/db/backends/sqlite3/operations.py
  10. 4 4
      django/db/migrations/autodetector.py
  11. 1 1
      django/db/migrations/state.py
  12. 2 2
      django/db/models/base.py
  13. 1 1
      django/db/models/options.py
  14. 1 1
      django/db/models/query.py
  15. 1 1
      django/db/models/sql/compiler.py
  16. 2 2
      django/db/models/sql/query.py
  17. 2 3
      django/forms/models.py
  18. 1 1
      django/forms/widgets.py
  19. 1 1
      django/template/context.py
  20. 1 1
      django/template/defaulttags.py
  21. 1 2
      django/urls/resolvers.py
  22. 1 1
      django/utils/datastructures.py
  23. 1 1
      django/utils/formats.py
  24. 1 1
      django/utils/functional.py
  25. 1 1
      django/utils/termcolors.py
  26. 1 1
      tests/backends/tests.py
  27. 1 1
      tests/basic/tests.py
  28. 1 1
      tests/cache/tests.py
  29. 1 1
      tests/file_uploads/views.py
  30. 6 6
      tests/forms_tests/tests/test_forms.py
  31. 5 7
      tests/gis_tests/gdal_tests/test_ds.py
  32. 7 3
      tests/httpwrappers/tests.py
  33. 1 1
      tests/invalid_models_tests/test_models.py
  34. 2 2
      tests/lookup/tests.py
  35. 1 1
      tests/messages_tests/base.py
  36. 2 2
      tests/migrations/test_operations.py
  37. 9 9
      tests/model_forms/tests.py
  38. 1 1
      tests/model_formsets/tests.py
  39. 8 8
      tests/requests/tests.py
  40. 1 1
      tests/servers/test_basehttp.py
  41. 1 1
      tests/test_client/views.py
  42. 1 1
      tests/user_commands/management/commands/dance.py
  43. 2 2
      tests/utils_tests/test_datastructures.py

+ 1 - 1
django/contrib/admin/options.py

@@ -1546,7 +1546,7 @@ class ModelAdmin(BaseModelAdmin):
             # and the 'invalid=1' parameter was already in the query string,
             # something is screwed up with the database, so display an error
             # page.
-            if ERROR_FLAG in request.GET.keys():
+            if ERROR_FLAG in request.GET:
                 return SimpleTemplateResponse('admin/invalid_setup.html', {
                     'title': _('Database error'),
                 })

+ 1 - 1
django/contrib/auth/forms.py

@@ -410,7 +410,7 @@ class AdminPasswordChangeForm(forms.Form):
     @property
     def changed_data(self):
         data = super().changed_data
-        for name in self.fields.keys():
+        for name in self.fields:
             if name not in data:
                 return []
         return ['password']

+ 1 - 1
django/contrib/postgres/validators.py

@@ -41,7 +41,7 @@ class KeysValidator:
             self.messages.update(messages)
 
     def __call__(self, value):
-        keys = set(value.keys())
+        keys = set(value)
         missing_keys = self.keys - keys
         if missing_keys:
             raise ValidationError(

+ 2 - 2
django/contrib/staticfiles/storage.py

@@ -232,7 +232,7 @@ class HashedFilesMixin:
         # build a list of adjustable files
         adjustable_paths = [
             path for path in paths
-            if matches_patterns(path, self._patterns.keys())
+            if matches_patterns(path, self._patterns)
         ]
         # Do a single pass first. Post-process all files once, then repeat for
         # adjustable files.
@@ -261,7 +261,7 @@ class HashedFilesMixin:
         def path_level(name):
             return len(name.split(os.sep))
 
-        for name in sorted(paths.keys(), key=path_level, reverse=True):
+        for name in sorted(paths, key=path_level, reverse=True):
             substitutions = True
             # use the original, local file, not the copied-but-unprocessed
             # file, which might be somewhere far away, like S3

+ 2 - 2
django/core/management/__init__.py

@@ -138,7 +138,7 @@ class ManagementUtility:
     def main_help_text(self, commands_only=False):
         """Return the script's main help text, as a string."""
         if commands_only:
-            usage = sorted(get_commands().keys())
+            usage = sorted(get_commands())
         else:
             usage = [
                 "",
@@ -154,7 +154,7 @@ class ManagementUtility:
                     app = app.rpartition('.')[-1]
                 commands_dict[app].append(name)
             style = color_style()
-            for app in sorted(commands_dict.keys()):
+            for app in sorted(commands_dict):
                 usage.append("")
                 usage.append(style.NOTICE("[%s]" % app))
                 for name in sorted(commands_dict[app]):

+ 1 - 1
django/core/management/commands/loaddata.py

@@ -215,7 +215,7 @@ class Command(BaseCommand):
 
         fixture_name, ser_fmt, cmp_fmt = self.parse_name(fixture_label)
         databases = [self.using, None]
-        cmp_fmts = list(self.compression_formats.keys()) if cmp_fmt is None else [cmp_fmt]
+        cmp_fmts = list(self.compression_formats) if cmp_fmt is None else [cmp_fmt]
         ser_fmts = serializers.get_public_serializer_formats() if ser_fmt is None else [ser_fmt]
 
         if self.verbosity >= 2:

+ 1 - 1
django/core/validators.py

@@ -495,7 +495,7 @@ def get_available_image_extensions():
         return []
     else:
         Image.init()
-        return [ext.lower()[1:] for ext in Image.EXTENSION.keys()]
+        return [ext.lower()[1:] for ext in Image.EXTENSION]
 
 
 validate_image_file_extension = FileExtensionValidator(

+ 1 - 1
django/db/backends/oracle/base.py

@@ -452,7 +452,7 @@ class FormatStylePlaceholderCursor:
             query = query
         elif hasattr(params, 'keys'):
             # Handle params as dict
-            args = {k: ":%s" % k for k in params.keys()}
+            args = {k: ":%s" % k for k in params}
             query = query % args
         elif unify_by_values and len(params) > 0:
             # Handle params as a dict with unified query parameters by their

+ 1 - 2
django/db/backends/sqlite3/operations.py

@@ -132,10 +132,9 @@ class DatabaseOperations(BaseDatabaseOperations):
             if isinstance(params, (list, tuple)):
                 params = self._quote_params_for_last_executed_query(params)
             else:
-                keys = params.keys()
                 values = tuple(params.values())
                 values = self._quote_params_for_last_executed_query(values)
-                params = dict(zip(keys, values))
+                params = dict(zip(params, values))
             return sql % params
         # For consistency with SQLiteCursorWrapper.execute(), just return sql
         # when there are no parameters. See #13648 and #17158.

+ 4 - 4
django/db/migrations/autodetector.py

@@ -133,7 +133,7 @@ class MigrationAutodetector:
         self.new_model_keys = []
         self.new_proxy_keys = []
         self.new_unmanaged_keys = []
-        for al, mn in sorted(self.from_state.models.keys()):
+        for al, mn in sorted(self.from_state.models):
             model = self.old_apps.get_model(al, mn)
             if not model._meta.managed:
                 self.old_unmanaged_keys.append((al, mn))
@@ -143,7 +143,7 @@ class MigrationAutodetector:
                 else:
                     self.old_model_keys.append((al, mn))
 
-        for al, mn in sorted(self.to_state.models.keys()):
+        for al, mn in sorted(self.to_state.models):
             model = self.new_apps.get_model(al, mn)
             if not model._meta.managed:
                 self.new_unmanaged_keys.append((al, mn))
@@ -249,7 +249,7 @@ class MigrationAutodetector:
             # try to chop it off from the rest and continue, but we only
             # do this if we've already been through the list once before
             # without any chopping and nothing has changed.
-            for app_label in sorted(self.generated_operations.keys()):
+            for app_label in sorted(self.generated_operations):
                 chopped = []
                 dependencies = set()
                 for operation in list(self.generated_operations[app_label]):
@@ -1193,7 +1193,7 @@ class MigrationAutodetector:
             for app_label in list(required_apps):
                 required_apps.update(app_dependencies.get(app_label, set()))
         # Remove all migrations that aren't needed
-        for app_label in list(changes.keys()):
+        for app_label in list(changes):
             if app_label not in required_apps:
                 del changes[app_label]
         return changes

+ 1 - 1
django/db/migrations/state.py

@@ -224,7 +224,7 @@ class ProjectState:
         return cls(app_models)
 
     def __eq__(self, other):
-        if set(self.models.keys()) != set(other.models.keys()):
+        if set(self.models) != set(other.models):
             return False
         if set(self.real_apps) != set(other.real_apps):
             return False

+ 2 - 2
django/db/models/base.py

@@ -1140,7 +1140,7 @@ class Model(metaclass=ModelBase):
 
         # Run unique checks, but only for fields that passed validation.
         if validate_unique:
-            for name in errors.keys():
+            for name in errors:
                 if name != NON_FIELD_ERRORS and name not in exclude:
                     exclude.append(name)
             try:
@@ -1594,7 +1594,7 @@ class Model(metaclass=ModelBase):
         db_alias = None
 
         # Find the minimum max allowed length among all specified db_aliases.
-        for db in settings.DATABASES.keys():
+        for db in settings.DATABASES:
             # skip databases where the model won't be created
             if not router.allow_migrate_model(db, cls):
                 continue

+ 1 - 1
django/db/models/options.py

@@ -192,7 +192,7 @@ class Options:
 
             # Any leftover attributes must be invalid.
             if meta_attrs != {}:
-                raise TypeError("'class Meta' got invalid attribute(s): %s" % ','.join(meta_attrs.keys()))
+                raise TypeError("'class Meta' got invalid attribute(s): %s" % ','.join(meta_attrs))
         else:
             self.verbose_name_plural = format_lazy('{}s', self.verbose_name)
         del self.meta

+ 1 - 1
django/db/models/query.py

@@ -334,7 +334,7 @@ class QuerySet:
             query.add_annotation(aggregate_expr, alias, is_summary=True)
             if not query.annotations[alias].contains_aggregate:
                 raise TypeError("%s is not an aggregate expression" % alias)
-        return query.get_aggregation(self.db, kwargs.keys())
+        return query.get_aggregation(self.db, kwargs)
 
     def count(self):
         """

+ 1 - 1
django/db/models/sql/compiler.py

@@ -820,7 +820,7 @@ class SQLCompiler:
                     select, model._meta, alias, cur_depth + 1,
                     next, restricted)
                 get_related_klass_infos(klass_info, next_klass_infos)
-            fields_not_found = set(requested.keys()).difference(fields_found)
+            fields_not_found = set(requested).difference(fields_found)
             if fields_not_found:
                 invalid_fields = ("'%s'" % s for s in fields_not_found)
                 raise FieldError(

+ 2 - 2
django/db/models/sql/query.py

@@ -756,7 +756,7 @@ class Query:
                 # Join type of 'alias' changed, so re-examine all aliases that
                 # refer to this one.
                 aliases.extend(
-                    join for join in self.alias_map.keys()
+                    join for join in self.alias_map
                     if self.alias_map[join].parent_alias == alias and join not in aliases
                 )
 
@@ -794,7 +794,7 @@ class Query:
         relabelling any references to them in select columns and the where
         clause.
         """
-        assert set(change_map.keys()).intersection(set(change_map.values())) == set()
+        assert set(change_map).intersection(set(change_map.values())) == set()
 
         # 1. Update references in "select" (normal columns plus aliases),
         # "group by" and "where".

+ 2 - 3
django/forms/models.py

@@ -248,8 +248,7 @@ class ModelFormMetaclass(DeclarativeFieldsMetaclass):
 
             # make sure opts.fields doesn't specify an invalid field
             none_model_fields = [k for k, v in fields.items() if not v]
-            missing_fields = (set(none_model_fields) -
-                              set(new_class.declared_fields.keys()))
+            missing_fields = set(none_model_fields) - set(new_class.declared_fields)
             if missing_fields:
                 message = 'Unknown field(s) (%s) specified for %s'
                 message = message % (', '.join(missing_fields),
@@ -317,7 +316,7 @@ class BaseModelForm(BaseForm):
 
             # Exclude fields that failed form validation. There's no need for
             # the model fields to validate them as well.
-            elif field in self._errors.keys():
+            elif field in self._errors:
                 exclude.append(f.name)
 
             # Exclude empty fields that are not required by the form, if the

+ 1 - 1
django/forms/widgets.py

@@ -63,7 +63,7 @@ class Media:
     def render_css(self):
         # To keep rendering order consistent, we can't just iterate over items().
         # We need to sort the keys, and iterate over the sorted list.
-        media = sorted(self._css.keys())
+        media = sorted(self._css)
         return chain.from_iterable([
             format_html(
                 '<link href="{}" type="text/css" media="{}" rel="stylesheet" />',

+ 1 - 1
django/template/context.py

@@ -70,7 +70,7 @@ class BaseContext:
         """
         context = self.dicts[-1]
         for d in reversed(self.dicts):
-            if key in d.keys():
+            if key in d:
                 context = d
                 break
         context[key] = value

+ 1 - 1
django/template/defaulttags.py

@@ -1026,7 +1026,7 @@ def find_library(parser, name):
     except KeyError:
         raise TemplateSyntaxError(
             "'%s' is not a registered tag library. Must be one of:\n%s" % (
-                name, "\n".join(sorted(parser.libraries.keys())),
+                name, "\n".join(sorted(parser.libraries)),
             ),
         )
 

+ 1 - 2
django/urls/resolvers.py

@@ -436,8 +436,7 @@ class RegexURLResolver(LocaleRegexProvider):
                         continue
                     candidate_subs = dict(zip(params, text_args))
                 else:
-                    if (set(kwargs.keys()) | set(defaults.keys()) != set(params) |
-                            set(defaults.keys())):
+                    if set(kwargs) | set(defaults) != set(params) | set(defaults):
                         continue
                     matches = True
                     for k, v in defaults.items():

+ 1 - 1
django/utils/datastructures.py

@@ -24,7 +24,7 @@ class OrderedSet:
             pass
 
     def __iter__(self):
-        return iter(self.dict.keys())
+        return iter(self.dict)
 
     def __contains__(self, item):
         return item in self.dict

+ 1 - 1
django/utils/formats.py

@@ -131,7 +131,7 @@ def get_format(format_type, lang=None, use_l10n=None):
         if format_type not in FORMAT_SETTINGS:
             return format_type
         val = getattr(settings, format_type)
-    elif format_type in ISO_INPUT_FORMATS.keys():
+    elif format_type in ISO_INPUT_FORMATS:
         # If a list of input formats from one of the format_modules was
         # retrieved, make sure the ISO_INPUT_FORMATS are in this list.
         val = list(val)

+ 1 - 1
django/utils/functional.py

@@ -82,7 +82,7 @@ def lazy(func, *resultclasses):
         def __prepare_class__(cls):
             for resultclass in resultclasses:
                 for type_ in resultclass.mro():
-                    for method_name in type_.__dict__.keys():
+                    for method_name in type_.__dict__:
                         # All __promise__ return the same wrapper method, they
                         # look up the correct implementation when called.
                         if hasattr(cls, method_name):

+ 1 - 1
django/utils/termcolors.py

@@ -199,7 +199,7 @@ def parse_color_setting(config_string):
                 definition['bg'] = colors[-1]
 
             # All remaining instructions are options
-            opts = tuple(s for s in styles if s in opt_dict.keys())
+            opts = tuple(s for s in styles if s in opt_dict)
             if opts:
                 definition['opts'] = opts
 

+ 1 - 1
tests/backends/tests.py

@@ -755,7 +755,7 @@ class BackendTestCase(TransactionTestCase):
 
         self.assertIsInstance(connection.queries, list)
         self.assertIsInstance(connection.queries[0], dict)
-        self.assertCountEqual(connection.queries[0].keys(), ['sql', 'time'])
+        self.assertCountEqual(connection.queries[0], ['sql', 'time'])
 
         reset_queries()
         self.assertEqual(0, len(connection.queries))

+ 1 - 1
tests/basic/tests.py

@@ -602,7 +602,7 @@ class ManagerTest(SimpleTestCase):
         `Manager` will need to be added to `ManagerTest.QUERYSET_PROXY_METHODS`.
         """
         self.assertEqual(
-            sorted(BaseManager._get_queryset_methods(QuerySet).keys()),
+            sorted(BaseManager._get_queryset_methods(QuerySet)),
             sorted(self.QUERYSET_PROXY_METHODS),
         )
 

+ 1 - 1
tests/cache/tests.py

@@ -240,7 +240,7 @@ def caches_setting_for_tests(base=None, exclude=None, **params):
     # params -> _caches_setting_base -> base
     base = base or {}
     exclude = exclude or set()
-    setting = {k: base.copy() for k in _caches_setting_base.keys() if k not in exclude}
+    setting = {k: base.copy() for k in _caches_setting_base if k not in exclude}
     for key, cache_params in setting.items():
         cache_params.update(_caches_setting_base[key])
         cache_params.update(params)

+ 1 - 1
tests/file_uploads/views.py

@@ -125,7 +125,7 @@ def file_upload_getlist_count(request):
     """
     file_counts = {}
 
-    for key in request.FILES.keys():
+    for key in request.FILES:
         file_counts[key] = len(request.FILES.getlist(key))
     return JsonResponse(file_counts)
 

+ 6 - 6
tests/forms_tests/tests/test_forms.py

@@ -1558,19 +1558,19 @@ value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#39;xss&#39;)&lt;/
                 self.order_fields(field_order=TestForm.field_order)
 
         p = TestFormParent()
-        self.assertEqual(list(p.fields.keys()), TestFormParent.field_order)
+        self.assertEqual(list(p.fields), TestFormParent.field_order)
         p = TestFormRemove()
-        self.assertEqual(list(p.fields.keys()), TestForm.field_order)
+        self.assertEqual(list(p.fields), TestForm.field_order)
         p = TestFormMissing()
-        self.assertEqual(list(p.fields.keys()), TestForm.field_order)
+        self.assertEqual(list(p.fields), TestForm.field_order)
         p = TestForm()
-        self.assertEqual(list(p.fields.keys()), TestFormMissing.field_order)
+        self.assertEqual(list(p.fields), TestFormMissing.field_order)
         p = TestFormInit()
         order = list(TestForm.field_order) + ['field1']
-        self.assertEqual(list(p.fields.keys()), order)
+        self.assertEqual(list(p.fields), order)
         TestForm.field_order = ['unknown']
         p = TestForm()
-        self.assertEqual(list(p.fields.keys()), ['field1', 'field2', 'field4', 'field5', 'field6', 'field3'])
+        self.assertEqual(list(p.fields), ['field1', 'field2', 'field4', 'field5', 'field6', 'field3'])
 
     def test_form_html_attributes(self):
         # Some Field classes have an effect on the HTML attributes of their associated

+ 5 - 7
tests/gis_tests/gdal_tests/test_ds.py

@@ -120,11 +120,9 @@ class DataSourceTest(unittest.TestCase):
                     layer.__getitem__(50000)
 
                 if hasattr(source, 'field_values'):
-                    fld_names = source.field_values.keys()
-
                     # Testing `Layer.get_fields` (which uses Layer.__iter__)
-                    for fld_name in fld_names:
-                        self.assertEqual(source.field_values[fld_name], layer.get_fields(fld_name))
+                    for fld_name, fld_value in source.field_values.items():
+                        self.assertEqual(fld_value, layer.get_fields(fld_name))
 
                     # Testing `Layer.__getitem__`.
                     for i, fid in enumerate(source.fids):
@@ -132,8 +130,8 @@ class DataSourceTest(unittest.TestCase):
                         self.assertEqual(fid, feat.fid)
                         # Maybe this should be in the test below, but we might as well test
                         # the feature values here while in this loop.
-                        for fld_name in fld_names:
-                            self.assertEqual(source.field_values[fld_name][i], feat.get(fld_name))
+                        for fld_name, fld_value in source.field_values.items():
+                            self.assertEqual(fld_value[i], feat.get(fld_name))
 
     def test03b_layer_slice(self):
         "Test indexing and slicing on Layers."
@@ -194,7 +192,7 @@ class DataSourceTest(unittest.TestCase):
 
                     # Testing Feature.__iter__
                     for fld in feat:
-                        self.assertIn(fld.name, source.fields.keys())
+                        self.assertIn(fld.name, source.fields)
 
     def test05_geometries(self):
         "Testing Geometries from Data Source Features."

+ 7 - 3
tests/httpwrappers/tests.py

@@ -53,6 +53,7 @@ class QueryDictTests(SimpleTestCase):
         q = QueryDict()
         self.assertEqual(q.getlist('foo'), [])
         self.assertNotIn('foo', q)
+        self.assertEqual(list(q), [])
         self.assertEqual(list(q.items()), [])
         self.assertEqual(list(q.lists()), [])
         self.assertEqual(list(q.keys()), [])
@@ -83,6 +84,7 @@ class QueryDictTests(SimpleTestCase):
         self.assertIn('foo', q)
         self.assertNotIn('bar', q)
 
+        self.assertEqual(list(q), ['foo'])
         self.assertEqual(list(q.items()), [('foo', 'bar')])
         self.assertEqual(list(q.lists()), [('foo', ['bar'])])
         self.assertEqual(list(q.keys()), ['foo'])
@@ -143,6 +145,7 @@ class QueryDictTests(SimpleTestCase):
         self.assertEqual(q['foo'], 'another')
         self.assertIn('foo', q)
 
+        self.assertCountEqual(q, ['foo', 'name'])
         self.assertCountEqual(q.items(), [('foo', 'another'), ('name', 'john')])
         self.assertCountEqual(q.lists(), [('foo', ['bar', 'baz', 'another']), ('name', ['john'])])
         self.assertCountEqual(q.keys(), ['foo', 'name'])
@@ -186,6 +189,7 @@ class QueryDictTests(SimpleTestCase):
 
         self.assertIn('vote', q)
         self.assertNotIn('foo', q)
+        self.assertEqual(list(q), ['vote'])
         self.assertEqual(list(q.items()), [('vote', 'no')])
         self.assertEqual(list(q.lists()), [('vote', ['yes', 'no'])])
         self.assertEqual(list(q.keys()), ['vote'])
@@ -697,13 +701,13 @@ class CookieTests(unittest.TestCase):
         """
         A single non-standard cookie name doesn't affect all cookies (#13007).
         """
-        self.assertIn('good_cookie', parse_cookie('good_cookie=yes;bad:cookie=yes').keys())
+        self.assertIn('good_cookie', parse_cookie('good_cookie=yes;bad:cookie=yes'))
 
     def test_repeated_nonstandard_keys(self):
         """
         A repeated non-standard name doesn't affect all cookies (#15852).
         """
-        self.assertIn('good_cookie', parse_cookie('a:=b; a:=c; good_cookie=yes').keys())
+        self.assertIn('good_cookie', parse_cookie('a:=b; a:=c; good_cookie=yes'))
 
     def test_python_cookies(self):
         """
@@ -737,7 +741,7 @@ class CookieTests(unittest.TestCase):
         """
         # Chunks without an equals sign appear as unnamed values per
         # https://bugzilla.mozilla.org/show_bug.cgi?id=169091
-        self.assertIn('django_language', parse_cookie('abc=def; unnamed; django_language=en').keys())
+        self.assertIn('django_language', parse_cookie('abc=def; unnamed; django_language=en'))
         # Even a double quote may be an unamed value.
         self.assertEqual(parse_cookie('a=b; "; c=d'), {'a': 'b', '': '"', 'c': 'd'})
         # Spaces in names and values, and an equals sign in values.

+ 1 - 1
tests/invalid_models_tests/test_models.py

@@ -14,7 +14,7 @@ def get_max_column_name_length():
     allowed_len = None
     db_alias = None
 
-    for db in settings.DATABASES.keys():
+    for db in settings.DATABASES:
         connection = connections[db]
         max_name_length = connection.ops.max_name_length()
         if max_name_length is None or connection.features.truncates_names:

+ 2 - 2
tests/lookup/tests.py

@@ -136,7 +136,7 @@ class LookupTests(TestCase):
         Author.objects.bulk_create([Author() for i in range(test_range - Author.objects.count())])
         authors = {author.pk: author for author in Author.objects.all()}
         with self.assertNumQueries(expected_num_queries):
-            self.assertEqual(Author.objects.in_bulk(authors.keys()), authors)
+            self.assertEqual(Author.objects.in_bulk(authors), authors)
 
     def test_values(self):
         # values() returns a list of dictionaries instead of object instances --
@@ -207,7 +207,7 @@ class LookupTests(TestCase):
             'id_plus_eight': 'id+8',
         }
         self.assertSequenceEqual(
-            Article.objects.filter(id=self.a1.id).extra(select=data).values(*data.keys()),
+            Article.objects.filter(id=self.a1.id).extra(select=data).values(*data),
             [{
                 'id_plus_one': self.a1.id + 1,
                 'id_plus_two': self.a1.id + 2,

+ 1 - 1
tests/messages_tests/base.py

@@ -172,7 +172,7 @@ class BaseTests:
             'messages': ['Test message %d' % x for x in range(5)],
         }
         show_url = reverse('show_template_response')
-        for level in self.levels.keys():
+        for level in self.levels:
             add_url = reverse('add_template_response', args=(level,))
             response = self.client.post(add_url, data, follow=True)
             self.assertRedirects(response, show_url)

+ 2 - 2
tests/migrations/test_operations.py

@@ -207,7 +207,7 @@ class OperationTests(OperationTestBase):
         definition = operation.deconstruct()
         self.assertEqual(definition[0], "CreateModel")
         self.assertEqual(definition[1], [])
-        self.assertEqual(sorted(definition[2].keys()), ["fields", "name"])
+        self.assertEqual(sorted(definition[2]), ["fields", "name"])
         # And default manager not in set
         operation = migrations.CreateModel("Foo", fields=[], managers=[("objects", models.Manager())])
         definition = operation.deconstruct()
@@ -430,7 +430,7 @@ class OperationTests(OperationTestBase):
         definition = operation.deconstruct()
         self.assertEqual(definition[0], "CreateModel")
         self.assertEqual(definition[1], [])
-        self.assertEqual(sorted(definition[2].keys()), ["bases", "fields", "name", "options"])
+        self.assertEqual(sorted(definition[2]), ["bases", "fields", "name", "options"])
 
     def test_create_unmanaged_model(self):
         """

+ 9 - 9
tests/model_forms/tests.py

@@ -2783,7 +2783,7 @@ class ModelFormInheritanceTests(SimpleTestCase):
                 model = Writer
                 fields = '__all__'
 
-        self.assertEqual(list(ModelForm().fields.keys()), ['name', 'age'])
+        self.assertEqual(list(ModelForm().fields), ['name', 'age'])
 
     def test_field_removal(self):
         class ModelForm(forms.ModelForm):
@@ -2800,13 +2800,13 @@ class ModelFormInheritanceTests(SimpleTestCase):
         class Form2(forms.Form):
             foo = forms.IntegerField()
 
-        self.assertEqual(list(ModelForm().fields.keys()), ['name'])
-        self.assertEqual(list(type('NewForm', (Mixin, Form), {})().fields.keys()), [])
-        self.assertEqual(list(type('NewForm', (Form2, Mixin, Form), {})().fields.keys()), ['foo'])
-        self.assertEqual(list(type('NewForm', (Mixin, ModelForm, Form), {})().fields.keys()), ['name'])
-        self.assertEqual(list(type('NewForm', (ModelForm, Mixin, Form), {})().fields.keys()), ['name'])
-        self.assertEqual(list(type('NewForm', (ModelForm, Form, Mixin), {})().fields.keys()), ['name', 'age'])
-        self.assertEqual(list(type('NewForm', (ModelForm, Form), {'age': None})().fields.keys()), ['name'])
+        self.assertEqual(list(ModelForm().fields), ['name'])
+        self.assertEqual(list(type('NewForm', (Mixin, Form), {})().fields), [])
+        self.assertEqual(list(type('NewForm', (Form2, Mixin, Form), {})().fields), ['foo'])
+        self.assertEqual(list(type('NewForm', (Mixin, ModelForm, Form), {})().fields), ['name'])
+        self.assertEqual(list(type('NewForm', (ModelForm, Mixin, Form), {})().fields), ['name'])
+        self.assertEqual(list(type('NewForm', (ModelForm, Form, Mixin), {})().fields), ['name', 'age'])
+        self.assertEqual(list(type('NewForm', (ModelForm, Form), {'age': None})().fields), ['name'])
 
     def test_field_removal_name_clashes(self):
         """
@@ -2974,7 +2974,7 @@ class FormFieldCallbackTests(SimpleTestCase):
         class InheritedForm(NewForm):
             pass
 
-        for name in NewForm.base_fields.keys():
+        for name in NewForm.base_fields:
             self.assertEqual(
                 type(InheritedForm.base_fields[name].widget),
                 type(NewForm.base_fields[name].widget)

+ 1 - 1
tests/model_formsets/tests.py

@@ -1463,7 +1463,7 @@ class ModelFormsetTest(TestCase):
         # a formset for a Model that has a custom primary key that still needs to be
         # added to the formset automatically
         FormSet = modelformset_factory(ClassyMexicanRestaurant, fields=["tacos_are_yummy"])
-        self.assertEqual(sorted(FormSet().forms[0].fields.keys()), ['tacos_are_yummy', 'the_restaurant'])
+        self.assertEqual(sorted(FormSet().forms[0].fields), ['tacos_are_yummy', 'the_restaurant'])
 
     def test_model_formset_with_initial_model_instance(self):
         # has_changed should compare model instance and primary key

+ 8 - 8
tests/requests/tests.py

@@ -21,10 +21,10 @@ from django.utils.timezone import utc
 class RequestsTests(SimpleTestCase):
     def test_httprequest(self):
         request = HttpRequest()
-        self.assertEqual(list(request.GET.keys()), [])
-        self.assertEqual(list(request.POST.keys()), [])
-        self.assertEqual(list(request.COOKIES.keys()), [])
-        self.assertEqual(list(request.META.keys()), [])
+        self.assertEqual(list(request.GET), [])
+        self.assertEqual(list(request.POST), [])
+        self.assertEqual(list(request.COOKIES), [])
+        self.assertEqual(list(request.META), [])
 
         # .GET and .POST should be QueryDicts
         self.assertEqual(request.GET.urlencode(), '')
@@ -76,11 +76,11 @@ class RequestsTests(SimpleTestCase):
             'CONTENT_TYPE': 'text/html; charset=utf8',
             'wsgi.input': BytesIO(b''),
         })
-        self.assertEqual(list(request.GET.keys()), [])
-        self.assertEqual(list(request.POST.keys()), [])
-        self.assertEqual(list(request.COOKIES.keys()), [])
+        self.assertEqual(list(request.GET), [])
+        self.assertEqual(list(request.POST), [])
+        self.assertEqual(list(request.COOKIES), [])
         self.assertEqual(
-            set(request.META.keys()),
+            set(request.META),
             {'PATH_INFO', 'REQUEST_METHOD', 'SCRIPT_NAME', 'CONTENT_TYPE', 'wsgi.input'}
         )
         self.assertEqual(request.META['PATH_INFO'], 'bogus')

+ 1 - 1
tests/servers/test_basehttp.py

@@ -46,7 +46,7 @@ class WSGIRequestHandlerTestCase(SimpleTestCase):
                     self.assertIn('GET A %d' % status_code, messages[0])
 
                     # Incorrect levels shouldn't have any messages.
-                    for wrong_level in level_status_codes.keys():
+                    for wrong_level in level_status_codes:
                         if wrong_level != level:
                             messages = _log_level_code(wrong_level, status_code)
                             self.assertEqual(len(messages), 0)

+ 1 - 1
tests/test_client/views.py

@@ -330,4 +330,4 @@ def django_project_redirect(request):
 
 def upload_view(request):
     """Prints keys of request.FILES to the response."""
-    return HttpResponse(', '.join(request.FILES.keys()))
+    return HttpResponse(', '.join(request.FILES))

+ 1 - 1
tests/user_commands/management/commands/dance.py

@@ -18,6 +18,6 @@ class Command(BaseCommand):
             raise CommandError()
         if options['verbosity'] > 0:
             self.stdout.write("I don't feel like dancing %s." % options["style"])
-            self.stdout.write(','.join(options.keys()))
+            self.stdout.write(','.join(options))
         if options['integer'] > 0:
             self.stdout.write("You passed %d as a positional argument." % options['integer'])

+ 2 - 2
tests/utils_tests/test_datastructures.py

@@ -94,8 +94,8 @@ class MultiValueDictTests(SimpleTestCase):
             'pm': ['Rory'],
         })
         d = mvd.dict()
-        self.assertEqual(sorted(d.keys()), sorted(mvd.keys()))
-        for key in mvd.keys():
+        self.assertEqual(sorted(d), sorted(mvd))
+        for key in mvd:
             self.assertEqual(d[key], mvd[key])
 
         self.assertEqual({}, MultiValueDict().dict())