Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix ambiguous register_default_module order #102

Merged
merged 2 commits into from
Nov 21, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 26 additions & 8 deletions src/miniflask/miniflask.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ def __init__(self, module_dirs, debug=False):
self._settings_parser_tracebacks = {}
self.settings_parser_required_arguments = []
self.default_modules = []
self.default_modules_overwrites = []
self.bind_events = True

# internal
Expand Down Expand Up @@ -483,7 +484,14 @@ def register_default_module(self, module, required_event=None, required_id=None,
Typically, the requirement will be tested after parsing the modules given using cli-arguments.

# Note {.alert}
It is only possibly to specify a requirement based on an event name *or* a module id regex.
- It is only possibly to specify a requirement based on an event name *or* a module id regex.
- In case of multiple `register_default_module` calls with the same dependency (i.e. the same required event), the calls are parsed as follows:
- in case the given default-modules differ in these calls
- the latest settings (i.e. `overwrite_globals`-dict) are used
- the settings of the unrealised calls are ignored
- in case the given default-modules are equal, all those calls are realized, and thus
- all settings are loaded, but
- the latest settings overwrite the older settings

Args:
- `module`: (required)
Expand Down Expand Up @@ -523,6 +531,7 @@ def register_default_module(self, module, required_event=None, required_id=None,
if not required_event and not required_id:
raise RegisterError("Default Modules should depend either on a event interface OR a regular expression. However, none are given")
self.default_modules.append((module, required_event, required_id, overwrite_globals, save_traceback()))
self.default_modules_overwrites.append((module, required_event, required_id, overwrite_globals, save_traceback()))

# saves function to a given (event-)name
def register_event(self, name, fn, unique=True, call_before_after=True):
Expand Down Expand Up @@ -885,35 +894,44 @@ def parse_args(self, # noqa: C901 too-complex pylint: disable=too-many-stateme
keys = self.modules_loaded.keys()
if len(self.default_modules) > 1:
self.print_heading("Loading Automatically Requested Default Modules")
for module, evt, glob, overwrite_globals, caller_traceback in self.default_modules:

# the default_module list gives us the order (last-in, first-out) of the default-modules to call
# we assume that newer default modules are meant to overwrite older ones
while len(self.default_modules) > 0:
module, evt, glob, overwrite_globals, caller_traceback = self.default_modules.pop()
del overwrite_globals, caller_traceback

if evt:
if not isinstance(module, list):
module = [module]
modules_already_loaded = all(self.getModuleId(m) in self.modules_loaded for m in module)
if not modules_already_loaded and evt not in self.event_objs:
self.load(module, loading_text=partial(highlight_loading_default, evt))
self.register_defaults(overwrite_globals, scope="", overwrite=True, caller_traceback=caller_traceback)
else:
found = self.event_objs[evt].modules
if not isinstance(found, list):
found = [found]
found = [f.module_id for f in found]
print(highlight_loaded_default(found, evt))

# overwrite defaults if loaded default module itself or did not load module yet
if modules_already_loaded:
self.register_defaults(overwrite_globals, scope="", overwrite=True, caller_traceback=caller_traceback)

elif glob:
found = [highlight_loading_module(x) for x in keys if re.search(glob, x)]
if len(found) == 0:
self.load(module, loading_text=partial(highlight_loading_default, glob))
self.register_defaults(overwrite_globals, scope="", overwrite=True, caller_traceback=caller_traceback)
elif len(found) > 1:
print(highlight_loaded_default(found, glob))
else:
print(highlight_loaded_default(found, glob))

# in case a default module / overwrite_global-combination is used in two places in the loading-tree,
# we assume that we want to overwrite the older values with the newer values
for module, evt, glob, overwrite_globals, caller_traceback in self.default_modules_overwrites:
del evt, glob
if not isinstance(module, list):
module = [module]
if all(self.getModuleId(m) in self.modules_loaded for m in module):
self.register_defaults(overwrite_globals, scope="", overwrite=True, caller_traceback=caller_traceback)

# check fuzzy matching of overwrites
for varname, val, cliargs, parsefn, caller_traceback, _mf in self._settings_parse_later_overwrites_list:
if varname not in self._settings_parse_later:
Expand Down