From 242a6a0f120e8823952df075462338597f83c966 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 24 Aug 2014 22:19:10 +0400 Subject: [PATCH 01/11] Add `None` mark to module object Applicable only when it fallbacks to the default value. This may output shown by travis more informative. And in any case old code contained a bug. --- powerline/lint/__init__.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/powerline/lint/__init__.py b/powerline/lint/__init__.py index f495cc18..89027a3a 100644 --- a/powerline/lint/__init__.py +++ b/powerline/lint/__init__.py @@ -1,21 +1,24 @@ # vim:fileencoding=utf-8:noet +import itertools +import sys +import os +import re +import logging + +from collections import defaultdict +from copy import copy + from powerline.lint.markedjson import load from powerline import generate_config_finder, get_config_paths, load_config from powerline.lib.config import ConfigLoader from powerline.lint.markedjson.error import echoerr, MarkedError +from powerline.lint.markedjson.markedvalue import MarkedUnicode from powerline.segments.vim import vim_modes from powerline.lint.inspect import getconfigargspec from powerline.lib.threaded import ThreadedSegment from powerline.lib import mergedicts_copy from powerline.lib.unicode import unicode -import itertools -import sys -import os -import re -from collections import defaultdict -from copy import copy -import logging def open_file(path): @@ -875,13 +878,17 @@ def check_full_segment_data(segment, data, context, echoerr): def import_segment(name, data, context, echoerr, module=None): if not module: - module = context[-2][1].get('module', context[0][1].get('default_module', 'powerline.segments.' + data['ext'])) + module = context[-2][1].get( + 'module', context[0][1].get( + 'default_module', MarkedUnicode( + 'powerline.segments.' + data['ext'], None))) with WithPath(data['import_paths']): try: func = getattr(__import__(str(module), fromlist=[str(name)]), str(name)) except ImportError: echoerr(context='Error while checking segments (key {key})'.format(key=context_key(context)), + context_mark=name.mark, problem='failed to import module {0}'.format(module), problem_mark=module.mark) return None @@ -893,6 +900,7 @@ def import_segment(name, data, context, echoerr, module=None): if not callable(func): echoerr(context='Error while checking segments (key {key})'.format(key=context_key(context)), + context_mark=name.mark, problem='imported "function" {0} from module {1} is not callable'.format(name, module), problem_mark=module.mark) return None From 26cc26a69a0f4d09c417692d2c40c7927b52e114 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 24 Aug 2014 23:04:50 +0400 Subject: [PATCH 02/11] Mark default value of default_module value --- powerline/lint/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/powerline/lint/__init__.py b/powerline/lint/__init__.py index 89027a3a..fbc82331 100644 --- a/powerline/lint/__init__.py +++ b/powerline/lint/__init__.py @@ -1223,7 +1223,8 @@ def get_all_possible_functions(data, context, echoerr): if segment.get('type', 'function') == 'function': module = segment.get( 'module', - theme_config.get('default_module', 'powerline.segments.' + data['ext']) + theme_config.get('default_module', MarkedUnicode( + 'powerline.segments.' + data['ext'], None)) ) func = import_segment(name, data, context, echoerr, module=module) if func: From 8b30e9d33ebacec02c3d1ea16ff6cb1468ddc5ca Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 24 Aug 2014 23:06:30 +0400 Subject: [PATCH 03/11] Also in another place, just in case --- powerline/lint/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/powerline/lint/__init__.py b/powerline/lint/__init__.py index fbc82331..9dda3c0a 100644 --- a/powerline/lint/__init__.py +++ b/powerline/lint/__init__.py @@ -855,7 +855,8 @@ def check_full_segment_data(segment, data, context, echoerr): names = [segment['name']] if segment.get('type', 'function') == 'function': - module = segment.get('module', context[0][1].get('default_module', 'powerline.segments.' + ext)) + module = segment.get('module', context[0][1].get('default_module', MarkedUnicode( + 'powerline.segments.' + ext, None))) names.insert(0, unicode(module) + '.' + unicode(names[0])) segment_copy = segment.copy() From b5fae89d6c11cb20eb3d51276c4628600844e534 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 24 Aug 2014 23:18:44 +0400 Subject: [PATCH 04/11] Check whether all values that should have mark attribute have it --- powerline/lint/__init__.py | 46 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/powerline/lint/__init__.py b/powerline/lint/__init__.py index 9dda3c0a..49e03d96 100644 --- a/powerline/lint/__init__.py +++ b/powerline/lint/__init__.py @@ -41,6 +41,20 @@ def context_key(context): return key_sep.join((c[0] for c in context)) +def havemarks(*args): + for i, v in enumerate(args): + if not hasattr(v, 'mark'): + raise AssertionError('Value #{0} has no attribute `mark`'.format(i)) + + +def context_has_marks(context): + for i, v in enumerate(context): + if not hasattr(v[0], 'mark'): + raise AssertionError('Key #{0} in context has no attribute `mark`'.format(i)) + if not hasattr(v[1], 'mark'): + raise AssertionError('Value #{0} in context has no attribute `mark`'.format(i)) + + class EchoErr(object): __slots__ = ('echoerr', 'logger',) @@ -130,6 +144,7 @@ class Spec(object): return self def check_type(self, value, context_mark, data, context, echoerr, types): + havemarks(value) if type(value.value) not in types: echoerr( context=self.cmsg.format(key=context_key(context)), @@ -145,6 +160,7 @@ class Spec(object): return True, False def check_func(self, value, context_mark, data, context, echoerr, func, msg_func): + havemarks(value) proceed, echo, hadproblem = func(value, data, context, echoerr) if echo and hadproblem: echoerr(context=self.cmsg.format(key=context_key(context)), @@ -154,9 +170,11 @@ class Spec(object): return proceed, hadproblem def check_list(self, value, context_mark, data, context, echoerr, item_func, msg_func): + havemarks(value) i = 0 hadproblem = False for item in value: + havemarks(item) if isinstance(item_func, int): spec = self.specs[item_func] proceed, fhadproblem = spec.match( @@ -181,6 +199,7 @@ class Spec(object): return True, hadproblem def check_either(self, value, context_mark, data, context, echoerr, start, end): + havemarks(value) new_echoerr = DelayedEchoErr(echoerr) hadproblem = False @@ -196,6 +215,7 @@ class Spec(object): return False, hadproblem def check_tuple(self, value, context_mark, data, context, echoerr, start, end): + havemarks(value) hadproblem = False for (i, item, spec) in zip(itertools.count(), value, self.specs[start:end]): proceed, ihadproblem = spec.match( @@ -360,6 +380,7 @@ class Spec(object): return True, hadproblem def match(self, value, context_mark=None, data=None, context=EMPTYTUPLE, echoerr=echoerr): + havemarks(value) proceed, hadproblem = self.match_checks(value, context_mark, data, context, echoerr) if proceed: if self.keys or self.uspecs: @@ -385,6 +406,7 @@ class Spec(object): problem='required key is missing: {0}'.format(key), problem_mark=value.mark) for key in value.keys(): + havemarks(key) if key not in self.keys: for keyfunc, vali in self.uspecs: valspec = self.specs[vali] @@ -429,6 +451,7 @@ class WithPath(object): def check_matcher_func(ext, match_name, data, context, echoerr): + havemarks(match_name) import_paths = [os.path.expanduser(path) for path in context[0][1].get('common', {}).get('paths', [])] match_module, separator, match_function = match_name.rpartition('.') @@ -470,6 +493,7 @@ def check_matcher_func(ext, match_name, data, context, echoerr): def check_ext(ext, data, context, echoerr): + havemarks(ext) hadsomedirs = False hadproblem = False if ext not in data['lists']['exts']: @@ -490,6 +514,7 @@ def check_ext(ext, data, context, echoerr): def check_config(d, theme, data, context, echoerr): + context_has_marks(context) if len(context) == 4: ext = context[-2][0] else: @@ -512,6 +537,8 @@ def check_config(d, theme, data, context, echoerr): def check_top_theme(theme, data, context, echoerr): + context_has_marks(context) + havemarks(theme) if theme not in data['configs']['top_themes']: echoerr(context='Error while checking extension configuration (key {key})'.format(key=context_key(context)), context_mark=context[-2][0].mark, @@ -615,6 +642,7 @@ colors_spec = (Spec( def check_color(color, data, context, echoerr): + havemarks(color) if (color not in data['colors_config'].get('colors', {}) and color not in data['colors_config'].get('gradients', {})): echoerr( @@ -632,6 +660,7 @@ def check_translated_group_name(group, data, context, echoerr): def check_group(group, data, context, echoerr): + havemarks(group) if not isinstance(group, unicode): return True, False, False colorscheme = data['colorscheme'] @@ -671,6 +700,7 @@ def check_group(group, data, context, echoerr): new_data['colorscheme'] = new_colorscheme else: new_data = data + havemarks(config) try: group_data = config['groups'][group] except KeyError: @@ -781,7 +811,10 @@ highlight_keys = set(('highlight_group', 'name')) def check_key_compatibility(segment, data, context, echoerr): + context_has_marks(context) + havemarks(segment) segment_type = segment.get('type', 'function') + havemarks(segment_type) if segment_type not in type_keys: echoerr(context='Error while checking segments (key {key})'.format(key=context_key(context)), @@ -828,6 +861,7 @@ def check_key_compatibility(segment, data, context, echoerr): def check_segment_module(module, data, context, echoerr): + havemarks(module) with WithPath(data['import_paths']): try: __import__(str(module)) @@ -878,11 +912,14 @@ def check_full_segment_data(segment, data, context, echoerr): def import_segment(name, data, context, echoerr, module=None): + context_has_marks(context) + havemarks(name) if not module: module = context[-2][1].get( 'module', context[0][1].get( 'default_module', MarkedUnicode( 'powerline.segments.' + data['ext'], None))) + havemarks(module) with WithPath(data['import_paths']): try: @@ -910,6 +947,7 @@ def import_segment(name, data, context, echoerr, module=None): def check_segment_name(name, data, context, echoerr): + havemarks(name) ext = data['ext'] if context[-2][1].get('type', 'function') == 'function': func = import_segment(name, data, context, echoerr) @@ -1007,6 +1045,7 @@ def check_segment_name(name, data, context, echoerr): def hl_exists(hl_group, data, context, echoerr, allow_gradients=False): + havemarks(hl_group) ext = data['ext'] if ext not in data['colorscheme_configs']: # No colorschemes. Error was already reported, no need to report it @@ -1018,12 +1057,14 @@ def hl_exists(hl_group, data, context, echoerr, allow_gradients=False): r.append(colorscheme) elif not allow_gradients or allow_gradients == 'force': group_config = cconfig['groups'][hl_group] + havemarks(group_config) hadgradient = False for ckey in ('fg', 'bg'): color = group_config.get(ckey) if not color: # No color. Error was already reported. continue + havemarks(color) # Gradients are only allowed for function segments. Note that # whether *either* color or gradient exists should have been # already checked @@ -1054,6 +1095,7 @@ def hl_exists(hl_group, data, context, echoerr, allow_gradients=False): def check_highlight_group(hl_group, data, context, echoerr): + havemarks(hl_group) r = hl_exists(hl_group, data, context, echoerr) if r: echoerr( @@ -1067,6 +1109,7 @@ def check_highlight_group(hl_group, data, context, echoerr): def check_highlight_groups(hl_groups, data, context, echoerr): + havemarks(hl_groups) rs = [hl_exists(hl_group, data, context, echoerr) for hl_group in hl_groups] if all(rs): echoerr( @@ -1103,6 +1146,7 @@ def list_themes(data, context): def check_segment_data_key(key, data, context, echoerr): + havemarks(key) has_module_name = '.' in key found = False for ext, theme in list_themes(data, context): @@ -1141,6 +1185,7 @@ threaded_args_specs = { def check_args_variant(func, args, data, context, echoerr): + havemarks(args) argspec = getconfigargspec(func) present_args = set(args) all_args = set(argspec.args) @@ -1181,6 +1226,7 @@ def check_args_variant(func, args, data, context, echoerr): def check_args(get_functions, args, data, context, echoerr): + context_has_marks(context) new_echoerr = DelayedEchoErr(echoerr) count = 0 hadproblem = False From 721dadd57c9a6fa5b9332bce9589be1f59775c8f Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 24 Aug 2014 23:23:31 +0400 Subject: [PATCH 05/11] Use init_context to initialize config context --- powerline/lint/__init__.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/powerline/lint/__init__.py b/powerline/lint/__init__.py index 49e03d96..66259e73 100644 --- a/powerline/lint/__init__.py +++ b/powerline/lint/__init__.py @@ -37,6 +37,10 @@ key_sep = JStr('/') list_sep = JStr(', ') +def init_context(config): + return ((MarkedUnicode('', config.mark), config),) + + def context_key(context): return key_sep.join((c[0] for c in context)) @@ -1474,7 +1478,7 @@ def check(paths=None, debug=False): if main_spec.match( main_config, data={'configs': configs, 'lists': lists}, - context=(('', main_config),), + context=init_context(main_config), echoerr=ee )[1]: hadproblem = True @@ -1492,7 +1496,7 @@ def check(paths=None, debug=False): sys.stderr.write(str(e) + '\n') hadproblem = True else: - if colors_spec.match(colors_config, context=(('', colors_config),), echoerr=ee)[1]: + if colors_spec.match(colors_config, context=init_context(colors_config), echoerr=ee)[1]: hadproblem = True if lhadproblem[0]: @@ -1517,7 +1521,7 @@ def check(paths=None, debug=False): hadproblem = True top_colorscheme_configs[colorscheme] = config data['colorscheme'] = colorscheme - if top_colorscheme_spec.match(config, context=(('', config),), data=data, echoerr=ee)[1]: + if top_colorscheme_spec.match(config, context=init_context(config), data=data, echoerr=ee)[1]: hadproblem = True ext_colorscheme_configs = defaultdict(lambda: {}) @@ -1549,7 +1553,7 @@ def check(paths=None, debug=False): spec = shell_colorscheme_spec else: spec = colorscheme_spec - if spec.match(config, context=(('', config),), data=data, echoerr=ee)[1]: + if spec.match(config, context=init_context(config), data=data, echoerr=ee)[1]: hadproblem = True colorscheme_configs = {} @@ -1618,7 +1622,7 @@ def check(paths=None, debug=False): else: data['theme_type'] = 'regular' spec = theme_spec - if spec.match(config, context=(('', config),), data=data, echoerr=ee)[1]: + if spec.match(config, context=init_context(config), data=data, echoerr=ee)[1]: hadproblem = True for top_theme, config in top_theme_configs.items(): @@ -1633,7 +1637,7 @@ def check(paths=None, debug=False): } data['theme_type'] = 'top' data['theme'] = top_theme - if top_theme_spec.match(config, context=(('', config),), data=data, echoerr=ee)[1]: + if top_theme_spec.match(config, context=init_context(config), data=data, echoerr=ee)[1]: hadproblem = True return hadproblem From 59e039ab5b00f507b38639aa4106a2118347f45e Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 24 Aug 2014 23:24:32 +0400 Subject: [PATCH 06/11] Make error messages from context_has_marks and havemarks more verbose --- powerline/lint/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/powerline/lint/__init__.py b/powerline/lint/__init__.py index 66259e73..51703da6 100644 --- a/powerline/lint/__init__.py +++ b/powerline/lint/__init__.py @@ -48,15 +48,15 @@ def context_key(context): def havemarks(*args): for i, v in enumerate(args): if not hasattr(v, 'mark'): - raise AssertionError('Value #{0} has no attribute `mark`'.format(i)) + raise AssertionError('Value #{0} ({1!r}) has no attribute `mark`'.format(i, v)) def context_has_marks(context): for i, v in enumerate(context): if not hasattr(v[0], 'mark'): - raise AssertionError('Key #{0} in context has no attribute `mark`'.format(i)) + raise AssertionError('Key #{0} ({1!r}) in context has no attribute `mark`'.format(i, v[0])) if not hasattr(v[1], 'mark'): - raise AssertionError('Value #{0} in context has no attribute `mark`'.format(i)) + raise AssertionError('Value #{0} ({1!r}) in context has no attribute `mark`'.format(i, v[1])) class EchoErr(object): From 3a608d838df2e6d318d224941171e4595a455dc8 Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 25 Aug 2014 00:36:43 +0400 Subject: [PATCH 07/11] Record docstring marks --- powerline/lint/__init__.py | 51 ++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/powerline/lint/__init__.py b/powerline/lint/__init__.py index 51703da6..6f38de9b 100644 --- a/powerline/lint/__init__.py +++ b/powerline/lint/__init__.py @@ -12,7 +12,7 @@ from copy import copy from powerline.lint.markedjson import load from powerline import generate_config_finder, get_config_paths, load_config from powerline.lib.config import ConfigLoader -from powerline.lint.markedjson.error import echoerr, MarkedError +from powerline.lint.markedjson.error import echoerr, MarkedError, Mark from powerline.lint.markedjson.markedvalue import MarkedUnicode from powerline.segments.vim import vim_modes from powerline.lint.inspect import getconfigargspec @@ -964,12 +964,24 @@ def check_segment_name(name, data, context, echoerr): if func.__doc__: H_G_USED_STR = 'Highlight groups used: ' + LHGUS = len(H_G_USED_STR) D_H_G_USED_STR = 'Divider highlight group used: ' - for line in func.__doc__.split('\n'): + LDHGUS = len(D_H_G_USED_STR) + pointer = 0 + mark_name = '<{0} docstring>'.format(name) + for i, line in enumerate(func.__doc__.split('\n')): if H_G_USED_STR in line: - hl_groups.append(line[line.index(H_G_USED_STR) + len(H_G_USED_STR):]) + idx = line.index(H_G_USED_STR) + LHGUS + hl_groups.append(( + line[idx:], + (mark_name, i + 1, idx + 1, func.__doc__), + pointer + idx + )) elif D_H_G_USED_STR in line: - divider_hl_group = line[line.index(D_H_G_USED_STR) + len(D_H_G_USED_STR) + 2:-3] + idx = line.index(D_H_G_USED_STR) + LDHGUS + 2 + mark = Mark(mark_name, i + 1, idx + 1, func.__doc__, pointer + idx) + divider_hl_group = MarkedUnicode(line[idx:-3], mark) + pointer += len(line) + len('\n') hadproblem = False @@ -988,11 +1000,28 @@ def check_segment_name(name, data, context, echoerr): if hl_groups: greg = re.compile(r'``([^`]+)``( \(gradient\))?') - hl_groups = [ - [greg.match(subs).groups() for subs in s.split(' or ')] - for s in (list_sep.join(hl_groups)).split(', ') - ] - for required_pack in hl_groups: + parsed_hl_groups = [] + for line, mark_args, pointer in hl_groups: + for s in line.split(', '): + required_pack = [] + sub_pointer = pointer + for subs in s.split(' or '): + match = greg.match(subs) + try: + if not match: + continue + hl_group = MarkedUnicode( + match.group(1), + Mark(*mark_args, pointer=sub_pointer + match.start(1)) + ) + gradient = bool(match.group(2)) + required_pack.append((hl_group, gradient)) + finally: + sub_pointer += len(subs) + len(' or ') + parsed_hl_groups.append(required_pack) + pointer += len(s) + len(', ') + del hl_group, gradient + for required_pack in parsed_hl_groups: rs = [ hl_exists(hl_group, data, context, echoerr, allow_gradients=('force' if gradient else False)) for hl_group, gradient in required_pack @@ -1080,7 +1109,7 @@ def hl_exists(hl_group, data, context, echoerr, allow_gradients=False): echoerr( context='Error while checking highlight group in theme (key {key})'.format( key=context_key(context)), - context_mark=getattr(hl_group, 'mark', None), + context_mark=hl_group.mark, problem='group {0} is using gradient {1} instead of a color'.format(hl_group, color), problem_mark=color.mark ) @@ -1090,7 +1119,7 @@ def hl_exists(hl_group, data, context, echoerr, allow_gradients=False): echoerr( context='Error while checking highlight group in theme (key {key})'.format( key=context_key(context)), - context_mark=getattr(hl_group, 'mark', None), + context_mark=hl_group.mark, problem='group {0} should have at least one gradient color, but it has no'.format(hl_group), problem_mark=group_config.mark ) From f8bea417fe0a09e50938d0fc837bd1ab97ac3a0b Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 25 Aug 2014 00:37:25 +0400 Subject: [PATCH 08/11] Add MarkedDict.keydict attribute Useful for preserving marked keys --- powerline/lint/markedjson/markedvalue.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/powerline/lint/markedjson/markedvalue.py b/powerline/lint/markedjson/markedvalue.py index 6c619c56..c7929cd2 100644 --- a/powerline/lint/markedjson/markedvalue.py +++ b/powerline/lint/markedjson/markedvalue.py @@ -64,9 +64,20 @@ class MarkedFloat(float): class MarkedDict(dict): __new__ = gen_new(dict) - __init__ = gen_init(dict) __getnewargs__ = gen_getnewargs(dict) + def __init__(self, value, mark): + dict.__init__(self, value) + self.keydict = dict(((key, key) for key in self)) + + def __setitem__(self, key, value): + dict.__setitem__(self, key, value) + self.keydict[key] = key + + def update(self, *args, **kwargs): + dict.update(self, *args, **kwargs) + self.keydict = dict(((key, key) for key in self)) + def copy(self): return MarkedDict(super(MarkedDict, self).copy(), self.mark) From 1cc1e3562455c02d33e73f54c4cb1a9a8136f151 Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 25 Aug 2014 00:38:04 +0400 Subject: [PATCH 09/11] Check whether values have marks recursively --- powerline/lint/__init__.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/powerline/lint/__init__.py b/powerline/lint/__init__.py index 6f38de9b..af599245 100644 --- a/powerline/lint/__init__.py +++ b/powerline/lint/__init__.py @@ -45,18 +45,22 @@ def context_key(context): return key_sep.join((c[0] for c in context)) -def havemarks(*args): +def havemarks(*args, **kwargs): + origin = kwargs.get('origin', '') for i, v in enumerate(args): if not hasattr(v, 'mark'): - raise AssertionError('Value #{0} ({1!r}) has no attribute `mark`'.format(i, v)) + raise AssertionError('Value #{0}/{1} ({2!r}) has no attribute `mark`'.format(origin, i, v)) + if isinstance(v, dict): + for key, val in v.items(): + havemarks(key, val, origin=(origin + '[' + unicode(i) + ']/' + unicode(key))) + elif isinstance(v, list): + havemarks(*v, origin=(origin + '[' + unicode(i) + ']')) def context_has_marks(context): for i, v in enumerate(context): - if not hasattr(v[0], 'mark'): - raise AssertionError('Key #{0} ({1!r}) in context has no attribute `mark`'.format(i, v[0])) - if not hasattr(v[1], 'mark'): - raise AssertionError('Value #{0} ({1!r}) in context has no attribute `mark`'.format(i, v[1])) + havemarks(v[0], origin='context key') + havemarks(v[1], origin='context val') class EchoErr(object): From 9d7c5dd390113fe1aabab20cbc6ad6a55159098d Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 25 Aug 2014 00:38:32 +0400 Subject: [PATCH 10/11] Add marks where they were forgotten --- powerline/lint/__init__.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/powerline/lint/__init__.py b/powerline/lint/__init__.py index af599245..aac214ae 100644 --- a/powerline/lint/__init__.py +++ b/powerline/lint/__init__.py @@ -94,6 +94,10 @@ class DelayedEchoErr(EchoErr): __bool__ = __nonzero__ +def new_context_item(key, value): + return ((value.keydict[key], value[key]),) + + class Spec(object): def __init__(self, **keys): self.specs = [] @@ -189,7 +193,7 @@ class Spec(object): item, value.mark, data, - context + (('list item ' + unicode(i), item),), + context + ((MarkedUnicode('list item ' + unicode(i), item.mark), item),), echoerr ) else: @@ -230,7 +234,7 @@ class Spec(object): item, value.mark, data, - context + (('tuple item ' + unicode(i), item),), + context + ((MarkedUnicode('tuple item ' + unicode(i), item.mark), item),), echoerr ) if ihadproblem: @@ -399,7 +403,7 @@ class Spec(object): value[key], value.mark, data, - context + ((key, value[key]),), + context + new_context_item(key, value), echoerr ) if mhadproblem: @@ -430,7 +434,7 @@ class Spec(object): value[key], value.mark, data, - context + ((key, value[key]),), + context + new_context_item(key, value), echoerr ) if vhadproblem: @@ -821,7 +825,7 @@ highlight_keys = set(('highlight_group', 'name')) def check_key_compatibility(segment, data, context, echoerr): context_has_marks(context) havemarks(segment) - segment_type = segment.get('type', 'function') + segment_type = segment.get('type', MarkedUnicode('function', None)) havemarks(segment_type) if segment_type not in type_keys: @@ -909,9 +913,7 @@ def check_full_segment_data(segment, data, context, echoerr): for name in names: try: val = segment_data[name][key] - # HACK to keep marks - l = list(segment_data[name]) - k = l[l.index(key)] + k = segment_data[name].keydict[key] segment_copy[k] = val except KeyError: pass @@ -1251,7 +1253,7 @@ def check_args_variant(func, args, data, context, echoerr): args[key], args.mark, data, - context + ((key, args[key]),), + context + new_context_item(key, args), echoerr ) if khadproblem: From aeea3331adc97209d3e3099baa9847b6f7646316 Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 25 Aug 2014 00:48:24 +0400 Subject: [PATCH 11/11] Fix python-2.6 support It was calling __setitem__ from copy.deepcopy on an unitialized dictionary. --- powerline/lint/markedjson/markedvalue.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/powerline/lint/markedjson/markedvalue.py b/powerline/lint/markedjson/markedvalue.py index c7929cd2..6a9600dc 100644 --- a/powerline/lint/markedjson/markedvalue.py +++ b/powerline/lint/markedjson/markedvalue.py @@ -63,12 +63,15 @@ class MarkedFloat(float): class MarkedDict(dict): - __new__ = gen_new(dict) + __init__ = gen_init(dict) __getnewargs__ = gen_getnewargs(dict) - def __init__(self, value, mark): - dict.__init__(self, value) - self.keydict = dict(((key, key) for key in self)) + def __new__(arg_cls, value, mark): + r = super(arg_cls, arg_cls).__new__(arg_cls, value) + r.mark = mark + r.value = value + r.keydict = dict(((key, key) for key in r)) + return r def __setitem__(self, key, value): dict.__setitem__(self, key, value)