55
55
56
56
SETTINGS_MODULE_ENV = "DJANGO_SETTINGS_MODULE"
57
57
CONFIGURATION_ENV = "DJANGO_CONFIGURATION"
58
+ CONFIGURATION_HOOK_ENV = "DJANGO_CONFIGURATION_HOOK"
58
59
INVALID_TEMPLATE_VARS_ENV = "FAIL_INVALID_TEMPLATE_VARS"
59
60
60
61
_report_header = []
@@ -98,6 +99,14 @@ def pytest_addoption(parser) -> None:
98
99
default = None ,
99
100
help = "Set DJANGO_CONFIGURATION." ,
100
101
)
102
+ group .addoption (
103
+ "--dch" ,
104
+ action = "store" ,
105
+ type = str ,
106
+ dest = "dch" ,
107
+ default = None ,
108
+ help = "Set DJANGO_CONFIGURATION_HOOK." ,
109
+ )
101
110
group .addoption (
102
111
"--nomigrations" ,
103
112
"--no-migrations" ,
@@ -124,6 +133,9 @@ def pytest_addoption(parser) -> None:
124
133
parser .addini (
125
134
SETTINGS_MODULE_ENV , "Django settings module to use by pytest-django."
126
135
)
136
+ parser .addini (
137
+ CONFIGURATION_HOOK_ENV , "Callback Hook to prepare Django settings alternatively."
138
+ )
127
139
128
140
parser .addini (
129
141
"django_find_project" ,
@@ -329,6 +341,7 @@ def _get_option_with_source(
329
341
330
342
ds , ds_source = _get_option_with_source (options .ds , SETTINGS_MODULE_ENV )
331
343
dc , dc_source = _get_option_with_source (options .dc , CONFIGURATION_ENV )
344
+ dch , dch_source = _get_option_with_source (options .dch , CONFIGURATION_HOOK_ENV )
332
345
333
346
if ds :
334
347
_report_header .append ("settings: {} (from {})" .format (ds , ds_source ))
@@ -349,6 +362,34 @@ def _get_option_with_source(
349
362
350
363
with _handle_import_error (_django_project_scan_outcome ):
351
364
dj_settings .DATABASES
365
+ elif dch :
366
+ # Forcefully load Django settings, throws ImportError or
367
+ # ImproperlyConfigured if settings cannot be loaded.
368
+ from django .conf import settings as dj_settings
369
+
370
+ # Call a HOOK that could initialize djangos
371
+ # object with a custom configuration
372
+
373
+ if "." not in dch :
374
+ raise ImportError (f"Invalid path for configuration hook: { dch } " )
375
+
376
+ pkg_parts = dch .split ("." )
377
+ module_path = "." .join (pkg_parts [:- 1 ])
378
+ function_name = pkg_parts [- 1 ]
379
+
380
+ import importlib
381
+
382
+ try :
383
+ mod = importlib .import_module (module_path )
384
+ except (ImportError , AttributeError ):
385
+ raise ImportError (f"Unable to import module { module_path } " )
386
+ func = getattr (mod , function_name , None )
387
+
388
+ if not func :
389
+ raise ImportError (f"No function found with name { function_name } in module { module_path } !" )
390
+
391
+ # Call the function
392
+ func ()
352
393
353
394
_setup_django ()
354
395
0 commit comments