def _append_custom(self, insert, input, before_prompt=False):
        """ A low-level method for appending content to the end of the buffer.

        If 'before_prompt' is enabled, the content will be inserted before the
        current prompt, if there is one.
        """
        # Determine where to insert the content.
        cursor = self._control.textCursor()
        if before_prompt and (self._reading or not self._executing):
            cursor.setPosition(self._append_before_prompt_pos)
        else:
            cursor.movePosition(QtGui.QTextCursor.End)
        start_pos = cursor.position()

        # Perform the insertion.
        result = insert(cursor, input)

        # Adjust the prompt position if we have inserted before it. This is safe
        # because buffer truncation is disabled when not executing.
        if before_prompt and not self._executing:
            diff = cursor.position() - start_pos
            self._append_before_prompt_pos += diff
            self._prompt_pos += diff

        return result

def _append_custom ( self , insert , input , before_prompt = False ) : cursor = self . _control . textCursor ( ) if before_prompt and ( self . _reading or not self . _executing ) : cursor . setPosition ( self . _append_before_prompt_pos ) else : cursor . movePosition ( QtGui . QTextCursor . End ) start_pos = cursor . position ( ) result = insert ( cursor , input ) if before_prompt and not self . _executing : diff = cursor . position ( ) - start_pos self . _append_before_prompt_pos += diff self . _prompt_pos += diff return result

A low - level method for appending content to the end of the buffer .


def _append_html(self, html, before_prompt=False):
        """ Appends HTML at the end of the console buffer.
        """
        self._append_custom(self._insert_html, html, before_prompt)

def _append_html ( self , html , before_prompt = False ) : self . _append_custom ( self . _insert_html , html , before_prompt )

Appends HTML at the end of the console buffer .


def _append_html_fetching_plain_text(self, html, before_prompt=False):
        """ Appends HTML, then returns the plain text version of it.
        """
        return self._append_custom(self._insert_html_fetching_plain_text,
                                   html, before_prompt)

def _append_html_fetching_plain_text ( self , html , before_prompt = False ) : return self . _append_custom ( self . _insert_html_fetching_plain_text , html , before_prompt )

Appends HTML then returns the plain text version of it .


def _append_plain_text(self, text, before_prompt=False):
        """ Appends plain text, processing ANSI codes if enabled.
        """
        self._append_custom(self._insert_plain_text, text, before_prompt)

def _append_plain_text ( self , text , before_prompt = False ) : self . _append_custom ( self . _insert_plain_text , text , before_prompt )

Appends plain text processing ANSI codes if enabled .


def _clear_temporary_buffer(self):
        """ Clears the "temporary text" buffer, i.e. all the text following
            the prompt region.
        """
        # Select and remove all text below the input buffer.
        cursor = self._get_prompt_cursor()
        prompt = self._continuation_prompt.lstrip()
        if(self._temp_buffer_filled):
            self._temp_buffer_filled = False
            while cursor.movePosition(QtGui.QTextCursor.NextBlock):
                temp_cursor = QtGui.QTextCursor(cursor)
                temp_cursor.select(QtGui.QTextCursor.BlockUnderCursor)
                text = temp_cursor.selection().toPlainText().lstrip()
                if not text.startswith(prompt):
                    break
        else:
            # We've reached the end of the input buffer and no text follows.
            return
        cursor.movePosition(QtGui.QTextCursor.Left) # Grab the newline.
        cursor.movePosition(QtGui.QTextCursor.End,
                            QtGui.QTextCursor.KeepAnchor)
        cursor.removeSelectedText()

        # After doing this, we have no choice but to clear the undo/redo
        # history. Otherwise, the text is not "temporary" at all, because it
        # can be recalled with undo/redo. Unfortunately, Qt does not expose
        # fine-grained control to the undo/redo system.
        if self._control.isUndoRedoEnabled():
            self._control.setUndoRedoEnabled(False)
            self._control.setUndoRedoEnabled(True)

def _clear_temporary_buffer ( self ) : cursor = self . _get_prompt_cursor ( ) prompt = self . _continuation_prompt . lstrip ( ) if ( self . _temp_buffer_filled ) : self . _temp_buffer_filled = False while cursor . movePosition ( QtGui . QTextCursor . NextBlock ) : temp_cursor = QtGui . QTextCursor ( cursor ) temp_cursor . select ( QtGui . QTextCursor . BlockUnderCursor ) text = temp_cursor . selection ( ) . toPlainText ( ) . lstrip ( ) if not text . startswith ( prompt ) : break else : return cursor . movePosition ( QtGui . QTextCursor . Left ) cursor . movePosition ( QtGui . QTextCursor . End , QtGui . QTextCursor . KeepAnchor ) cursor . removeSelectedText ( ) if self . _control . isUndoRedoEnabled ( ) : self . _control . setUndoRedoEnabled ( False ) self . _control . setUndoRedoEnabled ( True )

Clears the temporary text buffer i . e . all the text following the prompt region .


def _complete_with_items(self, cursor, items):
        """ Performs completion with 'items' at the specified cursor location.
        """
        self._cancel_completion()

        if len(items) == 1:
            cursor.setPosition(self._control.textCursor().position(),
                               QtGui.QTextCursor.KeepAnchor)
            cursor.insertText(items[0])

        elif len(items) > 1:
            current_pos = self._control.textCursor().position()
            prefix = commonprefix(items)
            if prefix:
                cursor.setPosition(current_pos, QtGui.QTextCursor.KeepAnchor)
                cursor.insertText(prefix)
                current_pos = cursor.position()

            cursor.movePosition(QtGui.QTextCursor.Left, n=len(prefix))
            self._completion_widget.show_items(cursor, items)

def _complete_with_items ( self , cursor , items ) : self . _cancel_completion ( ) if len ( items ) == 1 : cursor . setPosition ( self . _control . textCursor ( ) . position ( ) , QtGui . QTextCursor . KeepAnchor ) cursor . insertText ( items [ 0 ] ) elif len ( items ) > 1 : current_pos = self . _control . textCursor ( ) . position ( ) prefix = commonprefix ( items ) if prefix : cursor . setPosition ( current_pos , QtGui . QTextCursor . KeepAnchor ) cursor . insertText ( prefix ) current_pos = cursor . position ( ) cursor . movePosition ( QtGui . QTextCursor . Left , n = len ( prefix ) ) self . _completion_widget . show_items ( cursor , items )

Performs completion with items at the specified cursor location .


def _fill_temporary_buffer(self, cursor, text, html=False):
        """fill the area below the active editting zone with text"""

        current_pos = self._control.textCursor().position()

        cursor.beginEditBlock()
        self._append_plain_text('\n')
        self._page(text, html=html)
        cursor.endEditBlock()

        cursor.setPosition(current_pos)
        self._control.moveCursor(QtGui.QTextCursor.End)
        self._control.setTextCursor(cursor)

        self._temp_buffer_filled = True

def _fill_temporary_buffer ( self , cursor , text , html = False ) : current_pos = self . _control . textCursor ( ) . position ( ) cursor . beginEditBlock ( ) self . _append_plain_text ( '\n' ) self . _page ( text , html = html ) cursor . endEditBlock ( ) cursor . setPosition ( current_pos ) self . _control . moveCursor ( QtGui . QTextCursor . End ) self . _control . setTextCursor ( cursor ) self . _temp_buffer_filled = True


def _control_key_down(self, modifiers, include_command=False):
        """ Given a KeyboardModifiers flags object, return whether the Control
        key is down.

        Parameters:
        -----------
        include_command : bool, optional (default True)
            Whether to treat the Command key as a (mutually exclusive) synonym
            for Control when in Mac OS.
        """
        # Note that on Mac OS, ControlModifier corresponds to the Command key
        # while MetaModifier corresponds to the Control key.
        if sys.platform == 'darwin':
            down = include_command and (modifiers & QtCore.Qt.ControlModifier)
            return bool(down) ^ bool(modifiers & QtCore.Qt.MetaModifier)
        else:
            return bool(modifiers & QtCore.Qt.ControlModifier)

def _control_key_down ( self , modifiers , include_command = False ) : if sys . platform == 'darwin' : down = include_command and ( modifiers & QtCore . Qt . ControlModifier ) return bool ( down ) ^ bool ( modifiers & QtCore . Qt . MetaModifier ) else : return bool ( modifiers & QtCore . Qt . ControlModifier )

Given a KeyboardModifiers flags object return whether the Control key is down .


def _create_control(self):
        """ Creates and connects the underlying text widget.
        """
        # Create the underlying control.
        if self.custom_control:
            control = self.custom_control()
        elif self.kind == 'plain':
            control = QtGui.QPlainTextEdit()
        elif self.kind == 'rich':
            control = QtGui.QTextEdit()
            control.setAcceptRichText(False)

        # Install event filters. The filter on the viewport is needed for
        # mouse events and drag events.
        control.installEventFilter(self)
        control.viewport().installEventFilter(self)

        # Connect signals.
        control.customContextMenuRequested.connect(
            self._custom_context_menu_requested)
        control.copyAvailable.connect(self.copy_available)
        control.redoAvailable.connect(self.redo_available)
        control.undoAvailable.connect(self.undo_available)

        # Hijack the document size change signal to prevent Qt from adjusting
        # the viewport's scrollbar. We are relying on an implementation detail
        # of Q(Plain)TextEdit here, which is potentially dangerous, but without
        # this functionality we cannot create a nice terminal interface.
        layout = control.document().documentLayout()
        layout.documentSizeChanged.disconnect()
        layout.documentSizeChanged.connect(self._adjust_scrollbars)

        # Configure the control.
        control.setAttribute(QtCore.Qt.WA_InputMethodEnabled, True)
        control.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        control.setReadOnly(True)
        control.setUndoRedoEnabled(False)
        control.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
        return control

def _create_control ( self ) : if self . custom_control : control = self . custom_control ( ) elif self . kind == 'plain' : control = QtGui . QPlainTextEdit ( ) elif self . kind == 'rich' : control = QtGui . QTextEdit ( ) control . setAcceptRichText ( False ) control . installEventFilter ( self ) control . viewport ( ) . installEventFilter ( self ) control . customContextMenuRequested . connect ( self . _custom_context_menu_requested ) control . copyAvailable . connect ( self . copy_available ) control . redoAvailable . connect ( self . redo_available ) control . undoAvailable . connect ( self . undo_available ) layout = control . document ( ) . documentLayout ( ) layout . documentSizeChanged . disconnect ( ) layout . documentSizeChanged . connect ( self . _adjust_scrollbars ) control . setAttribute ( QtCore . Qt . WA_InputMethodEnabled , True ) control . setContextMenuPolicy ( QtCore . Qt . CustomContextMenu ) control . setReadOnly ( True ) control . setUndoRedoEnabled ( False ) control . setVerticalScrollBarPolicy ( QtCore . Qt . ScrollBarAlwaysOn ) return control

Creates and connects the underlying text widget .


def _create_page_control(self):
        """ Creates and connects the underlying paging widget.
        """
        if self.custom_page_control:
            control = self.custom_page_control()
        elif self.kind == 'plain':
            control = QtGui.QPlainTextEdit()
        elif self.kind == 'rich':
            control = QtGui.QTextEdit()
        control.installEventFilter(self)
        viewport = control.viewport()
        viewport.installEventFilter(self)
        control.setReadOnly(True)
        control.setUndoRedoEnabled(False)
        control.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
        return control

def _create_page_control ( self ) : if self . custom_page_control : control = self . custom_page_control ( ) elif self . kind == 'plain' : control = QtGui . QPlainTextEdit ( ) elif self . kind == 'rich' : control = QtGui . QTextEdit ( ) control . installEventFilter ( self ) viewport = control . viewport ( ) viewport . installEventFilter ( self ) control . setReadOnly ( True ) control . setUndoRedoEnabled ( False ) control . setVerticalScrollBarPolicy ( QtCore . Qt . ScrollBarAlwaysOn ) return control

Creates and connects the underlying paging widget .


def _event_filter_page_keypress(self, event):
        """ Filter key events for the paging widget to create console-like
            interface.
        """
        key = event.key()
        ctrl_down = self._control_key_down(event.modifiers())
        alt_down = event.modifiers() & QtCore.Qt.AltModifier

        if ctrl_down:
            if key == QtCore.Qt.Key_O:
                self._control.setFocus()
                intercept = True

        elif alt_down:
            if key == QtCore.Qt.Key_Greater:
                self._page_control.moveCursor(QtGui.QTextCursor.End)
                intercepted = True

            elif key == QtCore.Qt.Key_Less:
                self._page_control.moveCursor(QtGui.QTextCursor.Start)
                intercepted = True

        elif key in (QtCore.Qt.Key_Q, QtCore.Qt.Key_Escape):
            if self._splitter:
                self._page_control.hide()
                self._control.setFocus()
            else:
                self.layout().setCurrentWidget(self._control)
            return True

        elif key in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return,
                     QtCore.Qt.Key_Tab):
            new_event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress,
                                        QtCore.Qt.Key_PageDown,
                                        QtCore.Qt.NoModifier)
            QtGui.qApp.sendEvent(self._page_control, new_event)
            return True

        elif key == QtCore.Qt.Key_Backspace:
            new_event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress,
                                        QtCore.Qt.Key_PageUp,
                                        QtCore.Qt.NoModifier)
            QtGui.qApp.sendEvent(self._page_control, new_event)
            return True

        return False

def _event_filter_page_keypress ( self , event ) : key = event . key ( ) ctrl_down = self . _control_key_down ( event . modifiers ( ) ) alt_down = event . modifiers ( ) & QtCore . Qt . AltModifier if ctrl_down : if key == QtCore . Qt . Key_O : self . _control . setFocus ( ) intercept = True elif alt_down : if key == QtCore . Qt . Key_Greater : self . _page_control . moveCursor ( QtGui . QTextCursor . End ) intercepted = True elif key == QtCore . Qt . Key_Less : self . _page_control . moveCursor ( QtGui . QTextCursor . Start ) intercepted = True elif key in ( QtCore . Qt . Key_Q , QtCore . Qt . Key_Escape ) : if self . _splitter : self . _page_control . hide ( ) self . _control . setFocus ( ) else : self . layout ( ) . setCurrentWidget ( self . _control ) return True elif key in ( QtCore . Qt . Key_Enter , QtCore . Qt . Key_Return , QtCore . Qt . Key_Tab ) : new_event = QtGui . QKeyEvent ( QtCore . QEvent . KeyPress , QtCore . Qt . Key_PageDown , QtCore . Qt . NoModifier ) QtGui . qApp . sendEvent ( self . _page_control , new_event ) return True elif key == QtCore . Qt . Key_Backspace : new_event = QtGui . QKeyEvent ( QtCore . QEvent . KeyPress , QtCore . Qt . Key_PageUp , QtCore . Qt . NoModifier ) QtGui . qApp . sendEvent ( self . _page_control , new_event ) return True return False

Filter key events for the paging widget to create console - like interface .


def _get_block_plain_text(self, block):
        """ Given a QTextBlock, return its unformatted text.
        """
        cursor = QtGui.QTextCursor(block)
        cursor.movePosition(QtGui.QTextCursor.StartOfBlock)
        cursor.movePosition(QtGui.QTextCursor.EndOfBlock,
                            QtGui.QTextCursor.KeepAnchor)
        return cursor.selection().toPlainText()

def _get_block_plain_text ( self , block ) : cursor = QtGui . QTextCursor ( block ) cursor . movePosition ( QtGui . QTextCursor . StartOfBlock ) cursor . movePosition ( QtGui . QTextCursor . EndOfBlock , QtGui . QTextCursor . KeepAnchor ) return cursor . selection ( ) . toPlainText ( )

Given a QTextBlock return its unformatted text .


def _get_end_cursor(self):
        """ Convenience method that returns a cursor for the last character.
        """
        cursor = self._control.textCursor()
        cursor.movePosition(QtGui.QTextCursor.End)
        return cursor

def _get_end_cursor ( self ) : cursor = self . _control . textCursor ( ) cursor . movePosition ( QtGui . QTextCursor . End ) return cursor

Convenience method that returns a cursor for the last character .


def _get_input_buffer_cursor_column(self):
        """ Returns the column of the cursor in the input buffer, excluding the
            contribution by the prompt, or -1 if there is no such column.
        """
        prompt = self._get_input_buffer_cursor_prompt()
        if prompt is None:
            return -1
        else:
            cursor = self._control.textCursor()
            return cursor.columnNumber() - len(prompt)

def _get_input_buffer_cursor_column ( self ) : prompt = self . _get_input_buffer_cursor_prompt ( ) if prompt is None : return - 1 else : cursor = self . _control . textCursor ( ) return cursor . columnNumber ( ) - len ( prompt )

Returns the column of the cursor in the input buffer excluding the contribution by the prompt or - 1 if there is no such column .


def _get_input_buffer_cursor_line(self):
        """ Returns the text of the line of the input buffer that contains the
            cursor, or None if there is no such line.
        """
        prompt = self._get_input_buffer_cursor_prompt()
        if prompt is None:
            return None
        else:
            cursor = self._control.textCursor()
            text = self._get_block_plain_text(cursor.block())
            return text[len(prompt):]

def _get_input_buffer_cursor_line ( self ) : prompt = self . _get_input_buffer_cursor_prompt ( ) if prompt is None : return None else : cursor = self . _control . textCursor ( ) text = self . _get_block_plain_text ( cursor . block ( ) ) return text [ len ( prompt ) : ]

Returns the text of the line of the input buffer that contains the cursor or None if there is no such line .


def _get_prompt_cursor(self):
        """ Convenience method that returns a cursor for the prompt position.
        """
        cursor = self._control.textCursor()
        cursor.setPosition(self._prompt_pos)
        return cursor

def _get_prompt_cursor ( self ) : cursor = self . _control . textCursor ( ) cursor . setPosition ( self . _prompt_pos ) return cursor

Convenience method that returns a cursor for the prompt position .


def _get_selection_cursor(self, start, end):
        """ Convenience method that returns a cursor with text selected between
            the positions 'start' and 'end'.
        """
        cursor = self._control.textCursor()
        cursor.setPosition(start)
        cursor.setPosition(end, QtGui.QTextCursor.KeepAnchor)
        return cursor

def _get_selection_cursor ( self , start , end ) : cursor = self . _control . textCursor ( ) cursor . setPosition ( start ) cursor . setPosition ( end , QtGui . QTextCursor . KeepAnchor ) return cursor

Convenience method that returns a cursor with text selected between the positions start and end .


def _insert_continuation_prompt(self, cursor):
        """ Inserts new continuation prompt using the specified cursor.
        """
        if self._continuation_prompt_html is None:
            self._insert_plain_text(cursor, self._continuation_prompt)
        else:
            self._continuation_prompt = self._insert_html_fetching_plain_text(
                cursor, self._continuation_prompt_html)

def _insert_continuation_prompt ( self , cursor ) : if self . _continuation_prompt_html is None : self . _insert_plain_text ( cursor , self . _continuation_prompt ) else : self . _continuation_prompt = self . _insert_html_fetching_plain_text ( cursor , self . _continuation_prompt_html )

Inserts new continuation prompt using the specified cursor .


def _insert_html(self, cursor, html):
        """ Inserts HTML using the specified cursor in such a way that future
            formatting is unaffected.
        """
        cursor.beginEditBlock()
        cursor.insertHtml(html)

        # After inserting HTML, the text document "remembers" it's in "html
        # mode", which means that subsequent calls adding plain text will result
        # in unwanted formatting, lost tab characters, etc. The following code
        # hacks around this behavior, which I consider to be a bug in Qt, by
        # (crudely) resetting the document's style state.
        cursor.movePosition(QtGui.QTextCursor.Left,
                            QtGui.QTextCursor.KeepAnchor)
        if cursor.selection().toPlainText() == ' ':
            cursor.removeSelectedText()
        else:
            cursor.movePosition(QtGui.QTextCursor.Right)
        cursor.insertText(' ', QtGui.QTextCharFormat())
        cursor.endEditBlock()

def
_insert_html
(
self
,
cursor
,
html
)
:
cursor
.
beginEditBlock
(
)
cursor
.
insertHtml
(
html
)
cursor
.
movePosition
(
QtGui
.
QTextCursor
.
Left
,
QtGui
.
QTextCursor
.
KeepAnchor
)
if
cursor
.
selection
(
)
.
toPlainText
(
)
==
' '
:
cursor
.
removeSelectedText
(
)
else
:
cursor
.
movePosition
(
QtGui
.
QTextCursor
.
Right
)
cursor
.
insertText
(
' '
,
QtGui
.
QTextCharFormat
(
)
)
cursor
.
endEditBlock
(
)

Inserts HTML using the specified cursor in such a way that future formatting is unaffected .


def _insert_html_fetching_plain_text(self, cursor, html):
        """ Inserts HTML using the specified cursor, then returns its plain text
            version.
        """
        cursor.beginEditBlock()
        cursor.removeSelectedText()

        start = cursor.position()
        self._insert_html(cursor, html)
        end = cursor.position()
        cursor.setPosition(start, QtGui.QTextCursor.KeepAnchor)
        text = cursor.selection().toPlainText()

        cursor.setPosition(end)
        cursor.endEditBlock()
        return text

def _insert_html_fetching_plain_text ( self , cursor , html ) : cursor . beginEditBlock ( ) cursor . removeSelectedText ( ) start = cursor . position ( ) self . _insert_html ( cursor , html ) end = cursor . position ( ) cursor . setPosition ( start , QtGui . QTextCursor . KeepAnchor ) text = cursor . selection ( ) . toPlainText ( ) cursor . setPosition ( end ) cursor . endEditBlock ( ) return text

Inserts HTML using the specified cursor then returns its plain text version .


def _insert_plain_text(self, cursor, text):
        """ Inserts plain text using the specified cursor, processing ANSI codes
            if enabled.
        """
        cursor.beginEditBlock()
        if self.ansi_codes:
            for substring in self._ansi_processor.split_string(text):
                for act in self._ansi_processor.actions:

                    # Unlike real terminal emulators, we don't distinguish
                    # between the screen and the scrollback buffer. A screen
                    # erase request clears everything.
                    if act.action == 'erase' and act.area == 'screen':
                        cursor.select(QtGui.QTextCursor.Document)
                        cursor.removeSelectedText()

                    # Simulate a form feed by scrolling just past the last line.
                    elif act.action == 'scroll' and act.unit == 'page':
                        cursor.insertText('\n')
                        cursor.endEditBlock()
                        self._set_top_cursor(cursor)
                        cursor.joinPreviousEditBlock()
                        cursor.deletePreviousChar()

                    elif act.action == 'carriage-return':
                        cursor.movePosition(
                            cursor.StartOfLine, cursor.KeepAnchor)

                    elif act.action == 'beep':
                        QtGui.qApp.beep()

                    elif act.action == 'backspace':
                        if not cursor.atBlockStart():
                            cursor.movePosition(
                                cursor.PreviousCharacter, cursor.KeepAnchor)

                    elif act.action == 'newline':
                        cursor.movePosition(cursor.EndOfLine)

                format = self._ansi_processor.get_format()

                selection = cursor.selectedText()
                if len(selection) == 0:
                    cursor.insertText(substring, format)
                elif substring is not None:
                    # BS and CR are treated as a change in print
                    # position, rather than a backwards character
                    # deletion for output equivalence with (I)Python
                    # terminal.
                    if len(substring) >= len(selection):
                        cursor.insertText(substring, format)
                    else:
                        old_text = selection[len(substring):]
                        cursor.insertText(substring + old_text, format)
                        cursor.movePosition(cursor.PreviousCharacter,
                               cursor.KeepAnchor, len(old_text))
        else:
            cursor.insertText(text)
        cursor.endEditBlock()

def _insert_plain_text ( self , cursor , text ) : cursor . beginEditBlock ( ) if self . ansi_codes : for substring in self . _ansi_processor . split_string ( text ) : for act in self . _ansi_processor . actions : if act . action == 'erase' and act . area == 'screen' : cursor . select ( QtGui . QTextCursor . Document ) cursor . removeSelectedText ( ) elif act . action == 'scroll' and act . unit == 'page' : cursor . insertText ( '\n' ) cursor . endEditBlock ( ) self . _set_top_cursor ( cursor ) cursor . joinPreviousEditBlock ( ) cursor . deletePreviousChar ( ) elif act . action == 'carriage-return' : cursor . movePosition ( cursor . StartOfLine , cursor . KeepAnchor ) elif act . action == 'beep' : QtGui . qApp . beep ( ) elif act . action == 'backspace' : if not cursor . atBlockStart ( ) : cursor . movePosition ( cursor . PreviousCharacter , cursor . KeepAnchor ) elif act . action == 'newline' : cursor . movePosition ( cursor . EndOfLine ) format = self . _ansi_processor . get_format ( ) selection = cursor . selectedText ( ) if len ( selection ) == 0 : cursor . insertText ( substring , format ) elif substring is not None : if len ( substring ) >= len ( selection ) : cursor . insertText ( substring , format ) else : old_text = selection [ len ( substring ) : ] cursor . insertText ( substring + old_text , format ) cursor . movePosition ( cursor . PreviousCharacter , cursor . KeepAnchor , len ( old_text ) ) else : cursor . insertText ( text ) cursor . endEditBlock ( )

Inserts plain text using the specified cursor processing ANSI codes if enabled .


def _keep_cursor_in_buffer(self):
        """ Ensures that the cursor is inside the editing region. Returns
            whether the cursor was moved.
        """
        moved = not self._in_buffer()
        if moved:
            cursor = self._control.textCursor()
            cursor.movePosition(QtGui.QTextCursor.End)
            self._control.setTextCursor(cursor)
        return moved

def _keep_cursor_in_buffer ( self ) : moved = not self . _in_buffer ( ) if moved : cursor = self . _control . textCursor ( ) cursor . movePosition ( QtGui . QTextCursor . End ) self . _control . setTextCursor ( cursor ) return moved

Ensures that the cursor is inside the editing region . Returns whether the cursor was moved .


def _keyboard_quit(self):
        """ Cancels the current editing task ala Ctrl-G in Emacs.
        """
        if self._temp_buffer_filled :
            self._cancel_completion()
            self._clear_temporary_buffer()
        else:
            self.input_buffer = ''

def _keyboard_quit ( self ) : if self . _temp_buffer_filled : self . _cancel_completion ( ) self . _clear_temporary_buffer ( ) else : self . input_buffer = ''

Cancels the current editing task ala Ctrl - G in Emacs .


def _page(self, text, html=False):
        """ Displays text using the pager if it exceeds the height of the
        viewport.

        Parameters:
        -----------
        html : bool, optional (default False)
            If set, the text will be interpreted as HTML instead of plain text.
        """
        line_height = QtGui.QFontMetrics(self.font).height()
        minlines = self._control.viewport().height() / line_height
        if self.paging != 'none' and \
                re.match("(?:[^\n]*\n){%i}" % minlines, text):
            if self.paging == 'custom':
                self.custom_page_requested.emit(text)
            else:
                self._page_control.clear()
                cursor = self._page_control.textCursor()
                if html:
                    self._insert_html(cursor, text)
                else:
                    self._insert_plain_text(cursor, text)
                self._page_control.moveCursor(QtGui.QTextCursor.Start)

                self._page_control.viewport().resize(self._control.size())
                if self._splitter:
                    self._page_control.show()
                    self._page_control.setFocus()
                else:
                    self.layout().setCurrentWidget(self._page_control)
        elif html:
            self._append_html(text)
        else:
            self._append_plain_text(text)

def _page ( self , text , html = False ) : line_height = QtGui . QFontMetrics ( self . font ) . height ( ) minlines = self . _control . viewport ( ) . height ( ) / line_height if self . paging != 'none' and re . match ( "(?:[^\n]*\n){%i}" % minlines , text ) : if self . paging == 'custom' : self . custom_page_requested . emit ( text ) else : self . _page_control . clear ( ) cursor = self . _page_control . textCursor ( ) if html : self . _insert_html ( cursor , text ) else : self . _insert_plain_text ( cursor , text ) self . _page_control . moveCursor ( QtGui . QTextCursor . Start ) self . _page_control . viewport ( ) . resize ( self . _control . size ( ) ) if self . _splitter : self . _page_control . show ( ) self . _page_control . setFocus ( ) else : self . layout ( ) . setCurrentWidget ( self . _page_control ) elif html : self . _append_html ( text ) else : self . _append_plain_text ( text )

Displays text using the pager if it exceeds the height of the viewport .


def _prompt_started(self):
        """ Called immediately after a new prompt is displayed.
        """
        # Temporarily disable the maximum block count to permit undo/redo and
        # to ensure that the prompt position does not change due to truncation.
        self._control.document().setMaximumBlockCount(0)
        self._control.setUndoRedoEnabled(True)

        # Work around bug in QPlainTextEdit: input method is not re-enabled
        # when read-only is disabled.
        self._control.setReadOnly(False)
        self._control.setAttribute(QtCore.Qt.WA_InputMethodEnabled, True)

        if not self._reading:
            self._executing = False
        self._prompt_started_hook()

        # If the input buffer has changed while executing, load it.
        if self._input_buffer_pending:
            self.input_buffer = self._input_buffer_pending
            self._input_buffer_pending = ''

        self._control.moveCursor(QtGui.QTextCursor.End)

def _prompt_started ( self ) : self . _control . document ( ) . setMaximumBlockCount ( 0 ) self . _control . setUndoRedoEnabled ( True ) self . _control . setReadOnly ( False ) self . _control . setAttribute ( QtCore . Qt . WA_InputMethodEnabled , True ) if not self . _reading : self . _executing = False self . _prompt_started_hook ( ) if self . _input_buffer_pending : self . input_buffer = self . _input_buffer_pending self . _input_buffer_pending = '' self . _control . moveCursor ( QtGui . QTextCursor . End )

Called immediately after a new prompt is displayed .


def _readline(self, prompt='', callback=None):
        """ Reads one line of input from the user.

        Parameters
        ----------
        prompt : str, optional
            The prompt to print before reading the line.

        callback : callable, optional
            A callback to execute with the read line. If not specified, input is
            read *synchronously* and this method does not return until it has
            been read.

        Returns
        -------
        If a callback is specified, returns nothing. Otherwise, returns the
        input string with the trailing newline stripped.
        """
        if self._reading:
            raise RuntimeError('Cannot read a line. Widget is already reading.')

        if not callback and not self.isVisible():
            # If the user cannot see the widget, this function cannot return.
            raise RuntimeError('Cannot synchronously read a line if the widget '
                               'is not visible!')

        self._reading = True
        self._show_prompt(prompt, newline=False)

        if callback is None:
            self._reading_callback = None
            while self._reading:
                QtCore.QCoreApplication.processEvents()
            return self._get_input_buffer(force=True).rstrip('\n')

        else:
            self._reading_callback = lambda: \
                callback(self._get_input_buffer(force=True).rstrip('\n'))


def _set_continuation_prompt(self, prompt, html=False):
        """ Sets the continuation prompt.

        Parameters
        ----------
        prompt : str
            The prompt to show when more input is needed.

        html : bool, optional (default False)
            If set, the prompt will be inserted as formatted HTML. Otherwise,
            the prompt will be treated as plain text, though ANSI color codes
            will be handled.
        """
        if html:
            self._continuation_prompt_html = prompt
        else:
            self._continuation_prompt = prompt
            self._continuation_prompt_html = None

def _set_continuation_prompt ( self , prompt , html = False ) : if html : self . _continuation_prompt_html = prompt else : self . _continuation_prompt = prompt self . _continuation_prompt_html = None


def _set_top_cursor(self, cursor):
        """ Scrolls the viewport so that the specified cursor is at the top.
        """
        scrollbar = self._control.verticalScrollBar()
        scrollbar.setValue(scrollbar.maximum())
        original_cursor = self._control.textCursor()
        self._control.setTextCursor(cursor)
        self._control.ensureCursorVisible()
        self._control.setTextCursor(original_cursor)

def _set_top_cursor ( self , cursor ) : scrollbar = self . _control . verticalScrollBar ( ) scrollbar . setValue ( scrollbar . maximum ( ) ) original_cursor = self . _control . textCursor ( ) self . _control . setTextCursor ( cursor ) self . _control . ensureCursorVisible ( ) self . _control . setTextCursor ( original_cursor )

Scrolls the viewport so that the specified cursor is at the top .


def _show_prompt(self, prompt=None, html=False, newline=True):
        """ Writes a new prompt at the end of the buffer.

        Parameters
        ----------
        prompt : str, optional
            The prompt to show. If not specified, the previous prompt is used.

        html : bool, optional (default False)
            Only relevant when a prompt is specified. If set, the prompt will
            be inserted as formatted HTML. Otherwise, the prompt will be treated
            as plain text, though ANSI color codes will be handled.

        newline : bool, optional (default True)
            If set, a new line will be written before showing the prompt if
            there is not already a newline at the end of the buffer.
        """
        # Save the current end position to support _append*(before_prompt=True).
        cursor = self._get_end_cursor()
        self._append_before_prompt_pos = cursor.position()

        # Insert a preliminary newline, if necessary.
        if newline and cursor.position() > 0:
            cursor.movePosition(QtGui.QTextCursor.Left,
                                QtGui.QTextCursor.KeepAnchor)
            if cursor.selection().toPlainText() != '\n':
                self._append_plain_text('\n')

        # Write the prompt.
        self._append_plain_text(self._prompt_sep)
        if prompt is None:
            if self._prompt_html is None:
                self._append_plain_text(self._prompt)
            else:
                self._append_html(self._prompt_html)
        else:
            if html:
                self._prompt = self._append_html_fetching_plain_text(prompt)
                self._prompt_html = prompt
            else:
                self._append_plain_text(prompt)
                self._prompt = prompt
                self._prompt_html = None

        self._prompt_pos = self._get_end_cursor().position()
        self._prompt_started()

def _show_prompt ( self , prompt = None , html = False , newline = True ) : cursor = self . _get_end_cursor ( ) self . _append_before_prompt_pos = cursor . position ( ) if newline and cursor . position ( ) > 0 : cursor . movePosition ( QtGui . QTextCursor . Left , QtGui . QTextCursor . KeepAnchor ) if cursor . selection ( ) . toPlainText ( ) != '\n' : self . _append_plain_text ( '\n' ) self . _append_plain_text ( self . _prompt_sep ) if prompt is None : if self . _prompt_html is None : self . _append_plain_text ( self . _prompt ) else : self . _append_html ( self . _prompt_html ) else : if html : self . _prompt = self . _append_html_fetching_plain_text ( prompt ) self . _prompt_html = prompt else : self . _append_plain_text ( prompt ) self . _prompt = prompt self . _prompt_html = None self . _prompt_pos = self . _get_end_cursor ( ) . position ( ) self . _prompt_started ( )

Writes a new prompt at the end of the buffer .


def _adjust_scrollbars(self):
        """ Expands the vertical scrollbar beyond the range set by Qt.
        """
        # This code is adapted from _q_adjustScrollbars in qplaintextedit.cpp
        # and qtextedit.cpp.
        document = self._control.document()
        scrollbar = self._control.verticalScrollBar()
        viewport_height = self._control.viewport().height()
        if isinstance(self._control, QtGui.QPlainTextEdit):
            maximum = max(0, document.lineCount() - 1)
            step = viewport_height / self._control.fontMetrics().lineSpacing()
        else:
            # QTextEdit does not do line-based layout and blocks will not in
            # general have the same height. Therefore it does not make sense to
            # attempt to scroll in line height increments.
            maximum = document.size().height()
            step = viewport_height
        diff = maximum - scrollbar.maximum()
        scrollbar.setRange(0, maximum)
        scrollbar.setPageStep(step)

        # Compensate for undesirable scrolling that occurs automatically due to
        # maximumBlockCount() text truncation.
        if diff < 0 and document.blockCount() == document.maximumBlockCount():
            scrollbar.setValue(scrollbar.value() + diff)

def _adjust_scrollbars ( self ) : document = self . _control . document ( ) scrollbar = self . _control . verticalScrollBar ( ) viewport_height = self . _control . viewport ( ) . height ( ) if isinstance ( self . _control , QtGui . QPlainTextEdit ) : maximum = max ( 0 , document . lineCount ( ) - 1 ) step = viewport_height / self . _control . fontMetrics ( ) . lineSpacing ( ) else : maximum = document . size ( ) . height ( ) step = viewport_height diff = maximum - scrollbar . maximum ( ) scrollbar . setRange ( 0 , maximum ) scrollbar . setPageStep ( step ) if diff < 0 and document . blockCount ( ) == document . maximumBlockCount ( ) : scrollbar . setValue ( scrollbar . value ( ) + diff )

Expands the vertical scrollbar beyond the range set by Qt .


def main(args=None):
    """Entry point for pkginfo tool
    """
    options, paths = _parse_options(args)
    format = getattr(options, 'output', 'simple')
    formatter = _FORMATTERS[format](options)

    for path in paths:
        meta = get_metadata(path, options.metadata_version)
        if meta is None:
            continue

        if options.download_url_prefix:
            if meta.download_url is None:
                filename = os.path.basename(path)
                meta.download_url = '%s/%s' % (options.download_url_prefix,
                                               filename)

        formatter(meta)

    formatter.finish()

def main ( args = None ) : options , paths = _parse_options ( args ) format = getattr ( options , 'output' , 'simple' ) formatter = _FORMATTERS [ format ] ( options ) for path in paths : meta = get_metadata ( path , options . metadata_version ) if meta is None : continue if options . download_url_prefix : if meta . download_url is None : filename = os . path . basename ( path ) meta . download_url = '%s/%s' % ( options . download_url_prefix , filename ) formatter ( meta ) formatter . finish ( )


def copy_config_file(self, config_file, path=None, overwrite=False):
        """Copy a default config file into the active profile directory.

        Default configuration files are kept in :mod:`IPython.config.default`.
        This function moves these from that location to the working profile
        directory.
        """
        dst = os.path.join(self.location, config_file)
        if os.path.isfile(dst) and not overwrite:
            return False
        if path is None:
            path = os.path.join(get_ipython_package_dir(), u'config', u'profile', u'default')
        src = os.path.join(path, config_file)
        shutil.copy(src, dst)
        return True

def copy_config_file ( self , config_file , path = None , overwrite = False ) : dst = os . path . join ( self . location , config_file ) if os . path . isfile ( dst ) and not overwrite : return False if path is None : path = os . path . join ( get_ipython_package_dir ( ) , u'config' , u'profile' , u'default' ) src = os . path . join ( path , config_file ) shutil . copy ( src , dst ) return True

Copy a default config file into the active profile directory .


def create_profile_dir_by_name(cls, path, name=u'default', config=None):
        """Create a profile dir by profile name and path.

        Parameters
        ----------
        path : unicode
            The path (directory) to put the profile directory in.
        name : unicode
            The name of the profile.  The name of the profile directory will
            be "profile_<profile>".
        """
        if not os.path.isdir(path):
            raise ProfileDirError('Directory not found: %s' % path)
        profile_dir = os.path.join(path, u'profile_' + name)
        return cls(location=profile_dir, config=config)

def
create_profile_dir_by_name
(
cls
,
path
,
name
=
u'default'
,
config
=
)
:
if
not
os
.
path
.
isdir
(
path
)
:
raise
ProfileDirError
(
'Directory not found: %s'
%
path
)
profile_dir
=
os
.
path
.
join
(
path
,
u'profile_'
+
name
)
return
cls
(
location
=
profile_dir
,
config
=
config
)

Create a profile dir by profile name and path .


def find_profile_dir_by_name(cls, ipython_dir, name=u'default', config=None):
        """Find an existing profile dir by profile name, return its ProfileDir.

        This searches through a sequence of paths for a profile dir.  If it
        is not found, a :class:`ProfileDirError` exception will be raised.

        The search path algorithm is:
        1. ``os.getcwdu()``
        2. ``ipython_dir``

        Parameters
        ----------
        ipython_dir : unicode or str
            The IPython directory to use.
        name : unicode or str
            The name of the profile.  The name of the profile directory
            will be "profile_<profile>".
        """
        dirname = u'profile_' + name
        paths = [os.getcwdu(), ipython_dir]
        for p in paths:
            profile_dir = os.path.join(p, dirname)
            if os.path.isdir(profile_dir):
                return cls(location=profile_dir, config=config)
        else:
            raise ProfileDirError('Profile directory not found in paths: %s' % dirname)

Find an existing profile dir by profile name return its ProfileDir .


def cmp_to_key(mycmp):
    'Convert a cmp= function into a key= function'
    class Key(object):
        def __init__(self, obj):
            self.obj = obj
        def __lt__(self, other):
            return mycmp(self.obj, other.obj) < 0
        def __gt__(self, other):
            return mycmp(self.obj, other.obj) > 0
        def __eq__(self, other):
            return mycmp(self.obj, other.obj) == 0
    return Key

Convert a cmp = function into a key = function


def file_read(filename):
    """Read a file and close it.  Returns the file source."""
    fobj = open(filename,'r');
    source = fobj.read();
    fobj.close()
    return source

def file_read ( filename ) : fobj = open ( filename , 'r' ) source = fobj . read ( ) fobj . close ( ) return source

Read a file and close it . Returns the file source .


def raw_input_multi(header='', ps1='==> ', ps2='..> ',terminate_str = '.'):
    """Take multiple lines of input.

    A list with each line of input as a separate element is returned when a
    termination string is entered (defaults to a single '.'). Input can also
    terminate via EOF (^D in Unix, ^Z-RET in Windows).

    Lines of input which end in \\ are joined into single entries (and a
    secondary continuation prompt is issued as long as the user terminates
    lines with \\). This allows entering very long strings which are still
    meant to be treated as single entities.
    """

    try:
        if header:
            header += '\n'
        lines = [raw_input(header + ps1)]
    except EOFError:
        return []
    terminate = [terminate_str]
    try:
        while lines[-1:] != terminate:
            new_line = raw_input(ps1)
            while new_line.endswith('\\'):
                new_line = new_line[:-1] + raw_input(ps2)
            lines.append(new_line)

        return lines[:-1]  # don't return the termination command
    except EOFError:
        print()
        return lines

def
raw_input_multi
(
header
=
''
,
ps1
=
'==> '
,
ps2
=
'..> '
,
terminate_str
=
'.'
)
:
try
:
if
header
:
header
+=
'\n'
lines
=
[
raw_input
(
header
+
ps1
)
]
except
EOFError
:
return
[
]
terminate
=
[
terminate_str
]
try
:
while
lines
[
1
:
]
!=
terminate
:
new_line
=
raw_input
(
ps1
)
while
new_line
.
endswith
(
'\\'
)
:
new_line
=
new_line
[
:
1
]
+
raw_input
(
ps2
)
lines
.
append
(
new_line
)
return
lines
[
:
1
]
except
EOFError
:
print
(
)
return
lines


def temp_pyfile(src, ext='.py'):
    """Make a temporary python file, return filename and filehandle.

    Parameters
    ----------
    src : string or list of strings (no need for ending newlines if list)
      Source code to be written to the file.

    ext : optional, string
      Extension for the generated file.

    Returns
    -------
    (filename, open filehandle)
      It is the caller's responsibility to close the open file and unlink it.
    """
    fname = tempfile.mkstemp(ext)[1]
    f = open(fname,'w')
    f.write(src)
    f.flush()
    return fname, f

def temp_pyfile ( src , ext = '.py' ) : fname = tempfile . mkstemp ( ext ) [ 1 ] f = open ( fname , 'w' ) f . write ( src ) f . flush ( ) return fname , f

Make a temporary python file return filename and filehandle .


def close(self):
        """Close the file and restore the channel."""
        self.flush()
        setattr(sys, self.channel, self.ostream)
        self.file.close()
        self._closed = True

def close ( self ) : self . flush ( ) setattr ( sys , self . channel , self . ostream ) self . file . close ( ) self . _closed = True

Close the file and restore the channel .


def write(self, data):
        """Write data to both channels."""
        self.file.write(data)
        self.ostream.write(data)
        self.ostream.flush()

def write ( self , data ) : self . file . write ( data ) self . ostream . write ( data ) self . ostream . flush ( )


def add_new_heart_handler(self, handler):
        """add a new handler for new hearts"""
        self.log.debug("heartbeat::new_heart_handler: %s", handler)
        self._new_handlers.add(handler)

def
add_new_heart_handler
(
self
,
handler
)
:
self
.
log
.
debug
(
"heartbeat::new_heart_handler: %s"
,
handler
)
self
.
_new_handlers
.
add
(
handler
)


def add_heart_failure_handler(self, handler):
        """add a new handler for heart failure"""
        self.log.debug("heartbeat::new heart failure handler: %s", handler)
        self._failure_handlers.add(handler)


def handle_pong(self, msg):
        "a heart just beat"
        current = str_to_bytes(str(self.lifetime))
        last = str_to_bytes(str(self.last_ping))
        if msg[1] == current:
            delta = time.time()-self.tic
            # self.log.debug("heartbeat::heart %r took %.2f ms to respond"%(msg[0], 1000*delta))
            self.responses.add(msg[0])
        elif msg[1] == last:
            delta = time.time()-self.tic + (self.lifetime-self.last_ping)
            self.log.warn("heartbeat::heart %r missed a beat, and took %.2f ms to respond", msg[0], 1000*delta)
            self.responses.add(msg[0])
        else:
            self.log.warn("heartbeat::got bad heartbeat (possibly old?): %s (current=%.3f)", msg[1], self.lifetime)


def batch_list(sequence, batch_size, mod = 0, randomize = False):
    '''
    Converts a list into a list of lists with equal batch_size.

    Parameters
    ----------
    sequence : list
        list of items to be placed in batches
    batch_size : int
        length of each sub list
    mod : int
        remainder of list length devided by batch_size
        mod = len(sequence) % batch_size
    randomize = bool
        should the initial sequence be randomized before being batched

    '''

    if randomize:
        sequence = random.sample(sequence, len(sequence))

    return [sequence[x:x + batch_size] for x in xrange(0, len(sequence)-mod, batch_size)]

def batch_list ( sequence , batch_size , mod = 0 , randomize = False ) : if randomize : sequence = random . sample ( sequence , len ( sequence ) ) return [ sequence [ x : x + batch_size ] for x in xrange ( 0 , len ( sequence ) - mod , batch_size ) ]

Converts a list into a list of lists with equal batch_size .


def path_to_filename(pathfile):
    '''
    Takes a path filename string and returns the split between the path and the filename

    if filename is not given, filename = ''
    if path is not given, path = './'

    '''

    path = pathfile[:pathfile.rfind('/') + 1]
    if path == '':
        path = './'

    filename = pathfile[pathfile.rfind('/') + 1:len(pathfile)]
    if '.' not in filename:
        path = pathfile
        filename = ''

    if (filename == '') and (path[len(path) - 1] != '/'):
        path += '/'

    return path, filename

def path_to_filename ( pathfile ) : path = pathfile [ : pathfile . rfind ( '/' ) + 1 ] if path == '' : path = './' filename = pathfile [ pathfile . rfind ( '/' ) + 1 : len ( pathfile ) ] if '.' not in filename : path = pathfile filename = '' if ( filename == '' ) and ( path [ len ( path ) - 1 ] != '/' ) : path += '/' return path , filename


def Walk(root='.', recurse=True, pattern='*'):
    '''
    Generator for walking a directory tree.
    Starts at specified root folder, returning files that match our pattern.
    Optionally will also recurse through sub-folders.

    Parameters
    ----------
    root : string (default is *'.'*)
        Path for the root folder to look in.
    recurse : bool (default is *True*)
        If *True*, will also look in the subfolders.
    pattern : string (default is :emphasis:`'*'`, which means all the files are concerned)
        The pattern to look for in the files' name.

    Returns
    -------
    generator
        **Walk** yields a generator from the matching files paths.

    '''

    for path, subdirs, files in os.walk(root):
        for name in files:
            if fnmatch.fnmatch(name, pattern):
                yield os.path.join(path, name)
        if not recurse:
            break

def Walk ( root = '.' , recurse = True , pattern = '*' ) : for path , subdirs , files in os . walk ( root ) : for name in files : if fnmatch . fnmatch ( name , pattern ) : yield os . path . join ( path , name ) if not recurse : break

Generator for walking a directory tree . Starts at specified root folder returning files that match our pattern . Optionally will also recurse through sub - folders .


def displayAll(elapsed, display_amt, est_end, nLoops, count, numPrints):
    '''Displays time if verbose is true and count is within the display amount'''

    if numPrints > nLoops:
        display_amt = 1
    else:
        display_amt = round(nLoops / numPrints)

    if count % display_amt == 0:

        avg = elapsed / count
        est_end = round(avg * nLoops)

        (disp_elapsed,
         disp_avg,
         disp_est) = timeUnit(int(round(elapsed)),
                              int(round(avg)),
                              int(round(est_end)))

        print "%s%%" % str(round(count / float(nLoops) * 100)), "@" + str(count),

        totalTime = disp_est[0]
        unit = disp_est[1]

        if str(unit) == "secs":
            remain = totalTime - round(elapsed)
            remainUnit = "secs"
        elif str(unit) == "mins":
            remain = totalTime - round(elapsed) / 60
            remainUnit = "mins"
        elif str(unit) == "hr":
            remain = totalTime - round(elapsed) / 3600
            remainUnit = "hr"

        print "ETA: %s %s" % (str(remain), remainUnit)
        print

    return

def
displayAll
(
elapsed
,
display_amt
,
est_end
,
nLoops
,
count
,
numPrints
)
:
if
numPrints
>
nLoops
:
display_amt
=
1
else
:
display_amt
=
round
(
nLoops
/
numPrints
)
if
count
%
display_amt
==
0
:
avg
=
elapsed
/
count
est_end
=
round
(
avg
*
nLoops
)
(
disp_elapsed
,
disp_avg
,
disp_est
)
=
timeUnit
(
int
(
round
(
elapsed
)
)
,
int
(
round
(
avg
)
)
,
int
(
round
(
est_end
)
)
)
print
"%s%%"
%
str
(
round
(
count
/
float
(
nLoops
)
*
100
)
)
,
"@"
+
str
(
count
)
,
totalTime
=
disp_est
[
0
]
unit
=
disp_est
[
1
]
if
str
(
unit
)
==
"secs"
:
remain
=
totalTime
round
(
elapsed
)
remainUnit
=
"secs"
elif
str
(
unit
)
==
"mins"
:
remain
=
totalTime
round
(
elapsed
)
/
60
remainUnit
=
"mins"
elif
str
(
unit
)
==
"hr"
:
remain
=
totalTime
round
(
elapsed
)
/
3600
remainUnit
=
"hr"
print
"ETA: %s %s"
%
(
str
(
remain
)
,
remainUnit
)
print
return


def timeUnit(elapsed, avg, est_end):
    '''calculates unit of time to display'''
    minute = 60
    hr = 3600
    day = 86400

    if elapsed <= 3 * minute:
        unit_elapsed = (elapsed, "secs")
    if elapsed > 3 * minute:
        unit_elapsed = ((elapsed / 60), "mins")
    if elapsed > 3 * hr:
        unit_elapsed = ((elapsed / 3600), "hr")

    if avg <= 3 * minute:
        unit_avg = (avg, "secs")
    if avg > 3 * minute:
        unit_avg = ((avg / 60), "mins")
    if avg > 3 * hr:
        unit_avg = ((avg / 3600), "hr")

    if est_end <= 3 * minute:
        unit_estEnd = (est_end, "secs")
    if est_end > 3 * minute:
        unit_estEnd = ((est_end / 60), "mins")
    if est_end > 3 * hr:
        unit_estEnd = ((est_end / 3600), "hr")

    return [unit_elapsed, unit_avg, unit_estEnd]

def timeUnit ( elapsed , avg , est_end ) : minute = 60 hr = 3600 day = 86400 if elapsed <= 3 * minute : unit_elapsed = ( elapsed , "secs" ) if elapsed > 3 * minute : unit_elapsed = ( ( elapsed / 60 ) , "mins" ) if elapsed > 3 * hr : unit_elapsed = ( ( elapsed / 3600 ) , "hr" ) if avg <= 3 * minute : unit_avg = ( avg , "secs" ) if avg > 3 * minute : unit_avg = ( ( avg / 60 ) , "mins" ) if avg > 3 * hr : unit_avg = ( ( avg / 3600 ) , "hr" ) if est_end <= 3 * minute : unit_estEnd = ( est_end , "secs" ) if est_end > 3 * minute : unit_estEnd = ( ( est_end / 60 ) , "mins" ) if est_end > 3 * hr : unit_estEnd = ( ( est_end / 3600 ) , "hr" ) return [ unit_elapsed , unit_avg , unit_estEnd ]


def extract_wininst_cfg(dist_filename):
    """Extract configuration data from a bdist_wininst .exe

    Returns a ConfigParser.RawConfigParser, or None
    """
    f = open(dist_filename,'rb')
    try:
        endrec = zipfile._EndRecData(f)
        if endrec is None:
            return None

        prepended = (endrec[9] - endrec[5]) - endrec[6]
        if prepended < 12:  # no wininst data here
            return None
        f.seek(prepended-12)

        import struct, StringIO, ConfigParser
        tag, cfglen, bmlen = struct.unpack("<iii",f.read(12))
        if tag not in (0x1234567A, 0x1234567B):
            return None     # not a valid tag

        f.seek(prepended-(12+cfglen))
        cfg = ConfigParser.RawConfigParser({'version':'','target_version':''})
        try:
            part = f.read(cfglen)
            # part is in bytes, but we need to read up to the first null
            #  byte.
            if sys.version_info >= (2,6):
                null_byte = bytes([0])
            else:
                null_byte = chr(0)
            config = part.split(null_byte, 1)[0]
            # Now the config is in bytes, but on Python 3, it must be
            #  unicode for the RawConfigParser, so decode it. Is this the
            #  right encoding?
            config = config.decode('ascii')
            cfg.readfp(StringIO.StringIO(config))
        except ConfigParser.Error:
            return None
        if not cfg.has_section('metadata') or not cfg.has_section('Setup'):
            return None
        return cfg

    finally:
        f.close()

def extract_wininst_cfg ( dist_filename ) : f = open ( dist_filename , 'rb' ) try : endrec = zipfile . _EndRecData ( f ) if endrec is None : return None prepended = ( endrec [ 9 ] - endrec [ 5 ] ) - endrec [ 6 ] if prepended < 12 : return None f . seek ( prepended - 12 ) import struct , StringIO , ConfigParser tag , cfglen , bmlen = struct . unpack ( "<iii" , f . read ( 12 ) ) if tag not in ( 0x1234567A , 0x1234567B ) : return None f . seek ( prepended - ( 12 + cfglen ) ) cfg = ConfigParser . RawConfigParser ( { 'version' : '' , 'target_version' : '' } ) try : part = f . read ( cfglen ) if sys . version_info >= ( 2 , 6 ) : null_byte = bytes ( [ 0 ] ) else : null_byte = chr ( 0 ) config = part . split ( null_byte , 1 ) [ 0 ] config = config . decode ( 'ascii' ) cfg . readfp ( StringIO . StringIO ( config ) ) except ConfigParser . Error : return None if not cfg . has_section ( 'metadata' ) or not cfg . has_section ( 'Setup' ) : return None return cfg finally : f . close ( )

Extract configuration data from a bdist_wininst . exe


def uncache_zipdir(path):
    """Ensure that the importer caches dont have stale info for `path`"""
    from zipimport import _zip_directory_cache as zdc
    _uncache(path, zdc)
    _uncache(path, sys.path_importer_cache)

def uncache_zipdir ( path ) : from zipimport import _zip_directory_cache as zdc _uncache ( path , zdc ) _uncache ( path , sys . path_importer_cache )

Ensure that the importer caches dont have stale info for path


def nt_quote_arg(arg):
    """Quote a command line argument according to Windows parsing rules"""

    result = []
    needquote = False
    nb = 0

    needquote = (" " in arg) or ("\t" in arg)
    if needquote:
        result.append('"')

    for c in arg:
        if c == '\\':
            nb += 1
        elif c == '"':
            # double preceding backslashes, then add a \"
            result.append('\\' * (nb*2) + '\\"')
            nb = 0
        else:
            if nb:
                result.append('\\' * nb)
                nb = 0
            result.append(c)

    if nb:
        result.append('\\' * nb)

    if needquote:
        result.append('\\' * nb)    # double the trailing backslashes
        result.append('"')

    return ''.join(result)

def
nt_quote_arg
(
arg
)
:
result
=
[
]
needquote
=
False
nb
=
0
needquote
=
(
" "
in
arg
)
or
(
"\t"
in
arg
)
if
needquote
:
result
.
append
(
'"'
)
for
c
in
arg
:
if
c
==
'\\'
:
nb
+=
1
elif
c
==
'"'
:
result
.
append
(
'\\'
*
(
nb
*
2
)
+
'\\"'
)
nb
=
0
else
:
if
nb
:
result
.
append
(
'\\'
*
nb
)
nb
=
0
result
.
append
(
c
)
if
nb
:
result
.
append
(
'\\'
*
nb
)
if
needquote
:
result
.
append
(
'\\'
*
nb
)
result
.
append
(
'"'
)
return
''
.
join
(
result
)


def check_conflicts(self, dist):
        """Verify that there are no conflicting "old-style" packages"""

        return dist     # XXX temporarily disable until new strategy is stable
        from imp import find_module, get_suffixes
        from glob import glob

        blockers = []
        names = dict.fromkeys(dist._get_metadata('top_level.txt')) # XXX private attr

        exts = {'.pyc':1, '.pyo':1}     # get_suffixes() might leave one out
        for ext,mode,typ in get_suffixes():
            exts[ext] = 1

        for path,files in expand_paths([self.install_dir]+self.all_site_dirs):
            for filename in files:
                base,ext = os.path.splitext(filename)
                if base in names:
                    if not ext:
                        # no extension, check for package
                        try:
                            f, filename, descr = find_module(base, [path])
                        except ImportError:
                            continue
                        else:
                            if f: f.close()
                            if filename not in blockers:
                                blockers.append(filename)
                    elif ext in exts and base!='site':  # XXX ugh
                        blockers.append(os.path.join(path,filename))
        if blockers:
            self.found_conflicts(dist, blockers)

        return dist

def check_conflicts ( self , dist ) : return dist from imp import find_module , get_suffixes from glob import glob blockers = [ ] names = dict . fromkeys ( dist . _get_metadata ( 'top_level.txt' ) ) exts = { '.pyc' : 1 , '.pyo' : 1 } for ext , mode , typ in get_suffixes ( ) : exts [ ext ] = 1 for path , files in expand_paths ( [ self . install_dir ] + self . all_site_dirs ) : for filename in files : base , ext = os . path . splitext ( filename ) if base in names : if not ext : try : f , filename , descr = find_module ( base , [ path ] ) except ImportError : continue else : if f : f . close ( ) if filename not in blockers : blockers . append ( filename ) elif ext in exts and base != 'site' : blockers . append ( os . path . join ( path , filename ) ) if blockers : self . found_conflicts ( dist , blockers ) return dist

Verify that there are no conflicting old - style packages


def _set_fetcher_options(self, base):
        """
        When easy_install is about to run bdist_egg on a source dist, that
        source dist might have 'setup_requires' directives, requiring
        additional fetching. Ensure the fetcher options given to easy_install
        are available to that command as well.
        """
        # find the fetch options from easy_install and write them out
        #  to the setup.cfg file.
        ei_opts = self.distribution.get_option_dict('easy_install').copy()
        fetch_directives = (
            'find_links', 'site_dirs', 'index_url', 'optimize',
            'site_dirs', 'allow_hosts',
        )
        fetch_options = {}
        for key, val in ei_opts.iteritems():
            if key not in fetch_directives: continue
            fetch_options[key.replace('_', '-')] = val[1]
        # create a settings dictionary suitable for `edit_config`
        settings = dict(easy_install=fetch_options)
        cfg_filename = os.path.join(base, 'setup.cfg')
        setopt.edit_config(cfg_filename, settings)

def _set_fetcher_options ( self , base ) : ei_opts = self . distribution . get_option_dict ( 'easy_install' ) . copy ( ) fetch_directives = ( 'find_links' , 'site_dirs' , 'index_url' , 'optimize' , 'site_dirs' , 'allow_hosts' , ) fetch_options = { } for key , val in ei_opts . iteritems ( ) : if key not in fetch_directives : continue fetch_options [ key . replace ( '_' , '-' ) ] = val [ 1 ] settings = dict ( easy_install = fetch_options ) cfg_filename = os . path . join ( base , 'setup.cfg' ) setopt . edit_config ( cfg_filename , settings )

When easy_install is about to run bdist_egg on a source dist that source dist might have setup_requires directives requiring additional fetching . Ensure the fetcher options given to easy_install are available to that command as well .


def create_home_path(self):
        """Create directories under ~."""
        if not self.user:
            return
        home = convert_path(os.path.expanduser("~"))
        for name, path in self.config_vars.iteritems():
            if path.startswith(home) and not os.path.isdir(path):
                self.debug_print("os.makedirs('%s', 0700)" % path)
                os.makedirs(path, 0700)

def
create_home_path
(
self
)
:
if
not
self
.
user
:
return
home
=
convert_path
(
os
.
path
.
expanduser
(
"~"
)
)
for
name
,
path
in
self
.
config_vars
.
iteritems
(
)
:
if
path
.
startswith
(
home
)
and
not
os
.
path
.
isdir
(
path
)
:
self
.
debug_print
(
"os.makedirs('%s', 0700)"
%
path
)
os
.
makedirs
(
path
,
0700
)


def is_archive_file(name):
    """Return True if `name` is a considered as an archive file."""
    archives = (
        '.zip', '.tar.gz', '.tar.bz2', '.tgz', '.tar', '.whl'
    )
    ext = splitext(name)[1].lower()
    if ext in archives:
        return True
    return False

def is_archive_file ( name ) : archives = ( '.zip' , '.tar.gz' , '.tar.bz2' , '.tgz' , '.tar' , '.whl' ) ext = splitext ( name ) [ 1 ] . lower ( ) if ext in archives : return True return False

Return True if name is a considered as an archive file .


def mutable(obj):
    '''
    return a mutable proxy for the `obj`.

    all modify on the proxy will not apply on origin object.
    '''
    base_cls = type(obj)

    class Proxy(base_cls):
        def __getattribute__(self, name):
            try:
                return super().__getattribute__(name)
            except AttributeError:
                return getattr(obj, name)

    update_wrapper(Proxy, base_cls, updated = ())
    return Proxy()

def mutable ( obj ) : base_cls = type ( obj ) class Proxy ( base_cls ) : def __getattribute__ ( self , name ) : try : return super ( ) . __getattribute__ ( name ) except AttributeError : return getattr ( obj , name ) update_wrapper ( Proxy , base_cls , updated = ( ) ) return Proxy ( )


def readonly(obj, *, error_on_set = False):
    '''
    return a readonly proxy for the `obj`.

    all modify on the proxy will not apply on origin object.
    '''
    base_cls = type(obj)

    class ReadonlyProxy(base_cls):
        def __getattribute__(self, name):
            return getattr(obj, name)

        def __setattr__(self, name, value):
            if error_on_set:
                raise AttributeError('cannot set readonly object.')

    update_wrapper(ReadonlyProxy, base_cls, updated = ())
    return ReadonlyProxy()

def
readonly
(
obj
,
*
,
error_on_set
=
False
)
:
base_cls
=
type
(
obj
)
class
ReadonlyProxy
(
base_cls
)
:
def
__getattribute__
(
self
,
name
)
:
return
getattr
(
obj
,
name
)
def
__setattr__
(
self
,
name
,
value
)
:
if
error_on_set
:
raise
AttributeError
(
'cannot set readonly object.'
)
update_wrapper
(
ReadonlyProxy
,
base_cls
,
updated
=
(
)
)
return
ReadonlyProxy
(
)


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 = unicode(source)
    if rendered is not None:
        cell.rendered = unicode(rendered)
    cell.level = int(level)
    cell.metadata = NotebookNode(metadata or {})
    return cell

def new_heading_cell ( source = None , rendered = None , level = 1 , metadata = None ) : cell = NotebookNode ( ) cell . cell_type = u'heading' if source is not None : cell . source = unicode ( source ) if rendered is not None : cell . rendered = unicode ( rendered ) cell . level = int ( level ) cell . metadata = NotebookNode ( metadata or { } ) return cell

Create a new section cell with a given integer level .


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 = unicode(name)
    if authors is not None:
        metadata.authors = list(authors)
    if created is not None:
        metadata.created = unicode(created)
    if modified is not None:
        metadata.modified = unicode(modified)
    if license is not None:
        metadata.license = unicode(license)
    if gistid is not None:
        metadata.gistid = unicode(gistid)
    return metadata

def new_metadata ( name = None , authors = None , license = None , created = None , modified = None , gistid = None ) : metadata = NotebookNode ( ) if name is not None : metadata . name = unicode ( name ) if authors is not None : metadata . authors = list ( authors ) if created is not None : metadata . created = unicode ( created ) if modified is not None : metadata . modified = unicode ( modified ) if license is not None : metadata . license = unicode ( license ) if gistid is not None : metadata . gistid = unicode ( gistid ) return metadata


def new_author(name=None, email=None, affiliation=None, url=None):
    """Create a new author."""
    author = NotebookNode()
    if name is not None:
        author.name = unicode(name)
    if email is not None:
        author.email = unicode(email)
    if affiliation is not None:
        author.affiliation = unicode(affiliation)
    if url is not None:
        author.url = unicode(url)
    return author

def new_author ( name = None , email = None , affiliation = None , url = None ) : author = NotebookNode ( ) if name is not None : author . name = unicode ( name ) if email is not None : author . email = unicode ( email ) if affiliation is not None : author . affiliation = unicode ( affiliation ) if url is not None : author . url = unicode ( url ) return author


def _writable_dir(path):
    """Whether `path` is a directory, to which the user has write access."""
    return os.path.isdir(path) and os.access(path, os.W_OK)

def _writable_dir ( path ) : return os . path . isdir ( path ) and os . access ( path , os . W_OK )

Whether path is a directory to which the user has write access .


def unquote_filename(name, win32=(sys.platform=='win32')):
    """ On Windows, remove leading and trailing quotes from filenames.
    """
    if win32:
        if name.startswith(("'", '"')) and name.endswith(("'", '"')):
            name = name[1:-1]
    return name

def unquote_filename ( name , win32 = ( sys . platform == 'win32' ) ) : if win32 : if name . startswith ( ( "'" , '"' ) ) and name . endswith ( ( "'" , '"' ) ) : name = name [ 1 : - 1 ] return name

On Windows remove leading and trailing quotes from filenames .


def get_py_filename(name, force_win32=None):
    """Return a valid python filename in the current directory.

    If the given name is not a file, it adds '.py' and searches again.
    Raises IOError with an informative message if the file isn't found.

    On Windows, apply Windows semantics to the filename. In particular, remove
    any quoting that has been applied to it. This option can be forced for
    testing purposes.
    """

    name = os.path.expanduser(name)
    if force_win32 is None:
        win32 = (sys.platform == 'win32')
    else:
        win32 = force_win32
    name = unquote_filename(name, win32=win32)
    if not os.path.isfile(name) and not name.endswith('.py'):
        name += '.py'
    if os.path.isfile(name):
        return name
    else:
        raise IOError,'File `%r` not found.' % name

def
get_py_filename
(
name
,
force_win32
=
)
:
name
=
os
.
path
.
expanduser
(
name
)
if
force_win32
is
:
win32
=
(
sys
.
platform
==
'win32'
)
else
:
win32
=
force_win32
name
=
unquote_filename
(
name
,
win32
=
win32
)
if
not
os
.
path
.
isfile
(
name
)
and
not
name
.
endswith
(
'.py'
)
:
name
+=
'.py'
if
os
.
path
.
isfile
(
name
)
:
return
name
else
:
raise
IOError
,
'File `%r` not found.'
%
name

Return a valid python filename in the current directory .


def filefind(filename, path_dirs=None):
    """Find a file by looking through a sequence of paths.

    This iterates through a sequence of paths looking for a file and returns
    the full, absolute path of the first occurence of the file.  If no set of
    path dirs is given, the filename is tested as is, after running through
    :func:`expandvars` and :func:`expanduser`.  Thus a simple call::

        filefind('myfile.txt')

    will find the file in the current working dir, but::

        filefind('~/myfile.txt')

    Will find the file in the users home directory.  This function does not
    automatically try any paths, such as the cwd or the user's home directory.

    Parameters
    ----------
    filename : str
        The filename to look for.
    path_dirs : str, None or sequence of str
        The sequence of paths to look for the file in.  If None, the filename
        need to be absolute or be in the cwd.  If a string, the string is
        put into a sequence and the searched.  If a sequence, walk through
        each element and join with ``filename``, calling :func:`expandvars`
        and :func:`expanduser` before testing for existence.

    Returns
    -------
    Raises :exc:`IOError` or returns absolute path to file.
    """

    # If paths are quoted, abspath gets confused, strip them...
    filename = filename.strip('"').strip("'")
    # If the input is an absolute path, just check it exists
    if os.path.isabs(filename) and os.path.isfile(filename):
        return filename

    if path_dirs is None:
        path_dirs = ("",)
    elif isinstance(path_dirs, basestring):
        path_dirs = (path_dirs,)

    for path in path_dirs:
        if path == '.': path = os.getcwdu()
        testname = expand_path(os.path.join(path, filename))
        if os.path.isfile(testname):
            return os.path.abspath(testname)

    raise IOError("File %r does not exist in any of the search paths: %r" %
                  (filename, path_dirs) )

Find a file by looking through a sequence of paths .


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)

Return the home directory as a unicode string .


def get_xdg_dir():
    """Return the XDG_CONFIG_HOME, if it is defined and exists, else None.

    This is only for non-OS X posix (Linux,Unix,etc.) systems.
    """

    env = os.environ

    if os.name == 'posix' and sys.platform != 'darwin':
        # Linux, Unix, AIX, etc.
        # use ~/.config if empty OR not set
        xdg = env.get("XDG_CONFIG_HOME", None) or os.path.join(get_home_dir(), '.config')
        if xdg and _writable_dir(xdg):
            return py3compat.cast_unicode(xdg, fs_encoding)

    return None

def get_xdg_dir ( ) : env = os . environ if os . name == 'posix' and sys . platform != 'darwin' : xdg = env . get ( "XDG_CONFIG_HOME" , None ) or os . path . join ( get_home_dir ( ) , '.config' ) if xdg and _writable_dir ( xdg ) : return py3compat . cast_unicode ( xdg , fs_encoding ) return None

Return the XDG_CONFIG_HOME if it is defined and exists else None .


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'
    xdg_def = 'ipython'

    home_dir = get_home_dir()
    xdg_dir = get_xdg_dir()

    # import pdb; pdb.set_trace()  # dbg
    if 'IPYTHON_DIR' in env:
        warnings.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 XDG_CONFIG_HOME or HOME
        home_ipdir = pjoin(home_dir, ipdir_def)
        if xdg_dir:
            # use XDG, as long as the user isn't already
            # using $HOME/.ipython and *not* XDG/ipython

            xdg_ipdir = pjoin(xdg_dir, xdg_def)

            if _writable_dir(xdg_ipdir) or not _writable_dir(home_ipdir):
                ipdir = xdg_ipdir

        if ipdir is None:
            # not using XDG
            ipdir = home_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
        warnings.warn("IPython dir '%s' is not a writable location,"
                        " using a temp directory."%ipdir)
        ipdir = tempfile.mkdtemp()
    elif not os.path.exists(ipdir):
        parent = ipdir.rsplit(os.path.sep, 1)[0]
        if not _writable_dir(parent):
            # ipdir does not exist and parent isn't writable
            warnings.warn("IPython parent '%s' is not a writable location,"
                        " using a temp directory."%parent)
            ipdir = tempfile.mkdtemp()

    return py3compat.cast_unicode(ipdir, fs_encoding)

Get the IPython directory for this platform and user .


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)

def get_ipython_package_dir ( ) : ipdir = os . path . dirname ( IPython . __file__ ) return py3compat . cast_unicode ( ipdir , fs_encoding )

Get the base directory where IPython itself is installed .


def get_ipython_module_path(module_str):
    """Find the path to an IPython module in this version of IPython.

    This will always find the version of the module that is in this importable
    IPython package. This will always return the path to the ``.py``
    version of the module.
    """
    if module_str == 'IPython':
        return os.path.join(get_ipython_package_dir(), '__init__.py')
    mod = import_item(module_str)
    the_path = mod.__file__.replace('.pyc', '.py')
    the_path = the_path.replace('.pyo', '.py')
    return py3compat.cast_unicode(the_path, fs_encoding)

def get_ipython_module_path ( module_str ) : if module_str == 'IPython' : return os . path . join ( get_ipython_package_dir ( ) , '__init__.py' ) mod = import_item ( module_str ) the_path = mod . __file__ . replace ( '.pyc' , '.py' ) the_path = the_path . replace ( '.pyo' , '.py' ) return py3compat . cast_unicode ( the_path , fs_encoding )

Find the path to an IPython module in this version of IPython .


def target_outdated(target,deps):
    """Determine whether a target is out of date.

    target_outdated(target,deps) -> 1/0

    deps: list of filenames which MUST exist.
    target: single filename which may or may not exist.

    If target doesn't exist or is older than any file listed in deps, return
    true, otherwise return false.
    """
    try:
        target_time = os.path.getmtime(target)
    except os.error:
        return 1
    for dep in deps:
        dep_time = os.path.getmtime(dep)
        if dep_time > target_time:
            #print "For target",target,"Dep failed:",dep # dbg
            #print "times (dep,tar):",dep_time,target_time # dbg
            return 1
    return 0

def target_outdated ( target , deps ) : try : target_time = os . path . getmtime ( target ) except os . error : return 1 for dep in deps : dep_time = os . path . getmtime ( dep ) if dep_time > target_time : return 1 return 0

Determine whether a target is out of date .


def filehash(path):
    """Make an MD5 hash of a file, ignoring any differences in line
    ending characters."""
    with open(path, "rU") as f:
        return md5(py3compat.str_to_bytes(f.read())).hexdigest()

def filehash ( path ) : with open ( path , "rU" ) as f : return md5 ( py3compat . str_to_bytes ( f . read ( ) ) ) . hexdigest ( )

Make an MD5 hash of a file ignoring any differences in line ending characters .


def check_for_old_config(ipython_dir=None):
    """Check for old config files, and present a warning if they exist.

    A link to the docs of the new config is included in the message.

    This should mitigate confusion with the transition to the new
    config system in 0.11.
    """
    if ipython_dir is None:
        ipython_dir = get_ipython_dir()

    old_configs = ['ipy_user_conf.py', 'ipythonrc', 'ipython_config.py']
    warned = False
    for cfg in old_configs:
        f = os.path.join(ipython_dir, cfg)
        if os.path.exists(f):
            if filehash(f) == old_config_md5.get(cfg, ''):
                os.unlink(f)
            else:
                warnings.warn("Found old IPython config file %r (modified by user)"%f)
                warned = True

    if warned:
        warnings.warn("""
  The IPython configuration system has changed as of 0.11, and these files will
  be ignored. See http://ipython.github.com/ipython-doc/dev/config for details
  of the new config system.
  To start configuring IPython, do `ipython profile create`, and edit
  `ipython_config.py` in <ipython_dir>/profile_default.
  If you need to leave the old config files in place for an older version of
  IPython and want to suppress this warning message, set
  `c.InteractiveShellApp.ignore_old_config=True` in the new config.""")

Check for old config files and present a warning if they exist .


def update_suggestions_dictionary(request, object):
    """
    Updates the suggestions' dictionary for an object upon visiting its page
    """
    if request.user.is_authenticated():
        user = request.user
        content_type = ContentType.objects.get_for_model(type(object))
        try:
            # Check if the user has visited this page before
            ObjectView.objects.get(
                user=user, object_id=object.id, content_type=content_type)
        except:
            ObjectView.objects.create(user=user, content_object=object)
        # Get a list of all the objects a user has visited
        viewed = ObjectView.objects.filter(user=user)

    else:
        update_dict_for_guests(request, object, content_type)
        return

    if viewed:
        for obj in viewed:
            if content_type == obj.content_type:
                if not exists_in_dictionary(request, object,
                                            content_type,
                                            obj, True):
                    # Create an entry if it's non existent
                    if object.id != obj.object_id:
                        ObjectViewDictionary.objects.create(
                            current_object=object,
                            visited_before_object=obj.content_object)
                        if not exists_in_dictionary(request, obj,
                                                    obj.content_type,
                                                    object, False):
                            ObjectViewDictionary.objects.create(
                                current_object=obj.content_object,
                                visited_before_object=object)
    return

def update_suggestions_dictionary ( request , object ) : if request . user . is_authenticated ( ) : user = request . user content_type = ContentType . objects . get_for_model ( type ( object ) ) try : ObjectView . objects . get ( user = user , object_id = object . id , content_type = content_type ) except : ObjectView . objects . create ( user = user , content_object = object ) viewed = ObjectView . objects . filter ( user = user ) else : update_dict_for_guests ( request , object , content_type ) return if viewed : for obj in viewed : if content_type == obj . content_type : if not exists_in_dictionary ( request , object , content_type , obj , True ) : if object . id != obj . object_id : ObjectViewDictionary . objects . create ( current_object = object , visited_before_object = obj . content_object ) if not exists_in_dictionary ( request , obj , obj . content_type , object , False ) : ObjectViewDictionary . objects . create ( current_object = obj . content_object , visited_before_object = object ) return

Updates the suggestions dictionary for an object upon visiting its page


def get_suggestions_with_size(object, size):
    """ Gets a list with a certain size of suggestions for an object """
    content_type = ContentType.objects.get_for_model(type(object))
    try:
        return ObjectViewDictionary.objects.filter(
            current_object_id=object.id,
            current_content_type=content_type).extra(
            order_by=['-visits'])[:size]
    except:
        return ObjectViewDictionary.objects.filter(
            current_object_id=object.id,
            current_content_type=content_type).extra(order_by=['-visits'])

def get_suggestions_with_size ( object , size ) : content_type = ContentType . objects . get_for_model ( type ( object ) ) try : return ObjectViewDictionary . objects . filter ( current_object_id = object . id , current_content_type = content_type ) . extra ( order_by = [ '-visits' ] ) [ : size ] except : return ObjectViewDictionary . objects . filter ( current_object_id = object . id , current_content_type = content_type ) . extra ( order_by = [ '-visits' ] )


def get_suggestions(object):
    """ Gets a list of all suggestions for an object """
    content_type = ContentType.objects.get_for_model(type(object))
    return ObjectViewDictionary.objects.filter(
        current_object_id=object.id,
        current_content_type=content_type).extra(order_by=['-visits'])

def get_suggestions ( object ) : content_type = ContentType . objects . get_for_model ( type ( object ) ) return ObjectViewDictionary . objects . filter ( current_object_id = object . id , current_content_type = content_type ) . extra ( order_by = [ '-visits' ] )


def relpath(self):
        """ Return this path as a relative path,
        based from the current working directory.
        """
        cwd = self.__class__(os.getcwdu())
        return cwd.relpathto(self)

def relpath ( self ) : cwd = self . __class__ ( os . getcwdu ( ) ) return cwd . relpathto ( self )

Return this path as a relative path based from the current working directory .


def glob(self, pattern):
        """ Return a list of path objects that match the pattern.

        pattern - a path relative to this directory, with wildcards.

        For example, path('/users').glob('*/bin/*') returns a list
        of all the files users have in their bin directories.
        """
        cls = self.__class__
        return [cls(s) for s in glob.glob(unicode(self / pattern))]

def glob ( self , pattern ) : cls = self . __class__ return [ cls ( s ) for s in glob . glob ( unicode ( self / pattern ) ) ]

Return a list of path objects that match the pattern .


def lines(self, encoding=None, errors='strict', retain=True):
        r""" Open this file, read all lines, return them in a list.

        Optional arguments:
            encoding - The Unicode encoding (or character set) of
                the file.  The default is None, meaning the content
                of the file is read as 8-bit characters and returned
                as a list of (non-Unicode) str objects.
            errors - How to handle Unicode errors; see help(str.decode)
                for the options.  Default is 'strict'
            retain - If true, retain newline characters; but all newline
                character combinations ('\r', '\n', '\r\n') are
                translated to '\n'.  If false, newline characters are
                stripped off.  Default is True.

        This uses 'U' mode in Python 2.3 and later.
        """
        if encoding is None and retain:
            f = self.open('U')
            try:
                return f.readlines()
            finally:
                f.close()
        else:
            return self.text(encoding, errors).splitlines(retain)

def lines ( self , encoding = None , errors = 'strict' , retain = True ) : r if encoding is None and retain : f = self . open ( 'U' ) try : return f . readlines ( ) finally : f . close ( ) else : return self . text ( encoding , errors ) . splitlines ( retain )

r Open this file read all lines return them in a list .


def read_md5(self):
        """ Calculate the md5 hash for this file.

        This reads through the entire file.
        """
        f = self.open('rb')
        try:
            m = md5()
            while True:
                d = f.read(8192)
                if not d:
                    break
                m.update(d)
        finally:
            f.close()
        return m.digest()

def read_md5 ( self ) : f = self . open ( 'rb' ) try : m = md5 ( ) while True : d = f . read ( 8192 ) if not d : break m . update ( d ) finally : f . close ( ) return m . digest ( )


def begin(self):
        """Create profile stats file and load profiler.
        """
        if not self.available():
            return
        self._create_pfile()
        self.prof = hotshot.Profile(self.pfile)

def begin ( self ) : if not self . available ( ) : return self . _create_pfile ( ) self . prof = hotshot . Profile ( self . pfile )

Create profile stats file and load profiler .


def report(self, stream):
        """Output profiler report.
        """
        log.debug('printing profiler report')
        self.prof.close()
        prof_stats = stats.load(self.pfile)
        prof_stats.sort_stats(self.sort)

        # 2.5 has completely different stream handling from 2.4 and earlier.
        # Before 2.5, stats objects have no stream attribute; in 2.5 and later
        # a reference sys.stdout is stored before we can tweak it.
        compat_25 = hasattr(prof_stats, 'stream')
        if compat_25:
            tmp = prof_stats.stream
            prof_stats.stream = stream
        else:
            tmp = sys.stdout
            sys.stdout = stream
        try:
            if self.restrict:
                log.debug('setting profiler restriction to %s', self.restrict)
                prof_stats.print_stats(*self.restrict)
            else:
                prof_stats.print_stats()
        finally:
            if compat_25:
                prof_stats.stream = tmp
            else:
                sys.stdout = tmp

def
report
(
self
,
stream
)
:
log
.
debug
(
'printing profiler report'
)
self
.
prof
.
close
(
)
prof_stats
=
stats
.
load
(
self
.
pfile
)
prof_stats
.
sort_stats
(
self
.
sort
)
compat_25
=
hasattr
(
prof_stats
,
'stream'
)
if
compat_25
:
tmp
=
prof_stats
.
stream
prof_stats
.
stream
=
stream
else
:
tmp
=
sys
.
stdout
sys
.
stdout
=
stream
try
:
if
self
.
restrict
:
log
.
debug
(
'setting profiler restriction to %s'
,
self
.
restrict
)
prof_stats
.
print_stats
(
*
self
.
restrict
)
else
:
prof_stats
.
print_stats
(
)
finally
:
if
compat_25
:
prof_stats
.
stream
=
tmp
else
:
sys
.
stdout
=
tmp


def finalize(self, result):
        """Clean up stats file, if configured to do so.
        """
        if not self.available():
            return
        try:
            self.prof.close()
        except AttributeError:
            # TODO: is this trying to catch just the case where not
            # hasattr(self.prof, "close")?  If so, the function call should be
            # moved out of the try: suite.
            pass
        if self.clean_stats_file:
            if self.fileno:
                try:
                    os.close(self.fileno)
                except OSError:
                    pass
            try:
                os.unlink(self.pfile)
            except OSError:
                pass
        return None

def finalize ( self , result ) : if not self . available ( ) : return try : self . prof . close ( ) except AttributeError : pass if self . clean_stats_file : if self . fileno : try : os . close ( self . fileno ) except OSError : pass try : os . unlink ( self . pfile ) except OSError : pass return None

Clean up stats file if configured to do so .


def handle(self, *args, **options):
        """Handle CLI command"""
        try:
            while True:
                Channel(HEARTBEAT_CHANNEL).send({'time':time.time()})
                time.sleep(HEARTBEAT_FREQUENCY)
        except KeyboardInterrupt:
            print("Received keyboard interrupt, exiting...")


def enable_wx(self, app=None):
        """Enable event loop integration with wxPython.

        Parameters
        ----------
        app : WX Application, optional.
            Running application to use.  If not given, we probe WX for an
            existing application object, and create a new one if none is found.

        Notes
        -----
        This methods sets the ``PyOS_InputHook`` for wxPython, which allows
        the wxPython to integrate with terminal based applications like
        IPython.

        If ``app`` is not given we probe for an existing one, and return it if
        found.  If no existing app is found, we create an :class:`wx.App` as
        follows::

            import wx
            app = wx.App(redirect=False, clearSigInt=False)
        """
        import wx

        wx_version = V(wx.__version__).version

        if wx_version < [2, 8]:
            raise ValueError("requires wxPython >= 2.8, but you have %s" % wx.__version__)

        from IPython.lib.inputhookwx import inputhook_wx
        self.set_inputhook(inputhook_wx)
        self._current_gui = GUI_WX
        import wx
        if app is None:
            app = wx.GetApp()
        if app is None:
            app = wx.App(redirect=False, clearSigInt=False)
        app._in_event_loop = True
        self._apps[GUI_WX] = app
        return app

Enable event loop integration with wxPython .


def disable_wx(self):
        """Disable event loop integration with wxPython.

        This merely sets PyOS_InputHook to NULL.
        """
        if self._apps.has_key(GUI_WX):
            self._apps[GUI_WX]._in_event_loop = False
        self.clear_inputhook()

def disable_wx ( self ) : if self . _apps . has_key ( GUI_WX ) : self . _apps [ GUI_WX ] . _in_event_loop = False self . clear_inputhook ( )

Disable event loop integration with wxPython .


def disable_qt4(self):
        """Disable event loop integration with PyQt4.

        This merely sets PyOS_InputHook to NULL.
        """
        if self._apps.has_key(GUI_QT4):
            self._apps[GUI_QT4]._in_event_loop = False
        self.clear_inputhook()

def disable_qt4 ( self ) : if self . _apps . has_key ( GUI_QT4 ) : self . _apps [ GUI_QT4 ] . _in_event_loop = False self . clear_inputhook ( )

Disable event loop integration with PyQt4 .


def enable_gtk(self, app=None):
        """Enable event loop integration with PyGTK.

        Parameters
        ----------
        app : ignored
           Ignored, it's only a placeholder to keep the call signature of all
           gui activation methods consistent, which simplifies the logic of
           supporting magics.

        Notes
        -----
        This methods sets the PyOS_InputHook for PyGTK, which allows
        the PyGTK to integrate with terminal based applications like
        IPython.
        """
        import gtk
        try:
            gtk.set_interactive(True)
            self._current_gui = GUI_GTK
        except AttributeError:
            # For older versions of gtk, use our own ctypes version
            from IPython.lib.inputhookgtk import inputhook_gtk
            self.set_inputhook(inputhook_gtk)
            self._current_gui = GUI_GTK

def enable_gtk ( self , app = None ) : import gtk try : gtk . set_interactive ( True ) self . _current_gui = GUI_GTK except AttributeError : from IPython . lib . inputhookgtk import inputhook_gtk self . set_inputhook ( inputhook_gtk ) self . _current_gui = GUI_GTK

Enable event loop integration with PyGTK .