dav_base: cosmetics
Run tests / Execute tox to run the test suite (push) Successful in 3m29s

This commit is contained in:
2026-05-28 14:51:49 +02:00
parent efd2305b35
commit d9cfffb8c2
8 changed files with 63 additions and 41 deletions
+13 -8
View File
@@ -4,6 +4,8 @@ import re
from django.apps import AppConfig as _AppConfig
from django.core.exceptions import ImproperlyConfigured
from ..constants import DJANGO_MAIN_MODULE, MODULE_APP_SETTINGS_PREFIX
logger = logging.getLogger(__name__)
@@ -18,18 +20,21 @@ class DefaultSetting: # pylint: disable=too-few-public-methods
self.validator = validator
def validate(self, value):
if hasattr(self, 'validator') and self.validator is not None:
if callable(self.validator):
if not self.validator(value):
raise ImproperlyConfigured('Validator callback {clb} returned False'.format(clb=self.validator))
else:
if not re.search(self.validator, value):
raise ImproperlyConfigured('Does not match /{re}/'.format(re=self.validator))
if self.validator is None:
return
if callable(self.validator):
if not self.validator(value):
raise ImproperlyConfigured('Validator callback {clb} returned False'.format(clb=self.validator))
else:
if not re.search(self.validator, value):
raise ImproperlyConfigured('Does not match /{re}/'.format(re=self.validator))
class AppSettings: # pylint: disable=too-few-public-methods
def __init__(self, app_name, defaults):
settings_name = 'main.settings-' + app_name
settings_name = '{main_module}.{prefix}{app_name}'.format(main_module=DJANGO_MAIN_MODULE,
prefix=MODULE_APP_SETTINGS_PREFIX,
app_name=app_name)
try:
settings_module = importlib.import_module(settings_name)
+8 -3
View File
@@ -5,8 +5,7 @@ from importlib.resources import files as resource_files
from django.conf import settings
from django.urls import re_path, include
DJANGO_MAIN_MODULE = 'main'
MODULE_CONFIG_FILE_NAME = 'module_config.json'
from ..constants import DJANGO_MAIN_MODULE, MODULES_CONFIG_FILE_NAME
class ModuleConfigError(Exception):
@@ -64,6 +63,12 @@ class ModuleMeta:
url_conf = self._package_name + '.urls'
return re_path(url_pattern, include(url_conf, self.url_namespace))
@property
def root_url_name(self):
if self.url_namespace:
return '{}:{}'.format(self.url_namespace, self._root_url_name)
return self._root_url_name
def _load_from_package(self):
package_name = self._package_name
json_text = resource_files(package_name).joinpath(self._json_file).read_bytes()
@@ -97,7 +102,7 @@ class ModuleConfig:
if config_file_path is None:
if django_base_dir is None:
django_base_dir = settings.BASE_DIR
config_file_path = os.path.join(django_base_dir, DJANGO_MAIN_MODULE, MODULE_CONFIG_FILE_NAME)
config_file_path = os.path.join(django_base_dir, DJANGO_MAIN_MODULE, MODULES_CONFIG_FILE_NAME)
self._config_file_path = config_file_path
self._modules = {}
+14 -11
View File
@@ -5,7 +5,8 @@ import sys
from importlib.resources import files as resource_files
from django.core.management import execute_from_command_line
from dav_base.config.modules import DJANGO_MAIN_MODULE, ModuleConfig
from dav_base.constants import DJANGO_MAIN_MODULE, MODULE_APP_SETTINGS_PREFIX
from dav_base.config.modules import ModuleConfig
VERSION = '0.1'
@@ -94,46 +95,48 @@ class AdminCommand: # pylint: disable=too-few-public-methods
config = ModuleConfig(django_base_dir=django_base_dir)
config.save()
input_file = resource_files(__package__).joinpath('django_project_config', 'additional_settings.py')
input_file = resource_files(__package__).joinpath('django_project_config',
'additional_settings.py')
output_file = os.path.join(django_base_dir, django_main_module, 'settings.py')
with open(output_file, 'ab') as f:
f.write(input_file.read_bytes())
input_file = resource_files(__package__).joinpath('django_project_config', 'urls.py')
input_file = resource_files(__package__).joinpath('django_project_config',
'urls.py')
output_file = os.path.join(django_base_dir, django_main_module, 'urls.py')
with open(output_file, 'wb') as f:
f.write(input_file.read_bytes())
input_file = resource_files(__package__).joinpath('django_project_config', 'settings-dav_base.py')
output_file = os.path.join(django_base_dir, django_main_module, 'settings-dav_base.py')
input_file = resource_files(__package__).joinpath('django_project_config',
'{prefix}dav_base.py'.format(prefix=MODULE_APP_SETTINGS_PREFIX))
output_file = os.path.join(django_base_dir,
django_main_module,
'{prefix}dav_base.py'.format(prefix=MODULE_APP_SETTINGS_PREFIX))
with open(output_file, 'wb') as f:
f.write(input_file.read_bytes())
return posix.EX_OK
def _subcmd_enable_module(self, cmd_args):
django_main_module = DJANGO_MAIN_MODULE
django_base_dir = cmd_args.path
module_name = cmd_args.module
sys.path.append(django_base_dir)
os.environ['DJANGO_SETTINGS_MODULE'] = '{}.settings'.format(django_main_module)
os.environ['DJANGO_SETTINGS_MODULE'] = '{}.settings'.format(DJANGO_MAIN_MODULE)
execute_from_command_line(['manage.py', 'enable_module', module_name])
return posix.EX_OK
def _subcmd_disable_module(self, cmd_args):
django_main_module = DJANGO_MAIN_MODULE
django_base_dir = cmd_args.path
module_name = cmd_args.module
sys.path.append(django_base_dir)
os.environ['DJANGO_SETTINGS_MODULE'] = '{}.settings'.format(django_main_module)
os.environ['DJANGO_SETTINGS_MODULE'] = '{}.settings'.format(DJANGO_MAIN_MODULE)
execute_from_command_line(['manage.py', 'disable_module', module_name])
return posix.EX_OK
def _subcmd_list_modules(self, cmd_args):
django_main_module = DJANGO_MAIN_MODULE
django_base_dir = cmd_args.path
sys.path.append(django_base_dir)
os.environ['DJANGO_SETTINGS_MODULE'] = '{}.settings'.format(django_main_module)
os.environ['DJANGO_SETTINGS_MODULE'] = '{}.settings'.format(DJANGO_MAIN_MODULE)
execute_from_command_line(['manage.py', 'list_modules'])
return posix.EX_OK
+3
View File
@@ -0,0 +1,3 @@
DJANGO_MAIN_MODULE = 'main'
MODULES_CONFIG_FILE_NAME = 'module_config.json'
MODULE_APP_SETTINGS_PREFIX = 'settings-'
@@ -3,7 +3,8 @@ from importlib.resources import files as resource_files
from django.conf import settings
from django.core.management.base import BaseCommand, CommandError
from dav_base.config.modules import DJANGO_MAIN_MODULE, ModuleMeta
from dav_base.constants import DJANGO_MAIN_MODULE, MODULE_APP_SETTINGS_PREFIX
from dav_base.config.modules import ModuleMeta
class Command(BaseCommand):
@@ -22,7 +23,9 @@ class Command(BaseCommand):
if module_name in config.modules.keys():
raise CommandError('Module \'{}\' is already enabled'.format(module_name))
settings_file_name = 'settings-{}.py'.format(module_name)
settings_file_name = '{prefix}{module_name}.py'.format(prefix=MODULE_APP_SETTINGS_PREFIX,
module_name=module_name)
input_file = resource_files(module_name).joinpath('django_project_config', settings_file_name)
if input_file.is_file():
output_file = os.path.join(django_base_dir, django_main_module, settings_file_name)
+10 -1
View File
@@ -23,6 +23,7 @@ class ModuleMetaTestCase(SimpleTestCase):
self.assertEqual(mm.additional_apps, [])
self.assertEqual(mm.url_prefix, 'test')
self.assertEqual(mm.url_namespace, 'dav_base_tests_fake_app1')
self.assertEqual(mm.root_url_name, 'dav_base_tests_fake_app1:root')
pattern = mm.url_conf_pattern
self.assertIsInstance(pattern, URLResolver)
self.assertEqual('^test/', str(pattern.pattern))
@@ -33,10 +34,13 @@ class ModuleMetaTestCase(SimpleTestCase):
def test_init_without_load(self):
app_name = 'dav_base.tests.non_existent_app'
app_namespace = app_name.replace('.', '_')
mm = ModuleMeta(app_name, load=False)
self.assertEqual(mm.package, app_name)
self.assertEqual(mm.app, app_name)
self.assertEqual(mm.url_prefix, app_name)
self.assertEqual(mm.url_namespace, app_namespace)
self.assertEqual(mm.root_url_name, app_namespace + ':root')
def test_url_config_not_exists(self):
mm = ModuleMeta('dav_base.tests.fake_app1')
@@ -57,19 +61,24 @@ class ModuleMetaTestCase(SimpleTestCase):
'additional_apps': ['test1', 'test2.subtest'],
'url_prefix': 'test_url_prefix',
}
expected_namespace = dd['package'].replace('.', '_')
mm.load_from_dict(dd)
self.assertEqual(mm.package, dd['package'])
self.assertEqual(mm.app, dd['app_config'])
self.assertEqual(mm.additional_apps, dd['additional_apps'])
self.assertEqual(mm.url_prefix, dd['url_prefix'])
self.assertEqual(mm.url_namespace, dd['package'].replace('.', '_'))
self.assertEqual(mm.url_namespace, expected_namespace)
self.assertEqual(mm.root_url_name, expected_namespace + ':root')
dd = {'package': 'dav_base2.bar'}
expected_namespace = dd['package'].replace('.', '_')
mm.load_from_dict(dd)
self.assertEqual(mm.url_prefix, dd['package'])
self.assertEqual(mm.app, dd['package'])
self.assertEqual(mm.additional_apps, [])
self.assertEqual(mm.url_prefix, dd['package'])
self.assertEqual(mm.url_namespace, expected_namespace)
self.assertEqual(mm.root_url_name, expected_namespace + ':root')
def test_dump_as_dict(self):
mm = ModuleMeta('dav_base.tests.fake_app1')
+9 -13
View File
@@ -6,16 +6,12 @@ from ..views import RootView
class DummyModuleMeta:
def __init__(self, package, url_namespace=None):
def __init__(self, package):
self.package = package
self.url_namespace = url_namespace
@property
def url_name(self):
if self.url_namespace:
return self.url_namespace + ':root'
else:
return 'root'
def root_url_name(self):
return self.package.replace('.', '_') + ':root'
class DummyModuleConfig:
def __init__(self, modules):
@@ -30,17 +26,17 @@ class DummyModuleConfig:
class ViewsTestCase(SimpleTestCase):
def test_root(self):
modules = {
'module1': DummyModuleMeta('pkg1', url_namespace='ns1'),
'module1': DummyModuleMeta('pkg1'),
'module2': DummyModuleMeta('pkg2'),
'moduleC': DummyModuleMeta('pkgC', url_namespace='nsC'),
'moduleD': DummyModuleMeta('pkgD', url_namespace='nsD'),
'moduleC': DummyModuleMeta('pkgC'),
'moduleD': DummyModuleMeta('pkgD'),
}
expected_root_urls = [
('pkg1', 'ns1:root'), ('pkg2', 'root'), ('pkgD', 'nsD:root')
('pkg1', 'pkg1:root'), ('pkg2', 'pkg2:root'), ('pkgD', 'pkgD:root')
]
def fake_reverse(name):
if name == 'nsC:root':
if name == 'pkgC:root':
raise NoReverseMatch()
return '/'
@@ -57,7 +53,7 @@ class ViewsTestCase(SimpleTestCase):
called_names = [call.args[0] for call in mocked_reverse.call_args_list]
self.assertEqual(len(called_names), len(modules))
for m in modules.values():
self.assertIn(m.url_name, called_names)
self.assertIn(m.root_url_name, called_names)
def test_integrated_root(self):
with override_settings(MODULE_CONFIG=DummyModuleConfig({})):
+1 -3
View File
@@ -10,9 +10,7 @@ class RootView(generic.TemplateView):
c = super().get_context_data(**kwargs)
root_urls = []
for module_meta_obj in settings.MODULE_CONFIG.modules.values():
root_url_name = 'root'
if module_meta_obj.url_namespace:
root_url_name = '%s:%s' % (module_meta_obj.url_namespace, root_url_name)
root_url_name = module_meta_obj.root_url_name
try:
reverse(root_url_name)
root_urls.append((module_meta_obj.package, root_url_name))