def cmd_call(self, args_kwargs_str): """Call target with <ARGS>.""" if not probes.is_callable(self.ctx.target): raise CommandError("Item not callable.") try: self.ctx.mgr.transform(trans.Call(args_kwargs_str)) except Exception as ex: raise CommandError(f'Invalid invocation: {exc_to_str(ex)}') from ex return Commands.cmd_info, (self,)
def get_transformation(self, index): if self.ctx.target is not self.cached_target: raise CommandError('No cache for this target') try: key, transformation = self.cache[index] except Exception as ex: raise CommandError(ex) from ex if not transformation.available: raise CommandError('Item not available') return transformation
def cmd_help(self, alias=None): """Show list of available commands or context help on given command. <CMD> is optional and can be either full command name or just a nick (capital leters from the name). See also 'MANual' command. """ if alias is None: print_help('Available commands:') print_help() def get_summary(cmd): try: docstr = inspect.cleandoc(cmd.__doc__) except: return '' return (docstr + '\n').splitlines()[0] def get_header(cmd): return ' '.join( (p for p in (cmd.cmd_descr.name, cmd.cmd_descr.syntax) if p)) entires = [(get_header(cmd), get_summary(cmd)) for cmd in self] headers, summaries = zip(*entires) left_margin = ' ' col_sep = ' ' left_col_width = max(map(len, headers)) lines = (f"{left_margin}{header:<{left_col_width}}{col_sep}{summary}" for header, summary in entires) print_help('\n'.join(sorted(lines, key=lambda x: x.lower()))) print_help() print_help('Use either full command name or just capital leters from it (nick).') print_help('Whatever you type, it is case-insensitive.') print_help('E.g. you can invoke help by typing: h, H, help, Help, HeLp') print_help() print_help('Some of the commands have also keyboard bindings assigned.') print_help('Invoke "help CMD" for more help on specific command.') else: try: cmd_hdlr, _ = self[alias] except KeyError: cmds_custom = {cmd.cmd_descr.name.lower(): cmd for cmd in self if callable(cmd.cmd_descr.qualifier)} try: cmd_hdlr = cmds_custom[alias.lower()] except KeyError: raise CommandError(f'No such command: {alias}.') if cmd_hdlr.__doc__: parts = ('Syntax:', cmd_hdlr.cmd_descr.name, cmd_hdlr.cmd_descr.syntax) print_help(' '.join( (p for p in parts if p) )) print_help(inspect.cleandoc(cmd_hdlr.__doc__)) else: raise CommandError(f"No help on '{cmd_hdlr.cmd_descr.name}'.")
def cmd_self(self): """Bound object becomes a new target.""" try: self.ctx.mgr.transform(trans.Attrib('__self__')) except: raise CommandError(f"This target doesn't have bound object.") return Commands.cmd_info, (self,)
def cmd_items(self, offset): """Call <TARGET>.items() and iterate through results. This can be used for listing keys and values of the dictionary. Optional <OFFSET> can be used for skipping certain number of entires. """ target = self.ctx.target try: keys = target.keys() except Exception as ex: raise CommandError(exc_to_str(ex)) try: content = self.ctx.mgr.propose_subscr(keys) except: raise CommandError("Error while obtaining items to iterate.") self.ctx.explorer.fill(content, 'dict', offset)
def cmd_attrib(self, attr_name): """Return attribute <ATTRIB> of the target. """ try: self.ctx.mgr.transform(trans.Attrib(attr_name)) except: raise CommandError(f"Attribute cannot be obtained.") return Commands.cmd_info, (self,)
def cmd_index(self, expr): """Subscribe target with <EXPR>.""" if not probes.is_subscribable(self.ctx.target): raise CommandError("Item not subscribable.") self.ctx.mgr.transform(trans.SubscrExpr(expr)) return Commands.cmd_info, (self,)
def cmd_bases(self): """Tuple of base classes of the target becomes a new target. See also 'Mro' command. """ try: self.ctx.mgr.transform(trans.Attrib('__bases__')) except: raise CommandError(f"This target doesn't have bases.") return Commands.cmd_info, (self,)
def cmd_forward(self): """Make one step forward in history. See also '..', '/', '.' commands. """ try: self.ctx.mgr.select_next() return Commands.cmd_info, (self,) except IndexError: raise CommandError("This is the last item in history. Cannot go forward any more.")
def cmd_back(self): """Make one step backward in history. See also '-', '/', '.' commands. """ try: self.ctx.mgr.select_prev() return Commands.cmd_info, (self,) except IndexError: raise CommandError(f"This is the first item in history. Cannot go back any more.")
def cmd_mro(self): """MRO list of the target becomes a new target. See also 'Bases' command. """ try: self.ctx.mgr.transform(trans.Attrib('__mro__')) except: raise CommandError(f'There is no MRO list corresponding to this target.') return Commands.cmd_info, (self,)
def fill(self, content, style, offset=0): """style: 'attr', 'list', 'dict' """ str_func_styled = partial(str_func, style) try: self.cache = paged_cache.page(content, str_func_styled, offset) except paged_cache.TooManyInitialIterations as ex: raise CommandError(ex) from ex self.cached_target = self.ctx.target
def evaluate(self, prev, ctx): call = f'_({self.args_kwargs})' try: with CheckInvocation(caller_stack_depth=3): return ctx.eval_(call) except InvocationError as ex: raise CommandError(ex) from ex except Exception as ex: self.catched = True return ex
def cmd_iterate(self, offset): """Iterate target. This can be used for listing values of iterable. Optional <OFFSET> can be used for skipping certain number of entires. """ target = self.ctx.target try: content = self.ctx.mgr.propose_iter(offset) # TODO offset except TypeError: raise CommandError("Item is not iterable.") self.ctx.explorer.fill(content, 'list', offset)
def cmd_vars(self): """Call vars(<TARGET>) and show all the results. See also 'VarsPublic' command. """ target = self.ctx.target try: v = vars(target) except Exception as ex: raise CommandError(exc_to_str(ex)) content = self.ctx.mgr.propose_attr(v.keys(), v.values()) self.ctx.explorer.fill(content, 'attr')
def cmd_export(self): """Export target expression to IPython. This terminates peepshow and initiates next command in underlying IPython with the expression describing current target. See also 'Continue' and 'Quit' commands. """ try: import IPython ip = IPython.get_ipython() expr = dialect.Evaluable().stringify(self.ctx.mgr.selected) ip.set_next_input(expr) except: raise CommandError("IPython is not available.") raise goto.Stop(exit=False)
def cmd_vars_public(self): """Call vars(<TARGET>) and show results other than starting with '_'. See also 'Vars' command. """ target = self.ctx.target try: v = vars(target) except Exception as ex: raise CommandError(exc_to_str(ex)) items = ((k, v) for k,v in vars(target).items() if isaccess(k).public) try: keys, values = zip(*items) except ValueError: keys, values = (), () content = self.ctx.mgr.propose_attr(keys, values) self.ctx.explorer.fill(content, 'attr')
def cmd_eval(self, expr): """Evaluate <EXPR> and print the result. Empty <EXPR> will paste expression of current target and let you edit it. See also '$<EXPR>' command. """ expr = expr.strip() if expr: try: try: result = self.ctx.eval_(expr) print(repr(result)) except SyntaxError: self.ctx.exec_(expr) except Exception as ex: raise CommandError(exc_to_str(ex, show_type=True)) from ex terminal.update_suggestions(self.ctx.env.current) else: expr = dialect.Evaluable().stringify(self.ctx.mgr.selected) terminal.prefill_input('!' + expr)
def cmd_source(self): """Show source code of the target.""" try: target = self.ctx.target if isinstance(target, FrameSummary): file_name = target.file_name first_line_no = target.line_no first_line_no = max(first_line_no, 1) variable_list = '\n'.join(f'{name}={value}' for name, value in target.gloloc.items()) cmd = ('vim', '-', '--not-a-term', '-c', ':set syntax=config', '-c', f'vsplit {file_name}', '-c', 'map q :qa<CR>', '-c', 'map <CR> :qa<CR>', '-c', ':set number', '-RM', f'+{first_line_no}', '-c', 'normal zt') p = subprocess.Popen(cmd, stdin=subprocess.PIPE) p.stdin.write(variable_list.encode()) p.communicate() else: file_name = inspect.getsourcefile(target) _, first_line_no = inspect.getsourcelines(target) first_line_no = max(first_line_no, 1) shell_cmd = f'vim --not-a-term -c "map q :qa<CR>" -c "map <CR> :qa<CR>" -c ":set number" -RM +{first_line_no} -c "normal zt" {file_name}' os.system(shell_cmd) except Exception as ex: raise CommandError('Cannot find source code.')
def evaluate(self, prev, ctx): try: value = ctx.eval_(f"{self.func_name}(_)") except Exception as ex: raise CommandError(f"Invalid invocation: {exc_to_str(ex)}") from ex return value
def evaluate(self, prev, ctx): try: value = ctx.eval_(f"_[{self.expr}]") except Exception as ex: raise CommandError(exc_to_str(ex, show_type=True)) from ex return value
def recall(self): if self.ctx.target is not self.cached_target: raise CommandError('No cache for this target') self.cache.recall_cache()
def evaluate(self, prev, ctx): try: value = ctx.eval_(self.expr) except SyntaxError as ex: raise CommandError(exc_to_str(ex, show_type=True)) from ex return value
def cmd_docstring(self): """Show docstring of the target.""" try: print(inspect.cleandoc(self.ctx.target.__doc__)) except Exception as ex: raise CommandError('Cannot read docstring.')