From d2afa5eb2308e672b6313876856e32e2561b90f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B8=D0=BB=D1=8F=D0=BD=20=D0=9F=D0=B0=D0=BB=D0=B0?= =?UTF-8?q?=D1=83=D0=B7=D0=BE=D0=B2?= Date: Wed, 29 Nov 2017 11:54:34 -0500 Subject: [PATCH] Fixed #28860 -- Removed unnecessary len() calls. --- django/contrib/admin/tests.py | 2 +- django/contrib/contenttypes/admin.py | 2 +- .../contrib/flatpages/templatetags/flatpages.py | 3 +-- django/contrib/gis/geoip2/resources.py | 2 +- django/contrib/gis/geos/polygon.py | 2 +- django/core/management/__init__.py | 2 +- .../management/commands/createcachetable.py | 2 +- django/core/management/commands/dumpdata.py | 2 +- .../core/management/commands/makemigrations.py | 9 +++++---- django/db/backends/oracle/base.py | 2 +- django/db/backends/postgresql/operations.py | 2 +- django/db/migrations/autodetector.py | 2 +- django/db/migrations/graph.py | 2 +- django/db/migrations/loader.py | 2 +- django/db/migrations/questioner.py | 2 +- django/db/migrations/topological_sort.py | 2 +- django/db/models/base.py | 6 +++--- django/db/models/expressions.py | 4 ++-- django/db/models/fields/related.py | 4 ++-- django/db/models/query.py | 4 ++-- django/db/models/sql/query.py | 2 +- django/forms/models.py | 4 ++-- django/template/defaultfilters.py | 2 +- django/template/defaulttags.py | 4 ++-- django/test/testcases.py | 17 +++++++++-------- django/urls/resolvers.py | 2 +- django/utils/http.py | 2 +- django/utils/text.py | 2 +- django/utils/translation/trans_real.py | 10 +++++----- django/views/generic/dates.py | 2 +- django/views/generic/list.py | 2 +- docs/_ext/djangodocs.py | 2 +- tests/migrations/test_autodetector.py | 2 +- 33 files changed, 56 insertions(+), 55 deletions(-) diff --git a/django/contrib/admin/tests.py b/django/contrib/admin/tests.py index 80ff769846e..f623e6605c0 100644 --- a/django/contrib/admin/tests.py +++ b/django/contrib/admin/tests.py @@ -158,7 +158,7 @@ class AdminSeleniumTestCase(SeleniumTestCase, StaticLiveServerTestCase): # to be the case. with self.disable_implicit_wait(): self.wait_until( - lambda driver: len(driver.find_elements_by_css_selector(options_selector)) == 0 + lambda driver: not driver.find_elements_by_css_selector(options_selector) ) def assertSelectOptions(self, selector, values): diff --git a/django/contrib/contenttypes/admin.py b/django/contrib/contenttypes/admin.py index 063c37698a3..dd20249e622 100644 --- a/django/contrib/contenttypes/admin.py +++ b/django/contrib/contenttypes/admin.py @@ -25,7 +25,7 @@ class GenericInlineModelAdminChecks(InlineModelAdminChecks): f for f in obj.model._meta.private_fields if isinstance(f, GenericForeignKey) ] - if len(gfks) == 0: + if not gfks: return [ checks.Error( "'%s.%s' has no GenericForeignKey." % ( diff --git a/django/contrib/flatpages/templatetags/flatpages.py b/django/contrib/flatpages/templatetags/flatpages.py index 985083d3638..1d99104ce37 100644 --- a/django/contrib/flatpages/templatetags/flatpages.py +++ b/django/contrib/flatpages/templatetags/flatpages.py @@ -74,8 +74,7 @@ def get_flatpages(parser, token): "['url_starts_with'] [for user] as context_name" % {'tag_name': bits[0]}) # Must have at 3-6 bits in the tag - if len(bits) >= 3 and len(bits) <= 6: - + if 3 <= len(bits) <= 6: # If there's an even number of bits, there's no prefix if len(bits) % 2 == 0: prefix = bits[1] diff --git a/django/contrib/gis/geoip2/resources.py b/django/contrib/gis/geoip2/resources.py index 2ba5d8ac310..3de33461942 100644 --- a/django/contrib/gis/geoip2/resources.py +++ b/django/contrib/gis/geoip2/resources.py @@ -9,7 +9,7 @@ def City(response): 'latitude': response.location.latitude, 'longitude': response.location.longitude, 'postal_code': response.postal.code, - 'region': response.subdivisions[0].iso_code if len(response.subdivisions) else None, + 'region': response.subdivisions[0].iso_code if response.subdivisions else None, 'time_zone': response.location.time_zone, } diff --git a/django/contrib/gis/geos/polygon.py b/django/contrib/gis/geos/polygon.py index 26fcfbf42ac..9ed3b946bbc 100644 --- a/django/contrib/gis/geos/polygon.py +++ b/django/contrib/gis/geos/polygon.py @@ -37,7 +37,7 @@ class Polygon(GEOSGeometry): # If initialized as Polygon(shell, (LinearRing, LinearRing)) [for backward-compatibility] if n_holes == 1 and isinstance(init_holes[0], (tuple, list)): - if len(init_holes[0]) == 0: + if not init_holes[0]: init_holes = () n_holes = 0 elif isinstance(init_holes[0][0], LinearRing): diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py index 77c060c21ce..d6395e0a03e 100644 --- a/django/core/management/__init__.py +++ b/django/core/management/__init__.py @@ -351,7 +351,7 @@ class ManagementUtility: if subcommand == 'help': if '--commands' in args: sys.stdout.write(self.main_help_text(commands_only=True) + '\n') - elif len(options.args) < 1: + elif not options.args: sys.stdout.write(self.main_help_text() + '\n') else: self.fetch_command(options.args[0]).print_help(self.prog_name, options.args[0]) diff --git a/django/core/management/commands/createcachetable.py b/django/core/management/commands/createcachetable.py index 8f9482d3901..3acb3ddf72f 100644 --- a/django/core/management/commands/createcachetable.py +++ b/django/core/management/commands/createcachetable.py @@ -33,7 +33,7 @@ class Command(BaseCommand): db = options['database'] self.verbosity = options['verbosity'] dry_run = options['dry_run'] - if len(tablenames): + if tablenames: # Legacy behavior, tablename specified as argument for tablename in tablenames: self.create_table(db, tablename, dry_run) diff --git a/django/core/management/commands/dumpdata.py b/django/core/management/commands/dumpdata.py index d32b191b5a7..ae00a3b6bf0 100644 --- a/django/core/management/commands/dumpdata.py +++ b/django/core/management/commands/dumpdata.py @@ -84,7 +84,7 @@ class Command(BaseCommand): excluded_models, excluded_apps = parse_apps_and_model_labels(excludes) - if len(app_labels) == 0: + if not app_labels: if primary_keys: raise CommandError("You can only use --pks option with one model") app_list = OrderedDict.fromkeys( diff --git a/django/core/management/commands/makemigrations.py b/django/core/management/commands/makemigrations.py index 45fce19b0f9..777577f1488 100644 --- a/django/core/management/commands/makemigrations.py +++ b/django/core/management/commands/makemigrations.py @@ -162,10 +162,11 @@ class Command(BaseCommand): if not changes: # No changes? Tell them. if self.verbosity >= 1: - if len(app_labels) == 1: - self.stdout.write("No changes detected in app '%s'" % app_labels.pop()) - elif len(app_labels) > 1: - self.stdout.write("No changes detected in apps '%s'" % ("', '".join(app_labels))) + if app_labels: + if len(app_labels) == 1: + self.stdout.write("No changes detected in app '%s'" % app_labels.pop()) + else: + self.stdout.write("No changes detected in apps '%s'" % ("', '".join(app_labels))) else: self.stdout.write("No changes detected") else: diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py index ae77de57d05..b697758a36f 100644 --- a/django/db/backends/oracle/base.py +++ b/django/db/backends/oracle/base.py @@ -476,7 +476,7 @@ class FormatStylePlaceholderCursor: # Handle params as dict args = {k: ":%s" % k for k in params} query = query % args - elif unify_by_values and len(params) > 0: + elif unify_by_values and params: # Handle params as a dict with unified query parameters by their # values. It can be used only in single query execute() because # executemany() shares the formatted query with each of the params diff --git a/django/db/backends/postgresql/operations.py b/django/db/backends/postgresql/operations.py index c4a61f7070a..06a46f43035 100644 --- a/django/db/backends/postgresql/operations.py +++ b/django/db/backends/postgresql/operations.py @@ -132,7 +132,7 @@ class DatabaseOperations(BaseDatabaseOperations): for sequence_info in sequences: table_name = sequence_info['table'] column_name = sequence_info['column'] - if not (column_name and len(column_name) > 0): + if not column_name: # This will be the case if it's an m2m using an autogenerated # intermediate table (see BaseDatabaseIntrospection.sequence_list) column_name = 'id' diff --git a/django/db/migrations/autodetector.py b/django/db/migrations/autodetector.py index ece58b9babd..e7a8e20d4ef 100644 --- a/django/db/migrations/autodetector.py +++ b/django/db/migrations/autodetector.py @@ -1219,7 +1219,7 @@ class MigrationAutodetector: return "%s_%s" % (ops[0].model_name_lower, ops[0].name_lower) elif isinstance(ops[0], operations.RemoveField): return "remove_%s_%s" % (ops[0].model_name_lower, ops[0].name_lower) - elif len(ops) > 1: + elif ops: if all(isinstance(o, operations.CreateModel) for o in ops): return "_".join(sorted(o.name_lower for o in ops)) return "auto_%s" % get_migration_name_timestamp() diff --git a/django/db/migrations/graph.py b/django/db/migrations/graph.py index 687a9b3905b..4bb66b76157 100644 --- a/django/db/migrations/graph.py +++ b/django/db/migrations/graph.py @@ -360,7 +360,7 @@ class MigrationGraph: """ if nodes is None: nodes = list(self.leaf_nodes()) - if len(nodes) == 0: + if not nodes: return ProjectState() if not isinstance(nodes[0], tuple): nodes = [nodes] diff --git a/django/db/migrations/loader.py b/django/db/migrations/loader.py index 8a1cf431bd5..180d22cc935 100644 --- a/django/db/migrations/loader.py +++ b/django/db/migrations/loader.py @@ -133,7 +133,7 @@ class MigrationLoader: raise AmbiguityError( "There is more than one migration for '%s' with the prefix '%s'" % (app_label, name_prefix) ) - elif len(results) == 0: + elif not results: raise KeyError("There no migrations for '%s' with the prefix '%s'" % (app_label, name_prefix)) else: return self.disk_migrations[results[0]] diff --git a/django/db/migrations/questioner.py b/django/db/migrations/questioner.py index 7229ca2dbac..337d50844d7 100644 --- a/django/db/migrations/questioner.py +++ b/django/db/migrations/questioner.py @@ -85,7 +85,7 @@ class InteractiveMigrationQuestioner(MigrationQuestioner): result = input("%s " % question) if not result and default is not None: return default - while len(result) < 1 or result[0].lower() not in "yn": + while not result or result[0].lower() not in "yn": result = input("Please answer yes or no: ") return result[0].lower() == "y" diff --git a/django/db/migrations/topological_sort.py b/django/db/migrations/topological_sort.py index 7b1ec7cfc50..e0a22c92362 100644 --- a/django/db/migrations/topological_sort.py +++ b/django/db/migrations/topological_sort.py @@ -10,7 +10,7 @@ def topological_sort_as_sets(dependency_graph): """ todo = dependency_graph.copy() while todo: - current = {node for node, deps in todo.items() if len(deps) == 0} + current = {node for node, deps in todo.items() if not deps} if not current: raise ValueError('Cyclic dependency in graph: {}'.format( diff --git a/django/db/models/base.py b/django/db/models/base.py index 3f4d65571de..cc675c4273c 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -583,7 +583,7 @@ class Model(metaclass=ModelBase): of the field will call this method. """ if fields is not None: - if len(fields) == 0: + if not fields: return if any(LOOKUP_SEP in f for f in fields): raise ValueError( @@ -688,7 +688,7 @@ class Model(metaclass=ModelBase): # If update_fields is empty, skip the save. We do also check for # no-op saves later on for inheritance cases. This bailout is # still needed for skipping signal sending. - if len(update_fields) == 0: + if not update_fields: return update_fields = frozenset(update_fields) @@ -736,7 +736,7 @@ class Model(metaclass=ModelBase): """ using = using or router.db_for_write(self.__class__, instance=self) assert not (force_insert and (force_update or update_fields)) - assert update_fields is None or len(update_fields) > 0 + assert update_fields is None or update_fields cls = origin = self.__class__ # Skip proxies, but keep the origin as the proxy model. if cls._meta.proxy: diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index 82db5c8bf86..9ff79f08a41 100644 --- a/django/db/models/expressions.py +++ b/django/db/models/expressions.py @@ -161,7 +161,7 @@ class BaseExpression: return [] def set_source_expressions(self, exprs): - assert len(exprs) == 0 + assert not exprs def _parse_expressions(self, *expressions): return [ @@ -780,7 +780,7 @@ class ExpressionList(Func): template = '%(expressions)s' def __init__(self, *expressions, **extra): - if len(expressions) == 0: + if not expressions: raise ValueError('%s requires at least one expression.' % self.__class__.__name__) super().__init__(*expressions, **extra) diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index e2e2bb23a64..db0558b5edd 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -600,7 +600,7 @@ class ForeignObject(RelatedField): return name, path, args, kwargs def resolve_related_fields(self): - if len(self.from_fields) < 1 or len(self.from_fields) != len(self.to_fields): + if not self.from_fields or len(self.from_fields) != len(self.to_fields): raise ValueError('Foreign Object from and to fields must be the same non-zero length') if isinstance(self.remote_field.model, str): raise ValueError('Related model %r cannot be resolved' % self.remote_field.model) @@ -1165,7 +1165,7 @@ class ManyToManyField(RelatedField): ) ) - if len(self._validators) > 0: + if self._validators: warnings.append( checks.Warning( 'ManyToManyField does not support validators.', diff --git a/django/db/models/query.py b/django/db/models/query.py index 17dfa6d1363..9de3535bab5 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -1433,7 +1433,7 @@ def prefetch_related_objects(model_instances, *related_lookups): Populate prefetched object caches for a list of model instances based on the lookups/Prefetch instances given. """ - if len(model_instances) == 0: + if not model_instances: return # nothing to do # We need to be able to dynamically add to the list of prefetch_related @@ -1461,7 +1461,7 @@ def prefetch_related_objects(model_instances, *related_lookups): through_attrs = lookup.prefetch_through.split(LOOKUP_SEP) for level, through_attr in enumerate(through_attrs): # Prepare main instances - if len(obj_list) == 0: + if not obj_list: break prefetch_to = lookup.get_current_prefetch_to(level) diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index e7456de0375..ab5c41ed4f9 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -1061,7 +1061,7 @@ class Query: and get_transform(). """ # __exact is the default lookup if one isn't given. - if len(lookups) == 0: + if not lookups: lookups = ['exact'] for name in lookups[:-1]: diff --git a/django/forms/models.py b/django/forms/models.py index 84a0c97de79..3ba7725d53c 100644 --- a/django/forms/models.py +++ b/django/forms/models.py @@ -1006,7 +1006,7 @@ def _get_foreign_key(parent_model, model, fk_name=None, can_fail=False): raise ValueError( "fk_name '%s' is not a ForeignKey to '%s'." % (fk_name, parent_model._meta.label) ) - elif len(fks_to_parent) == 0: + elif not fks_to_parent: raise ValueError( "'%s' has no field named '%s'." % (model._meta.label, fk_name) ) @@ -1021,7 +1021,7 @@ def _get_foreign_key(parent_model, model, fk_name=None, can_fail=False): ] if len(fks_to_parent) == 1: fk = fks_to_parent[0] - elif len(fks_to_parent) == 0: + elif not fks_to_parent: if can_fail: return raise ValueError( diff --git a/django/template/defaultfilters.py b/django/template/defaultfilters.py index d4bed6898d1..c5f520bc336 100644 --- a/django/template/defaultfilters.py +++ b/django/template/defaultfilters.py @@ -568,7 +568,7 @@ def slice_filter(value, arg): try: bits = [] for x in arg.split(':'): - if len(x) == 0: + if not x: bits.append(None) else: bits.append(int(x)) diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py index 143082c47de..84677c9dc03 100644 --- a/django/template/defaulttags.py +++ b/django/template/defaulttags.py @@ -715,7 +715,7 @@ def firstof(parser, token): """ bits = token.split_contents()[1:] asvar = None - if len(bits) < 1: + if not bits: raise TemplateSyntaxError("'firstof' statement requires at least one argument") if len(bits) >= 2 and bits[-2] == 'as': @@ -1363,7 +1363,7 @@ def url(parser, token): asvar = bits[-1] bits = bits[:-2] - if len(bits): + if bits: for bit in bits: match = kwarg_re.match(bit) if not match: diff --git a/django/test/testcases.py b/django/test/testcases.py index 4c32c87da55..c099258befd 100644 --- a/django/test/testcases.py +++ b/django/test/testcases.py @@ -114,11 +114,12 @@ class _AssertTemplateUsedContext: if not self.test(): message = self.message() - if len(self.rendered_templates) == 0: - message += ' No template was rendered.' - else: + if self.rendered_templates: message += ' Following templates were rendered: %s' % ( - ', '.join(self.rendered_template_names)) + ', '.join(self.rendered_template_names) + ) + else: + message += ' No template was rendered.' self.test_case.fail(message) @@ -255,7 +256,7 @@ class SimpleTestCase(unittest.TestCase): if hasattr(response, 'redirect_chain'): # The request was a followed redirect self.assertTrue( - len(response.redirect_chain) > 0, + response.redirect_chain, msg_prefix + "Response didn't redirect as expected: Response code was %d (expected %d)" % (response.status_code, status_code) ) @@ -488,7 +489,7 @@ class SimpleTestCase(unittest.TestCase): elif form_index is not None: non_field_errors = context[formset].forms[form_index].non_field_errors() self.assertFalse( - len(non_field_errors) == 0, + not non_field_errors, msg_prefix + "The formset '%s', form %d in context %d " "does not contain any non-field errors." % (formset, form_index, i) ) @@ -501,7 +502,7 @@ class SimpleTestCase(unittest.TestCase): else: non_form_errors = context[formset].non_form_errors() self.assertFalse( - len(non_form_errors) == 0, + not non_form_errors, msg_prefix + "The formset '%s' in context %d does not " "contain any non-form errors." % (formset, i) ) @@ -602,7 +603,7 @@ class SimpleTestCase(unittest.TestCase): kwargs: Extra kwargs. """ callable_obj = None - if len(args): + if args: callable_obj = args[0] args = args[1:] diff --git a/django/urls/resolvers.py b/django/urls/resolvers.py index b8a33aaf7d5..55785a696fd 100644 --- a/django/urls/resolvers.py +++ b/django/urls/resolvers.py @@ -379,7 +379,7 @@ class URLResolver: self._local = threading.local() def __repr__(self): - if isinstance(self.urlconf_name, list) and len(self.urlconf_name): + if isinstance(self.urlconf_name, list) and self.urlconf_name: # Don't bother to output the whole list, it can be huge urlconf_repr = '<%s list>' % self.urlconf_name[0].__class__.__name__ else: diff --git a/django/utils/http.py b/django/utils/http.py index 48dacf4b280..7e4e58229ff 100644 --- a/django/utils/http.py +++ b/django/utils/http.py @@ -420,7 +420,7 @@ def limited_parse_qsl(qs, keep_blank_values=False, encoding='utf-8', nv.append('') else: continue - if len(nv[1]) or keep_blank_values: + if nv[1] or keep_blank_values: name = nv[0].replace('+', ' ') name = unquote(name, encoding=encoding, errors=errors) value = nv[1].replace('+', ' ') diff --git a/django/utils/text.py b/django/utils/text.py index 3e04f8bec77..e69f1e16c8b 100644 --- a/django/utils/text.py +++ b/django/utils/text.py @@ -247,7 +247,7 @@ def get_text_list(list_, last_word=gettext_lazy('or')): >>> get_text_list([]) '' """ - if len(list_) == 0: + if not list_: return '' if len(list_) == 1: return str(list_[0]) diff --git a/django/utils/translation/trans_real.py b/django/utils/translation/trans_real.py index c640c42a372..cb8e79287df 100644 --- a/django/utils/translation/trans_real.py +++ b/django/utils/translation/trans_real.py @@ -304,15 +304,15 @@ def gettext(message): eol_message = message.replace('\r\n', '\n').replace('\r', '\n') - if len(eol_message) == 0: - # Return an empty value of the corresponding type if an empty message - # is given, instead of metadata, which is the default gettext behavior. - result = type(message)("") - else: + if eol_message: _default = _default or translation(settings.LANGUAGE_CODE) translation_object = getattr(_active, "value", _default) result = translation_object.gettext(eol_message) + else: + # Return an empty value of the corresponding type if an empty message + # is given, instead of metadata, which is the default gettext behavior. + result = type(message)('') if isinstance(message, SafeData): return mark_safe(result) diff --git a/django/views/generic/dates.py b/django/views/generic/dates.py index 2aedf3aacd4..1673a7a263f 100644 --- a/django/views/generic/dates.py +++ b/django/views/generic/dates.py @@ -333,7 +333,7 @@ class BaseDateListView(MultipleObjectMixin, DateMixin, View): if not allow_empty: # When pagination is enabled, it's better to do a cheap query # than to load the unpaginated queryset in memory. - is_empty = len(qs) == 0 if paginate_by is None else not qs.exists() + is_empty = not qs if paginate_by is None else not qs.exists() if is_empty: raise Http404(_("No %(verbose_name_plural)s available") % { 'verbose_name_plural': qs.model._meta.verbose_name_plural, diff --git a/django/views/generic/list.py b/django/views/generic/list.py index 6753c1ab225..00e5e5df2b8 100644 --- a/django/views/generic/list.py +++ b/django/views/generic/list.py @@ -149,7 +149,7 @@ class BaseListView(MultipleObjectMixin, View): if self.get_paginate_by(self.object_list) is not None and hasattr(self.object_list, 'exists'): is_empty = not self.object_list.exists() else: - is_empty = len(self.object_list) == 0 + is_empty = not self.object_list if is_empty: raise Http404(_("Empty list and '%(class_name)s.allow_empty' is False.") % { 'class_name': self.__class__.__name__, diff --git a/docs/_ext/djangodocs.py b/docs/_ext/djangodocs.py index 66e87cdddf0..21abe990630 100644 --- a/docs/_ext/djangodocs.py +++ b/docs/_ext/djangodocs.py @@ -277,7 +277,7 @@ class DjangoHTMLTranslator(HTMLTranslator): if version_text: title = "%s%s" % ( version_text % node['version'], - ":" if len(node) else "." + ":" if node else "." ) self.body.append('%s ' % title) diff --git a/tests/migrations/test_autodetector.py b/tests/migrations/test_autodetector.py index 95aeec57aa0..a111b8f70de 100644 --- a/tests/migrations/test_autodetector.py +++ b/tests/migrations/test_autodetector.py @@ -1164,7 +1164,7 @@ class AutodetectorTests(TestCase): def test(from_state, to_state, msg): changes = self.get_changes([from_state], [to_state]) - if len(changes) > 0: + if changes: ops = ', '.join(o.__class__.__name__ for o in changes['a'][0].operations) self.fail('Created operation(s) %s from %s' % (ops, msg))