def _validate_import(self, module_line, lineno): """Try to validate the given iport line """ if 'noqa' in module_line: return True error = [] error_string = 'can\'t import {0}' valid = True for word in module_line.split(): if word in ('from', 'import', 'as'): continue offset = int(module_line.find(word) + len(word) / 2) s = Script(self.source, lineno, offset, self.filename) if not self.filename: s = Script(module_line, 1, offset) if not s.goto_assignments(): if valid is True: valid = False error.append(word) err = '' if valid else error_string.format(' '.join(error)) return err, valid
def test_module_attributes(): def_, = Script('__name__').completions() assert def_.name == '__name__' assert def_.line == None assert def_.column == None str_, = def_._goto_definitions() assert str_.name == 'str'
def do_completion(self): source = self.area.get("1.0", "end") line = self.area.indcur()[0] size = len(self.area.get("insert linestart", "insert")) script = Script(source, line, size, self.area.filename) completions = script.completions() for ind in completions: self.insert("end", ind.name)
def feed(self): source = self.area.get('1.0', 'end') line = self.area.indcur()[0] size = len(self.area.get('insert linestart', 'insert')) script = Script(source, line, size, self.area.filename) completions = script.completions() for ind in completions: self.box.insert('end', ind.name)
def test_completion_docstring(): """ Jedi should follow imports in certain conditions """ c = Script('import jedi\njed').completions()[0] assert c.docstring(fast=False) == cleandoc(jedi_doc) c = Script('import jedi\njedi.Scr').completions()[0] assert c.docstring(raw=True, fast=False) == cleandoc(Script.__doc__)
def __init__(self, area, *args, **kwargs): CompleteBox.__init__(self, area, *args, **kwargs) source = self.area.get('1.0', 'end') line = self.area.indcur()[0] size = len(self.area.get('insert linestart', 'insert')) script = Script(source, line, size, self.area.filename) completions = script.completions() for ind in completions: self.insert('end', ind.name)
def run(self, *args, **kwargs): request = self.__request script = Script(request.source_code, request.line, request.col, request.filename, request.encoding) try: call = script.get_in_function_call() if call: self.resultsAvailable.signal.emit(call, request) else: self.failedEvent.signal.emit() except: self.failedEvent.signal.emit()
def ComputeCandidates( self, unused_query, unused_start_column ): filename = vim.current.buffer.name line, column = vimsupport.CurrentLineAndColumn() # Jedi expects lines to start at 1, not 0 line += 1 contents = '\n'.join( vim.current.buffer ) script = Script( contents, line, column, filename ) return [ { 'word': str( completion.word ), 'menu': str( completion.description ), 'info': str( completion.doc ) } for completion in script.complete() ]
def test_add_dynamic_mods(self): fname = '__main__.py' api.settings.additional_dynamic_modules = [fname] # Fictional module that defines a function. src1 = "def r(a): return a" # Other fictional modules in another place in the fs. src2 = 'from .. import setup; setup.r(1)' script = Script(src1, path='../setup.py') imports.load_module(script._evaluator, os.path.abspath(fname), src2) result = script.goto_definitions() assert len(result) == 1 assert result[0].description == 'class int'
def do_complete(self, data): file_ = self.db.get_file(self.current_file) file_ = to_unicode(file_) lines = file_.splitlines() lno = self.current['lno'] line_before = '' if len(lines) >= lno: line_before = lines[lno - 1] indent = len(line_before) - len(line_before.lstrip()) segments = data.splitlines() for segment in reversed(segments): line = u(' ') * indent + segment lines.insert(lno - 1, line) script = Script( u('\n').join(lines), lno - 1 + len(segments), len(segments[-1]) + indent, '') try: completions = script.completions() except Exception: self.db.send('Suggest') self.notify_exc('Completion failed for %s' % ( '\n'.join(reversed(segments)))) return try: funs = script.call_signatures() or [] except Exception: self.db.send('Suggest') self.notify_exc('Completion of function failed for %s' % ( '\n'.join(reversed(segments)))) return try: suggest_obj = { 'params': [{ 'params': [p.get_code().replace('\n', '') for p in fun.params], 'index': fun.index, 'module': fun.module.path, 'call_name': fun.call_name} for fun in funs], 'completions': [{ 'base': comp.name[ :len(comp.name) - len(comp.complete)], 'complete': comp.complete, 'description': comp.description } for comp in completions if comp.name.endswith( comp.complete)] } self.db.send('Suggest|%s' % dump(suggest_obj)) except Exception: self.db.send('Suggest') self.notify_exc('Completion generation failed for %s' % ( '\n'.join(reversed(segments))))
def test_loading_unicode_files_with_bad_global_charset(monkeypatch, tmpdir): dirname = str(tmpdir.mkdir('jedi-test')) filename1 = os.path.join(dirname, 'test1.py') filename2 = os.path.join(dirname, 'test2.py') if sys.version_info < (3, 0): data = "# coding: latin-1\nfoo = 'm\xf6p'\n" else: data = "# coding: latin-1\nfoo = 'm\xf6p'\n".encode("latin-1") with open(filename1, "wb") as f: f.write(data) s = Script("from test1 import foo\nfoo.", line=2, column=4, path=filename2) s.completions()
def test_dict_literal_in_incomplete_call(): source = """\ import json def foo(): json.loads( json.load.return_value = {'foo': [], 'bar': True} c = Foo() """ script = Script(dedent(source), line=4, column=15) assert script.call_signatures()
class Traverser: def __init__(self): self._script = Script('', 1, 0, 'example.py') self._module = self._script._get_module() def names_in_module(self, module_name): try: _import_module(module_name) except Exception as e: pp.pprint(e) return [] imp = Importer( self._script._evaluator, [FakeName('.'.join(module_name))], self._module, 0) try: scope_set = imp.follow() except Exception as e: # print('Error "{}" in {}, ignoring...'.format(e, module_name)) return [] all_names = [] for s in scope_set: names = [] for names_dict in s.names_dicts(search_global=False): names += chain.from_iterable(names_dict.values()) all_names += finder.filter_definition_names(names, self._module) return all_names
def test_completion_docstring(): """ Jedi should follow imports in certain conditions """ def docstr(src, result): c = Script(src).completions()[0] assert c.docstring(raw=True, fast=False) == cleandoc(result) c = Script('import jedi\njed').completions()[0] assert c.docstring(fast=False) == cleandoc(jedi_doc) docstr('import jedi\njedi.Scr', cleandoc(Script.__doc__)) docstr('abcd=3;abcd', '') docstr('"hello"\nabcd=3\nabcd', '') docstr(dedent(''' def x(): "hello" 0 x'''), 'hello' ) docstr(dedent(''' def x(): "hello";0 x'''), 'hello' ) # Shouldn't work with a tuple. docstr(dedent(''' def x(): "hello",0 x'''), '' ) # Should also not work if we rename something. docstr(dedent(''' def x(): "hello" y = x y'''), '' )
def test_completion_docstring(): """ Jedi should follow imports in certain conditions """ def docstr(src, result): c = Script(src).completions()[0] assert c.docstring(raw=True, fast=False) == cleandoc(result) c = Script('import jedi\njed').completions()[0] assert c.docstring(fast=False) == cleandoc(jedi_doc) docstr('import jedi\njedi.Scr', cleandoc(Script.__doc__)) docstr('abcd=3;abcd', '') docstr('"hello"\nabcd=3\nabcd', 'hello') # It works with a ; as well. docstr('"hello"\nabcd=3;abcd', 'hello') # Shouldn't work with a tuple. docstr('"hello",0\nabcd=3\nabcd', '')
def SetCandidates( self ): while True: try: WaitAndClear( self._query_ready ) filename = vim.current.buffer.name line, column = vimsupport.CurrentLineAndColumn() # Jedi expects lines to start at 1, not 0 line += 1 contents = '\n'.join( vim.current.buffer ) script = Script( contents, line, column, filename ) self._candidates = [ { 'word': str( completion.word ), 'menu': str( completion.description ), 'info': str( completion.doc ) } for completion in script.complete() ] except: self._query_ready.clear() self._candidates = [] self._candidates_ready.set()
def finddocstring(self): ''' find the docstring at current cursor location ''' import StringIO from jedi import Script i=editor.get_selection() t=editor.get_text() (line,txt)=[(line,n) for (line,n) in enumerate(StringIO.StringIO(editor.get_text()[:i[1]]))][-1] script = Script(t, line+1, len(txt)) dfn = script.goto_definitions() if dfn: doc=dfn[0].doc import ui v=ui.TextView() v.width=100 v.height=50 v.text=doc editor._set_toolbar(v)
def do_complete(self, data): file_ = self.db.get_file(self.current_file) file_ = to_unicode(file_) lines = file_.splitlines() lno = self.current['lno'] line_before = '' if len(lines) >= lno: line_before = lines[lno - 1] indent = len(line_before) - len(line_before.lstrip()) segments = data.splitlines() for segment in reversed(segments): line = u(' ') * indent + segment lines.insert(lno - 1, line) script = Script( u('\n').join(lines), lno - 1 + len(segments), len(segments[-1]) + indent, '') try: completions = script.complete() except: log.info('Completion failed', exc_info=True) self.db.send('Log|%s' % dump({ 'message': 'Completion failed for %s' % '\n'.join(reversed(segments)) })) else: fun = script.get_in_function_call() self.db.send('Suggest|%s' % dump({ 'params': { 'params': [p.get_code().replace('\n', '') for p in fun.params], 'index': fun.index, 'module': fun.module.path, 'call_name': fun.call_name} if fun else None, 'completions': [{ 'base': comp.word[ :len(comp.word) - len(comp.complete)], 'complete': comp.complete, 'description': comp.description } for comp in completions if comp.word.endswith( comp.complete)] }))
def update(self, source_code, line, col, filename, encoding): # complete with jedi try: script = Script(source_code, line, col, filename, encoding) completions = script.complete() # clean suggestion list self._suggestions[:] = [] for completion in completions: # get type from description desc = completion.description suggestionType = desc.split(":")[0] # get the associated icon if any icon = None if suggestionType in Icons: icon = Icons[suggestionType] else: print "PCEF WARNING: Unimplemented suggestion type: %s" % suggestionType # add the suggestion to the list self._suggestions.append(Suggestion(completion.word, icon=icon, description=desc.split(":")[1])) except: pass
def make_definitions(): """ Return a list of definitions for parametrized tests. :rtype: [jedi.api_classes.BaseDefinition] """ source = dedent( """ import sys class C: pass x = C() def f(): pass def g(): yield h = lambda: None """ ) definitions = [] definitions += defined_names(source) source += dedent( """ variable = sys or C or x or f or g or g() or h""" ) lines = source.splitlines() script = Script(source, len(lines), len("variable"), None) definitions += script.goto_definitions() script2 = Script(source, 4, len("class C"), None) definitions += script2.usages() source_param = "def f(a): return a" script_param = Script(source_param, 1, len(source_param), None) definitions += script_param.goto_assignments() return definitions
def test_os_nowait(self): """ github issue #45 """ s = Script("import os; os.P_").completions() assert 'P_NOWAIT' in [i.name for i in s]
def check(source, result, column=None): completions = Script(source, column=column).completions() assert [c.name for c in completions] == result
def paths(src): script = Script(src, path='/foo/bar.py') expr_stmt = script._get_module_node().children[0] return set( sys_path._paths_from_assignment(script._get_module(), expr_stmt))
def test_issue436(): code = "bar = 0\nbar += 'foo' + 4" errors = set(repr(e) for e in Script(code)._analysis()) assert len(errors) == 2 assert '<Error type-error-operation: None@2,4>' in errors assert '<Error type-error-operation: None@2,13>' in errors
def test_type(): """ Github issue #397, type should never raise an error. """ for c in Script('import os; os.path.').completions(): assert c.type
def bracket_start(src): signatures = Script(src).call_signatures() assert len(signatures) == 1 return signatures[0].bracket_start
def get(source): return Script(source).call_signatures()[0]
def params(self, source, line=None, column=None): signatures = Script(source, line, column).call_signatures() assert len(signatures) == 1 return signatures[0].params
def test_flow_call(self): assert not Script('if (1').call_signatures()
def test_function_definitions_should_break(self): """ Function definitions (and other tokens that cannot exist within call signatures) should break and not be able to return a call signature. """ assert not Script('str(\ndef x').call_signatures()
def paths(src): script = Script(src) stmt = script._get_module_node().statements[0] return set(sys_path._paths_from_assignment(script._get_module(), stmt))
def test_equals(source): script = Script(source) node = script._get_module_node().children[0].children[0] first, = script._get_module().eval_node(node) assert isinstance(first, CompiledObject) and first.obj is True
def script(project: Optional[Project], document: Document) -> Script: """Simplifies getting jedi Script.""" return Script(code=document.source, path=document.path, project=project)
from operator import abs from jedi import Script s = Script(code="""def mula(muusa:int, puusa:str) -> str: x = "dadocstring" return puusa musi = 3 suur = 4 mula(mu""") comps = s.complete(line=6, column=7, fuzzy=True) ii = 3 ss = "asdf" def kala(x: int): return x def showsig(x): if not x: return x return x[0].to_string() + "(%s, %s)" % (x[0].index, x[0].bracket_start) for comp in comps: print(comp, comp.type, showsig(comp.get_signatures()),
def test_named_import(): """named import - jedi-vim issue #8""" s = "import time as dt" assert len(Script(s, 1, 15, '/').goto_definitions()) == 1 assert len(Script(s, 1, 10, '/').goto_definitions()) == 1
def wrapper(source, line, column, path): return f(Script(source, line, column, path, environment=script_env))
def _parent(self, source, line=None, column=None): defs = Script(dedent(source), line, column).goto_assignments() assert len(defs) == 1 return defs[0].parent()
def _parent(self, source, line=None, column=None): def_, = Script(dedent(source), line, column).goto_assignments() return def_.parent()
def get_types(source, **kwargs): return set([t.type for t in Script(source, **kwargs).completions()])
def paths(src): script = Script(src) expr_stmt = script._get_module_node().children[0].children[0] return set(sys_path._paths_from_assignment(script._get_module(), expr_stmt))
def check_module_test(code): module_context = Script(code)._get_module() return check_sys_path_modifications(module_context)
def test_time_docstring(): import time comp, = Script('import time\ntime.sleep').completions() assert comp.docstring() == time.sleep.__doc__
def test_goto_following_on_imports(): s = "import multiprocessing.dummy; multiprocessing.dummy" g = Script(s).goto_assignments() assert len(g) == 1 assert (g[0].line, g[0].column) != (0, 0)
def get_definition_and_evaluator(source): first, = Script(dedent(source)).goto_definitions() return first._name._context, first._evaluator
def get_def(pos): return [d.description for d in Script(s, *pos).goto_definitions()]
def test_completion_params(): c = Script('import string; string.capwords').completions()[0] assert [p.name for p in c.params] == ['s', 'sep']
def _search_func(self, string, complete=False, all_scopes=False): # Using a Script is they easiest way to get an empty module context. from jedi import Script s = Script('', project=self) inference_state = s._inference_state empty_module_context = s._get_module_context() if inference_state.grammar.version_info < ( 3, 6) or sys.version_info < (3, 6): raise NotImplementedError( "No support for refactorings/search on Python 2/3.5") debug.dbg('Search for string %s, complete=%s', string, complete) wanted_type, wanted_names = split_search_string(string) name = wanted_names[0] stub_folder_name = name + '-stubs' ios = recurse_find_python_folders_and_files(FolderIO(self._path)) file_ios = [] # 1. Search for modules in the current project for folder_io, file_io in ios: if file_io is None: file_name = folder_io.get_base_name() if file_name == name or file_name == stub_folder_name: f = folder_io.get_file_io('__init__.py') try: m = load_module_from_path(inference_state, f).as_context() except FileNotFoundError: f = folder_io.get_file_io('__init__.pyi') try: m = load_module_from_path(inference_state, f).as_context() except FileNotFoundError: m = load_namespace_from_path( inference_state, folder_io).as_context() else: continue else: file_ios.append(file_io) file_name = os.path.basename(file_io.path) if file_name in (name + '.py', name + '.pyi'): m = load_module_from_path(inference_state, file_io).as_context() else: continue debug.dbg('Search of a specific module %s', m) for x in search_in_module( inference_state, m, names=[m.name], wanted_type=wanted_type, wanted_names=wanted_names, complete=complete, convert=True, ignore_imports=True, ): yield x # Python 2... # 2. Search for identifiers in the project. for module_context in search_in_file_ios(inference_state, file_ios, name): names = get_module_names(module_context.tree_node, all_scopes=all_scopes) names = [module_context.create_name(n) for n in names] names = _remove_imports(names) for x in search_in_module( inference_state, module_context, names=names, wanted_type=wanted_type, wanted_names=wanted_names, complete=complete, ignore_imports=True, ): yield x # Python 2... # 3. Search for modules on sys.path sys_path = [ p for p in self._get_sys_path(inference_state) # Exclude folders that are handled by recursing of the Python # folders. if not p.startswith(self._path) ] names = list( iter_module_names(inference_state, empty_module_context, sys_path)) for x in search_in_module( inference_state, empty_module_context, names=names, wanted_type=wanted_type, wanted_names=wanted_names, complete=complete, convert=True, ): yield x # Python 2...
def _interaction( self, frame, tb, exception, exception_description): log.debug('Interaction for %r %r %r %r' % ( frame, tb, exception, exception_description)) stack, trace, current_index = self.get_trace(frame, tb) current = trace[current_index] locals_ = map(lambda x: x[0].f_locals, stack) if self.begun: self.send('Trace|%s' % dump({ 'trace': trace, 'cwd': os.getcwd() })) current_file = current['file'] self.send('Check|%s' % dump({ 'name': current_file, 'sha512': sha512(self.get_file(current_file)).hexdigest() })) else: self.begun = True while True: message = self.receive() if '|' in message: pipe = message.index('|') cmd = message[:pipe] data = message[pipe + 1:] else: cmd = message data = '' log.debug('Cmd %s #Data %d' % (cmd, len(data))) if cmd == 'Start': self.send('Init|%s' % dump({ 'cwd': os.getcwd() })) self.send('Title|%s' % dump({ 'title': exception, 'subtitle': exception_description })) self.send('Trace|%s' % dump({ 'trace': trace })) current_file = current['file'] self.send('Check|%s' % dump({ 'name': current_file, 'sha512': sha512(self.get_file(current_file)).hexdigest() })) elif cmd == 'Select': current_index = int(data) current = trace[current_index] current_file = current['file'] self.send('Check|%s' % dump({ 'name': current_file, 'sha512': sha512(self.get_file(current_file)).hexdigest() })) elif cmd == 'File': current_file = current['file'] self.send('Select|%s' % dump({ 'frame': current, 'breaks': self.get_file_breaks(current_file), 'file': self.get_file(current_file), 'name': current_file, 'sha512': sha512(self.get_file(current_file)).hexdigest() })) elif cmd == 'NoFile': self.send('Select|%s' % dump({ 'frame': current, 'breaks': self.get_file_breaks(current['file']) })) elif cmd == 'Inspect': try: thing = reverse_id(int(data)) except: continue self.send('Dump|%s' % dump({ 'for': escape(repr(thing)), 'val': dmp(thing)})) elif cmd == 'Dump': globals_ = dict(stack[current_index][0].f_globals) try: thing = eval(data, globals_, locals_[current_index]) except: continue self.send('Dump|%s' % dump({ 'for': escape(repr(thing)), 'val': dmp(thing)})) elif cmd == 'Trace': self.send('Trace|%s' % dump({ 'trace': trace })) elif cmd == 'Eval': globals_ = dict(stack[current_index][0].f_globals) # Hack for function scope eval globals_.update(locals_[current_index]) globals_.setdefault('_pprint', pprint) globals_.setdefault('_dump', dmp) with capture_output() as (out, err): try: compiled_code = compile(data, '<stdin>', 'single') exec compiled_code in globals_, locals_[current_index] except Exception: type_, value, tb = exc_info() print '%s: %s' % (type_.__name__, str(value)) self.send('Print|%s' % dump({ 'result': escape('\n'.join(out) + '\n'.join(err)) })) elif cmd == 'Ping': self.send('Pong') elif cmd == 'Step': if hasattr(self, 'botframe'): self.set_step() break elif cmd == 'Next': if hasattr(self, 'botframe'): self.set_next(stack[current_index][0]) break elif cmd == 'Continue': if hasattr(self, 'botframe'): self.set_continue() break elif cmd == 'Return': if hasattr(self, 'botframe'): self.set_return(stack[current_index][0]) break elif cmd == 'Until': if hasattr(self, 'botframe'): self.set_until(stack[current_index][0]) break elif cmd in ('TBreak', 'Break'): if ':' in data: fn, lno = data.split(':') else: fn, lno = current['file'], data cond = None if ',' in lno: lno, cond = lno.split(',') cond = cond.lstrip() lno = int(lno) rv = self.set_break(fn, lno, int(cmd == 'TBreak'), cond) if rv is not None: for path in sys.path: rv = self.set_break( os.path.join(path, fn), lno, int(cmd == 'TBreak'), cond) if rv is None: break if rv is None: log.info('Break set at %s:%d [%s]' % (fn, lno, rv)) if fn == current['file']: self.send('BreakSet|%s' % dump({ 'lno': lno, 'cond': cond })) else: self.send('BreakSet|%s' % dump({})) else: self.send('Log|%s' % dump({ 'message': rv })) elif cmd == 'Unbreak': lno = int(data) current_file = current['file'] log.info('Break unset at %s:%d' % (current_file, lno)) self.clear_break(current_file, lno) self.send('BreakUnset|%s' % dump({'lno': lno})) elif cmd == 'Jump': lno = int(data) if current_index != len(trace) - 1: log.error('Must be at bottom frame') continue try: stack[current_index][0].f_lineno = lno except ValueError: log.error('Jump failed') continue trace[current_index]['lno'] = lno self.send('Trace|%s' % dump({ 'trace': trace })) self.send('Select|%s' % dump({ 'frame': current, 'breaks': self.get_file_breaks(current['file']) })) elif cmd == 'Complete': current_file = current['file'] file_ = self.get_file(current_file, False).decode('utf-8') lines = file_.split(u'\n') lno = trace[current_index]['lno'] line_before = lines[lno - 1] indent = len(line_before) - len(line_before.lstrip()) segments = data.split(u'\n') for segment in reversed(segments): line = u' ' * indent + segment lines.insert(lno - 1, line) script = Script( u'\n'.join(lines), lno - 1 + len(segments), len(segments[-1]) + indent, '') try: completions = script.complete() except: self.send('Log|%s' % dump({ 'message': 'Completion failed for %s' % '\n'.join(reversed(segments)) })) else: fun = script.get_in_function_call() self.send('Suggest|%s' % dump({ 'params': { 'params': [p.get_code().replace('\n', '') for p in fun.params], 'index': fun.index, 'module': fun.module.path, 'call_name': fun.call_name} if fun else None, 'completions': [{ 'base': comp.word[ :len(comp.word) - len(comp.complete)], 'complete': comp.complete, 'description': comp.description } for comp in completions if comp.word.endswith( comp.complete)] })) elif cmd == 'Quit': if hasattr(self, 'botframe'): self.set_continue() raise BdbQuit() break else: log.warn('Unknown command %s' % cmd)
def _interaction(self, frame, tb, exception, exception_description): log.debug("Interaction for %r %r %r %r" % (frame, tb, exception, exception_description)) stack, trace, current_index = self.get_trace(frame, tb) current = trace[current_index] locals_ = map(lambda x: x[0].f_locals, stack) if self.begun: self.send("Trace|%s" % dump({"trace": trace, "cwd": os.getcwd()})) current_file = current["file"] self.send( "Check|%s" % dump({"name": current_file, "sha512": sha512(self.get_file(current_file)).hexdigest()}) ) else: self.begun = True while True: try: message = self.receive() if "|" in message: pipe = message.index("|") cmd = message[:pipe] data = message[pipe + 1 :] else: cmd = message data = "" def fail(title=None, message=None): if message is None: message = self.handle_exc() else: message = escape(message) self.send("Echo|%s" % dump({"for": escape(title or "%s failed" % cmd), "val": message})) log.debug("Cmd %s #Data %d" % (cmd, len(data))) if cmd == "Start": self.send("Init|%s" % dump({"cwd": os.getcwd()})) self.send("Title|%s" % dump({"title": exception, "subtitle": exception_description})) self.send("Trace|%s" % dump({"trace": trace})) current_file = current["file"] self.send( "Check|%s" % dump({"name": current_file, "sha512": sha512(self.get_file(current_file)).hexdigest()}) ) elif cmd == "Select": current_index = int(data) current = trace[current_index] current_file = current["file"] self.send( "Check|%s" % dump({"name": current_file, "sha512": sha512(self.get_file(current_file)).hexdigest()}) ) elif cmd == "File": current_file = current["file"] self.send( "Select|%s" % dump( { "frame": current, "breaks": self.get_file_breaks(current_file), "file": self.get_file(current_file), "name": current_file, "sha512": sha512(self.get_file(current_file)).hexdigest(), } ) ) elif cmd == "NoFile": self.send("Select|%s" % dump({"frame": current, "breaks": self.get_file_breaks(current["file"])})) elif cmd == "Inspect": try: thing = self.obj_cache.get(int(data)) except Exception: fail() continue self.send("Dump|%s" % dump({"for": escape(repr(thing)), "val": self.dmp(thing)})) elif cmd == "Dump": globals_ = dict(stack[current_index][0].f_globals) try: thing = eval(data, globals_, locals_[current_index]) except Exception: fail() continue else: self.send( "Dump|%s" % dump({"for": escape(u"%s ⟶ %s " % (data, repr(thing))), "val": self.dmp(thing)}) ) elif cmd == "Trace": self.send("Trace|%s" % dump({"trace": trace})) elif cmd == "Eval": redir = None raw_data = data = data.strip() if "!>" in data: data, redir = data.split("!>") data = data.strip() redir = redir.strip() elif data.startswith("!<"): filename = data[2:].strip() try: with open(filename, "r") as f: data = f.read() except Exception: fail("Unable to read from file %s" % filename) continue globals_ = dict(stack[current_index][0].f_globals) # Hack for function scope eval globals_.update(locals_[current_index]) globals_.setdefault("_pprint", pprint) with self.capture_output(with_hook=redir is None) as (out, err): try: compiled_code = compile(data, "<stdin>", "single") l = locals_[current_index] exec compiled_code in globals_, l except Exception: self.hooked = self.handle_exc() if redir: try: with open(redir, "w") as f: f.write("\n".join(out) + "\n".join(err) + "\n") except Exception: fail("Unable to write to file %s" % redir) continue self.send( "Print|%s" % dump({"for": escape(raw_data), "result": escape("Written to file %s" % redir)}) ) else: self.send( "Print|%s" % dump( { "for": escape(raw_data), "result": self.hooked + escape("\n".join(out) + "\n".join(err)), } ) ) elif cmd == "Ping": self.send("Pong") elif cmd == "Step": if hasattr(self, "botframe"): self.set_step() break elif cmd == "Next": if hasattr(self, "botframe"): self.set_next(stack[current_index][0]) break elif cmd == "Continue": if hasattr(self, "botframe"): self.set_continue() break elif cmd == "Return": if hasattr(self, "botframe"): self.set_return(stack[current_index][0]) break elif cmd == "Until": if hasattr(self, "botframe"): self.set_until(stack[current_index][0]) break elif cmd in ("TBreak", "Break"): break_fail = lambda x: fail("Break on %s failed" % data, message=x) if ":" in data: fn, lno = data.split(":") else: fn, lno = current["file"], data cond = None if "," in lno: lno, cond = lno.split(",") cond = cond.lstrip() try: lno = int(lno) except: break_fail("Wrong breakpoint format must be " "[file:]lno[,cond].") continue line = getline(fn, lno, stack[current_index][0].f_globals) if not line: break_fail("Line does not exist") continue line = line.strip() if not line or (line[0] == "#") or (line[:3] == '"""') or line[:3] == "'''": break_fail("Blank line or comment") continue first_rv = rv = self.set_break(fn, lno, int(cmd == "TBreak"), cond) if rv is not None: for path in sys.path: rv = self.set_break(os.path.join(path, fn), lno, int(cmd == "TBreak"), cond) if rv is None: break if rv is None: log.info("Break set at %s:%d [%s]" % (fn, lno, rv)) if fn == current["file"]: self.send("BreakSet|%s" % dump({"lno": lno, "cond": cond})) else: self.send("BreakSet|%s" % dump({})) else: break_fail(first_rv) elif cmd == "Unbreak": lno = int(data) current_file = current["file"] log.info("Break unset at %s:%d" % (current_file, lno)) self.clear_break(current_file, lno) self.send("BreakUnset|%s" % dump({"lno": lno})) elif cmd == "Jump": lno = int(data) if current_index != len(trace) - 1: log.error("Must be at bottom frame") continue try: stack[current_index][0].f_lineno = lno except ValueError: fail() continue trace[current_index]["lno"] = lno self.send("Trace|%s" % dump({"trace": trace})) self.send("Select|%s" % dump({"frame": current, "breaks": self.get_file_breaks(current["file"])})) elif cmd == "Complete": current_file = current["file"] file_ = self.get_file(current_file, False).decode("utf-8") lines = file_.split(u"\n") lno = trace[current_index]["lno"] line_before = lines[lno - 1] indent = len(line_before) - len(line_before.lstrip()) segments = data.split(u"\n") for segment in reversed(segments): line = u" " * indent + segment lines.insert(lno - 1, line) script = Script(u"\n".join(lines), lno - 1 + len(segments), len(segments[-1]) + indent, "") try: completions = script.complete() except: log.exception("Completion failed") self.send( "Log|%s" % dump({"message": "Completion failed for %s" % "\n".join(reversed(segments))}) ) else: fun = script.get_in_function_call() self.send( "Suggest|%s" % dump( { "params": { "params": [p.get_code().replace("\n", "") for p in fun.params], "index": fun.index, "module": fun.module.path, "call_name": fun.call_name, } if fun else None, "completions": [ { "base": comp.word[: len(comp.word) - len(comp.complete)], "complete": comp.complete, "description": comp.description, } for comp in completions if comp.word.endswith(comp.complete) ], } ) ) elif cmd == "Quit": if hasattr(self, "botframe"): self.set_continue() raise BdbQuit() break else: log.warn("Unknown command %s" % cmd) except BdbQuit: raise except Exception: try: exc = self.handle_exc() type_, value = exc_info()[:2] link = ( '<a href="https://github.com/Kozea/wdb/issues/new?' 'title=%s&body=%s&labels=defect" class="nogood">' "Please click here to report it on Github</a>" ) % ( quote("%s: %s" % (type_.__name__, str(value))), quote("```\n%s\n```\n" % traceback.format_exc()), ) self.send( "Echo|%s" % dump({"for": escape("Error in Wdb, this is bad"), "val": exc + "<br>" + link}) ) except: self.send( "Echo|%s" % dump( { "for": escape("Too many errors"), "val": escape("Don't really know what to say. " "Maybe it will work tomorrow."), } ) ) continue
def __init__(self): self._script = Script('', 1, 0, 'example.py') self._module = self._script._get_module()
def test_call_signature_on_module(self): """github issue #240""" s = 'import datetime; datetime(' # just don't throw an exception (if numpy doesn't exist, just ignore it) assert Script(s).call_signatures() == []
def test_position_none_if_builtin(): gotos = Script('import sys; sys.path').goto_assignments() assert gotos[0].line is None assert gotos[0].column is None
def test_goto_definition_on_import(): assert Script("import sys_blabla", 1, 8).goto_definitions() == [] assert len(Script("import sys", 1, 8).goto_definitions()) == 1
def test_is_keyword(): #results = Script('import ', 1, 1, None).goto_definitions() #assert len(results) == 1 and results[0].is_keyword is True results = Script('str', 1, 1, None).goto_definitions() assert len(results) == 1 and results[0].is_keyword is False
def test_dict_values(): assert Script('import sys/sys.modules["alshdb;lasdhf"]').goto_definitions()
def docstr(src, result): c = Script(src).completions()[0] assert c.docstring(raw=True, fast=False) == cleandoc(result)
def typ(string): d = Script("a = %s; a" % string).goto_definitions()[0] return d.name
def _interaction( self, frame, tb, exception, exception_description): log.debug('Interaction for %r %r %r %r' % ( frame, tb, exception, exception_description)) stack, trace, current_index = self.get_trace(frame, tb) current = trace[current_index] locals_ = map(lambda x: x[0].f_locals, stack) if self.begun: self.send('Trace|%s' % dump({ 'trace': trace, 'cwd': os.getcwd() })) current_file = current['file'] self.send('Check|%s' % dump({ 'name': current_file, 'sha512': sha512(self.get_file(current_file)).hexdigest() })) else: self.begun = True while True: try: message = self.receive() if '|' in message: pipe = message.index('|') cmd = message[:pipe] data = message[pipe + 1:] else: cmd = message data = '' def fail(title=None, message=None): if message is None: message = self.handle_exc() else: message = escape(message) self.send('Echo|%s' % dump({ 'for': escape(title or '%s failed' % cmd), 'val': message })) log.debug('Cmd %s #Data %d' % (cmd, len(data))) if cmd == 'Start': self.send('Init|%s' % dump({ 'cwd': os.getcwd() })) self.send('Title|%s' % dump({ 'title': exception, 'subtitle': exception_description })) self.send('Trace|%s' % dump({ 'trace': trace })) current_file = current['file'] self.send('Check|%s' % dump({ 'name': current_file, 'sha512': sha512( self.get_file(current_file)).hexdigest() })) elif cmd == 'Select': current_index = int(data) current = trace[current_index] current_file = current['file'] self.send('Check|%s' % dump({ 'name': current_file, 'sha512': sha512( self.get_file(current_file)).hexdigest() })) elif cmd == 'File': current_file = current['file'] self.send('Select|%s' % dump({ 'frame': current, 'breaks': self.get_file_breaks(current_file), 'file': self.get_file(current_file), 'name': current_file, 'sha512': sha512( self.get_file(current_file)).hexdigest() })) elif cmd == 'NoFile': self.send('Select|%s' % dump({ 'frame': current, 'breaks': self.get_file_breaks(current['file']) })) elif cmd == 'Inspect': try: thing = self.obj_cache.get(int(data)) except Exception: fail() continue self.send('Dump|%s' % dump({ 'for': escape(repr(thing)), 'val': self.dmp(thing)})) elif cmd == 'Dump': globals_ = dict(stack[current_index][0].f_globals) try: thing = eval(data, globals_, locals_[current_index]) except Exception: fail() continue else: self.send('Dump|%s' % dump({ 'for': escape(u'%s ⟶ %s ' % (data, repr(thing))), 'val': self.dmp(thing)})) elif cmd == 'Trace': self.send('Trace|%s' % dump({ 'trace': trace })) elif cmd == 'Eval': redir = None raw_data = data = data.strip() if '!>' in data: data, redir = data.split('!>') data = data.strip() redir = redir.strip() elif data.startswith('!<'): filename = data[2:].strip() try: with open(filename, 'r') as f: data = f.read() except Exception: fail('Unable to read from file %s' % filename) continue globals_ = dict(stack[current_index][0].f_globals) # Hack for function scope eval globals_.update(locals_[current_index]) globals_.setdefault('_pprint', pprint) with self.capture_output( with_hook=redir is None) as (out, err): try: compiled_code = compile(data, '<stdin>', 'single') l = locals_[current_index] exec compiled_code in globals_, l except Exception: self.hooked = self.handle_exc() if redir: try: with open(redir, 'w') as f: f.write('\n'.join(out) + '\n'.join(err) + '\n') except Exception: fail('Unable to write to file %s' % redir) continue self.send('Print|%s' % dump({ 'for': escape(raw_data), 'result': escape('Written to file %s' % redir) })) else: self.send('Print|%s' % dump({ 'for': escape(raw_data), 'result': self.hooked + escape( '\n'.join(out) + '\n'.join(err)) })) elif cmd == 'Ping': self.send('Pong') elif cmd == 'Step': if hasattr(self, 'botframe'): self.set_step() break elif cmd == 'Next': if hasattr(self, 'botframe'): self.set_next(stack[current_index][0]) break elif cmd == 'Continue': if hasattr(self, 'botframe'): self.set_continue() break elif cmd == 'Return': if hasattr(self, 'botframe'): self.set_return(stack[current_index][0]) break elif cmd == 'Until': if hasattr(self, 'botframe'): self.set_until(stack[current_index][0]) break elif cmd in ('TBreak', 'Break'): break_fail = lambda x: fail( 'Break on %s failed' % data, message=x) if ':' in data: fn, lno = data.split(':') else: fn, lno = current['file'], data cond = None if ',' in lno: lno, cond = lno.split(',') cond = cond.lstrip() try: lno = int(lno) except: break_fail( 'Wrong breakpoint format must be ' '[file:]lno[,cond].') continue line = getline( fn, lno, stack[current_index][0].f_globals) if not line: break_fail('Line does not exist') continue line = line.strip() if ((not line or (line[0] == '#') or (line[:3] == '"""') or line[:3] == "'''")): break_fail('Blank line or comment') continue first_rv = rv = self.set_break( fn, lno, int(cmd == 'TBreak'), cond) if rv is not None: for path in sys.path: rv = self.set_break( os.path.join(path, fn), lno, int(cmd == 'TBreak'), cond) if rv is None: break if rv is None: log.info('Break set at %s:%d [%s]' % (fn, lno, rv)) if fn == current['file']: self.send('BreakSet|%s' % dump({ 'lno': lno, 'cond': cond })) else: self.send('BreakSet|%s' % dump({})) else: break_fail(first_rv) elif cmd == 'Unbreak': lno = int(data) current_file = current['file'] log.info('Break unset at %s:%d' % (current_file, lno)) self.clear_break(current_file, lno) self.send('BreakUnset|%s' % dump({'lno': lno})) elif cmd == 'Jump': lno = int(data) if current_index != len(trace) - 1: log.error('Must be at bottom frame') continue try: stack[current_index][0].f_lineno = lno except ValueError: fail() continue trace[current_index]['lno'] = lno self.send('Trace|%s' % dump({ 'trace': trace })) self.send('Select|%s' % dump({ 'frame': current, 'breaks': self.get_file_breaks(current['file']) })) elif cmd == 'Complete': current_file = current['file'] file_ = self.get_file(current_file, False).decode('utf-8') lines = file_.split(u'\n') lno = trace[current_index]['lno'] line_before = lines[lno - 1] indent = len(line_before) - len(line_before.lstrip()) segments = data.split(u'\n') for segment in reversed(segments): line = u' ' * indent + segment lines.insert(lno - 1, line) script = Script( u'\n'.join(lines), lno - 1 + len(segments), len(segments[-1]) + indent, '') try: completions = script.complete() except: log.exception('Completion failed') self.send('Log|%s' % dump({ 'message': 'Completion failed for %s' % '\n'.join(reversed(segments)) })) else: fun = script.get_in_function_call() self.send('Suggest|%s' % dump({ 'params': { 'params': [p.get_code().replace('\n', '') for p in fun.params], 'index': fun.index, 'module': fun.module.path, 'call_name': fun.call_name} if fun else None, 'completions': [{ 'base': comp.word[ :len(comp.word) - len(comp.complete)], 'complete': comp.complete, 'description': comp.description } for comp in completions if comp.word.endswith( comp.complete)] })) elif cmd == 'Quit': if hasattr(self, 'botframe'): self.set_continue() raise BdbQuit() break else: log.warn('Unknown command %s' % cmd) except BdbQuit: raise except Exception: try: exc = self.handle_exc() type_, value = exc_info()[:2] link = ('<a href="https://github.com/Kozea/wdb/issues/new?' 'title=%s&body=%s&labels=defect" class="nogood">' 'Please click here to report it on Github</a>') % ( quote('%s: %s' % (type_.__name__, str(value))), quote('```\n%s\n```\n' % traceback.format_exc())) self.send('Echo|%s' % dump({ 'for': escape('Error in Wdb, this is bad'), 'val': exc + '<br>' + link })) except: self.send('Echo|%s' % dump({ 'for': escape('Too many errors'), 'val': escape("Don't really know what to say. " "Maybe it will work tomorrow.") })) continue