def tkinter_clipboard_get():
    """ Get the clipboard's text using Tkinter.

    This is the default on systems that are not Windows or OS X. It may
    interfere with other UI toolkits and should be replaced with an
    implementation that uses that toolkit.
    """
    try:
        from tkinter import Tk, TclError  # Py 3
    except ImportError:
        try:
            from Tkinter import Tk, TclError  # Py 2
        except ImportError:
            raise TryNext("Getting text from the clipboard on this platform "
                          "requires Tkinter.")
    root = Tk()
    root.withdraw()
    try:
        text = root.clipboard_get()
    except TclError:
        raise ClipboardEmpty
    finally:
        root.destroy()
    text = py3compat.cast_unicode(text, py3compat.DEFAULT_ENCODING)
    return text
Exemple #2
0
def getsource(obj, oname=""):
    """Wrapper around inspect.getsource.

    This can be modified by other projects to provide customized source
    extraction.

    Parameters
    ----------
    obj : object
        an object whose source code we will attempt to extract
    oname : str
        (optional) a name under which the object is known

    Returns
    -------
    src : unicode or None

    """

    if isinstance(obj, property):
        sources = []
        for attrname in ["fget", "fset", "fdel"]:
            fn = getattr(obj, attrname)
            if fn is not None:
                encoding = get_encoding(fn)
                oname_prefix = ("%s." % oname) if oname else ""
                sources.append(cast_unicode("".join(("# ", oname_prefix, attrname)), encoding=encoding))
                if inspect.isfunction(fn):
                    sources.append(dedent(getsource(fn)))
                else:
                    # Default str/repr only prints function name,
                    # pretty.pretty prints module name too.
                    sources.append(
                        cast_unicode("%s%s = %s\n" % (oname_prefix, attrname, pretty(fn)), encoding=encoding)
                    )
        if sources:
            return "\n".join(sources)
        else:
            return None

    else:
        # Get source for non-property objects.

        obj = _get_wrapped(obj)

        try:
            src = inspect.getsource(obj)
        except TypeError:
            # The object itself provided no meaningful source, try looking for
            # its class definition instead.
            if hasattr(obj, "__class__"):
                try:
                    src = inspect.getsource(obj.__class__)
                except TypeError:
                    return None

        encoding = get_encoding(obj)
        return cast_unicode(src, encoding=encoding)
Exemple #3
0
def get_home_dir(require_writable=False):
    """Return the 'home' directory, as a unicode string.

    * First, check for frozen env in case of py2exe
    * Otherwise, defer to os.path.expanduser('~')
    
    See stdlib docs for how this is determined.
    $HOME is first priority on *ALL* platforms.
    
    Parameters
    ----------
    
    require_writable : bool [default: False]
        if True:
            guarantees the return value is a writable directory, otherwise
            raises HomeDirError
        if False:
            The path is resolved, but it is not guaranteed to exist or be writable.
    """

    # first, check py2exe distribution root directory for _ipython.
    # This overrides all. Normally does not exist.

    if hasattr(sys, "frozen"): #Is frozen by py2exe
        if '\\library.zip\\' in IPython.__file__.lower():#libraries compressed to zip-file
            root, rest = IPython.__file__.lower().split('library.zip')
        else:
            root=os.path.join(os.path.split(IPython.__file__)[0],"../../")
        root=os.path.abspath(root).rstrip('\\')
        if _writable_dir(os.path.join(root, '_ipython')):
            os.environ["IPYKITROOT"] = root
        return py3compat.cast_unicode(root, fs_encoding)
    
    homedir = os.path.expanduser('~')
    # Next line will make things work even when /home/ is a symlink to
    # /usr/home as it is on FreeBSD, for example
    homedir = os.path.realpath(homedir)
    
    if not _writable_dir(homedir) and os.name == 'nt':
        # expanduser failed, use the registry to get the 'My Documents' folder.
        try:
            import _winreg as wreg
            key = wreg.OpenKey(
                wreg.HKEY_CURRENT_USER,
                "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
            )
            homedir = wreg.QueryValueEx(key,'Personal')[0]
            key.Close()
        except:
            pass
    
    if (not require_writable) or _writable_dir(homedir):
        return py3compat.cast_unicode(homedir, fs_encoding)
    else:
        raise HomeDirError('%s is not a writable dir, '
                'set $HOME environment variable to override' % homedir)
Exemple #4
0
def new_heading_cell(source=None, rendered=None, level=1, metadata=None):
    """Create a new section cell with a given integer level."""
    cell = NotebookNode()
    cell.cell_type = u'heading'
    if source is not None:
        cell.source = cast_unicode(source)
    if rendered is not None:
        cell.rendered = cast_unicode(rendered)
    cell.level = int(level)
    cell.metadata = NotebookNode(metadata or {})
    return cell
Exemple #5
0
def new_author(name=None, email=None, affiliation=None, url=None):
    """Create a new author."""
    author = NotebookNode()
    if name is not None:
        author.name = cast_unicode(name)
    if email is not None:
        author.email = cast_unicode(email)
    if affiliation is not None:
        author.affiliation = cast_unicode(affiliation)
    if url is not None:
        author.url = cast_unicode(url)
    return author
Exemple #6
0
def new_text_cell(cell_type, source=None, rendered=None, metadata=None):
    """Create a new text cell."""
    cell = NotebookNode()
    # VERSIONHACK: plaintext -> raw
    # handle never-released plaintext name for raw cells
    if cell_type == 'plaintext':
        cell_type = 'raw'
    if source is not None:
        cell.source = cast_unicode(source)
    if rendered is not None:
        cell.rendered = cast_unicode(rendered)
    cell.metadata = NotebookNode(metadata or {})
    cell.cell_type = cell_type
    return cell
Exemple #7
0
    def format_stack_entry(self, frame_lineno, lprefix=": ", context=3):
        try:
            import reprlib  # Py 3
        except ImportError:
            import repr as reprlib  # Py 2

        ret = []

        Colors = self.color_scheme_table.active_colors
        ColorsNormal = Colors.Normal
        tpl_link = u"%s%%s%s" % (Colors.filenameEm, ColorsNormal)
        tpl_call = u"%s%%s%s%%s%s" % (Colors.vName, Colors.valEm, ColorsNormal)
        tpl_line = u"%%s%s%%s %s%%s" % (Colors.lineno, ColorsNormal)
        tpl_line_em = u"%%s%s%%s %s%%s%s" % (Colors.linenoEm, Colors.line, ColorsNormal)

        frame, lineno = frame_lineno

        return_value = ""
        if "__return__" in frame.f_locals:
            rv = frame.f_locals["__return__"]
            # return_value += '->'
            return_value += reprlib.repr(rv) + "\n"
        ret.append(return_value)

        # s = filename + '(' + `lineno` + ')'
        filename = self.canonic(frame.f_code.co_filename)
        link = tpl_link % py3compat.cast_unicode(filename)

        if frame.f_code.co_name:
            func = frame.f_code.co_name
        else:
            func = "<lambda>"

        call = ""
        if func != "?":
            if "__args__" in frame.f_locals:
                args = reprlib.repr(frame.f_locals["__args__"])
            else:
                args = "()"
            call = tpl_call % (func, args)

        # The level info should be generated in the same format pdb uses, to
        # avoid breaking the pdbtrack functionality of python-mode in *emacs.
        if frame is self.curframe:
            ret.append("> ")
        else:
            ret.append("  ")
        ret.append(u"%s(%s)%s\n" % (link, lineno, call))

        start = lineno - 1 - context // 2
        lines = ulinecache.getlines(filename)
        start = min(start, len(lines) - context)
        start = max(start, 0)
        lines = lines[start : start + context]

        for i, line in enumerate(lines):
            show_arrow = start + 1 + i == lineno
            linetpl = (frame is self.curframe or show_arrow) and tpl_line_em or tpl_line
            ret.append(self.__format_line(linetpl, filename, start + 1 + i, line, arrow=show_arrow))
        return "".join(ret)
Exemple #8
0
    def vformat(self, format_string, args, kwargs):
        result = []
        for literal_text, field_name, format_spec, conversion in self.parse(format_string):

            # output the literal text
            if literal_text:
                result.append(literal_text)

            # if there's a field, output it
            if field_name is not None:
                # this is some markup, find the object and do
                # the formatting

                if format_spec:
                    # override format spec, to allow slicing:
                    field_name = ":".join([field_name, format_spec])

                # eval the contents of the field for the object
                # to be formatted
                obj = eval(field_name, kwargs)

                # do any conversion on the resulting object
                obj = self.convert_field(obj, conversion)

                # format the object and append to the result
                result.append(self.format_field(obj, ""))

        return u"".join(py3compat.cast_unicode(s) for s in result)
 def complete_request(self, text):
     line = str_to_unicode(readline.get_line_buffer())
     byte_cursor_pos = readline.get_endidx()
     
     # get_endidx is a byte offset
     # account for multi-byte characters to get correct cursor_pos
     bytes_before_cursor = cast_bytes(line)[:byte_cursor_pos]
     cursor_pos = len(cast_unicode(bytes_before_cursor))
     
     # send completion request to kernel
     # Give the kernel up to 5s to respond
     msg_id = self.client.complete(
         code=line,
         cursor_pos=cursor_pos,
     )
 
     msg = self.client.shell_channel.get_msg(timeout=self.timeout)
     if msg['parent_header']['msg_id'] == msg_id:
         content = msg['content']
         cursor_start = content['cursor_start']
         matches = [ line[:cursor_start] + m for m in content['matches'] ]
         if content["cursor_end"] < cursor_pos:
             extra = line[content["cursor_end"]: cursor_pos]
             matches = [m + extra for m in matches]
         matches = [ unicode_to_str(m) for m in matches ]
         return matches
     return []
Exemple #10
0
    def push(self, lines):
        """Push one or more lines of IPython input.
        """
        if not lines:
            return super(IPythonInputSplitter, self).push(lines)

        # We must ensure all input is pure unicode
        lines = cast_unicode(lines, self.encoding)

        lines_list = lines.splitlines()

        transforms = [transform_ipy_prompt, transform_classic_prompt,
                      transform_help_end, transform_escaped,
                      transform_assign_system, transform_assign_magic]

        # Transform logic
        #
        # We only apply the line transformers to the input if we have either no
        # input yet, or complete input, or if the last line of the buffer ends
        # with ':' (opening an indented block).  This prevents the accidental
        # transformation of escapes inside multiline expressions like
        # triple-quoted strings or parenthesized expressions.
        #
        # The last heuristic, while ugly, ensures that the first line of an
        # indented block is correctly transformed.
        #
        # FIXME: try to find a cleaner approach for this last bit.

        # If we were in 'block' mode, since we're going to pump the parent
        # class by hand line by line, we need to temporarily switch out to
        # 'line' mode, do a single manual reset and then feed the lines one
        # by one.  Note that this only matters if the input has more than one
        # line.
        changed_input_mode = False

        if self.input_mode == 'cell':
            self.reset()
            changed_input_mode = True
            saved_input_mode = 'cell'
            self.input_mode = 'line'

        # Store raw source before applying any transformations to it.  Note
        # that this must be done *after* the reset() call that would otherwise
        # flush the buffer.
        self._store(lines, self._buffer_raw, 'source_raw')
        
        try:
            push = super(IPythonInputSplitter, self).push
            for line in lines_list:
                if self._is_complete or not self._buffer or \
                   (self._buffer and (self._buffer[-1].rstrip().endswith(':') or\
                     self._buffer[-1].rstrip().endswith(','))):
                    for f in transforms:
                        line = f(line)

                out = push(line)
        finally:
            if changed_input_mode:
                self.input_mode = saved_input_mode
        return out
Exemple #11
0
    def _vformat(self, format_string, args, kwargs, used_args, recursion_depth):
        if recursion_depth < 0:
            raise ValueError('Max string recursion exceeded')
        result = []
        for literal_text, field_name, format_spec, conversion in \
                self.parse(format_string):

            # output the literal text
            if literal_text:
                result.append(literal_text)

            # if there's a field, output it
            if field_name is not None:
                # this is some markup, find the object and do
                # the formatting

                if format_spec:
                    # override format spec, to allow slicing:
                    field_name = ':'.join([field_name, format_spec])

                # eval the contents of the field for the object
                # to be formatted
                obj = eval(field_name, kwargs)

                # do any conversion on the resulting object
                obj = self.convert_field(obj, conversion)

                # format the object and append to the result
                result.append(self.format_field(obj, ''))

        return u''.join(py3compat.cast_unicode(s) for s in result)
Exemple #12
0
def find_file(obj):
    """Find the absolute path to the file where an object was defined.

    This is essentially a robust wrapper around `inspect.getabsfile`.

    Returns None if no file can be found.

    Parameters
    ----------
    obj : any Python object

    Returns
    -------
    fname : str
      The absolute path to the file where the object was defined.
    """
    # get source if obj was decorated with @decorator
    if safe_hasattr(obj, '__wrapped__'):
        obj = obj.__wrapped__

    fname = None
    try:
        fname = inspect.getabsfile(obj)
    except TypeError:
        # For an instance, the file that matters is where its class was
        # declared.
        if hasattr(obj, '__class__'):
            try:
                fname = inspect.getabsfile(obj.__class__)
            except TypeError:
                # Can happen for builtins
                pass
    except:
        pass
    return cast_unicode(fname)
Exemple #13
0
def getsource(obj,is_binary=False):
    """Wrapper around inspect.getsource.

    This can be modified by other projects to provide customized source
    extraction.

    Inputs:

    - obj: an object whose source code we will attempt to extract.

    Optional inputs:

    - is_binary: whether the object is known to come from a binary source.
      This implementation will skip returning any output for binary objects, but
      custom extractors may know how to meaningfully process them."""

    if is_binary:
        return None
    else:
        # get source if obj was decorated with @decorator
        if hasattr(obj,"__wrapped__"):
            obj = obj.__wrapped__
        try:
            src = inspect.getsource(obj)
        except TypeError:
            if hasattr(obj,'__class__'):
                src = inspect.getsource(obj.__class__)
        encoding = get_encoding(obj)
        return cast_unicode(src, encoding=encoding)
Exemple #14
0
def getdoc(obj):
    """Stable wrapper around inspect.getdoc.

    This can't crash because of attribute problems.

    It also attempts to call a getdoc() method on the given object.  This
    allows objects which provide their docstrings via non-standard mechanisms
    (like Pyro proxies) to still be inspected by ipython's ? system."""
    # Allow objects to offer customized documentation via a getdoc method:
    try:
        ds = obj.getdoc()
    except Exception:
        pass
    else:
        # if we get extra info, we add it to the normal docstring.
        if isinstance(ds, string_types):
            return inspect.cleandoc(ds)
    
    try:
        docstr = inspect.getdoc(obj)
        encoding = get_encoding(obj)
        return py3compat.cast_unicode(docstr, encoding=encoding)
    except Exception:
        # Harden against an inspect failure, which can occur with
        # SWIG-wrapped extensions.
        raise
        return None
Exemple #15
0
def setup_kernel(cmd):
    """start an embedded kernel in a subprocess, and wait for it to be ready

    Returns
    -------
    kernel_manager: connected KernelManager instance
    """
    kernel = Popen([sys.executable, "-c", cmd], stdout=PIPE, stderr=PIPE, env=env)
    connection_file = os.path.join(IPYTHONDIR, "profile_default", "security", "kernel-%i.json" % kernel.pid)
    # wait for connection file to exist, timeout after 5s
    tic = time.time()
    while not os.path.exists(connection_file) and kernel.poll() is None and time.time() < tic + SETUP_TIMEOUT:
        time.sleep(0.1)

    if kernel.poll() is not None:
        o, e = kernel.communicate()
        e = py3compat.cast_unicode(e)
        raise IOError("Kernel failed to start:\n%s" % e)

    if not os.path.exists(connection_file):
        if kernel.poll() is None:
            kernel.terminate()
        raise IOError("Connection file %r never arrived" % connection_file)

    client = BlockingKernelClient(connection_file=connection_file)
    client.load_connection_file()
    client.start_channels()

    try:
        yield client
    finally:
        client.stop_channels()
        kernel.terminate()
Exemple #16
0
def latex_to_png(s, encode=False, backend=None, wrap=False):
    """Render a LaTeX string to PNG.

    Parameters
    ----------
    s : text
        The raw string containing valid inline LaTeX.
    encode : bool, optional
        Should the PNG data base64 encoded to make it JSON'able.
    backend : {matplotlib, dvipng}
        Backend for producing PNG data.
    wrap : bool
        If true, Automatically wrap `s` as a LaTeX equation.

    None is returned when the backend cannot be used.

    """
    s = cast_unicode(s)
    allowed_backends = LaTeXTool.instance().backends
    if backend is None:
        backend = allowed_backends[0]
    if backend not in allowed_backends:
        return None
    if backend == 'matplotlib':
        f = latex_to_png_mpl
    elif backend == 'dvipng':
        f = latex_to_png_dvipng
    else:
        raise ValueError('No such backend {0}'.format(backend))
    bin_data = f(s, wrap)
    if encode and bin_data:
        bin_data = encodebytes(bin_data)
    return bin_data
def split_user_input(line, pattern=None):
    """Split user input into initial whitespace, escape character, function part
    and the rest.
    """
    # We need to ensure that the rest of this routine deals only with unicode
    encoding = get_stream_enc(sys.stdin, 'utf-8')
    line = py3compat.cast_unicode(line, encoding)

    if pattern is None:
        pattern = line_split
    match = pattern.match(line)
    if not match:
        # print "match failed for line '%s'" % line
        try:
            ifun, the_rest = line.split(None, 1)
        except ValueError:
            # print "split failed for line '%s'" % line
            ifun, the_rest = line, u''
        pre = re.match('^(\s*)(.*)', line).groups()[0]
        esc = ""
    else:
        pre, esc, ifun, the_rest = match.groups()

    # print 'line:<%s>' % line # dbg
    # print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun.strip(),the_rest) # dbg
    return pre, esc or '', ifun.strip(), the_rest.lstrip()
Exemple #18
0
def get_ipython_dir():
    """Get the IPython directory for this platform and user.

    This uses the logic in `get_home_dir` to find the home directory
    and then adds .ipython to the end of the path.
    """

    env = os.environ
    pjoin = os.path.join

    ipdir_def = ".ipython"

    home_dir = get_home_dir()
    xdg_dir = get_xdg_dir()

    # import pdb; pdb.set_trace()  # dbg
    if "IPYTHON_DIR" in env:
        warn("The environment variable IPYTHON_DIR is deprecated. " "Please use IPYTHONDIR instead.")
    ipdir = env.get("IPYTHONDIR", env.get("IPYTHON_DIR", None))
    if ipdir is None:
        # not set explicitly, use ~/.ipython
        ipdir = pjoin(home_dir, ipdir_def)
        if xdg_dir:
            # Several IPython versions (up to 1.x) defaulted to .config/ipython
            # on Linux. We have decided to go back to using .ipython everywhere
            xdg_ipdir = pjoin(xdg_dir, "ipython")

            if _writable_dir(xdg_ipdir):
                cu = compress_user
                if os.path.exists(ipdir):
                    warn(
                        ("Ignoring {0} in favour of {1}. Remove {0} to " "get rid of this message").format(
                            cu(xdg_ipdir), cu(ipdir)
                        )
                    )
                elif os.path.islink(xdg_ipdir):
                    warn(
                        ("{0} is deprecated. Move link to {1} to " "get rid of this message").format(
                            cu(xdg_ipdir), cu(ipdir)
                        )
                    )
                else:
                    warn("Moving {0} to {1}".format(cu(xdg_ipdir), cu(ipdir)))
                    shutil.move(xdg_ipdir, ipdir)

    ipdir = os.path.normpath(os.path.expanduser(ipdir))

    if os.path.exists(ipdir) and not _writable_dir(ipdir):
        # ipdir exists, but is not writable
        warn("IPython dir '{0}' is not a writable location," " using a temp directory.".format(ipdir))
        ipdir = tempfile.mkdtemp()
    elif not os.path.exists(ipdir):
        parent = os.path.dirname(ipdir)
        if not _writable_dir(parent):
            # ipdir does not exist and parent isn't writable
            warn("IPython parent '{0}' is not a writable location," " using a temp directory.".format(parent))
            ipdir = tempfile.mkdtemp()

    return py3compat.cast_unicode(ipdir, fs_encoding)
Exemple #19
0
def patch_find_file(obj):
    fname = old_find_file(obj)
    if fname is None:
        try:
            fname = cast_unicode(getfile(obj))
        except:
            pass
    return fname
Exemple #20
0
def new_metadata(name=None, authors=None, license=None, created=None,
    modified=None, gistid=None):
    """Create a new metadata node."""
    metadata = NotebookNode()
    if name is not None:
        metadata.name = cast_unicode(name)
    if authors is not None:
        metadata.authors = list(authors)
    if created is not None:
        metadata.created = cast_unicode(created)
    if modified is not None:
        metadata.modified = cast_unicode(modified)
    if license is not None:
        metadata.license = cast_unicode(license)
    if gistid is not None:
        metadata.gistid = cast_unicode(gistid)
    return metadata
Exemple #21
0
 def add_fields(fields):
     for title, key in fields:
         field = info[key]
         if field is not None:
             if key == "source":
                 displayfields.append((title, self.format(cast_unicode(field.rstrip()))))
             else:
                 displayfields.append((title, field.rstrip()))
Exemple #22
0
def run_iptestall():
    """Run the entire IPython test suite by calling nose and trial.

    This function constructs :class:`IPTester` instances for all IPython
    modules and package and then runs each of them.  This causes the modules
    and packages of IPython to be tested each in their own subprocess using
    nose.
    """

    runners = make_runners()

    # Run the test runners in a temporary dir so we can nuke it when finished
    # to clean up any junk files left over by accident.  This also makes it
    # robust against being run in non-writeable directories by mistake, as the
    # temp dir will always be user-writeable.
    curdir = os.getcwdu()
    testdir = tempfile.gettempdir()
    os.chdir(testdir)

    # Run all test runners, tracking execution time
    failed = []
    t_start = time.time()
    try:
        for (name, runner) in runners:
            print('*'*70)
            print('IPython test group:',name)
            res = runner.run()
            if res:
                failed.append( (name, runner) )
    finally:
        os.chdir(curdir)
    t_end = time.time()
    t_tests = t_end - t_start
    nrunners = len(runners)
    nfail = len(failed)
    # summarize results
    print()
    print('*'*70)
    print('Test suite completed for system with the following information:')
    print(report())
    print('Ran %s test groups in %.3fs' % (nrunners, t_tests))
    print()
    print('Status:')
    if not failed:
        print('OK')
    else:
        # If anything went wrong, point out what command to rerun manually to
        # see the actual errors and individual summary
        print('ERROR - %s out of %s test groups failed.' % (nfail, nrunners))
        for name, failed_runner in failed:
            print('-'*40)
            print('Runner failed:',name)
            print('You may wish to rerun this one individually, with:')
            failed_call_args = [py3compat.cast_unicode(x) for x in failed_runner.call_args]
            print(u' '.join(failed_call_args))
            print()
        # Ensure that our exit code indicates failure
        sys.exit(1)
Exemple #23
0
    def pinfo(self, obj, oname="", formatter=None, info=None, detail_level=0):
        """Show detailed information about an object.

        Optional arguments:

        - oname: name of the variable pointing to the object.

        - formatter: special formatter for docstrings (see pdoc)

        - info: a structure with some information fields which may have been
          precomputed already.

        - detail_level: if set to 1, more information is given.
        """
        info = self.info(obj, oname=oname, formatter=formatter, info=info, detail_level=detail_level)
        displayfields = []

        def add_fields(fields):
            for title, key in fields:
                field = info[key]
                if field is not None:
                    displayfields.append((title, field.rstrip()))

        add_fields(self.pinfo_fields1)

        # Base class for old-style instances
        if (not py3compat.PY3) and isinstance(obj, types.InstanceType) and info["base_class"]:
            displayfields.append(("Base Class", info["base_class"].rstrip()))

        add_fields(self.pinfo_fields2)

        # Namespace
        if info["namespace"] != "Interactive":
            displayfields.append(("Namespace", info["namespace"].rstrip()))

        add_fields(self.pinfo_fields3)
        if info["isclass"] and info["init_definition"]:
            displayfields.append(("Init definition", info["init_definition"].rstrip()))

        # Source or docstring, depending on detail level and whether
        # source found.
        if detail_level > 0 and info["source"] is not None:
            displayfields.append(("Source", self.format(cast_unicode(info["source"]))))
        elif info["docstring"] is not None:
            displayfields.append(("Docstring", info["docstring"]))

        # Constructor info for classes
        if info["isclass"]:
            if info["init_docstring"] is not None:
                displayfields.append(("Init docstring", info["init_docstring"]))

        # Info for objects:
        else:
            add_fields(self.pinfo_fields_obj)

        # Finally send to printer/pager:
        if displayfields:
            page.page(self._format_fields(displayfields))
Exemple #24
0
def osx_clipboard_get():
    """ Get the clipboard's text on OS X.
    """
    p = subprocess.Popen(["pbpaste", "-Prefer", "ascii"], stdout=subprocess.PIPE)
    text, stderr = p.communicate()
    # Text comes in with old Mac \r line endings. Change them to \n.
    text = text.replace(b"\r", b"\n")
    text = py3compat.cast_unicode(text, py3compat.DEFAULT_ENCODING)
    return text
Exemple #25
0
 def open(self, kernel_id):
     self.kernel_id = cast_unicode(kernel_id, 'ascii')
     
     # start the pinging
     if self.ping_interval > 0:
         self.last_ping = ioloop.IOLoop.instance().time()  # Remember time of last ping
         self.last_pong = self.last_ping
         self.ping_callback = ioloop.PeriodicCallback(self.send_ping, self.ping_interval)
         self.ping_callback.start()
    def _save_to_file(self, path, identifier, content, debug=False):
            pypath = os.path.splitext(path)[0] + '.py'
            code_identifier = "# -- ==%s== --" % identifier
            new_content = []
            if not os.path.isfile(pypath):
                # The file does not exist, so simple create a new one
                if debug:
                    print("Created new file: %s" % pypath)
                new_content.extend([u'# -*- coding: utf-8 -*-\n\n', code_identifier , content, code_identifier])
            else:
                # If file exist, read in the content and either replace the code or append it
                in_code_block = False
                included_new = False
                lineno = 0
                with io.open(pypath, 'r', encoding='utf-8') as f:
                    for line in f:
                        if line[-1] == "\n":
                            line = line[:-1]
                        lineno += 1
                        if line.strip() == code_identifier:
                            if included_new and not in_code_block:
                                # we found a third one -> Error!
                                raise Exception("Found more than two lines with identifier '%s' in file '%s' in line %s. "
                                    "Please fix the file so that the identifier is included exactly two times." % (code_identifier, pypath, lineno))
                            # Now we are either in the codeblock or just outside
                            # Switch the state to either "in our codeblock" or outside again
                            in_code_block = True if not in_code_block else False
                            if not included_new:
                                # The code was not included yet, so add it here...
                                # No need to add a code indentifier to the end as we just add the ending indentifier from the last
                                # time when the state is switched again.
                                new_content.extend([code_identifier, content])
                                included_new = True
                        # This is something from other code cells, so just include it. All code
                        # "in_code_block" is replaced, so do not include it
                        if not in_code_block:
                            new_content.append(line)
                # the file is finished, ensure we didn't see only one identifier, but not the second one
                if in_code_block:
                    raise Exception("Found only one line with identifier '%s' in file '%s'. "
                                    "Please fix the file so that the identifier is included exactly two times." % (code_identifier, pypath))
                # And if we didn't include our code yet, lets append it to the end...
                if not included_new:
                    new_content.extend(["\n", code_identifier, content, code_identifier, "\n"])

            new_content = py3compat.cast_unicode(u'\n'.join(new_content))

            #Now write the complete code back to the file
            self.ensure_dir(pypath)
            with io.open(pypath,'w', encoding='utf-8') as f:
                if not py3compat.PY3 and not isinstance(new_content, unicode):
                    # this branch is likely only taken for JSON on Python 2
                    new_content = py3compat.str_to_unicode(new_content)
                f.write(new_content)
                if debug:
                    print("Wrote cell to file: %s" % pypath)
Exemple #27
0
    def _format_fields(self, fields, title_width=12):
        """Formats a list of fields for display.

        Parameters
        ----------
        fields : list
          A list of 2-tuples: (field_title, field_content)
        title_width : int
          How many characters to pad titles to. Default 12.
        """
        out = []
        header = self.__head
        for title, content in fields:
            if len(content.splitlines()) > 1:
                title = header(title + ":") + "\n"
            else:
                title = header((title+":").ljust(title_width))
            out.append(cast_unicode(title) + cast_unicode(content))
        return "\n".join(out)
Exemple #28
0
    def open(self, kernel_id):
        self.kernel_id = cast_unicode(kernel_id, 'ascii')
        # Check to see that origin matches host directly, including ports
        if not self.same_origin():
            self.log.warn("Cross Origin WebSocket Attempt.")
            raise web.HTTPError(404)

        self.session = Session(config=self.config)
        self.save_on_message = self.on_message
        self.on_message = self.on_first_message
Exemple #29
0
    def _getdef(self,obj,oname=''):
        """Return the call signature for any callable object.

        If any exception is generated, None is returned instead and the
        exception is suppressed."""
        try:
            hdef = oname + inspect.formatargspec(*getargspec(obj))
            return cast_unicode(hdef)
        except:
            return None
    def _getdef(self,obj,oname=''):
        """Return the call signature for any callable object.

        If any exception is generated, None is returned instead and the
        exception is suppressed."""
        try:
            hdef = _render_signature(signature(obj), oname)
            return cast_unicode(hdef)
        except:
            return None
Exemple #31
0
 def data(self, svg):
     if svg is None:
         self._data = None
         return
     # parse into dom object
     from xml.dom import minidom
     svg = cast_bytes_py2(svg)
     x = minidom.parseString(svg)
     # get svg tag (should be 1)
     found_svg = x.getElementsByTagName('svg')
     if found_svg:
         svg = found_svg[0].toxml()
     else:
         # fallback on the input, trust the user
         # but this is probably an error.
         pass
     svg = cast_unicode(svg)
     self._data = svg
Exemple #32
0
    def _reserialize_reply(self, msg_list, channel=None):
        """Reserialize a reply message using JSON.

        This takes the msg list from the ZMQ socket, deserializes it using
        self.session and then serializes the result using JSON. This method
        should be used by self._on_zmq_reply to build messages that can
        be sent back to the browser.
        """
        idents, msg_list = self.session.feed_identities(msg_list)
        msg = self.session.deserialize(msg_list)
        if channel:
            msg['channel'] = channel
        if msg['buffers']:
            buf = serialize_binary_message(msg)
            return buf
        else:
            smsg = json.dumps(msg, default=date_default)
            return cast_unicode(smsg)
Exemple #33
0
    def open(self, kernel_id):
        self.kernel_id = cast_unicode(kernel_id, 'ascii')
        # Check to see that origin matches host directly, including ports
        # Tornado 4 already does CORS checking
        if tornado.version_info[0] < 4:
            if not self.check_origin(self.get_origin()):
                self.log.warn("Cross Origin WebSocket Attempt from %s", self.get_origin())
                raise web.HTTPError(403)

        self.session = Session(config=self.config)
        self.save_on_message = self.on_message
        self.on_message = self.on_first_message
        
        # start the pinging
        if self.ping_interval > 0:
            self.last_ping = ioloop.IOLoop.instance().time()  # Remember time of last ping
            self.last_pong = self.last_ping
            self.ping_callback = ioloop.PeriodicCallback(self.send_ping, self.ping_interval)
            self.ping_callback.start()
Exemple #34
0
def tkinter_clipboard_get():
    """ Get the clipboard's text using Tkinter.

    This is the default on systems that are not Windows or OS X. It may
    interfere with other UI toolkits and should be replaced with an
    implementation that uses that toolkit.
    """
    try:
        import Tkinter
    except ImportError:
        raise TryNext("Getting text from the clipboard on this platform "
                      "requires the %s-tk package." %
                      ("python3" if py3compat.PY3 else "python"))
    root = Tkinter.Tk()
    root.withdraw()
    text = root.clipboard_get()
    root.destroy()
    text = py3compat.cast_unicode(text, py3compat.DEFAULT_ENCODING)
    return text
Exemple #35
0
    def save(self, parameter_s=''):
        """Save a set of lines or a macro to a given filename.

        Usage:\\
          %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ...

        Options:

          -r: use 'raw' input.  By default, the 'processed' history is used,
          so that magics are loaded in their transformed version to valid
          Python.  If this option is given, the raw input as typed as the
          command line is used instead.

        This function uses the same syntax as %history for input ranges,
        then saves the lines to the filename you specify.

        It adds a '.py' extension to the file if you don't do so yourself, and
        it asks for confirmation before overwriting existing files.

        If `-r` option is used, the default extension is `.ipy`.
        """

        opts,args = self.parse_options(parameter_s,'r',mode='list')
        raw = 'r' in opts
        ext = u'.ipy' if raw else u'.py'
        fname, codefrom = unquote_filename(args[0]), " ".join(args[1:])
        if not fname.endswith((u'.py',u'.ipy')):
            fname += ext
        if os.path.isfile(fname):
            overwrite = self.shell.ask_yes_no('File `%s` exists. Overwrite (y/[N])? ' % fname, default='n')
            if not overwrite :
                print 'Operation cancelled.'
                return
        try:
            cmds = self.shell.find_user_code(codefrom,raw)
        except (TypeError, ValueError) as e:
            print e.args[0]
            return
        with io.open(fname,'w', encoding="utf-8") as f:
            f.write(u"# coding: utf-8\n")
            f.write(py3compat.cast_unicode(cmds))
        print 'The following commands were written to file `%s`:' % fname
        print cmds
Exemple #36
0
def get_home_dir(require_writable=False):
    """Return the 'home' directory, as a unicode string.

    Uses os.path.expanduser('~'), and checks for writability.
    
    See stdlib docs for how this is determined.
    $HOME is first priority on *ALL* platforms.
    
    Parameters
    ----------
    
    require_writable : bool [default: False]
        if True:
            guarantees the return value is a writable directory, otherwise
            raises HomeDirError
        if False:
            The path is resolved, but it is not guaranteed to exist or be writable.
    """

    homedir = os.path.expanduser('~')
    # Next line will make things work even when /home/ is a symlink to
    # /usr/home as it is on FreeBSD, for example
    homedir = os.path.realpath(homedir)

    if not _writable_dir(homedir) and os.name == 'nt':
        # expanduser failed, use the registry to get the 'My Documents' folder.
        try:
            import _winreg as wreg
            key = wreg.OpenKey(
                wreg.HKEY_CURRENT_USER,
                "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
            )
            homedir = wreg.QueryValueEx(key, 'Personal')[0]
            key.Close()
        except:
            pass

    if (not require_writable) or _writable_dir(homedir):
        return py3compat.cast_unicode(homedir, fs_encoding)
    else:
        raise HomeDirError('%s is not a writable dir, '
                           'set $HOME environment variable to override' %
                           homedir)
Exemple #37
0
    def get(self, *args, **kwargs):
        # Check to see that origin matches host directly, including ports
        # Tornado 4 already does CORS checking
        if tornado.version_info[0] < 4:
            if not self.check_origin(self.get_origin()):
                raise web.HTTPError(403)

        # authenticate the request before opening the websocket
        if self.get_current_user() is None:
            self.log.warn("Couldn't authenticate WebSocket connection")
            raise web.HTTPError(403)

        if self.get_argument('session_id', False):
            self.session.session = cast_unicode(
                self.get_argument('session_id'))
        else:
            self.log.warn("No session ID specified")

        return super(AuthenticatedZMQStreamHandler, self).get(*args, **kwargs)
Exemple #38
0
    def parse_command_line(self, argv=None):
        """Parse the command line arguments."""
        argv = sys.argv[1:] if argv is None else argv
        self.argv = [py3compat.cast_unicode(arg) for arg in argv]

        if argv and argv[0] == 'help':
            # turn `ipython help notebook` into `ipython notebook -h`
            argv = argv[1:] + ['-h']

        if self.subcommands and len(argv) > 0:
            # we have subcommands, and one may have been specified
            subc, subargv = argv[0], argv[1:]
            if re.match(r'^\w(\-?\w)*$', subc) and subc in self.subcommands:
                # it's a subcommand, and *not* a flag or class parameter
                return self.initialize_subcommand(subc, subargv)

        # Arguments after a '--' argument are for the script IPython may be
        # about to run, not IPython iteslf. For arguments parsed here (help and
        # version), we want to only search the arguments up to the first
        # occurrence of '--', which we're calling interpreted_argv.
        try:
            interpreted_argv = argv[:argv.index('--')]
        except ValueError:
            interpreted_argv = argv

        if any(x in interpreted_argv for x in ('-h', '--help-all', '--help')):
            self.print_help('--help-all' in interpreted_argv)
            self.exit(0)

        if '--version' in interpreted_argv or '-V' in interpreted_argv:
            self.print_version()
            self.exit(0)

        # flatten flags&aliases, so cl-args get appropriate priority:
        flags, aliases = self.flatten_flags()
        loader = KVArgParseConfigLoader(argv=argv,
                                        aliases=aliases,
                                        flags=flags,
                                        log=self.log)
        config = loader.load_config()
        self.update_config(config)
        # store unparsed args in extra_args
        self.extra_args = loader.extra_args
Exemple #39
0
def getdoc(obj):
    """Stable wrapper around inspect.getdoc.

    This can't crash because of attribute problems.

    It also attempts to call a getdoc() method on the given object.  This
    allows objects which provide their docstrings via non-standard mechanisms
    (like Pyro proxies) to still be inspected by ipython's ? system.
    """
    # Allow objects to offer customized documentation via a getdoc method:
    try:
        ds = obj.getdoc()
    except Exception:
        pass
    else:
        if isinstance(ds, str):
            return inspect.cleandoc(ds)
    docstr = inspect.getdoc(obj)
    encoding = get_encoding(obj)
    return py3compat.cast_unicode(docstr, encoding=encoding)
Exemple #40
0
    def push(self, lines):
        """Push one or more lines of IPython input.

        This stores the given lines and returns a status code indicating
        whether the code forms a complete Python block or not, after processing
        all input lines for special IPython syntax.

        Any exceptions generated in compilation are swallowed, but if an
        exception was produced, the method returns True.

        Parameters
        ----------
        lines : string
          One or more lines of Python input.

        Returns
        -------
        is_complete : boolean
          True if the current input source (the result of the current input
        plus prior inputs) forms a complete Python execution block.  Note that
        this value is also stored as a private attribute (_is_complete), so it
        can be queried at any time.
        """

        # We must ensure all input is pure unicode
        lines = cast_unicode(lines, self.encoding)

        # ''.splitlines() --> [], but we need to push the empty line to transformers
        lines_list = lines.splitlines()
        if not lines_list:
            lines_list = ['']

        # Store raw source before applying any transformations to it.  Note
        # that this must be done *after* the reset() call that would otherwise
        # flush the buffer.
        self._store(lines, self._buffer_raw, 'source_raw')

        for line in lines_list:
            out = self.push_line(line)

        return out
Exemple #41
0
    def _inject_cookie_message(self, msg):
        """Inject the first message, which is the document cookie,
        for authentication."""
        if not PY3 and isinstance(msg, str):
            # Cookie constructor doesn't accept unicode strings
            # under Python 2.x for some reason
            msg = msg.encode('utf8', 'replace')
        try:
            identity, msg = msg.split(':', 1)
            self.session.session = cast_unicode(identity, 'ascii')
        except Exception:
            logging.error(
                "First ws message didn't have the form 'identity:[cookie]' - %r",
                msg)

        try:
            self.request._cookies = http.cookies.SimpleCookie(msg)
        except:
            self.log.warn("couldn't parse cookie string: %s",
                          msg,
                          exc_info=True)
Exemple #42
0
def setup_kernel(cmd):
    """start an embedded kernel in a subprocess, and wait for it to be ready

    Returns
    -------
    kernel_manager: connected KernelManager instance
    """
    kernel = Popen([sys.executable, '-c', cmd],
                   stdout=PIPE,
                   stderr=PIPE,
                   env=env)
    connection_file = os.path.join(IPYTHONDIR, 'profile_default', 'security',
                                   'kernel-%i.json' % kernel.pid)
    # wait for connection file to exist, timeout after 5s
    tic = time.time()
    while not os.path.exists(connection_file) \
        and kernel.poll() is None \
        and time.time() < tic + SETUP_TIMEOUT:
        time.sleep(0.1)

    if kernel.poll() is not None:
        o, e = kernel.communicate()
        e = py3compat.cast_unicode(e)
        raise IOError("Kernel failed to start:\n%s" % e)

    if not os.path.exists(connection_file):
        if kernel.poll() is None:
            kernel.terminate()
        raise IOError("Connection file %r never arrived" % connection_file)

    client = BlockingKernelClient(connection_file=connection_file)
    client.load_connection_file()
    client.start_channels()
    client.wait_for_ready()

    try:
        yield client
    finally:
        client.stop_channels()
        kernel.terminate()
Exemple #43
0
def tkinter_clipboard_get():
    """ Get the clipboard's text using Tkinter.

    This is the default on systems that are not Windows or OS X. It may
    interfere with other UI toolkits and should be replaced with an
    implementation that uses that toolkit.
    """
    try:
        from tkinter import Tk, TclError 
    except ImportError as e:
        raise TryNext("Getting text from the clipboard on this platform requires tkinter.") from e
        
    root = Tk()
    root.withdraw()
    try:
        text = root.clipboard_get()
    except TclError as e:
        raise ClipboardEmpty from e
    finally:
        root.destroy()
    text = py3compat.cast_unicode(text, py3compat.DEFAULT_ENCODING)
    return text
def win32_clipboard_get():
    """ Get the current clipboard's text on Windows.

    Requires Mark Hammond's pywin32 extensions.
    """
    try:
        import win32clipboard
    except ImportError:
        raise TryNext("Getting text from the clipboard requires the pywin32 "
                      "extensions: http://sourceforge.net/projects/pywin32/")
    win32clipboard.OpenClipboard()
    try:
        text = win32clipboard.GetClipboardData(win32clipboard.CF_UNICODETEXT)
    except (TypeError, win32clipboard.error):
        try:
            text = win32clipboard.GetClipboardData(win32clipboard.CF_TEXT)
            text = py3compat.cast_unicode(text, py3compat.DEFAULT_ENCODING)
        except (TypeError, win32clipboard.error):
            raise ClipboardEmpty
    finally:
        win32clipboard.CloseClipboard()
    return text
Exemple #45
0
def _format_filename(file, ColorFilename, ColorNormal):
    """
    Format filename lines with `In [n]` if it's the nth code cell or `File *.py` if it's a module.

    Parameters
    ----------
    file : str
    ColorFilename
        ColorScheme's filename coloring to be used.
    ColorNormal
        ColorScheme's normal coloring to be used.
    """
    ipinst = get_ipython()

    if ipinst is not None and file in ipinst.compile._filename_map:
        file = "[%s]" % ipinst.compile._filename_map[file]
        tpl_link = "In %s%%s%s" % (ColorFilename, ColorNormal)
    else:
        file = util_path.compress_user(
            py3compat.cast_unicode(file, util_path.fs_encoding))
        tpl_link = "File %s%%s%s" % (ColorFilename, ColorNormal)

    return tpl_link % file
Exemple #46
0
    def _mime_format(self, text, formatter=None):
        """Return a mime bundle representation of the input text.

        - if `formatter` is None, the returned mime bundle has
           a `text/plain` field, with the input text.
           a `text/html` field with a `<pre>` tag containing the input text.

        - if `formatter` is not None, it must be a callable transforming the
          input text into a mime bundle. Default values for `text/plain` and
          `text/html` representations are the ones described above.

        Note:

        Formatters returning strings are supported but this behavior is deprecated.

        """
        text = cast_unicode(text)
        defaults = {
            'text/plain': text,
            'text/html': '<pre>' + text + '</pre>'
        }

        if formatter is None:
            return defaults
        else:
            formatted = formatter(text)

            if not isinstance(formatted, dict):
                # Handle the deprecated behavior of a formatter returning
                # a string instead of a mime bundle.
                return {
                    'text/plain': formatted,
                    'text/html': '<pre>' + formatted + '</pre>'
                }

            else:
                return dict(defaults, **formatted)
Exemple #47
0
def run_iptestall(inc_slow=False):
    """Run the entire IPython test suite by calling nose and trial.

    This function constructs :class:`IPTester` instances for all IPython
    modules and package and then runs each of them.  This causes the modules
    and packages of IPython to be tested each in their own subprocess using
    nose.
    
    Parameters
    ----------
    
    inc_slow : bool, optional
      Include slow tests, like IPython.parallel. By default, these tests aren't
      run.
    """

    runners = make_runners(inc_slow=inc_slow)

    # Run the test runners in a temporary dir so we can nuke it when finished
    # to clean up any junk files left over by accident.  This also makes it
    # robust against being run in non-writeable directories by mistake, as the
    # temp dir will always be user-writeable.
    curdir = os.getcwdu()
    testdir = tempfile.gettempdir()
    os.chdir(testdir)

    # Run all test runners, tracking execution time
    failed = []
    t_start = time.time()
    try:
        for (name, runner) in runners:
            print('*' * 70)
            print('IPython test group:', name)
            res = runner.run()
            if res:
                failed.append((name, runner))
                if res == -signal.SIGINT:
                    print("Interrupted")
                    break
    finally:
        os.chdir(curdir)
    t_end = time.time()
    t_tests = t_end - t_start
    nrunners = len(runners)
    nfail = len(failed)
    # summarize results
    print()
    print('*' * 70)
    print('Test suite completed for system with the following information:')
    print(report())
    print('Ran %s test groups in %.3fs' % (nrunners, t_tests))
    print()
    print('Status:')
    if not failed:
        print('OK')
    else:
        # If anything went wrong, point out what command to rerun manually to
        # see the actual errors and individual summary
        print('ERROR - %s out of %s test groups failed.' % (nfail, nrunners))
        for name, failed_runner in failed:
            print('-' * 40)
            print('Runner failed:', name)
            print('You may wish to rerun this one individually, with:')
            failed_call_args = [
                py3compat.cast_unicode(x) for x in failed_runner.call_args
            ]
            print(u' '.join(failed_call_args))
            print()
        # Ensure that our exit code indicates failure
        sys.exit(1)
Exemple #48
0
def get_ipython_package_dir():
    """Get the base directory where IPython itself is installed."""
    ipdir = os.path.dirname(IPython.__file__)
    return py3compat.cast_unicode(ipdir, fs_encoding)
Exemple #49
0
    def format_stack_entry(self, frame_lineno, lprefix=': ', context=None):
        if context is None:
            context = self.context
        try:
            context = int(context)
            if context <= 0:
                print("Context must be a positive integer")
        except (TypeError, ValueError):
            print("Context must be a positive integer")
        try:
            import reprlib  # Py 3
        except ImportError:
            import repr as reprlib  # Py 2

        ret = []

        Colors = self.color_scheme_table.active_colors
        ColorsNormal = Colors.Normal
        tpl_link = u'%s%%s%s' % (Colors.filenameEm, ColorsNormal)
        tpl_call = u'%s%%s%s%%s%s' % (Colors.vName, Colors.valEm, ColorsNormal)
        tpl_line = u'%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
        tpl_line_em = u'%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line,
                                             ColorsNormal)

        frame, lineno = frame_lineno

        return_value = ''
        if '__return__' in frame.f_locals:
            rv = frame.f_locals['__return__']
            #return_value += '->'
            return_value += reprlib.repr(rv) + '\n'
        ret.append(return_value)

        #s = filename + '(' + `lineno` + ')'
        filename = self.canonic(frame.f_code.co_filename)
        link = tpl_link % py3compat.cast_unicode(filename)

        if frame.f_code.co_name:
            func = frame.f_code.co_name
        else:
            func = "<lambda>"

        call = ''
        if func != '?':
            if '__args__' in frame.f_locals:
                args = reprlib.repr(frame.f_locals['__args__'])
            else:
                args = '()'
            call = tpl_call % (func, args)

        # The level info should be generated in the same format pdb uses, to
        # avoid breaking the pdbtrack functionality of python-mode in *emacs.
        if frame is self.curframe:
            ret.append('> ')
        else:
            ret.append('  ')
        ret.append(u'%s(%s)%s\n' % (link, lineno, call))

        start = lineno - 1 - context // 2
        lines = ulinecache.getlines(filename)
        start = min(start, len(lines) - context)
        start = max(start, 0)
        lines = lines[start:start + context]

        for i, line in enumerate(lines):
            show_arrow = (start + 1 + i == lineno)
            linetpl = (frame is self.curframe or show_arrow) \
                      and tpl_line_em \
                      or tpl_line
            ret.append(
                self.__format_line(linetpl,
                                   filename,
                                   start + 1 + i,
                                   line,
                                   arrow=show_arrow))
        return ''.join(ret)
Exemple #50
0
 def _parse_args(self, args):
     """self.parser->self.parsed_data"""
     # decode sys.argv to support unicode command-line options
     enc = DEFAULT_ENCODING
     uargs = [py3compat.cast_unicode(a, enc) for a in args]
     self.parsed_data, self.extra_args = self.parser.parse_known_args(uargs)
Exemple #51
0
    def _format_exception_only(self, etype, value):
        """Format the exception part of a traceback.

        The arguments are the exception type and value such as given by
        sys.exc_info()[:2]. The return value is a list of strings, each ending
        in a newline.  Normally, the list contains a single string; however,
        for SyntaxError exceptions, it contains several lines that (when
        printed) display detailed information about where the syntax error
        occurred.  The message indicating which exception occurred is the
        always last string in the list.

        Also lifted nearly verbatim from traceback.py
        """
        have_filedata = False
        Colors = self.Colors
        list = []
        stype = py3compat.cast_unicode(Colors.excName + etype.__name__ +
                                       Colors.Normal)
        if value is None:
            # Not sure if this can still happen in Python 2.6 and above
            list.append(stype + '\n')
        else:
            if issubclass(etype, SyntaxError):
                have_filedata = True
                if not value.filename: value.filename = "<string>"
                if value.lineno:
                    lineno = value.lineno
                    textline = linecache.getline(value.filename, value.lineno)
                else:
                    lineno = "unknown"
                    textline = ""
                list.append("%s  %s, line %s%s%s\n" % (
                    Colors.normalEm,
                    _format_filename(value.filename, Colors.filenameEm,
                                     Colors.normalEm),
                    Colors.linenoEm,
                    lineno,
                    Colors.Normal,
                ))
                if textline == "":
                    textline = py3compat.cast_unicode(value.text, "utf-8")

                if textline is not None:
                    i = 0
                    while i < len(textline) and textline[i].isspace():
                        i += 1
                    list.append('%s    %s%s\n' %
                                (Colors.line, textline.strip(), Colors.Normal))
                    if value.offset is not None:
                        s = '    '
                        for c in textline[i:value.offset - 1]:
                            if c.isspace():
                                s += c
                            else:
                                s += ' '
                        list.append('%s%s^%s\n' %
                                    (Colors.caret, s, Colors.Normal))

            try:
                s = value.msg
            except Exception:
                s = self._some_str(value)
            if s:
                list.append('%s%s:%s %s\n' %
                            (stype, Colors.excName, Colors.Normal, s))
            else:
                list.append('%s\n' % stype)

        # sync with user hooks
        if have_filedata:
            ipinst = get_ipython()
            if ipinst is not None:
                ipinst.hooks.synchronize_with_editor(value.filename,
                                                     value.lineno, 0)

        return list
Exemple #52
0
    def save(self, parameter_s=''):
        """Save a set of lines or a macro to a given filename.

        Usage:\\
          %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ...

        Options:

          -r: use 'raw' input.  By default, the 'processed' history is used,
          so that magics are loaded in their transformed version to valid
          Python.  If this option is given, the raw input as typed as the
          command line is used instead.
          
          -f: force overwrite.  If file exists, %save will prompt for overwrite
          unless -f is given.

          -a: append to the file instead of overwriting it.

        This function uses the same syntax as %history for input ranges,
        then saves the lines to the filename you specify.

        It adds a '.py' extension to the file if you don't do so yourself, and
        it asks for confirmation before overwriting existing files.

        If `-r` option is used, the default extension is `.ipy`.
        """

        opts, args = self.parse_options(parameter_s, 'fra', mode='list')
        if not args:
            raise UsageError('Missing filename.')
        raw = 'r' in opts
        force = 'f' in opts
        append = 'a' in opts
        mode = 'a' if append else 'w'
        ext = u'.ipy' if raw else u'.py'
        fname, codefrom = args[0], " ".join(args[1:])
        if not fname.endswith((u'.py', u'.ipy')):
            fname += ext
        file_exists = os.path.isfile(fname)
        if file_exists and not force and not append:
            try:
                overwrite = self.shell.ask_yes_no(
                    'File `%s` exists. Overwrite (y/[N])? ' % fname,
                    default='n')
            except StdinNotImplementedError:
                print(
                    "File `%s` exists. Use `%%save -f %s` to force overwrite" %
                    (fname, parameter_s))
                return
            if not overwrite:
                print('Operation cancelled.')
                return
        try:
            cmds = self.shell.find_user_code(codefrom, raw)
        except (TypeError, ValueError) as e:
            print(e.args[0])
            return
        out = py3compat.cast_unicode(cmds)
        with io.open(fname, mode, encoding="utf-8") as f:
            if not file_exists or not append:
                f.write(u"# coding: utf-8\n")
            f.write(out)
            # make sure we end on a newline
            if not out.endswith(u'\n'):
                f.write(u'\n')
        print('The following commands were written to file `%s`:' % fname)
        print(cmds)
def patch_getsource(obj, is_binary=False):
    if is_binary:
        return cast_unicode(getsource(obj))

    else:
        return old_getsource(obj, is_binary)
Exemple #54
0
    def format_record(self, frame_info):
        """Format a single stack frame"""
        Colors = self.Colors  # just a shorthand + quicker name lookup
        ColorsNormal = Colors.Normal  # used a lot



        if isinstance(frame_info, stack_data.RepeatedFrames):
            return '    %s[... skipping similar frames: %s]%s\n' % (
                Colors.excName, frame_info.description, ColorsNormal)

        indent = ' ' * INDENT_SIZE
        em_normal = '%s\n%s%s' % (Colors.valEm, indent, ColorsNormal)
        tpl_link = '%s%%s%s' % (Colors.filenameEm, ColorsNormal)
        tpl_call = 'in %s%%s%s%%s%s' % (Colors.vName, Colors.valEm,
                                        ColorsNormal)
        tpl_call_fail = 'in %s%%s%s(***failed resolving arguments***)%s' % \
                        (Colors.vName, Colors.valEm, ColorsNormal)
        tpl_local_var = '%s%%s%s' % (Colors.vName, ColorsNormal)
        tpl_name_val = '%%s %s= %%s%s' % (Colors.valEm, ColorsNormal)

        file = frame_info.filename
        file = py3compat.cast_unicode(file, util_path.fs_encoding)
        link = tpl_link % util_path.compress_user(file)
        args, varargs, varkw, locals_ = inspect.getargvalues(frame_info.frame)

        func = frame_info.executing.code_qualname()
        if func == '<module>':
            call = tpl_call % (func, '')
        else:
            # Decide whether to include variable details or not
            var_repr = eqrepr if self.include_vars else nullrepr
            try:
                call = tpl_call % (func, inspect.formatargvalues(args,
                                                                 varargs, varkw,
                                                                 locals_, formatvalue=var_repr))
            except KeyError:
                # This happens in situations like errors inside generator
                # expressions, where local variables are listed in the
                # line, but can't be extracted from the frame.  I'm not
                # 100% sure this isn't actually a bug in inspect itself,
                # but since there's no info for us to compute with, the
                # best we can do is report the failure and move on.  Here
                # we must *not* call any traceback construction again,
                # because that would mess up use of %debug later on.  So we
                # simply report the failure and move on.  The only
                # limitation will be that this frame won't have locals
                # listed in the call signature.  Quite subtle problem...
                # I can't think of a good way to validate this in a unit
                # test, but running a script consisting of:
                #  dict( (k,v.strip()) for (k,v) in range(10) )
                # will illustrate the error, if this exception catch is
                # disabled.
                call = tpl_call_fail % func

        lvals = ''
        lvals_list = []
        if self.include_vars:
            for var in frame_info.variables_in_executing_piece:
                lvals_list.append(tpl_name_val % (var.name, repr(var.value)))
        if lvals_list:
            lvals = '%s%s' % (indent, em_normal.join(lvals_list))

        result = '%s %s\n' % (link, call)

        result += ''.join(_format_traceback_lines(frame_info.lines, Colors, self.has_colors, lvals))
        return result
Exemple #55
0
class APITest(NotebookTestBase):
    """Test the kernels web service API"""
    dirs_nbs = [
        ('', 'inroot'),
        ('Directory with spaces in', 'inspace'),
        (u'unicodé', 'innonascii'),
        ('foo', 'a'),
        ('foo', 'b'),
        ('foo', 'name with spaces'),
        ('foo', u'unicodé'),
        ('foo/bar', 'baz'),
        ('ordering', 'A'),
        ('ordering', 'b'),
        ('ordering', 'C'),
        (u'å b', u'ç d'),
    ]
    hidden_dirs = ['.hidden', '__pycache__']

    # Don't include root dir.
    dirs = uniq_stable([py3compat.cast_unicode(d) for (d, n) in dirs_nbs[1:]])
    top_level_dirs = {normalize('NFC', d.split('/')[0]) for d in dirs}

    @staticmethod
    def _blob_for_name(name):
        return name.encode('utf-8') + b'\xFF'

    @staticmethod
    def _txt_for_name(name):
        return u'%s text file' % name

    def to_os_path(self, api_path):
        return to_os_path(api_path, root=self.notebook_dir.name)

    def make_dir(self, api_path):
        """Create a directory at api_path"""
        os_path = self.to_os_path(api_path)
        try:
            os.makedirs(os_path)
        except OSError:
            print("Directory already exists: %r" % os_path)

    def make_txt(self, api_path, txt):
        """Make a text file at a given api_path"""
        os_path = self.to_os_path(api_path)
        with io.open(os_path, 'w', encoding='utf-8') as f:
            f.write(txt)

    def make_blob(self, api_path, blob):
        """Make a binary file at a given api_path"""
        os_path = self.to_os_path(api_path)
        with io.open(os_path, 'wb') as f:
            f.write(blob)

    def make_nb(self, api_path, nb):
        """Make a notebook file at a given api_path"""
        os_path = self.to_os_path(api_path)

        with io.open(os_path, 'w', encoding='utf-8') as f:
            write(nb, f, version=4)

    def delete_dir(self, api_path):
        """Delete a directory at api_path, removing any contents."""
        os_path = self.to_os_path(api_path)
        shutil.rmtree(os_path, ignore_errors=True)

    def delete_file(self, api_path):
        """Delete a file at the given path if it exists."""
        if self.isfile(api_path):
            os.unlink(self.to_os_path(api_path))

    def isfile(self, api_path):
        return os.path.isfile(self.to_os_path(api_path))

    def isdir(self, api_path):
        return os.path.isdir(self.to_os_path(api_path))

    def setUp(self):

        for d in (self.dirs + self.hidden_dirs):
            self.make_dir(d)

        for d, name in self.dirs_nbs:
            # create a notebook
            nb = new_notebook()
            self.make_nb(u'{}/{}.ipynb'.format(d, name), nb)

            # create a text file
            txt = self._txt_for_name(name)
            self.make_txt(u'{}/{}.txt'.format(d, name), txt)

            # create a binary file
            blob = self._blob_for_name(name)
            self.make_blob(u'{}/{}.blob'.format(d, name), blob)

        self.api = API(self.base_url())

    def tearDown(self):
        for dname in (list(self.top_level_dirs) + self.hidden_dirs):
            self.delete_dir(dname)
        self.delete_file('inroot.ipynb')

    def test_list_notebooks(self):
        nbs = notebooks_only(self.api.list().json())
        self.assertEqual(len(nbs), 1)
        self.assertEqual(nbs[0]['name'], 'inroot.ipynb')

        nbs = notebooks_only(
            self.api.list('/Directory with spaces in/').json())
        self.assertEqual(len(nbs), 1)
        self.assertEqual(nbs[0]['name'], 'inspace.ipynb')

        nbs = notebooks_only(self.api.list(u'/unicodé/').json())
        self.assertEqual(len(nbs), 1)
        self.assertEqual(nbs[0]['name'], 'innonascii.ipynb')
        self.assertEqual(nbs[0]['path'], u'unicodé/innonascii.ipynb')

        nbs = notebooks_only(self.api.list('/foo/bar/').json())
        self.assertEqual(len(nbs), 1)
        self.assertEqual(nbs[0]['name'], 'baz.ipynb')
        self.assertEqual(nbs[0]['path'], 'foo/bar/baz.ipynb')

        nbs = notebooks_only(self.api.list('foo').json())
        self.assertEqual(len(nbs), 4)
        nbnames = {normalize('NFC', n['name']) for n in nbs}
        expected = [
            u'a.ipynb', u'b.ipynb', u'name with spaces.ipynb', u'unicodé.ipynb'
        ]
        expected = {normalize('NFC', name) for name in expected}
        self.assertEqual(nbnames, expected)

        nbs = notebooks_only(self.api.list('ordering').json())
        nbnames = [n['name'] for n in nbs]
        expected = ['A.ipynb', 'b.ipynb', 'C.ipynb']
        self.assertEqual(nbnames, expected)

    def test_list_dirs(self):
        dirs = dirs_only(self.api.list().json())
        dir_names = {normalize('NFC', d['name']) for d in dirs}
        self.assertEqual(dir_names,
                         self.top_level_dirs)  # Excluding hidden dirs

    def test_get_dir_no_content(self):
        for d in self.dirs:
            model = self.api.read(d, content=False).json()
            self.assertEqual(model['path'], d)
            self.assertEqual(model['type'], 'directory')
            self.assertIn('content', model)
            self.assertEqual(model['content'], None)

    def test_list_nonexistant_dir(self):
        with assert_http_error(404):
            self.api.list('nonexistant')

    def test_get_nb_contents(self):
        for d, name in self.dirs_nbs:
            path = url_path_join(d, name + '.ipynb')
            nb = self.api.read(path).json()
            self.assertEqual(nb['name'], u'%s.ipynb' % name)
            self.assertEqual(nb['path'], path)
            self.assertEqual(nb['type'], 'notebook')
            self.assertIn('content', nb)
            self.assertEqual(nb['format'], 'json')
            self.assertIn('metadata', nb['content'])
            self.assertIsInstance(nb['content']['metadata'], dict)

    def test_get_nb_no_content(self):
        for d, name in self.dirs_nbs:
            path = url_path_join(d, name + '.ipynb')
            nb = self.api.read(path, content=False).json()
            self.assertEqual(nb['name'], u'%s.ipynb' % name)
            self.assertEqual(nb['path'], path)
            self.assertEqual(nb['type'], 'notebook')
            self.assertIn('content', nb)
            self.assertEqual(nb['content'], None)

    def test_get_contents_no_such_file(self):
        # Name that doesn't exist - should be a 404
        with assert_http_error(404):
            self.api.read('foo/q.ipynb')

    def test_get_text_file_contents(self):
        for d, name in self.dirs_nbs:
            path = url_path_join(d, name + '.txt')
            model = self.api.read(path).json()
            self.assertEqual(model['name'], u'%s.txt' % name)
            self.assertEqual(model['path'], path)
            self.assertIn('content', model)
            self.assertEqual(model['format'], 'text')
            self.assertEqual(model['type'], 'file')
            self.assertEqual(model['content'], self._txt_for_name(name))

        # Name that doesn't exist - should be a 404
        with assert_http_error(404):
            self.api.read('foo/q.txt')

        # Specifying format=text should fail on a non-UTF-8 file
        with assert_http_error(400):
            self.api.read('foo/bar/baz.blob', type='file', format='text')

    def test_get_binary_file_contents(self):
        for d, name in self.dirs_nbs:
            path = url_path_join(d, name + '.blob')
            model = self.api.read(path).json()
            self.assertEqual(model['name'], u'%s.blob' % name)
            self.assertEqual(model['path'], path)
            self.assertIn('content', model)
            self.assertEqual(model['format'], 'base64')
            self.assertEqual(model['type'], 'file')
            self.assertEqual(
                base64.decodestring(model['content'].encode('ascii')),
                self._blob_for_name(name),
            )

        # Name that doesn't exist - should be a 404
        with assert_http_error(404):
            self.api.read('foo/q.txt')

    def test_get_bad_type(self):
        with assert_http_error(400):
            self.api.read(u'unicodé', type='file')  # this is a directory

        with assert_http_error(400):
            self.api.read(u'unicodé/innonascii.ipynb', type='directory')

    def _check_created(self, resp, path, type='notebook'):
        self.assertEqual(resp.status_code, 201)
        location_header = py3compat.str_to_unicode(resp.headers['Location'])
        self.assertEqual(location_header,
                         url_escape(url_path_join(u'/api/contents', path)))
        rjson = resp.json()
        self.assertEqual(rjson['name'], path.rsplit('/', 1)[-1])
        self.assertEqual(rjson['path'], path)
        self.assertEqual(rjson['type'], type)
        isright = self.isdir if type == 'directory' else self.isfile
        assert isright(path)

    def test_create_untitled(self):
        resp = self.api.create_untitled(path=u'å b')
        self._check_created(resp, u'å b/Untitled.ipynb')

        # Second time
        resp = self.api.create_untitled(path=u'å b')
        self._check_created(resp, u'å b/Untitled1.ipynb')

        # And two directories down
        resp = self.api.create_untitled(path='foo/bar')
        self._check_created(resp, 'foo/bar/Untitled.ipynb')

    def test_create_untitled_txt(self):
        resp = self.api.create_untitled(path='foo/bar', ext='.txt')
        self._check_created(resp, 'foo/bar/untitled.txt', type='file')

        resp = self.api.read(path='foo/bar/untitled.txt')
        model = resp.json()
        self.assertEqual(model['type'], 'file')
        self.assertEqual(model['format'], 'text')
        self.assertEqual(model['content'], '')

    def test_upload(self):
        nb = new_notebook()
        nbmodel = {'content': nb, 'type': 'notebook'}
        path = u'å b/Upload tést.ipynb'
        resp = self.api.upload(path, body=json.dumps(nbmodel))
        self._check_created(resp, path)

    def test_mkdir_untitled(self):
        resp = self.api.mkdir_untitled(path=u'å b')
        self._check_created(resp, u'å b/Untitled Folder', type='directory')

        # Second time
        resp = self.api.mkdir_untitled(path=u'å b')
        self._check_created(resp, u'å b/Untitled Folder 1', type='directory')

        # And two directories down
        resp = self.api.mkdir_untitled(path='foo/bar')
        self._check_created(resp, 'foo/bar/Untitled Folder', type='directory')

    def test_mkdir(self):
        path = u'å b/New ∂ir'
        resp = self.api.mkdir(path)
        self._check_created(resp, path, type='directory')

    def test_mkdir_hidden_400(self):
        with assert_http_error(400):
            resp = self.api.mkdir(u'å b/.hidden')

    def test_upload_txt(self):
        body = u'ünicode téxt'
        model = {
            'content': body,
            'format': 'text',
            'type': 'file',
        }
        path = u'å b/Upload tést.txt'
        resp = self.api.upload(path, body=json.dumps(model))

        # check roundtrip
        resp = self.api.read(path)
        model = resp.json()
        self.assertEqual(model['type'], 'file')
        self.assertEqual(model['format'], 'text')
        self.assertEqual(model['content'], body)

    def test_upload_b64(self):
        body = b'\xFFblob'
        b64body = base64.encodestring(body).decode('ascii')
        model = {
            'content': b64body,
            'format': 'base64',
            'type': 'file',
        }
        path = u'å b/Upload tést.blob'
        resp = self.api.upload(path, body=json.dumps(model))

        # check roundtrip
        resp = self.api.read(path)
        model = resp.json()
        self.assertEqual(model['type'], 'file')
        self.assertEqual(model['path'], path)
        self.assertEqual(model['format'], 'base64')
        decoded = base64.decodestring(model['content'].encode('ascii'))
        self.assertEqual(decoded, body)

    def test_upload_v2(self):
        nb = v2.new_notebook()
        ws = v2.new_worksheet()
        nb.worksheets.append(ws)
        ws.cells.append(v2.new_code_cell(input='print("hi")'))
        nbmodel = {'content': nb, 'type': 'notebook'}
        path = u'å b/Upload tést.ipynb'
        resp = self.api.upload(path, body=json.dumps(nbmodel))
        self._check_created(resp, path)
        resp = self.api.read(path)
        data = resp.json()
        self.assertEqual(data['content']['nbformat'], 4)

    def test_copy(self):
        resp = self.api.copy(u'å b/ç d.ipynb', u'å b')
        self._check_created(resp, u'å b/ç d-Copy1.ipynb')

        resp = self.api.copy(u'å b/ç d.ipynb', u'å b')
        self._check_created(resp, u'å b/ç d-Copy2.ipynb')

    def test_copy_copy(self):
        resp = self.api.copy(u'å b/ç d.ipynb', u'å b')
        self._check_created(resp, u'å b/ç d-Copy1.ipynb')

        resp = self.api.copy(u'å b/ç d-Copy1.ipynb', u'å b')
        self._check_created(resp, u'å b/ç d-Copy2.ipynb')

    def test_copy_path(self):
        resp = self.api.copy(u'foo/a.ipynb', u'å b')
        self._check_created(resp, u'å b/a.ipynb')

        resp = self.api.copy(u'foo/a.ipynb', u'å b')
        self._check_created(resp, u'å b/a-Copy1.ipynb')

    def test_copy_put_400(self):
        with assert_http_error(400):
            resp = self.api.copy_put(u'å b/ç d.ipynb', u'å b/cøpy.ipynb')

    def test_copy_dir_400(self):
        # can't copy directories
        with assert_http_error(400):
            resp = self.api.copy(u'å b', u'foo')

    def test_delete(self):
        for d, name in self.dirs_nbs:
            print('%r, %r' % (d, name))
            resp = self.api.delete(url_path_join(d, name + '.ipynb'))
            self.assertEqual(resp.status_code, 204)

        for d in self.dirs + ['/']:
            nbs = notebooks_only(self.api.list(d).json())
            print('------')
            print(d)
            print(nbs)
            self.assertEqual(nbs, [])

    def test_delete_dirs(self):
        # depth-first delete everything, so we don't try to delete empty directories
        for name in sorted(self.dirs + ['/'], key=len, reverse=True):
            listing = self.api.list(name).json()['content']
            for model in listing:
                self.api.delete(model['path'])
        listing = self.api.list('/').json()['content']
        self.assertEqual(listing, [])

    def test_delete_non_empty_dir(self):
        """delete non-empty dir raises 400"""
        with assert_http_error(400):
            self.api.delete(u'å b')

    def test_rename(self):
        resp = self.api.rename('foo/a.ipynb', 'foo/z.ipynb')
        self.assertEqual(resp.headers['Location'].split('/')[-1], 'z.ipynb')
        self.assertEqual(resp.json()['name'], 'z.ipynb')
        self.assertEqual(resp.json()['path'], 'foo/z.ipynb')
        assert self.isfile('foo/z.ipynb')

        nbs = notebooks_only(self.api.list('foo').json())
        nbnames = set(n['name'] for n in nbs)
        self.assertIn('z.ipynb', nbnames)
        self.assertNotIn('a.ipynb', nbnames)

    def test_checkpoints_follow_file(self):

        # Read initial file state
        orig = self.api.read('foo/a.ipynb')

        # Create a checkpoint of initial state
        r = self.api.new_checkpoint('foo/a.ipynb')
        cp1 = r.json()

        # Modify file and save
        nbcontent = json.loads(orig.text)['content']
        nb = from_dict(nbcontent)
        hcell = new_markdown_cell('Created by test')
        nb.cells.append(hcell)
        nbmodel = {'content': nb, 'type': 'notebook'}
        self.api.save('foo/a.ipynb', body=json.dumps(nbmodel))

        # Rename the file.
        self.api.rename('foo/a.ipynb', 'foo/z.ipynb')

        # Looking for checkpoints in the old location should yield no results.
        self.assertEqual(self.api.get_checkpoints('foo/a.ipynb').json(), [])

        # Looking for checkpoints in the new location should work.
        cps = self.api.get_checkpoints('foo/z.ipynb').json()
        self.assertEqual(cps, [cp1])

        # Delete the file.  The checkpoint should be deleted as well.
        self.api.delete('foo/z.ipynb')
        cps = self.api.get_checkpoints('foo/z.ipynb').json()
        self.assertEqual(cps, [])

    def test_rename_existing(self):
        with assert_http_error(409):
            self.api.rename('foo/a.ipynb', 'foo/b.ipynb')

    def test_save(self):
        resp = self.api.read('foo/a.ipynb')
        nbcontent = json.loads(resp.text)['content']
        nb = from_dict(nbcontent)
        nb.cells.append(new_markdown_cell(u'Created by test ³'))

        nbmodel = {'content': nb, 'type': 'notebook'}
        resp = self.api.save('foo/a.ipynb', body=json.dumps(nbmodel))

        nbcontent = self.api.read('foo/a.ipynb').json()['content']
        newnb = from_dict(nbcontent)
        self.assertEqual(newnb.cells[0].source, u'Created by test ³')

    def test_checkpoints(self):
        resp = self.api.read('foo/a.ipynb')
        r = self.api.new_checkpoint('foo/a.ipynb')
        self.assertEqual(r.status_code, 201)
        cp1 = r.json()
        self.assertEqual(set(cp1), {'id', 'last_modified'})
        self.assertEqual(r.headers['Location'].split('/')[-1], cp1['id'])

        # Modify it
        nbcontent = json.loads(resp.text)['content']
        nb = from_dict(nbcontent)
        hcell = new_markdown_cell('Created by test')
        nb.cells.append(hcell)
        # Save
        nbmodel = {'content': nb, 'type': 'notebook'}
        resp = self.api.save('foo/a.ipynb', body=json.dumps(nbmodel))

        # List checkpoints
        cps = self.api.get_checkpoints('foo/a.ipynb').json()
        self.assertEqual(cps, [cp1])

        nbcontent = self.api.read('foo/a.ipynb').json()['content']
        nb = from_dict(nbcontent)
        self.assertEqual(nb.cells[0].source, 'Created by test')

        # Restore cp1
        r = self.api.restore_checkpoint('foo/a.ipynb', cp1['id'])
        self.assertEqual(r.status_code, 204)
        nbcontent = self.api.read('foo/a.ipynb').json()['content']
        nb = from_dict(nbcontent)
        self.assertEqual(nb.cells, [])

        # Delete cp1
        r = self.api.delete_checkpoint('foo/a.ipynb', cp1['id'])
        self.assertEqual(r.status_code, 204)
        cps = self.api.get_checkpoints('foo/a.ipynb').json()
        self.assertEqual(cps, [])

    def test_file_checkpoints(self):
        """
        Test checkpointing of non-notebook files.
        """
        filename = 'foo/a.txt'
        resp = self.api.read(filename)
        orig_content = json.loads(resp.text)['content']

        # Create a checkpoint.
        r = self.api.new_checkpoint(filename)
        self.assertEqual(r.status_code, 201)
        cp1 = r.json()
        self.assertEqual(set(cp1), {'id', 'last_modified'})
        self.assertEqual(r.headers['Location'].split('/')[-1], cp1['id'])

        # Modify the file and save.
        new_content = orig_content + '\nsecond line'
        model = {
            'content': new_content,
            'type': 'file',
            'format': 'text',
        }
        resp = self.api.save(filename, body=json.dumps(model))

        # List checkpoints
        cps = self.api.get_checkpoints(filename).json()
        self.assertEqual(cps, [cp1])

        content = self.api.read(filename).json()['content']
        self.assertEqual(content, new_content)

        # Restore cp1
        r = self.api.restore_checkpoint(filename, cp1['id'])
        self.assertEqual(r.status_code, 204)
        restored_content = self.api.read(filename).json()['content']
        self.assertEqual(restored_content, orig_content)

        # Delete cp1
        r = self.api.delete_checkpoint(filename, cp1['id'])
        self.assertEqual(r.status_code, 204)
        cps = self.api.get_checkpoints(filename).json()
        self.assertEqual(cps, [])

    @contextmanager
    def patch_cp_root(self, dirname):
        """
        Temporarily patch the root dir of our checkpoint manager.
        """
        cpm = self.notebook.contents_manager.checkpoints
        old_dirname = cpm.root_dir
        cpm.root_dir = dirname
        try:
            yield
        finally:
            cpm.root_dir = old_dirname

    def test_checkpoints_separate_root(self):
        """
        Test that FileCheckpoints functions correctly even when it's
        using a different root dir from FileContentsManager.  This also keeps
        the implementation honest for use with ContentsManagers that don't map
        models to the filesystem

        Override this method to a no-op when testing other managers.
        """
        with TemporaryDirectory() as td:
            with self.patch_cp_root(td):
                self.test_checkpoints()

        with TemporaryDirectory() as td:
            with self.patch_cp_root(td):
                self.test_file_checkpoints()
Exemple #56
0
def getsource(obj, oname=''):
    """Wrapper around inspect.getsource.

    This can be modified by other projects to provide customized source
    extraction.

    Parameters
    ----------
    obj : object
        an object whose source code we will attempt to extract
    oname : str
        (optional) a name under which the object is known

    Returns
    -------
    src : unicode or None

    """

    if isinstance(obj, property):
        sources = []
        for attrname in ['fget', 'fset', 'fdel']:
            fn = getattr(obj, attrname)
            if fn is not None:
                encoding = get_encoding(fn)
                oname_prefix = ('%s.' % oname) if oname else ''
                sources.append(
                    cast_unicode(''.join(('# ', oname_prefix, attrname)),
                                 encoding=encoding))
                if inspect.isfunction(fn):
                    sources.append(dedent(getsource(fn)))
                else:
                    # Default str/repr only prints function name,
                    # pretty.pretty prints module name too.
                    sources.append(
                        cast_unicode('%s%s = %s\n' %
                                     (oname_prefix, attrname, pretty(fn)),
                                     encoding=encoding))
        if sources:
            return '\n'.join(sources)
        else:
            return None

    else:
        # Get source for non-property objects.

        obj = _get_wrapped(obj)

        try:
            src = inspect.getsource(obj)
        except TypeError:
            # The object itself provided no meaningful source, try looking for
            # its class definition instead.
            if hasattr(obj, '__class__'):
                try:
                    src = inspect.getsource(obj.__class__)
                except TypeError:
                    return None

        encoding = get_encoding(obj)
        return cast_unicode(src, encoding=encoding)
Exemple #57
0
 def _some_str(self, value):
     # Lifted from traceback.py
     try:
         return py3compat.cast_unicode(str(value))
     except:
         return u'<unprintable %s object>' % type(value).__name__
Exemple #58
0
 def write(self, text):
     return super(CUnicodeIO, self).write(
         cast_unicode(text, encoding=get_stream_enc(sys.stdout)))
Exemple #59
0
 def write(self, s):
     s = py3compat.cast_unicode(s, encoding=DEFAULT_ENCODING)
     super(MyStringIO, self).write(s)
Exemple #60
0
def new_output(output_type,
               output_text=None,
               output_png=None,
               output_html=None,
               output_svg=None,
               output_latex=None,
               output_json=None,
               output_javascript=None,
               output_jpeg=None,
               prompt_number=None,
               ename=None,
               evalue=None,
               traceback=None,
               stream=None,
               metadata=None):
    """Create a new output, to go in the ``cell.outputs`` list of a code cell.
    """
    output = NotebookNode()
    output.output_type = unicode_type(output_type)

    if metadata is None:
        metadata = {}
    if not isinstance(metadata, dict):
        raise TypeError("metadata must be dict")
    output.metadata = metadata

    if output_type != 'pyerr':
        if output_text is not None:
            output.text = cast_unicode(output_text)
        if output_png is not None:
            output.png = cast_unicode(output_png)
        if output_jpeg is not None:
            output.jpeg = cast_unicode(output_jpeg)
        if output_html is not None:
            output.html = cast_unicode(output_html)
        if output_svg is not None:
            output.svg = cast_unicode(output_svg)
        if output_latex is not None:
            output.latex = cast_unicode(output_latex)
        if output_json is not None:
            output.json = cast_unicode(output_json)
        if output_javascript is not None:
            output.javascript = cast_unicode(output_javascript)

    if output_type == u'pyout':
        if prompt_number is not None:
            output.prompt_number = int(prompt_number)

    if output_type == u'pyerr':
        if ename is not None:
            output.ename = cast_unicode(ename)
        if evalue is not None:
            output.evalue = cast_unicode(evalue)
        if traceback is not None:
            output.traceback = [
                cast_unicode(frame) for frame in list(traceback)
            ]

    if output_type == u'stream':
        output.stream = 'stdout' if stream is None else cast_unicode(stream)

    return output