def __init__(self, source, module_path=None, user_position=None, no_docstr=False, offset=(0, 0), is_fast_parser=None, top_module=None): self.user_position = user_position self.user_scope = None self.user_stmt = None self.no_docstr = no_docstr self.start_pos = self.end_pos = 1 + offset[0], offset[1] # initialize global Scope self.module = pr.SubModule(module_path, self.start_pos, top_module) self._scope = self.module self._current = (None, None) source = source + '\n' # end with \n, because the parser needs it buf = StringIO(source) self._gen = common.NoErrorTokenizer(buf.readline, offset, is_fast_parser) self.top_module = top_module or self.module try: self._parse() except (common.MultiLevelStopIteration, StopIteration): # StopIteration needs to be added as well, because python 2 has a # strange way of handling StopIterations. # sometimes StopIteration isn't catched. Just ignore it. pass # clean up unused decorators for d in self._decorators: # set a parent for unused decorators, avoid NullPointerException # because of `self.module.used_names`. d.parent = self.module if self._current[0] in (tokenize.NL, tokenize.NEWLINE): # we added a newline before, so we need to "remove" it again. self.end_pos = self._gen.previous[2] elif self._current[0] == tokenize.INDENT: self.end_pos = self._gen.last_previous[2] self.start_pos = self.module.start_pos self.module.end_pos = self.end_pos del self._gen
def collect_dir_tests(base_dir, test_files, check_thirdparty=False): for f_name in os.listdir(base_dir): files_to_execute = [a for a in test_files.items() if a[0] in f_name] lines_to_execute = reduce(lambda x, y: x + y[1], files_to_execute, []) if f_name.endswith(".py") and (not test_files or files_to_execute): skip = None if check_thirdparty: lib = f_name.replace('_.py', '') try: # there is always an underline at the end. # It looks like: completion/thirdparty/pylab_.py __import__(lib) except ImportError: skip = 'Thirdparty-Library %s not found.' % lib path = os.path.join(base_dir, f_name) source = open(path).read() for case in collect_file_tests(StringIO(source), lines_to_execute): case.path = path case.source = source if skip: case.skip = skip yield case
def run_test(source, f_name, lines_to_execute): """ This is the completion test for some cases. The tests are not unit test like, they are rather integration tests. It uses comments to specify a test in the next line. The comment also says, which results are expected. The comment always begins with `#?`. The last row symbolizes the cursor. For example: >>> #? ['ab'] >>> ab = 3; a >>> #? int() >>> ab = 3; ab """ def get_defs(correct, correct_start, path): def defs(line_nr, indent): script = jedi.Script(source, line_nr, indent, path) return set(script.get_definition()) should_be = set() number = 0 for index in re.finditer('(?: +|$)', correct): if correct == ' ': continue # -1 for the comment, +3 because of the comment start `#? ` start = index.start() if base.print_debug: jedi.set_debug_function(None) number += 1 try: should_be |= defs(line_nr - 1, start + correct_start) except Exception: print('could not resolve %s indent %s' % (line_nr - 1, start)) raise if base.print_debug: jedi.set_debug_function(debug.print_to_stdout) # because the objects have different ids, `repr` it, then compare it. should_str = set(r.desc_with_module for r in should_be) if len(should_str) < number: raise Exception('Solution @%s not right, too few test results: %s' % (line_nr - 1, should_str)) return should_str fails = 0 tests = 0 correct = None test_type = None start = None for line_nr, line in enumerate(StringIO(source)): line_nr += 1 # py2.5 doesn't know about the additional enumerate param line = unicode(line) if correct: r = re.match('^(\d+)\s*(.*)$', correct) if r: index = int(r.group(1)) correct = r.group(2) start += r.regs[2][0] # second group, start index else: index = len(line) - 1 # -1 for the \n # if a list is wanted, use the completion test, otherwise the # get_definition test path = completion_test_dir + os.path.sep + f_name try: script = jedi.Script(source, line_nr, index, path) if test_type == '!': fails += run_goto_test(script, correct, line_nr) elif test_type == '<': fails += run_related_name_test(script, correct, line_nr) elif correct.startswith('['): fails += run_completion_test(script, correct, line_nr) else: should_str = get_defs(correct, start, path) fails += run_definition_test(script, should_str, line_nr) except Exception: print(traceback.format_exc()) print('test @%s: %s' % (line_nr - 1, line)) fails += 1 correct = None tests += 1 else: try: r = re.search(r'(?:^|(?<=\s))#([?!<])\s*([^\n]+)', line) # test_type is ? for completion and ! for goto test_type = r.group(1) correct = r.group(2) start = r.start() except AttributeError: correct = None else: # reset the test, if only one specific test is wanted if lines_to_execute and line_nr not in lines_to_execute: correct = None return tests, fails