def test_multibyte_script(Script): """ `medi.Script` must accept multi-byte string source. """ try: code = u("import datetime; datetime.d") comment = u("# multi-byte comment あいうえおä") s = (u('%s\n%s') % (code, comment)).encode('utf-8') except NameError: pass # python 3 has no unicode method else: assert len(Script(s).complete(1, len(code)))
def test_unicode_attribute(Script): """ github medi-vim issue #94 """ s1 = u('#-*- coding: utf-8 -*-\nclass Person():\n' ' name = "e"\n\nPerson().name.') completions1 = Script(s1).complete() assert 'strip' in [c.name for c in completions1] s2 = u('#-*- coding: utf-8 -*-\nclass Person():\n' ' name = "é"\n\nPerson().name.') completions2 = Script(s2).complete() assert 'strip' in [c.name for c in completions2]
def test_unicode_script(Script): """ normally no unicode objects are being used. (<=2.7) """ s = unicode("import datetime; datetime.timedelta") completions = Script(s).complete() assert len(completions) assert type(completions[0].description) is unicode s = u("author='öä'; author") completions = Script(s).complete() x = completions[0].description assert type(x) is unicode s = u("#-*- coding: iso-8859-1 -*-\nauthor='öä'; author") s = s.encode('latin-1') completions = Script(s).complete() assert type(completions[0].description) is unicode
def warning(message, *args, **kwargs): format = kwargs.pop('format', True) assert not kwargs if debug_function and enable_warning: i = ' ' * _debug_indent if format: message = message % tuple(u(repr(a)) for a in args) debug_function('RED', i + 'warning: ' + message)
def dbg(message, *args, **kwargs): """ Looks at the stack, to see if a debug message should be printed. """ # Python 2 compatibility, because it doesn't understand default args color = kwargs.pop('color', 'GREEN') assert color if debug_function and enable_notice: i = ' ' * _debug_indent _lazy_colorama_init() debug_function(color, i + 'dbg: ' + message % tuple(u(repr(a)) for a in args))
def _get_code_for_stack(code_lines, leaf, position): # It might happen that we're on whitespace or on a comment. This means # that we would not get the right leaf. if leaf.start_pos >= position: # If we're not on a comment simply get the previous leaf and proceed. leaf = leaf.get_previous_leaf() if leaf is None: return u('') # At the beginning of the file. is_after_newline = leaf.type == 'newline' while leaf.type == 'newline': leaf = leaf.get_previous_leaf() if leaf is None: return u('') if leaf.type == 'error_leaf' or leaf.type == 'string': if leaf.start_pos[0] < position[0]: # On a different line, we just begin anew. return u('') # Error leafs cannot be parsed, completion in strings is also # impossible. raise OnErrorLeaf(leaf) else: user_stmt = leaf while True: if user_stmt.parent.type in ('file_input', 'suite', 'simple_stmt'): break user_stmt = user_stmt.parent if is_after_newline: if user_stmt.start_pos[1] > position[1]: # This means that it's actually a dedent and that means that we # start without value (part of a suite). return u('') # This is basically getting the relevant lines. return _get_code(code_lines, user_stmt.get_start_pos_of_prefix(), position)
def _infer_for_statement_string(module_context, string): code = dedent(u(""" def pseudo_docstring_stuff(): ''' Create a pseudo function for docstring statements. Need this docstring so that if the below part is not valid Python this is still a function. ''' {} """)) if string is None: return [] for element in re.findall(r'((?:\w+\.)*\w+)\.', string): # Try to import module part in dotted name. # (e.g., 'threading' in 'threading.Thread'). string = 'import %s\n' % element + string # Take the default grammar here, if we load the Python 2.7 grammar here, it # will be impossible to use `...` (Ellipsis) as a token. Docstring types # don't need to conform with the current grammar. debug.dbg('Parse docstring code %s', string, color='BLUE') grammar = module_context.inference_state.latest_grammar try: module = grammar.parse(code.format(indent_block(string)), error_recovery=False) except ParserSyntaxError: return [] try: funcdef = next(module.iter_funcdefs()) # First pick suite, then simple_stmt and then the node, # which is also not the last item, because there's a newline. stmt = funcdef.children[-1].children[-1].children[-2] except (AttributeError, IndexError): return [] if stmt.type not in ('name', 'atom', 'atom_expr'): return [] from medi.inference.value import FunctionValue function_value = FunctionValue( module_context.inference_state, module_context, funcdef ) func_execution_context = function_value.as_context() # Use the module of the param. # TODO this module is not the module of the param in case of a function # call. In that case it's the module of the function call. # stuffed with content from a function call. return list(_execute_types_in_stmt(func_execution_context, stmt))
def main(args): if args['--debug']: medi.set_debug_function(notices=True) with open(args['<file>']) as f: code = f.read() grammar = load_grammar() parser = ParserWithRecovery(grammar, u(code)) # Make sure used_names is loaded parser.module.used_names code = code + '\na\n' # Add something so the diff parser needs to run. lines = splitlines(code, keepends=True) cProfile.runctx('run(parser, lines)', globals(), locals(), sort=args['-s'])
def test_encoding_parameter(Script): name = u('hö') s = Script(name.encode('latin-1'), encoding='latin-1') assert s._module_node.get_code() == name