Skip to content
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
53 changes: 40 additions & 13 deletions src/miniflask/modules/settings/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import os
import copy
from enum import EnumMeta
from itertools import zip_longest
from collections import deque

from colored import attr, fg

Expand All @@ -14,6 +16,28 @@
html_val_overwrite = lambda x: x # noqa: E731 no-lambda


def sorted_by_state_key_modules(items):
"""Sort items based on state keys with module nesting, and alphabetical order."""
module_tree_template = {"modules": {}, "params": []}
module_tree = copy.deepcopy(module_tree_template)
for k, v in items:
leaf = module_tree
for mod in k.split('.')[:-1]:
_leaf = leaf["modules"].get(mod, copy.deepcopy(module_tree_template))
if mod not in leaf:
leaf["modules"][mod] = _leaf
leaf = _leaf
leaf["params"].append((k, v))
# iterate over tree
modules = deque([module_tree])
while modules:
mod = modules.pop()
for m in sorted(mod["modules"], reverse=True, key=str.lower):
modules.append(mod["modules"][m])
for e in sorted(mod["params"], key=lambda tup: str.lower(tup[0])):
yield e


def listsettings(mf, state, asciicodes=True):

# colors
Expand All @@ -24,20 +48,23 @@ def listsettings(mf, state, asciicodes=True):
linesep = os.linesep if asciicodes else "\n"
attr_fn = (lambda x: '') if not asciicodes else attr

text_list = []
last_k = []
if len(state.all) == 0:
return "No Settings available."
maxklen = max(len(k) for k in state.all.keys())
text = "Folder│" + color_name("module") + "│" + color_module("variable") + (" " * (maxklen - 22)) + " = " + color_val("value") + linesep
text += "—" * (maxklen + 8) + linesep if asciicodes else ''
for k, v in sorted(state.all.items()):
max_k_len = max(len(k) for k in state.all.keys())

preamble_text = "Folder│" + color_name("module") + "│" + color_module("variable") + (" " * (max_k_len - 22)) + " = " + color_val("value") + linesep
preamble_text += "—" * (max_k_len + 8) + linesep if asciicodes else ''

for k, v in sorted_by_state_key_modules(state.all.items()):

# ignore state variables that are not registered for argument parsing
if k not in state.default:
continue

klen = len(k)
korig = k
k_len = len(k)
k_orig = k
overwritten = v != (state.default[k].default if hasattr(state.default[k], 'default') else state.default[k])
k = k.split(".")
if len(k) > 1:
Expand All @@ -49,20 +76,20 @@ def listsettings(mf, state, asciicodes=True):
k_hidden = k
k_hidden[-1] = color_module(k_hidden[-1])

is_lambda = callable(state.default[korig]) and not isinstance(state.default[korig], type) and not isinstance(state.default[korig], EnumMeta) and not isinstance(state.default[korig], like)
value_str = attr_fn('dim') + "λ ⟶ " + attr_fn('reset') + str(state.default[korig].default) if is_lambda else state.default[korig].str(asciicodes=False) if hasattr(state.default[korig], 'str') else str(state.default[korig])
is_lambda = callable(state.default[k_orig]) and not isinstance(state.default[k_orig], type) and not isinstance(state.default[k_orig], EnumMeta) and not isinstance(state.default[k_orig], like)
value_str = attr_fn('dim') + "λ ⟶ " + attr_fn('reset') + str(state.default[k_orig].default) if is_lambda else state.default[k_orig].str(asciicodes=False) if hasattr(state.default[k_orig], 'str') else str(state.default[k_orig])
append = "" if not overwritten else " ⟶ " + color_val_overwrite(str(v))
text += "│".join(k_hidden) + (" " * (maxklen - klen)) + " = " + color_val(value_str) + append + linesep
text_list.append("│".join(k_hidden) + (" " * (max_k_len - k_len)) + " = " + color_val(value_str) + append)

# add definition paths
if state["show_registration_definitions"]:
prefix = "│".join([" " * len(k) for k in korig.split(".")]) + (" " * (maxklen - klen)) + " "
for definition_type, caller_traceback in mf._settings_parser_tracebacks[korig]:
prefix = "│".join([" " * len(k) for k in k_orig.split(".")]) + (" " * (max_k_len - k_len)) + " "
for definition_type, caller_traceback in mf._settings_parser_tracebacks[k_orig]:
summary = next(filter(lambda t: not t.filename.endswith("miniflask/miniflask.py"), reversed(caller_traceback)))
arg_err_str = (fg('blue') + "definition" if definition_type == "definition" else fg('yellow') + "overwritten") + attr('reset') + " in line %s in file '%s'." % (highlight_event(str(summary.lineno)), attr('dim') + os.path.relpath(summary.filename) + attr('reset'))
text += prefix + arg_err_str + linesep
text_list.append(prefix + arg_err_str)

return text
return preamble_text + linesep.join(text_list)


def init(mf, state):
Expand Down