def __init__(self): self.prev_tracer = DefaultNotGiven self.files = set() self.usecolor = True self.lexer = pyghooks.XonshLexer() self.formatter = terminal.TerminalFormatter() self._last = ("", -1) # filename, lineno tuple
def tracer_format_line(fname, lineno, line, color=True, lexer=None, formatter=None): """Formats a trace line suitable for printing.""" fname = min(fname, prompt._replace_home(fname), os.path.relpath(fname), key=len) if not color: return COLORLESS_LINE.format(fname=fname, lineno=lineno, line=line) cline = COLOR_LINE.format(fname=fname, lineno=lineno) if not HAS_PYGMENTS: return cline + line # OK, so we have pygments tokens = pyghooks.partial_color_tokenize(cline) lexer = lexer or pyghooks.XonshLexer() tokens += pygments.lex(line, lexer=lexer) if tokens[-1][1] == "\n": del tokens[-1] elif tokens[-1][1].endswith("\n"): tokens[-1] = (tokens[-1][0], tokens[-1][1].rstrip()) return tokens
def _pprint_displayhook(value): if value is None: return builtins._ = None # Set '_' to None to avoid recursion if isinstance(value, HiddenCommandPipeline): builtins._ = value return env = builtins.__xonsh_env__ if env.get('PRETTY_PRINT_RESULTS'): printed_val = pretty(value) else: printed_val = repr(value) if HAS_PYGMENTS and env.get('COLOR_RESULTS'): tokens = list(pygments.lex(printed_val, lexer=pyghooks.XonshLexer())) print_color(tokens) else: print(printed_val) # black & white case builtins._ = value
def _pprint_displayhook(value): if value is None: return builtins._ = None # Set '_' to None to avoid recursion if isinstance(value, HiddenCommandPipeline): builtins._ = value return env = builtins.__xonsh__.env if env.get("PRETTY_PRINT_RESULTS"): printed_val = pretty(value) else: printed_val = repr(value) if HAS_PYGMENTS and env.get("COLOR_RESULTS"): tokens = list(pygments.lex(printed_val, lexer=pyghooks.XonshLexer())) end = "" if env.get("SHELL_TYPE") == "prompt_toolkit2" else "\n" print_color(tokens, end=end) else: print(printed_val) # black & white case builtins._ = value
def info(self, obj, oname="", info=None, detail_level=0): """Compute a dict with detailed information about an object. Optional arguments: - oname: name of the variable pointing to the object. - info: a structure with some information fields which may have been precomputed already. - detail_level: if set to 1, more information is given. """ obj_type = type(obj) if info is None: ismagic = 0 isalias = 0 ospace = "" else: ismagic = info.ismagic isalias = info.isalias ospace = info.namespace # Get docstring, special-casing aliases: if isalias: if not callable(obj): if len(obj) >= 2 and isinstance(obj[1], str): ds = "Alias to the system command:\n {0}".format(obj[1]) else: # pylint:disable=bare-except ds = "Alias: " + str(obj) else: ds = "Alias to " + str(obj) if obj.__doc__: ds += "\nDocstring:\n" + obj.__doc__ else: ds = getdoc(obj) if ds is None: ds = "<no docstring>" # store output in a dict, we initialize it here and fill it as we go out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic) string_max = 200 # max size of strings to show (snipped if longer) shalf = int((string_max - 5) / 2) if ismagic: obj_type_name = "Magic function" elif isalias: obj_type_name = "System alias" else: obj_type_name = obj_type.__name__ out["type_name"] = obj_type_name try: bclass = obj.__class__ out["base_class"] = str(bclass) except: # pylint:disable=bare-except pass # String form, but snip if too long in ? form (full in ??) if detail_level >= self.str_detail_level: try: ostr = str(obj) str_head = "string_form" if not detail_level and len(ostr) > string_max: ostr = ostr[:shalf] + " <...> " + ostr[-shalf:] ostr = ("\n" + " " * len(str_head.expandtabs())).join( q.strip() for q in ostr.split("\n")) out[str_head] = ostr except: # pylint:disable=bare-except pass if ospace: out["namespace"] = ospace # Length (for strings and lists) try: out["length"] = str(len(obj)) except: # pylint:disable=bare-except pass # Filename where object was defined binary_file = False fname = find_file(obj) if fname is None: # if anything goes wrong, we don't want to show source, so it's as # if the file was binary binary_file = True else: if fname.endswith((".so", ".dll", ".pyd")): binary_file = True elif fname.endswith("<string>"): fname = "Dynamically generated function. " "No source code available." out["file"] = fname # Docstrings only in detail 0 mode, since source contains them (we # avoid repetitions). If source fails, we add them back, see below. if ds and detail_level == 0: out["docstring"] = ds # Original source code for any callable if detail_level: # Flush the source cache because inspect can return out-of-date # source linecache.checkcache() source = None try: try: source = getsource(obj, binary_file) except TypeError: if hasattr(obj, "__class__"): source = getsource(obj.__class__, binary_file) if source is not None: source = source.rstrip() if HAS_PYGMENTS: lexer = pyghooks.XonshLexer() source = list(pygments.lex(source, lexer=lexer)) out["source"] = source except Exception: # pylint:disable=broad-except pass if ds and source is None: out["docstring"] = ds # Constructor docstring for classes if inspect.isclass(obj): out["isclass"] = True # reconstruct the function definition and print it: try: obj_init = obj.__init__ except AttributeError: init_def = init_ds = None else: init_def = self._getdef(obj_init, oname) init_ds = getdoc(obj_init) # Skip Python's auto-generated docstrings if init_ds == _object_init_docstring: init_ds = None if init_def or init_ds: if init_def: out["init_definition"] = init_def if init_ds: out["init_docstring"] = init_ds # and class docstring for instances: else: # reconstruct the function definition and print it: defln = self._getdef(obj, oname) if defln: out["definition"] = defln # First, check whether the instance docstring is identical to the # class one, and print it separately if they don't coincide. In # most cases they will, but it's nice to print all the info for # objects which use instance-customized docstrings. if ds: try: cls = getattr(obj, "__class__") except: # pylint:disable=bare-except class_ds = None else: class_ds = getdoc(cls) # Skip Python's auto-generated docstrings if class_ds in _builtin_type_docstrings: class_ds = None if class_ds and ds != class_ds: out["class_docstring"] = class_ds # Next, try to show constructor docstrings try: init_ds = getdoc(obj.__init__) # Skip Python's auto-generated docstrings if init_ds == _object_init_docstring: init_ds = None except AttributeError: init_ds = None if init_ds: out["init_docstring"] = init_ds # Call form docstring for callable instances if safe_hasattr(obj, "__call__") and not is_simple_callable(obj): call_def = self._getdef(obj.__call__, oname) if call_def: call_def = call_def # it may never be the case that call def and definition # differ, but don't include the same signature twice if call_def != out.get("definition"): out["call_def"] = call_def call_ds = getdoc(obj.__call__) # Skip Python's auto-generated docstrings if call_ds == _func_call_docstring: call_ds = None if call_ds: out["call_docstring"] = call_ds # Compute the object's argspec as a callable. The key is to decide # whether to pull it from the object itself, from its __init__ or # from its __call__ method. if inspect.isclass(obj): # Old-style classes need not have an __init__ callable_obj = getattr(obj, "__init__", None) elif callable(obj): callable_obj = obj else: callable_obj = None if callable_obj: try: argspec = getargspec(callable_obj) except (TypeError, AttributeError): # For extensions/builtins we can't retrieve the argspec pass else: # named tuples' _asdict() method returns an OrderedDict, but we # we want a normal out["argspec"] = argspec_dict = dict(argspec._asdict()) # We called this varkw before argspec became a named tuple. # With getfullargspec it's also called varkw. if "varkw" not in argspec_dict: argspec_dict["varkw"] = argspec_dict.pop("keywords") return object_info(**out)