1- import importlib .util
21from importlib .machinery import PathFinder
32import logging
43import os
@@ -47,12 +46,12 @@ def create_parser(self, prog_name, subcommand):
4746 return parser
4847
4948 base .BaseCommand .create_parser = create_parser
50- importer = ConfigurationImporter (check_options = check_options )
49+ importer = ConfigurationFinder (check_options = check_options )
5150 sys .meta_path .insert (0 , importer )
5251 installed = True
5352
5453
55- class ConfigurationImporter :
54+ class ConfigurationFinder ( PathFinder ) :
5655 modvar = SETTINGS_ENVIRONMENT_VARIABLE
5756 namevar = CONFIGURATION_ENVIRONMENT_VARIABLE
5857 error_msg = ("Configuration cannot be imported, "
@@ -71,7 +70,7 @@ def __init__(self, check_options=False):
7170 self .announce ()
7271
7372 def __repr__ (self ):
74- return "<ConfigurationImporter for '{}.{}'>" .format (self .module ,
73+ return "<ConfigurationFinder for '{}.{}'>" .format (self .module ,
7574 self .name )
7675
7776 @property
@@ -129,56 +128,53 @@ def stylize(text):
129128
130129 def find_spec (self , fullname , path = None , target = None ):
131130 if fullname is not None and fullname == self .module :
132- spec = PathFinder .find_spec (fullname , path )
131+ spec = super () .find_spec (fullname , path , target )
133132 if spec is not None :
134- return importlib .machinery .ModuleSpec (spec .name ,
135- ConfigurationLoader (self .name , spec ),
136- origin = spec .origin )
137- return None
138-
139-
140- class ConfigurationLoader :
141-
142- def __init__ (self , name , spec ):
143- self .name = name
144- self .spec = spec
145-
146- def load_module (self , fullname ):
147- if fullname in sys .modules :
148- mod = sys .modules [fullname ] # pragma: no cover
133+ wrap_loader (spec .loader , self .name )
134+ return spec
149135 else :
150- mod = importlib .util .module_from_spec (self .spec )
151- sys .modules [fullname ] = mod
152- self .spec .loader .exec_module (mod )
153-
154- cls_path = f'{ mod .__name__ } .{ self .name } '
155-
156- try :
157- cls = getattr (mod , self .name )
158- except AttributeError as err : # pragma: no cover
159- reraise (err , "Couldn't find configuration '{}' "
160- "in module '{}'" .format (self .name ,
161- mod .__package__ ))
162- try :
163- cls .pre_setup ()
164- cls .setup ()
165- obj = cls ()
166- attributes = uppercase_attributes (obj ).items ()
167- for name , value in attributes :
168- if callable (value ) and not getattr (value , 'pristine' , False ):
169- value = value ()
170- # in case a method returns a Value instance we have
171- # to do the same as the Configuration.setup method
172- if isinstance (value , Value ):
173- setup_value (mod , name , value )
174- continue
175- setattr (mod , name , value )
176-
177- setattr (mod , 'CONFIGURATION' , '{}.{}' .format (fullname ,
178- self .name ))
179- cls .post_setup ()
180-
181- except Exception as err :
182- reraise (err , f"Couldn't setup configuration '{ cls_path } '" )
183-
184- return mod
136+ return None
137+
138+
139+ def wrap_loader (loader , class_name ):
140+ class ConfigurationLoader (loader .__class__ ):
141+ def exec_module (self , module ):
142+ super ().exec_module (module )
143+
144+ mod = module
145+
146+ cls_path = f'{ mod .__name__ } .{ class_name } '
147+
148+ try :
149+ cls = getattr (mod , class_name )
150+ except AttributeError as err : # pragma: no cover
151+ reraise (
152+ err ,
153+ (
154+ f"Couldn't find configuration '{ class_name } ' in "
155+ f"module '{ mod .__package__ } '"
156+ ),
157+ )
158+ try :
159+ cls .pre_setup ()
160+ cls .setup ()
161+ obj = cls ()
162+ attributes = uppercase_attributes (obj ).items ()
163+ for name , value in attributes :
164+ if callable (value ) and not getattr (value , 'pristine' , False ):
165+ value = value ()
166+ # in case a method returns a Value instance we have
167+ # to do the same as the Configuration.setup method
168+ if isinstance (value , Value ):
169+ setup_value (mod , name , value )
170+ continue
171+ setattr (mod , name , value )
172+
173+ setattr (mod , 'CONFIGURATION' , '{0}.{1}' .format (module .__name__ ,
174+ class_name ))
175+ cls .post_setup ()
176+
177+ except Exception as err :
178+ reraise (err , f"Couldn't setup configuration '{ cls_path } '" )
179+
180+ loader .__class__ = ConfigurationLoader
0 commit comments