Browse Source

Fixed #28996 -- Simplified some boolean constructs and removed trivial continue statements.

Дилян Палаузов 7 years ago
parent
commit
a38ae914d8

+ 2 - 3
django/contrib/admin/filters.py

@@ -152,9 +152,8 @@ class FieldListFilter(ListFilter):
     @classmethod
     def create(cls, field, request, params, model, model_admin, field_path):
         for test, list_filter_class in cls._field_list_filters:
-            if not test(field):
-                continue
-            return list_filter_class(field, request, params, model, model_admin, field_path=field_path)
+            if test(field):
+                return list_filter_class(field, request, params, model, model_admin, field_path=field_path)
 
 
 class RelatedFieldListFilter(FieldListFilter):

+ 2 - 3
django/contrib/admin/helpers.py

@@ -367,9 +367,8 @@ class InlineFieldset(Fieldset):
     def __iter__(self):
         fk = getattr(self.formset, "fk", None)
         for field in self.fields:
-            if fk and fk.name == field:
-                continue
-            yield Fieldline(self.form, field, self.readonly_fields, model_admin=self.model_admin)
+            if not fk or fk.name != field:
+                yield Fieldline(self.form, field, self.readonly_fields, model_admin=self.model_admin)
 
 
 class AdminErrorList(forms.utils.ErrorList):

+ 3 - 7
django/contrib/admin/options.py

@@ -831,10 +831,7 @@ class ModelAdmin(BaseModelAdmin):
         # Then gather them from the model admin and all parent classes,
         # starting with self and working back up.
         for klass in self.__class__.mro()[::-1]:
-            class_actions = getattr(klass, 'actions', [])
-            # Avoid trying to iterate over None
-            if not class_actions:
-                continue
+            class_actions = getattr(klass, 'actions', []) or []
             actions.extend(self.get_action(action) for action in class_actions)
 
         # get_action might have returned None, so filter any of those out.
@@ -1498,11 +1495,10 @@ class ModelAdmin(BaseModelAdmin):
         ModelForm = self.get_form(request, obj)
         if request.method == 'POST':
             form = ModelForm(request.POST, request.FILES, instance=obj)
-            if form.is_valid():
-                form_validated = True
+            form_validated = form.is_valid()
+            if form_validated:
                 new_object = self.save_form(request, form, change=not add)
             else:
-                form_validated = False
                 new_object = form.instance
             formsets, inline_instances = self._create_formsets(request, new_object, change=not add)
             if all_valid(formsets) and form_validated:

+ 3 - 4
django/contrib/admin/templatetags/admin_list.py

@@ -128,10 +128,9 @@ def result_headers(cl):
         order_type = ''
         new_order_type = 'asc'
         sort_priority = 0
-        sorted = False
         # Is it currently being sorted on?
-        if i in ordering_field_columns:
-            sorted = True
+        is_sorted = i in ordering_field_columns
+        if is_sorted:
             order_type = ordering_field_columns.get(i).lower()
             sort_priority = list(ordering_field_columns).index(i) + 1
             th_classes.append('sorted %sending' % order_type)
@@ -165,7 +164,7 @@ def result_headers(cl):
         yield {
             "text": text,
             "sortable": True,
-            "sorted": sorted,
+            "sorted": is_sorted,
             "ascending": order_type == "asc",
             "sort_priority": sort_priority,
             "url_primary": cl.get_query_string({ORDER_VAR: '.'.join(o_list_primary)}),

+ 2 - 5
django/contrib/admin/utils.py

@@ -53,11 +53,8 @@ def prepare_lookup_value(key, value):
     if key.endswith('__in'):
         value = value.split(',')
     # if key ends with __isnull, special case '' and the string literals 'false' and '0'
-    if key.endswith('__isnull'):
-        if value.lower() in ('', 'false', '0'):
-            value = False
-        else:
-            value = True
+    elif key.endswith('__isnull'):
+        value = value.lower() not in ('', 'false', '0')
     return value
 
 

+ 2 - 3
django/contrib/admin/views/main.py

@@ -378,9 +378,8 @@ class ChangeList:
             else:
                 if isinstance(field.remote_field, models.ManyToOneRel):
                     # <FK>_id field names don't require a join.
-                    if field_name == field.get_attname():
-                        continue
-                    return True
+                    if field_name != field.get_attname():
+                        return True
         return False
 
     def url_for_result(self, result):

+ 1 - 2
django/contrib/admin/widgets.py

@@ -438,8 +438,7 @@ class AutocompleteMixin:
                 str(option_value) in value and
                 (has_selected is False or self.allow_multiple_selected)
             )
-            if selected is True and has_selected is False:
-                has_selected = True
+            has_selected |= selected
             index = len(default[1])
             subgroup = default[1]
             subgroup.append(self.create_option(name, option_value, option_label, selected_choices, index))

+ 5 - 6
django/contrib/contenttypes/management/commands/remove_stale_contenttypes.py

@@ -41,12 +41,11 @@ class Command(BaseCommand):
                         collector.collect([ct])
 
                         for obj_type, objs in collector.data.items():
-                            if objs == {ct}:
-                                continue
-                            ct_info.append('    - %s %s object(s)' % (
-                                len(objs),
-                                obj_type._meta.label,
-                            ))
+                            if objs != {ct}:
+                                ct_info.append('    - %s %s object(s)' % (
+                                    len(objs),
+                                    obj_type._meta.label,
+                                ))
                     content_type_display = '\n'.join(ct_info)
                     self.stdout.write("""Some content types in your database are stale and can be deleted.
 Any objects that depend on these content types will also be deleted.

+ 0 - 3
django/contrib/gis/gdal/geometries.py

@@ -142,12 +142,9 @@ class OGRGeometry(GDALBase):
     def _from_json(geom_input):
         ptr = capi.from_json(geom_input)
         if GDAL_VERSION < (2, 0):
-            has_srs = True
             try:
                 capi.get_geom_srs(ptr)
             except SRSException:
-                has_srs = False
-            if not has_srs:
                 srs = SpatialReference(4326)
                 capi.assign_srs(ptr, srs.ptr)
         return ptr

+ 8 - 9
django/contrib/gis/geos/linestring.py

@@ -49,7 +49,14 @@ class LineString(LinearGeometryMixin, GEOSGeometry):
                 )
             )
 
-        if isinstance(coords, (tuple, list)):
+        numpy_coords = not isinstance(coords, (tuple, list))
+        if numpy_coords:
+            shape = coords.shape  # Using numpy's shape.
+            if len(shape) != 2:
+                raise TypeError('Too many dimensions.')
+            self._checkdim(shape[1])
+            ndim = shape[1]
+        else:
             # Getting the number of coords and the number of dimensions -- which
             #  must stay the same, e.g., no LineString((1, 2), (1, 2, 3)).
             ndim = None
@@ -63,14 +70,6 @@ class LineString(LinearGeometryMixin, GEOSGeometry):
                     self._checkdim(ndim)
                 elif len(coord) != ndim:
                     raise TypeError('Dimension mismatch.')
-            numpy_coords = False
-        else:
-            shape = coords.shape  # Using numpy's shape.
-            if len(shape) != 2:
-                raise TypeError('Too many dimensions.')
-            self._checkdim(shape[1])
-            ndim = shape[1]
-            numpy_coords = True
 
         # Creating a coordinate sequence object because it is easier to
         # set the points using its methods.

+ 2 - 4
django/contrib/sessions/backends/file.py

@@ -61,10 +61,8 @@ class SessionStore(SessionBase):
         modification = os.stat(self._key_to_file()).st_mtime
         if settings.USE_TZ:
             modification = datetime.datetime.utcfromtimestamp(modification)
-            modification = modification.replace(tzinfo=timezone.utc)
-        else:
-            modification = datetime.datetime.fromtimestamp(modification)
-        return modification
+            return modification.replace(tzinfo=timezone.utc)
+        return datetime.datetime.fromtimestamp(modification)
 
     def _expiry_date(self, session_data):
         """

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

@@ -86,8 +86,8 @@ class HashedFilesMixin:
         parsed_name = urlsplit(unquote(name))
         clean_name = parsed_name.path.strip()
         filename = (filename and urlsplit(unquote(filename)).path.strip()) or clean_name
-        opened = False
-        if content is None:
+        opened = content is None
+        if opened:
             if not self.exists(filename):
                 raise ValueError("The file '%s' could not be found with %r." % (filename, self))
             try:
@@ -95,7 +95,6 @@ class HashedFilesMixin:
             except IOError:
                 # Handle directory paths and fragments
                 return name
-            opened = True
         try:
             file_hash = self.file_hash(clean_name, content)
         finally:

+ 4 - 7
django/core/checks/templates.py

@@ -17,13 +17,10 @@ E002 = Error(
 
 @register(Tags.templates)
 def check_setting_app_dirs_loaders(app_configs, **kwargs):
-    passed_check = True
-    for conf in settings.TEMPLATES:
-        if not conf.get('APP_DIRS'):
-            continue
-        if 'loaders' in conf.get('OPTIONS', {}):
-            passed_check = False
-    return [] if passed_check else [E001]
+    return [E001] if any(
+        conf.get('APP_DIRS') and 'loaders' in conf.get('OPTIONS', {})
+        for conf in settings.TEMPLATES
+    ) else []
 
 
 @register(Tags.templates)

+ 1 - 4
django/core/files/uploadhandler.py

@@ -160,10 +160,7 @@ class MemoryFileUploadHandler(FileUploadHandler):
         """
         # Check the content-length header to see if we should
         # If the post is too large, we cannot use the Memory handler.
-        if content_length > settings.FILE_UPLOAD_MAX_MEMORY_SIZE:
-            self.activated = False
-        else:
-            self.activated = True
+        self.activated = content_length <= settings.FILE_UPLOAD_MAX_MEMORY_SIZE
 
     def new_file(self, *args, **kwargs):
         super().new_file(*args, **kwargs)

+ 2 - 3
django/core/mail/message.py

@@ -271,9 +271,8 @@ class EmailMessage:
             # Use cached DNS_NAME for performance
             msg['Message-ID'] = make_msgid(domain=DNS_NAME)
         for name, value in self.extra_headers.items():
-            if name.lower() == 'from':  # From is already handled
-                continue
-            msg[name] = value
+            if name.lower() != 'from':  # From is already handled
+                msg[name] = value
         return msg
 
     def recipients(self):

+ 2 - 3
django/core/signing.py

@@ -132,11 +132,10 @@ def loads(s, key=None, salt='django.core.signing', serializer=JSONSerializer, ma
     # TimestampSigner.unsign() returns str but base64 and zlib compression
     # operate on bytes.
     base64d = force_bytes(TimestampSigner(key, salt=salt).unsign(s, max_age=max_age))
-    decompress = False
-    if base64d[:1] == b'.':
+    decompress = base64d[:1] == b'.'
+    if decompress:
         # It's compressed; uncompress it first
         base64d = base64d[1:]
-        decompress = True
     data = b64_decode(base64d)
     if decompress:
         data = zlib.decompress(data)

+ 2 - 3
django/db/backends/base/schema.py

@@ -570,12 +570,11 @@ class BaseDatabaseSchemaEditor:
             # db_index=True.
             index_names = self._constraint_names(model, [old_field.column], index=True, type_=Index.suffix)
             for index_name in index_names:
-                if index_name in meta_index_names:
+                if index_name not in meta_index_names:
                     # The only way to check if an index was created with
                     # db_index=True or with Index(['field'], name='foo')
                     # is to look at its name (refs #28053).
-                    continue
-                self.execute(self._delete_constraint_sql(self.sql_delete_index, model, index_name))
+                    self.execute(self._delete_constraint_sql(self.sql_delete_index, model, index_name))
         # Change check constraints?
         if old_db_params['check'] != new_db_params['check'] and old_db_params['check']:
             constraint_names = self._constraint_names(model, [old_field.column], check=True)

+ 8 - 9
django/db/migrations/autodetector.py

@@ -261,8 +261,8 @@ class MigrationAutodetector:
                     deps_satisfied = True
                     operation_dependencies = set()
                     for dep in operation._auto_deps:
-                        is_swappable_dep = False
-                        if dep[0] == "__setting__":
+                        is_swappable_dep = dep[0] == '__setting__'
+                        if is_swappable_dep:
                             # We need to temporarily resolve the swappable dependency to prevent
                             # circular references. While keeping the dependency checks on the
                             # resolved model we still add the swappable dependencies.
@@ -270,7 +270,6 @@ class MigrationAutodetector:
                             resolved_app_label, resolved_object_name = getattr(settings, dep[1]).split('.')
                             original_dep = dep
                             dep = (resolved_app_label, resolved_object_name.lower(), dep[2], dep[3])
-                            is_swappable_dep = True
                         if dep[0] != app_label and dep[0] != "__setting__":
                             # External app dependency. See if it's not yet
                             # satisfied.
@@ -831,18 +830,18 @@ class MigrationAutodetector:
             dependencies.extend(self._get_dependencies_for_foreign_key(field))
         # You can't just add NOT NULL fields with no default or fields
         # which don't allow empty strings as default.
-        preserve_default = True
         time_fields = (models.DateField, models.DateTimeField, models.TimeField)
-        if (not field.null and not field.has_default() and
-                not field.many_to_many and
-                not (field.blank and field.empty_strings_allowed) and
-                not (isinstance(field, time_fields) and field.auto_now)):
+        preserve_default = (
+            field.null or field.has_default() or field.many_to_many or
+            (field.blank and field.empty_strings_allowed) or
+            (isinstance(field, time_fields) and field.auto_now)
+        )
+        if not preserve_default:
             field = field.clone()
             if isinstance(field, time_fields) and field.auto_now_add:
                 field.default = self.questioner.ask_auto_now_add_addition(field_name, model_name)
             else:
                 field.default = self.questioner.ask_not_null_addition(field_name, model_name)
-            preserve_default = False
         self.add_operation(
             app_label,
             operations.AddField(

+ 1 - 3
django/db/migrations/graph.py

@@ -367,9 +367,7 @@ class MigrationGraph:
         plan = []
         for node in nodes:
             for migration in self.forwards_plan(node):
-                if migration not in plan:
-                    if not at_end and migration in nodes:
-                        continue
+                if migration in plan or at_end or migration not in nodes:
                     plan.append(migration)
         project_state = ProjectState(real_apps=real_apps)
         for node in plan:

+ 3 - 4
django/db/migrations/loader.py

@@ -172,10 +172,9 @@ class MigrationLoader:
         dependencies find the correct root node.
         """
         for parent in migration.dependencies:
-            if parent[0] != key[0] or parent[1] == '__first__':
-                # Ignore __first__ references to the same app (#22325).
-                continue
-            self.graph.add_dependency(migration, key, parent, skip_validation=True)
+            # Ignore __first__ references to the same app.
+            if parent[0] == key[0] and parent[1] != '__first__':
+                self.graph.add_dependency(migration, key, parent, skip_validation=True)
 
     def add_external_dependencies(self, key, migration):
         for parent in migration.dependencies:

+ 1 - 5
django/db/models/fields/related.py

@@ -109,11 +109,7 @@ class RelatedField(FieldCacheMixin, Field):
         related_name = self.remote_field.related_name
         if related_name is None:
             return []
-        is_valid_id = True
-        if keyword.iskeyword(related_name):
-            is_valid_id = False
-        if not related_name.isidentifier():
-            is_valid_id = False
+        is_valid_id = not keyword.iskeyword(related_name) and related_name.isidentifier()
         if not (is_valid_id or related_name.endswith('+')):
             return [
                 checks.Error(

+ 4 - 6
django/db/models/options.py

@@ -753,10 +753,9 @@ class Options:
 
         # We must keep track of which models we have already seen. Otherwise we
         # could include the same field multiple times from different models.
-        topmost_call = False
-        if seen_models is None:
+        topmost_call = seen_models is None
+        if topmost_call:
             seen_models = set()
-            topmost_call = True
         seen_models.add(self.model)
 
         # Creates a cache key composed of all arguments
@@ -785,9 +784,8 @@ class Options:
                 for obj in parent._meta._get_fields(
                         forward=forward, reverse=reverse, include_parents=include_parents,
                         include_hidden=include_hidden, seen_models=seen_models):
-                    if getattr(obj, 'parent_link', False) and obj.model != self.concrete_model:
-                        continue
-                    fields.append(obj)
+                    if not getattr(obj, 'parent_link', False) or obj.model == self.concrete_model:
+                        fields.append(obj)
         if reverse and not self.proxy:
             # Tree is computed once and cached until the app cache is expired.
             # It is composed of a list of fields pointing to the current model

+ 8 - 13
django/db/models/sql/compiler.py

@@ -114,13 +114,10 @@ class SQLCompiler:
             for col in cols:
                 expressions.append(col)
         for expr, (sql, params, is_ref) in order_by:
-            if expr.contains_aggregate:
-                continue
-            # We can skip References to select clause, as all expressions in
-            # the select clause are already part of the group by.
-            if is_ref:
-                continue
-            expressions.extend(expr.get_source_expressions())
+            # Skip References to the select clause, as all expressions in the
+            # select clause are already part of the group by.
+            if not expr.contains_aggregate and not is_ref:
+                expressions.extend(expr.get_source_expressions())
         having_group_by = self.having.get_group_by_cols() if self.having else ()
         for expr in having_group_by:
             expressions.append(expr)
@@ -283,7 +280,7 @@ class SQLCompiler:
                 continue
 
             col, order = get_order_dir(field, asc)
-            descending = True if order == 'DESC' else False
+            descending = order == 'DESC'
 
             if col in self.query.annotation_select:
                 # Reference to expression in SELECT clause
@@ -646,7 +643,7 @@ class SQLCompiler:
         The 'name' is of the form 'field1__field2__...__fieldN'.
         """
         name, order = get_order_dir(name, default_order)
-        descending = True if order == 'DESC' else False
+        descending = order == 'DESC'
         pieces = name.split(LOOKUP_SEP)
         field, targets, alias, joins, path, opts = self._setup_joins(pieces, opts, alias)
 
@@ -747,11 +744,9 @@ class SQLCompiler:
         # included in the related selection.
         fields_found = set()
         if requested is None:
-            if isinstance(self.query.select_related, dict):
+            restricted = isinstance(self.query.select_related, dict)
+            if restricted:
                 requested = self.query.select_related
-                restricted = True
-            else:
-                restricted = False
 
         def get_related_klass_infos(klass_info, related_klass_infos):
             klass_info['related_klass_infos'] = related_klass_infos

+ 3 - 4
django/db/models/sql/query.py

@@ -666,10 +666,9 @@ class Query:
             workset = {}
             for model, values in seen.items():
                 for field in model._meta.local_fields:
-                    if field in values:
-                        continue
-                    m = field.model._meta.concrete_model
-                    add_to_dict(workset, m, field)
+                    if field not in values:
+                        m = field.model._meta.concrete_model
+                        add_to_dict(workset, m, field)
             for model, values in must_include.items():
                 # If we haven't included a model in workset, we don't add the
                 # corresponding must_include fields for that model, since an

+ 2 - 3
django/forms/models.py

@@ -587,9 +587,8 @@ class BaseModelFormSet(BaseFormSet):
         return field.to_python
 
     def _construct_form(self, i, **kwargs):
-        pk_required = False
-        if i < self.initial_form_count():
-            pk_required = True
+        pk_required = i < self.initial_form_count()
+        if pk_required:
             if self.is_bound:
                 pk_key = '%s-%s' % (self.add_prefix(i), self.model._meta.pk.name)
                 try:

+ 1 - 2
django/forms/widgets.py

@@ -599,8 +599,7 @@ class ChoiceWidget(Widget):
                     str(subvalue) in value and
                     (not has_selected or self.allow_multiple_selected)
                 )
-                if selected and not has_selected:
-                    has_selected = True
+                has_selected |= selected
                 subgroup.append(self.create_option(
                     name, subvalue, sublabel, selected, index,
                     subindex=subindex, attrs=attrs,

+ 2 - 3
django/utils/cache.py

@@ -376,9 +376,8 @@ def learn_cache_key(request, response, cache_timeout=None, key_prefix=None, cach
         headerlist = []
         for header in cc_delim_re.split(response['Vary']):
             header = header.upper().replace('-', '_')
-            if header == 'ACCEPT_LANGUAGE' and is_accept_language_redundant:
-                continue
-            headerlist.append('HTTP_' + header)
+            if header != 'ACCEPT_LANGUAGE' or not is_accept_language_redundant:
+                headerlist.append('HTTP_' + header)
         headerlist.sort()
         cache.set(cache_key, headerlist, cache_timeout)
         return _generate_cache_key(request, request.method, headerlist, key_prefix)

+ 2 - 4
django/utils/datastructures.py

@@ -275,11 +275,9 @@ class DictWrapper(dict):
         present). If the prefix is present, pass the value through self.func
         before returning, otherwise return the raw value.
         """
-        if key.startswith(self.prefix):
-            use_func = True
+        use_func = key.startswith(self.prefix)
+        if use_func:
             key = key[len(self.prefix):]
-        else:
-            use_func = False
         value = super().__getitem__(key)
         if use_func:
             return self.func(value)

+ 1 - 2
django/utils/regex_helper.py

@@ -176,8 +176,7 @@ def normalize(pattern):
 
             if consume_next:
                 ch, escaped = next(pattern_iter)
-            else:
-                consume_next = True
+            consume_next = True
     except StopIteration:
         pass
     except NotImplementedError:

+ 2 - 3
docs/ref/contrib/admin/index.txt

@@ -1694,9 +1694,8 @@ templates used by the :class:`ModelAdmin` views:
             def get_formsets_with_inlines(self, request, obj=None):
                 for inline in self.get_inline_instances(request, obj):
                     # hide MyInline in the add view
-                    if isinstance(inline, MyInline) and obj is None:
-                        continue
-                    yield inline.get_formset(request, obj), inline
+                    if not isinstance(inline, MyInline) or obj is not None:
+                        yield inline.get_formset(request, obj), inline
 
 .. method:: ModelAdmin.formfield_for_foreignkey(db_field, request, **kwargs)
 

+ 1 - 5
tests/gis_tests/distapp/tests.py

@@ -81,11 +81,7 @@ class DistanceTest(TestCase):
         # Now performing the `dwithin` queries on a geodetic coordinate system.
         for dist in au_dists:
             with self.subTest(dist=dist):
-                if isinstance(dist, D) and not oracle:
-                    type_error = True
-                else:
-                    type_error = False
-
+                type_error = isinstance(dist, D) and not oracle
                 if isinstance(dist, tuple):
                     if oracle or spatialite:
                         # Result in meters

+ 2 - 7
tests/invalid_models_tests/test_models.py

@@ -17,13 +17,8 @@ def get_max_column_name_length():
     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:
-            continue
-        else:
-            if allowed_len is None:
-                allowed_len = max_name_length
-                db_alias = db
-            elif max_name_length < allowed_len:
+        if max_name_length is not None and not connection.features.truncates_names:
+            if allowed_len is None or max_name_length < allowed_len:
                 allowed_len = max_name_length
                 db_alias = db
 

+ 1 - 1
tests/messages_tests/base.py

@@ -252,7 +252,7 @@ class BaseTests:
     def test_middleware_disabled_fail_silently(self):
         """
         When the middleware is disabled, an exception is not raised
-        if 'fail_silently' = True
+        if 'fail_silently' is True.
         """
         data = {
             'messages': ['Test message %d' % x for x in range(5)],

+ 10 - 13
tests/runtests.py

@@ -85,12 +85,11 @@ def get_test_modules():
 
     for modpath, dirpath in discovery_paths:
         for f in os.listdir(dirpath):
-            if ('.' in f or
-                    os.path.basename(f) in SUBDIRS_TO_SKIP or
-                    os.path.isfile(f) or
-                    not os.path.exists(os.path.join(dirpath, f, '__init__.py'))):
-                continue
-            modules.append((modpath, f))
+            if ('.' not in f and
+                    os.path.basename(f) not in SUBDIRS_TO_SKIP and
+                    not os.path.isfile(f) and
+                    os.path.exists(os.path.join(dirpath, f, '__init__.py'))):
+                modules.append((modpath, f))
     return modules
 
 
@@ -189,13 +188,11 @@ def setup(verbosity, test_labels, parallel):
         # if the module (or an ancestor) was named on the command line, or
         # no modules were named (i.e., run all), import
         # this module and add it to INSTALLED_APPS.
-        if not test_labels:
-            module_found_in_labels = True
-        else:
-            module_found_in_labels = any(
-                # exact match or ancestor match
-                module_label == label or module_label.startswith(label + '.')
-                for label in test_labels_set)
+        module_found_in_labels = not test_labels or any(
+            # exact match or ancestor match
+            module_label == label or module_label.startswith(label + '.')
+            for label in test_labels_set
+        )
 
         if module_name in CONTRIB_TESTS_TO_APPS and module_found_in_labels:
             settings.INSTALLED_APPS.append(CONTRIB_TESTS_TO_APPS[module_name])