Skip to content

Commit

Permalink
Make FIRST_PARTY_APPS handling match the behaviour of INSTALLED_APPS
Browse files Browse the repository at this point in the history
Supercedes #62.
  • Loading branch information
adamchainz committed Apr 8, 2021
1 parent efed6ad commit b0553c1
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 2 deletions.
5 changes: 5 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
History
=======

* Make ``FIRST_PARTY_APPS`` handling match the behaviour of ``INSTALLED_APPS``.

Thanks to Martin Bächtold for the report in `Pull Request #62
<https://github.com/adamchainz/django-linear-migrations/pull/62>`__.

* Stop distributing tests to reduce package size. Tests are not intended to be
run outside of the tox setup in the repository. Repackagers can use GitHub's
tarballs per tag.
Expand Down
21 changes: 19 additions & 2 deletions src/django_linear_migrations/apps.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import pkgutil
from functools import lru_cache
from importlib import import_module, reload
from pathlib import Path

from django.apps import AppConfig, apps
from django.conf import settings
from django.core.checks import Error, Tags, register
from django.core.signals import setting_changed
from django.db.migrations.loader import MigrationLoader
from django.dispatch import receiver
from django.utils.functional import cached_property

from django_linear_migrations.compat import is_namespace_module
Expand All @@ -19,9 +22,23 @@ def ready(self):
register(Tags.models)(check_max_migration_files)


@lru_cache(maxsize=1)
def get_first_party_app_labels():
if not settings.is_overridden("FIRST_PARTY_APPS"):
return None
return {AppConfig.create(name).label for name in settings.FIRST_PARTY_APPS}


@receiver(setting_changed)
def reset_first_party_app_labels(*, setting, **kwargs):
if setting == "FIRST_PARTY_APPS":
get_first_party_app_labels.cache_clear()


def is_first_party_app_config(app_config):
if settings.is_overridden("FIRST_PARTY_APPS"):
return app_config.label in settings.FIRST_PARTY_APPS
first_party_labels = get_first_party_app_labels()
if first_party_labels is not None:
return app_config.label in first_party_labels

# Check if it seems to be installed in a virtualenv
path = Path(app_config.path)
Expand Down
31 changes: 31 additions & 0 deletions tests/test_apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from django.apps import apps
from django.test import SimpleTestCase
from django.test.utils import override_settings

from django_linear_migrations.apps import is_first_party_app_config


class IsFirstPartyAppConfigTests(SimpleTestCase):
@override_settings(FIRST_PARTY_APPS=[])
def test_empty(self):
app_config = apps.get_app_config("testapp")

assert not is_first_party_app_config(app_config)

@override_settings(FIRST_PARTY_APPS=["django_linear_migrations"])
def test_not_named(self):
app_config = apps.get_app_config("testapp")

assert not is_first_party_app_config(app_config)

@override_settings(FIRST_PARTY_APPS=["tests.testapp"])
def test_named_by_path(self):
app_config = apps.get_app_config("testapp")

assert is_first_party_app_config(app_config)

@override_settings(FIRST_PARTY_APPS=["tests.testapp.apps.TestAppConfig"])
def test_named_by_app_config_path(self):
app_config = apps.get_app_config("testapp")

assert is_first_party_app_config(app_config)
4 changes: 4 additions & 0 deletions tests/testapp/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import django

if django.VERSION < (3, 2):
default_app_config = "tests.testapp.apps.TestAppConfig"
6 changes: 6 additions & 0 deletions tests/testapp/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class TestAppConfig(AppConfig):
name = "tests.testapp"
verbose_name = "Test App"

0 comments on commit b0553c1

Please sign in to comment.