##// END OF EJS Templates
Merge branch 'master' into jedi_completion
Kelly Liu -
r22293:eca61c4d merge
parent child Browse files
Show More
@@ -71,11 +71,10 b' from IPython.core.error import TryNext'
71 71 from IPython.core.inputsplitter import ESC_MAGIC
72 72 from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol
73 73 from IPython.utils import generics
74 from IPython.utils import io
75 74 from IPython.utils.decorators import undoc
76 75 from IPython.utils.dir2 import dir2, get_real_method
77 76 from IPython.utils.process import arg_split
78 from IPython.utils.py3compat import builtin_mod, string_types, PY3
77 from IPython.utils.py3compat import builtin_mod, string_types, PY3, cast_unicode_py2
79 78 from traitlets import CBool, Enum
80 79
81 80 try:
@@ -201,6 +200,9 b' def completions_sorting_key(word):'
201 200 elif word.startswith('_'):
202 201 prio1 = 1
203 202
203 if word.endswith('='):
204 prio1 = -1
205
204 206 if word.startswith('%%'):
205 207 # If there's another % in there, this is something else, so leave it alone
206 208 if not "%" in word[2:]:
@@ -358,7 +360,7 b' class Completer(Configurable):'
358 360 for word in lst:
359 361 if word[:n] == text and word != "__builtins__":
360 362 match_append(word)
361 return matches
363 return [cast_unicode_py2(m) for m in matches]
362 364
363 365 def attr_matches(self, text):
364 366 """Compute matches when text contains a dot.
@@ -410,8 +412,7 b' class Completer(Configurable):'
410 412 pass
411 413 # Build match list to return
412 414 n = len(attr)
413 res = ["%s.%s" % (expr, w) for w in words if w[:n] == attr ]
414 return res
415 return [u"%s.%s" % (expr, w) for w in words if w[:n] == attr ]
415 416
416 417
417 418 def get__all__entries(obj):
@@ -421,7 +422,7 b' def get__all__entries(obj):'
421 422 except:
422 423 return []
423 424
424 return [w for w in words if isinstance(w, string_types)]
425 return [cast_unicode_py2(w) for w in words if isinstance(w, string_types)]
425 426
426 427
427 428 def match_dict_keys(keys, prefix, delims):
@@ -695,9 +696,9 b' class IPCompleter(Completer):'
695 696 # when escaped with backslash
696 697 if text.startswith('!'):
697 698 text = text[1:]
698 text_prefix = '!'
699 text_prefix = u'!'
699 700 else:
700 text_prefix = ''
701 text_prefix = u''
701 702
702 703 text_until_cursor = self.text_until_cursor
703 704 # track strings with open quotes
@@ -728,7 +729,7 b' class IPCompleter(Completer):'
728 729 text = os.path.expanduser(text)
729 730
730 731 if text == "":
731 return [text_prefix + protect_filename(f) for f in self.glob("*")]
732 return [text_prefix + cast_unicode_py2(protect_filename(f)) for f in self.glob("*")]
732 733
733 734 # Compute the matches from the filesystem
734 735 m0 = self.clean_glob(text.replace('\\',''))
@@ -751,8 +752,7 b' class IPCompleter(Completer):'
751 752 protect_filename(f) for f in m0]
752 753
753 754 # Mark directories in input list by appending '/' to their names.
754 matches = [x+'/' if os.path.isdir(x) else x for x in matches]
755 return matches
755 return [cast_unicode_py2(x+'/') if os.path.isdir(x) else x for x in matches]
756 756
757 757 def magic_matches(self, text):
758 758 """Match magics"""
@@ -773,7 +773,7 b' class IPCompleter(Completer):'
773 773 comp = [ pre2+m for m in cell_magics if m.startswith(bare_text)]
774 774 if not text.startswith(pre2):
775 775 comp += [ pre+m for m in line_magics if m.startswith(bare_text)]
776 return comp
776 return [cast_unicode_py2(c) for c in comp]
777 777
778 778 def python_jedi_matches(self, text, line_buffer, cursor_pos):
779 779 """Match attributes or global Python names using Jedi."""
@@ -849,7 +849,6 b' class IPCompleter(Completer):'
849 849 matches = []
850 850 else:
851 851 matches = self.global_matches(text)
852
853 852 return matches
854 853
855 854 def _default_arguments_from_docstring(self, doc):
@@ -978,7 +977,7 b' class IPCompleter(Completer):'
978 977
979 978 for namedArg in namedArgs:
980 979 if namedArg.startswith(text):
981 argMatches.append("%s=" %namedArg)
980 argMatches.append(u"%s=" %namedArg)
982 981 return argMatches
983 982
984 983 def dict_key_matches(self, text):
@@ -1164,12 +1163,12 b' class IPCompleter(Completer):'
1164 1163 res = c(event)
1165 1164 if res:
1166 1165 # first, try case sensitive match
1167 withcase = [r for r in res if r.startswith(text)]
1166 withcase = [cast_unicode_py2(r) for r in res if r.startswith(text)]
1168 1167 if withcase:
1169 1168 return withcase
1170 1169 # if none, then case insensitive ones are ok too
1171 1170 text_low = text.lower()
1172 return [r for r in res if r.lower().startswith(text_low)]
1171 return [cast_unicode_py2(r) for r in res if r.lower().startswith(text_low)]
1173 1172 except TryNext:
1174 1173 pass
1175 1174
@@ -944,7 +944,7 b' def format_display_data(obj, include=None, exclude=None):'
944 944 """
945 945 from IPython.core.interactiveshell import InteractiveShell
946 946
947 InteractiveShell.instance().display_formatter.format(
947 return InteractiveShell.instance().display_formatter.format(
948 948 obj,
949 949 include,
950 950 exclude
@@ -1,18 +1,10 b''
1 1 """ History related magics and functionality """
2 #-----------------------------------------------------------------------------
3 # Copyright (C) 2010-2011 The IPython Development Team.
4 #
5 # Distributed under the terms of the BSD License.
6 #
7 # The full license is in the file COPYING.txt, distributed with this software.
8 #-----------------------------------------------------------------------------
9 2
10 #-----------------------------------------------------------------------------
11 # Imports
12 #-----------------------------------------------------------------------------
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
5
13 6 from __future__ import print_function
14 7
15 # Stdlib imports
16 8 import atexit
17 9 import datetime
18 10 import os
@@ -26,7 +18,6 b' except ImportError:'
26 18 sqlite3 = None
27 19 import threading
28 20
29 # Our own packages
30 21 from traitlets.config.configurable import LoggingConfigurable
31 22 from decorator import decorator
32 23 from IPython.utils.decorators import undoc
@@ -80,27 +71,52 b' else:'
80 71 class OperationalError(Exception):
81 72 "Dummy exception when sqlite could not be imported. Should never occur."
82 73
74 # use 16kB as threshold for whether a corrupt history db should be saved
75 # that should be at least 100 entries or so
76 _SAVE_DB_SIZE = 16384
77
83 78 @decorator
84 79 def catch_corrupt_db(f, self, *a, **kw):
85 80 """A decorator which wraps HistoryAccessor method calls to catch errors from
86 81 a corrupt SQLite database, move the old database out of the way, and create
87 82 a new one.
83
84 We avoid clobbering larger databases because this may be triggered due to filesystem issues,
85 not just a corrupt file.
88 86 """
89 87 try:
90 88 return f(self, *a, **kw)
91 except (DatabaseError, OperationalError):
92 if os.path.isfile(self.hist_file):
93 # Try to move the file out of the way
94 base,ext = os.path.splitext(self.hist_file)
95 newpath = base + '-corrupt' + ext
96 os.rename(self.hist_file, newpath)
89 except (DatabaseError, OperationalError) as e:
90 self._corrupt_db_counter += 1
91 self.log.error("Failed to open SQLite history %s (%s).", self.hist_file, e)
92 if self.hist_file != ':memory:':
93 if self._corrupt_db_counter > self._corrupt_db_limit:
94 self.hist_file = ':memory:'
95 self.log.error("Failed to load history too many times, history will not be saved.")
96 elif os.path.isfile(self.hist_file):
97 # move the file out of the way
98 base, ext = os.path.splitext(self.hist_file)
99 size = os.stat(self.hist_file).st_size
100 if size >= _SAVE_DB_SIZE:
101 # if there's significant content, avoid clobbering
102 now = datetime.datetime.now().isoformat().replace(':', '.')
103 newpath = base + '-corrupt-' + now + ext
104 # don't clobber previous corrupt backups
105 for i in range(100):
106 if not os.path.isfile(newpath):
107 break
108 else:
109 newpath = base + '-corrupt-' + now + (u'-%i' % i) + ext
110 else:
111 # not much content, possibly empty; don't worry about clobbering
112 # maybe we should just delete it?
113 newpath = base + '-corrupt' + ext
114 os.rename(self.hist_file, newpath)
115 self.log.error("History file was moved to %s and a new file created.", newpath)
97 116 self.init_db()
98 print("ERROR! History file wasn't a valid SQLite database.",
99 "It was moved to %s" % newpath, "and a new file created.")
100 117 return []
101
102 118 else:
103 # The hist_file is probably :memory: or something else.
119 # Failed with :memory:, something serious is wrong
104 120 raise
105 121
106 122 class HistoryAccessorBase(LoggingConfigurable):
@@ -126,6 +142,11 b' class HistoryAccessor(HistoryAccessorBase):'
126 142 This is intended for use by standalone history tools. IPython shells use
127 143 HistoryManager, below, which is a subclass of this."""
128 144
145 # counter for init_db retries, so we don't keep trying over and over
146 _corrupt_db_counter = 0
147 # after two failures, fallback on :memory:
148 _corrupt_db_limit = 2
149
129 150 # String holding the path to the history file
130 151 hist_file = Unicode(config=True,
131 152 help="""Path to file to use for SQLite history database.
@@ -239,6 +260,8 b' class HistoryAccessor(HistoryAccessorBase):'
239 260 (session integer, line integer, output text,
240 261 PRIMARY KEY (session, line))""")
241 262 self.db.commit()
263 # success! reset corrupt db count
264 self._corrupt_db_counter = 0
242 265
243 266 def writeout_cache(self):
244 267 """Overridden by HistoryManager to dump the cache before certain
@@ -57,7 +57,7 b' from IPython.core.prefilter import PrefilterManager'
57 57 from IPython.core.profiledir import ProfileDir
58 58 from IPython.core.prompts import PromptManager
59 59 from IPython.core.usage import default_banner
60 from IPython.testing.skipdoctest import skip_doctest
60 from IPython.testing.skipdoctest import skip_doctest_py2, skip_doctest
61 61 from IPython.utils import PyColorize
62 62 from IPython.utils import io
63 63 from IPython.utils import py3compat
@@ -1939,6 +1939,7 b' class InteractiveShell(SingletonConfigurable):'
1939 1939 self.set_hook('complete_command', reset_completer, str_key = '%reset')
1940 1940
1941 1941
1942 @skip_doctest_py2
1942 1943 def complete(self, text, line=None, cursor_pos=None):
1943 1944 """Return the completed text and a list of completions.
1944 1945
@@ -61,12 +61,12 b' class TimeitResult(object):'
61 61 """
62 62 Object returned by the timeit magic with info about the run.
63 63
64 Contain the following attributes :
64 Contains the following attributes :
65 65
66 loops: (int) number of loop done per measurement
67 repeat: (int) number of time the mesurement has been repeated
68 best: (float) best execusion time / number
69 all_runs: (list of float) execusion time of each run (in s)
66 loops: (int) number of loops done per measurement
67 repeat: (int) number of times the measurement has been repeated
68 best: (float) best execution time / number
69 all_runs: (list of float) execution time of each run (in s)
70 70 compile_time: (float) time of statement compilation (s)
71 71
72 72 """
@@ -298,7 +298,7 b' def get_pager_cmd(pager_cmd=None):'
298 298 Makes some attempts at finding an OS-correct one.
299 299 """
300 300 if os.name == 'posix':
301 default_pager_cmd = 'less -r' # -r for color control sequences
301 default_pager_cmd = 'less -R' # -R for color control sequences
302 302 elif os.name in ['nt','dos']:
303 303 default_pager_cmd = 'type'
304 304
@@ -308,8 +308,8 b' def get_pager_cmd(pager_cmd=None):'
308 308 except:
309 309 pager_cmd = default_pager_cmd
310 310
311 if pager_cmd == 'less' and '-r' not in os.environ.get('LESS', ''):
312 pager_cmd += ' -r'
311 if pager_cmd == 'less' and '-r' not in os.environ.get('LESS', '').lower():
312 pager_cmd += ' -R'
313 313
314 314 return pager_cmd
315 315
@@ -790,6 +790,7 b' def test_nested_import_module_completer():'
790 790 _, matches = ip.complete(None, 'import IPython.co', 17)
791 791 nt.assert_in('IPython.core', matches)
792 792 nt.assert_not_in('import IPython.core', matches)
793 nt.assert_not_in('IPython.display', matches)
793 794
794 795 def test_import_module_completer():
795 796 ip = get_ipython()
@@ -99,6 +99,21 b' class NonAsciiTest(unittest.TestCase):'
99 99 with tt.AssertPrints("ZeroDivisionError"):
100 100 with tt.AssertPrints(u'дбИЖ', suppress=False):
101 101 ip.run_cell('fail()')
102
103 def test_nonascii_msg(self):
104 cell = u"raise Exception('é')"
105 expected = u"Exception('é')"
106 ip.run_cell("%xmode plain")
107 with tt.AssertPrints(expected):
108 ip.run_cell(cell)
109
110 ip.run_cell("%xmode verbose")
111 with tt.AssertPrints(expected):
112 ip.run_cell(cell)
113
114 ip.run_cell("%xmode context")
115 with tt.AssertPrints(expected):
116 ip.run_cell(cell)
102 117
103 118
104 119 class NestedGenExprTestCase(unittest.TestCase):
@@ -709,10 +709,10 b' class ListTB(TBTools):'
709 709 have_filedata = False
710 710 Colors = self.Colors
711 711 list = []
712 stype = Colors.excName + etype.__name__ + Colors.Normal
712 stype = py3compat.cast_unicode(Colors.excName + etype.__name__ + Colors.Normal)
713 713 if value is None:
714 714 # Not sure if this can still happen in Python 2.6 and above
715 list.append(py3compat.cast_unicode(stype) + '\n')
715 list.append(stype + '\n')
716 716 else:
717 717 if issubclass(etype, SyntaxError):
718 718 have_filedata = True
@@ -752,10 +752,10 b' class ListTB(TBTools):'
752 752 except Exception:
753 753 s = self._some_str(value)
754 754 if s:
755 list.append('%s%s:%s %s\n' % (str(stype), Colors.excName,
755 list.append('%s%s:%s %s\n' % (stype, Colors.excName,
756 756 Colors.Normal, s))
757 757 else:
758 list.append('%s\n' % str(stype))
758 list.append('%s\n' % stype)
759 759
760 760 # sync with user hooks
761 761 if have_filedata:
@@ -793,9 +793,9 b' class ListTB(TBTools):'
793 793 def _some_str(self, value):
794 794 # Lifted from traceback.py
795 795 try:
796 return str(value)
796 return py3compat.cast_unicode(str(value))
797 797 except:
798 return '<unprintable %s object>' % type(value).__name__
798 return u'<unprintable %s object>' % type(value).__name__
799 799
800 800
801 801 #----------------------------------------------------------------------------
@@ -1432,6 +1432,7 b' class SyntaxTB(ListTB):'
1432 1432 newtext = ulinecache.getline(value.filename, value.lineno)
1433 1433 if newtext:
1434 1434 value.text = newtext
1435 self.last_syntax_error = value
1435 1436 return super(SyntaxTB, self).structured_traceback(etype, value, elist,
1436 1437 tb_offset=tb_offset, context=context)
1437 1438
@@ -41,7 +41,7 b' class Audio(DisplayObject):'
41 41 filename : unicode
42 42 Path to a local file to load the data from.
43 43 embed : boolean
44 Should the image data be embedded using a data URI (True) or should
44 Should the audio data be embedded using a data URI (True) or should
45 45 the original source be referenced. Set this to True if you want the
46 46 audio to playable later with no internet connection in the notebook.
47 47
@@ -15,7 +15,7 b' from IPython.core import ultratb, compilerop'
15 15 from IPython.core.magic import Magics, magics_class, line_magic
16 16 from IPython.core.interactiveshell import DummyMod
17 17 from IPython.core.interactiveshell import InteractiveShell
18 from IPython.terminal.interactiveshell import TerminalInteractiveShell
18 from IPython.terminal.ptshell import TerminalInteractiveShell
19 19 from IPython.terminal.ipapp import load_default_config
20 20
21 21 from traitlets import Bool, CBool, Unicode
@@ -136,6 +136,9 b' class InteractiveShellEmbed(TerminalInteractiveShell):'
136 136 else:
137 137 self.old_banner2 = ''
138 138
139 if self.display_banner:
140 self.show_banner()
141
139 142 # Call the embedding code with a stack depth of 1 so it can skip over
140 143 # our call and get the original caller's namespaces.
141 144 self.mainloop(local_ns, module, stack_depth=stack_depth,
@@ -182,6 +185,9 b' class InteractiveShellEmbed(TerminalInteractiveShell):'
182 185 module = DummyMod()
183 186 module.__dict__ = global_ns
184 187
188 if (display_banner is not None):
189 warnings.warn("The display_banner parameter is deprecated.", DeprecationWarning)
190
185 191 # Get locals and globals from caller
186 192 if ((local_ns is None or module is None or compile_flags is None)
187 193 and self.default_user_namespaces):
@@ -191,7 +197,14 b' class InteractiveShellEmbed(TerminalInteractiveShell):'
191 197 local_ns = call_frame.f_locals
192 198 if module is None:
193 199 global_ns = call_frame.f_globals
194 module = sys.modules[global_ns['__name__']]
200 try:
201 module = sys.modules[global_ns['__name__']]
202 except KeyError:
203 warnings.warn("Failed to get module %s" % \
204 global_ns.get('__name__', 'unknown module')
205 )
206 module = DummyMod()
207 module.__dict__ = global_ns
195 208 if compile_flags is None:
196 209 compile_flags = (call_frame.f_code.co_flags &
197 210 compilerop.PyCF_MASK)
@@ -226,7 +239,7 b' class InteractiveShellEmbed(TerminalInteractiveShell):'
226 239 self.set_completer_frame()
227 240
228 241 with self.builtin_trap, self.display_trap:
229 self.interact(display_banner=display_banner)
242 self.interact()
230 243
231 244 # now, purge out the local namespace of IPython's hidden variables.
232 245 if local_ns is not None:
@@ -4,18 +4,22 b' from __future__ import print_function'
4 4 import os
5 5 import sys
6 6 import signal
7 import unicodedata
8 from warnings import warn
9 from wcwidth import wcwidth
7 10
11 from IPython.core.error import TryNext
8 12 from IPython.core.interactiveshell import InteractiveShell
9 13 from IPython.utils.py3compat import PY3, cast_unicode_py2, input
10 14 from IPython.utils.terminal import toggle_set_term_title, set_term_title
11 15 from IPython.utils.process import abbrev_cwd
12 from traitlets import Bool, Unicode, Dict
16 from traitlets import Bool, CBool, Unicode, Dict, Integer
13 17
14 18 from prompt_toolkit.completion import Completer, Completion
15 from prompt_toolkit.enums import DEFAULT_BUFFER
19 from prompt_toolkit.enums import DEFAULT_BUFFER, SEARCH_BUFFER
16 20 from prompt_toolkit.filters import HasFocus, HasSelection, Condition
17 21 from prompt_toolkit.history import InMemoryHistory
18 from prompt_toolkit.shortcuts import create_prompt_application, create_eventloop
22 from prompt_toolkit.shortcuts import create_prompt_application, create_eventloop, create_prompt_layout
19 23 from prompt_toolkit.interface import CommandLineInterface
20 24 from prompt_toolkit.key_binding.manager import KeyBindingManager
21 25 from prompt_toolkit.key_binding.vi_state import InputMode
@@ -23,9 +27,9 b' from prompt_toolkit.key_binding.bindings.vi import ViStateFilter'
23 27 from prompt_toolkit.keys import Keys
24 28 from prompt_toolkit.layout.lexers import Lexer
25 29 from prompt_toolkit.layout.lexers import PygmentsLexer
26 from prompt_toolkit.styles import PygmentsStyle
30 from prompt_toolkit.styles import PygmentsStyle, DynamicStyle
27 31
28 from pygments.styles import get_style_by_name
32 from pygments.styles import get_style_by_name, get_all_styles
29 33 from pygments.lexers import Python3Lexer, BashLexer, PythonLexer
30 34 from pygments.token import Token
31 35
@@ -33,7 +37,6 b' from .pt_inputhooks import get_inputhook_func'
33 37 from .interactiveshell import get_default_editor, TerminalMagics
34 38
35 39
36
37 40 class IPythonPTCompleter(Completer):
38 41 """Adaptor to provide IPython completions to prompt_toolkit"""
39 42 def __init__(self, ipy_completer):
@@ -49,6 +52,22 b' class IPythonPTCompleter(Completer):'
49 52 )
50 53 start_pos = -len(used)
51 54 for m in matches:
55 m = unicodedata.normalize('NFC', m)
56
57 # When the first character of the completion has a zero length,
58 # then it's probably a decomposed unicode character. E.g. caused by
59 # the "\dot" completion. Try to compose again with the previous
60 # character.
61 if wcwidth(m[0]) == 0:
62 if document.cursor_position + start_pos > 0:
63 char_before = document.text[document.cursor_position + start_pos - 1]
64 m = unicodedata.normalize('NFC', char_before + m)
65
66 # Yield the modified completion instead, if this worked.
67 if wcwidth(m[0:1]) == 1:
68 yield Completion(m, start_position=start_pos - 1)
69 continue
70
52 71 # TODO: Use Jedi to determine meta_text
53 72 # (Jedi currently has a bug that results in incorrect information.)
54 73 # meta_text = ''
@@ -74,8 +93,23 b' class IPythonPTLexer(Lexer):'
74 93 class TerminalInteractiveShell(InteractiveShell):
75 94 colors_force = True
76 95
96 space_for_menu = Integer(6, config=True, help='Number of line at the bottom of the screen '
97 'to reserve for the completion menu')
98
99 def _space_for_menu_changed(self, old, new):
100 self._update_layout()
101
77 102 pt_cli = None
78 103
104 autoedit_syntax = CBool(False, config=True,
105 help="auto editing of files with syntax errors.")
106
107 confirm_exit = CBool(True, config=True,
108 help="""
109 Set to confirm when you try to exit IPython with an EOF (Control-D
110 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
111 you can force a direct exit without any confirmation.""",
112 )
79 113 vi_mode = Bool(False, config=True,
80 114 help="Use vi style keybindings at the prompt",
81 115 )
@@ -84,10 +118,13 b' class TerminalInteractiveShell(InteractiveShell):'
84 118 help="Enable mouse support in the prompt"
85 119 )
86 120
87 highlighting_style = Unicode('', config=True,
88 help="The name of a Pygments style to use for syntax highlighting"
121 highlighting_style = Unicode('default', config=True,
122 help="The name of a Pygments style to use for syntax highlighting: \n %s" % ', '.join(get_all_styles())
89 123 )
90 124
125 def _highlighting_style_changed(self, old, new):
126 self._style = self._make_style_from_name(self.highlighting_style)
127
91 128 highlighting_style_overrides = Dict(config=True,
92 129 help="Override highlighting format for specific tokens"
93 130 )
@@ -158,6 +195,13 b' class TerminalInteractiveShell(InteractiveShell):'
158 195 def _(event):
159 196 event.current_buffer.reset()
160 197
198 @kbmanager.registry.add_binding(Keys.ControlC, filter=HasFocus(SEARCH_BUFFER))
199 def _(event):
200 if event.current_buffer.document.text:
201 event.current_buffer.reset()
202 else:
203 event.cli.push_focus(DEFAULT_BUFFER)
204
161 205 supports_suspend = Condition(lambda cli: hasattr(signal, 'SIGTSTP'))
162 206
163 207 @kbmanager.registry.add_binding(Keys.ControlZ, filter=supports_suspend)
@@ -189,13 +233,33 b' class TerminalInteractiveShell(InteractiveShell):'
189 233 if cell and (cell != last_cell):
190 234 history.append(cell)
191 235
236 self._style = self._make_style_from_name(self.highlighting_style)
237 style = DynamicStyle(lambda: self._style)
238
239 self._app = create_prompt_application(
240 key_bindings_registry=kbmanager.registry,
241 history=history,
242 completer=IPythonPTCompleter(self.Completer),
243 enable_history_search=True,
244 style=style,
245 mouse_support=self.mouse_support,
246 **self._layout_options()
247 )
248 self.pt_cli = CommandLineInterface(self._app,
249 eventloop=create_eventloop(self.inputhook))
250
251 def _make_style_from_name(self, name):
252 """
253 Small wrapper that make an IPython compatible style from a style name
254
255 We need that to add style for prompt ... etc.
256 """
257 style_cls = get_style_by_name(name)
192 258 style_overrides = {
193 259 Token.Prompt: '#009900',
194 260 Token.PromptNum: '#00ff00 bold',
195 261 }
196 if self.highlighting_style:
197 style_cls = get_style_by_name(self.highlighting_style)
198 else:
262 if name is 'default':
199 263 style_cls = get_style_by_name('default')
200 264 # The default theme needs to be visible on both a dark background
201 265 # and a light background, because we can't tell what the terminal
@@ -212,21 +276,27 b' class TerminalInteractiveShell(InteractiveShell):'
212 276 style = PygmentsStyle.from_defaults(pygments_style_cls=style_cls,
213 277 style_dict=style_overrides)
214 278
215 app = create_prompt_application(multiline=True,
216 lexer=IPythonPTLexer(),
217 get_prompt_tokens=self.get_prompt_tokens,
218 get_continuation_tokens=self.get_continuation_tokens,
219 key_bindings_registry=kbmanager.registry,
220 history=history,
221 completer=IPythonPTCompleter(self.Completer),
222 enable_history_search=True,
223 style=style,
224 mouse_support=self.mouse_support,
225 reserve_space_for_menu=6,
226 )
279 return style
280
281 def _layout_options(self):
282 """
283 Return the current layout option for the current Terminal InteractiveShell
284 """
285 return {
286 'lexer':IPythonPTLexer(),
287 'reserve_space_for_menu':self.space_for_menu,
288 'get_prompt_tokens':self.get_prompt_tokens,
289 'get_continuation_tokens':self.get_continuation_tokens,
290 'multiline':True,
291 }
227 292
228 self.pt_cli = CommandLineInterface(app,
229 eventloop=create_eventloop(self.inputhook))
293
294 def _update_layout(self):
295 """
296 Ask for a re computation of the application layout, if for example ,
297 some configuration options have changed.
298 """
299 self._app.layout = create_prompt_layout(**self._layout_options())
230 300
231 301 def prompt_for_code(self):
232 302 document = self.pt_cli.run(pre_run=self.pre_prompt)
@@ -286,12 +356,15 b' class TerminalInteractiveShell(InteractiveShell):'
286 356 try:
287 357 code = self.prompt_for_code()
288 358 except EOFError:
289 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'):
359 if (not self.confirm_exit) \
360 or self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'):
290 361 self.ask_exit()
291 362
292 363 else:
293 364 if code:
294 365 self.run_cell(code, store_history=True)
366 if self.autoedit_syntax and self.SyntaxTB.last_syntax_error:
367 self.edit_syntax_error()
295 368
296 369 def mainloop(self):
297 370 # An extra layer of protection in case someone mashing Ctrl-C breaks
@@ -314,5 +387,69 b' class TerminalInteractiveShell(InteractiveShell):'
314 387 else:
315 388 self._inputhook = None
316 389
390 # Methods to support auto-editing of SyntaxErrors:
391
392 def edit_syntax_error(self):
393 """The bottom half of the syntax error handler called in the main loop.
394
395 Loop until syntax error is fixed or user cancels.
396 """
397
398 while self.SyntaxTB.last_syntax_error:
399 # copy and clear last_syntax_error
400 err = self.SyntaxTB.clear_err_state()
401 if not self._should_recompile(err):
402 return
403 try:
404 # may set last_syntax_error again if a SyntaxError is raised
405 self.safe_execfile(err.filename, self.user_ns)
406 except:
407 self.showtraceback()
408 else:
409 try:
410 with open(err.filename) as f:
411 # This should be inside a display_trap block and I
412 # think it is.
413 sys.displayhook(f.read())
414 except:
415 self.showtraceback()
416
417 def _should_recompile(self, e):
418 """Utility routine for edit_syntax_error"""
419
420 if e.filename in ('<ipython console>', '<input>', '<string>',
421 '<console>', '<BackgroundJob compilation>',
422 None):
423 return False
424 try:
425 if (self.autoedit_syntax and
426 not self.ask_yes_no(
427 'Return to editor to correct syntax error? '
428 '[Y/n] ', 'y')):
429 return False
430 except EOFError:
431 return False
432
433 def int0(x):
434 try:
435 return int(x)
436 except TypeError:
437 return 0
438
439 # always pass integer line and offset values to editor hook
440 try:
441 self.hooks.fix_error_editor(e.filename,
442 int0(e.lineno), int0(e.offset),
443 e.msg)
444 except TryNext:
445 warn('Could not open editor')
446 return False
447 return True
448
449 # Run !system commands directly, not through pipes, so terminal programs
450 # work correctly.
451 system = InteractiveShell.system_raw
452
453
317 454 if __name__ == '__main__':
318 455 TerminalInteractiveShell.instance().interact()
@@ -25,8 +25,6 b' import logging'
25 25 import os
26 26 import re
27 27 import sys
28 import traceback
29 import unittest
30 28
31 29 from testpath import modified_env
32 30
@@ -41,10 +39,9 b' from doctest import (REPORTING_FLAGS, REPORT_ONLY_FIRST_FAILURE,'
41 39 linecache)
42 40
43 41 # Third-party modules
44 import nose.core
45 42
46 43 from nose.plugins import doctests, Plugin
47 from nose.util import anyp, getpackage, test_address, resolve_name, tolist
44 from nose.util import anyp, tolist
48 45
49 46 # Our own imports
50 47 from IPython.utils.py3compat import builtin_mod, PY3, getcwd
@@ -143,7 +140,7 b' class DocTestFinder(doctest.DocTestFinder):'
143 140 # doctests in extension modules.
144 141
145 142 # Local shorthands
146 from inspect import isroutine, isclass, ismodule
143 from inspect import isroutine, isclass
147 144
148 145 # Look for tests in a module's contained objects.
149 146 if inspect.ismodule(obj) and self._recurse:
@@ -36,3 +36,8 b' def skip_doctest_py3(f):'
36 36 """Decorator - skip the doctest under Python 3."""
37 37 f.skip_doctest = (sys.version_info[0] >= 3)
38 38 return f
39
40 def skip_doctest_py2(f):
41 """Decorator - skip the doctest under Python 3."""
42 f.skip_doctest = (sys.version_info[0] < 3)
43 return f
@@ -9,22 +9,18 b' Authors:'
9 9 * Alexander Belchenko (e-mail: bialix AT ukr.net)
10 10 """
11 11
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2008-2011 The IPython Development Team
14 #
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
18
19 #-----------------------------------------------------------------------------
20 # Imports
21 #-----------------------------------------------------------------------------
12 # Copyright (c) IPython Development Team.
13 # Distributed under the terms of the Modified BSD License.
22 14
23 15 import os
24 16 import struct
25 17 import sys
26 18 import warnings
27 import backports.shutil_get_terminal_size
19 try:
20 from shutil import get_terminal_size as _get_terminal_size
21 except ImportError:
22 # use backport on Python 2
23 from backports.shutil_get_terminal_size import get_terminal_size as _get_terminal_size
28 24
29 25 from . import py3compat
30 26
@@ -122,4 +118,4 b' def freeze_term_title():'
122 118
123 119
124 120 def get_terminal_size(defaultx=80, defaulty=25):
125 return backports.shutil_get_terminal_size.get_terminal_size((defaultx, defaulty))
121 return _get_terminal_size((defaultx, defaulty))
@@ -19,7 +19,11 b' import random'
19 19 import sys
20 20
21 21 import nose.tools as nt
22 import path
22 try:
23 from pathlib import Path
24 except ImportError:
25 # Python 2 backport
26 from pathlib2 import Path
23 27
24 28 from IPython.utils import text
25 29
@@ -207,7 +211,7 b' def test_LSString():'
207 211 nt.assert_equal(lss.l, ['abc', 'def'])
208 212 nt.assert_equal(lss.s, 'abc def')
209 213 lss = text.LSString(os.getcwd())
210 nt.assert_is_instance(lss.p[0], path.path)
214 nt.assert_is_instance(lss.p[0], Path)
211 215
212 216 def test_SList():
213 217 sl = text.SList(['a 11', 'b 1', 'a 2'])
@@ -14,6 +14,11 b' import re'
14 14 import sys
15 15 import textwrap
16 16 from string import Formatter
17 try:
18 from pathlib import Path
19 except ImportError:
20 # Python 2 backport
21 from pathlib2 import Path
17 22
18 23 from IPython.testing.skipdoctest import skip_doctest_py3, skip_doctest
19 24 from IPython.utils import py3compat
@@ -64,11 +69,10 b' class LSString(str):'
64 69 n = nlstr = property(get_nlstr)
65 70
66 71 def get_paths(self):
67 from path import path
68 72 try:
69 73 return self.__paths
70 74 except AttributeError:
71 self.__paths = [path(p) for p in self.split('\n') if os.path.exists(p)]
75 self.__paths = [Path(p) for p in self.split('\n') if os.path.exists(p)]
72 76 return self.__paths
73 77
74 78 p = paths = property(get_paths)
@@ -123,11 +127,10 b' class SList(list):'
123 127 n = nlstr = property(get_nlstr)
124 128
125 129 def get_paths(self):
126 from path import path
127 130 try:
128 131 return self.__paths
129 132 except AttributeError:
130 self.__paths = [path(p) for p in self if os.path.exists(p)]
133 self.__paths = [Path(p) for p in self if os.path.exists(p)]
131 134 return self.__paths
132 135
133 136 p = paths = property(get_paths)
@@ -28,7 +28,7 b' these manuals. If you have Sphinx installed, you can build them by typing'
28 28 See the `install page <http://ipython.org/install.html>`__ to install IPython.
29 29
30 30 The Notebook, Qt console and a number of other pieces are now parts of *Jupyter*.
31 See the `Jupyter installation docs <http://jupyter.readthedocs.org/en/latest/install.html>`__
31 See the `Jupyter installation docs <http://jupyter.readthedocs.io/en/latest/install.html>`__
32 32 if you want to use these.
33 33
34 34 Officially, IPython requires Python version 2.7, or 3.3 and above.
@@ -22,7 +22,7 b" ON_RTD = os.environ.get('READTHEDOCS', None) == 'True'"
22 22 if ON_RTD:
23 23 # Mock the presence of matplotlib, which we don't have on RTD
24 24 # see
25 # http://read-the-docs.readthedocs.org/en/latest/faq.html
25 # http://read-the-docs.readthedocs.io/en/latest/faq.html
26 26 tags.add('rtd')
27 27
28 28 # RTD doesn't use the Makefile, so re-run autogen_{things}.py here.
@@ -201,12 +201,12 b' html_additional_pages = {'
201 201 # Output file base name for HTML help builder.
202 202 htmlhelp_basename = 'ipythondoc'
203 203
204 intersphinx_mapping = {'python': ('http://docs.python.org/2/', None),
204 intersphinx_mapping = {'python': ('http://docs.python.org/3/', None),
205 205 'rpy2': ('http://rpy.sourceforge.net/rpy2/doc-2.4/html/', None),
206 'traitlets': ('http://traitlets.readthedocs.org/en/latest/', None),
207 'jupyterclient': ('http://jupyter-client.readthedocs.org/en/latest/', None),
208 'ipyparallel': ('http://ipyparallel.readthedocs.org/en/latest/', None),
209 'jupyter': ('http://jupyter.readthedocs.org/en/latest/', None),
206 'traitlets': ('http://traitlets.readthedocs.io/en/latest/', None),
207 'jupyterclient': ('http://jupyter-client.readthedocs.io/en/latest/', None),
208 'ipyparallel': ('http://ipyparallel.readthedocs.io/en/latest/', None),
209 'jupyter': ('http://jupyter.readthedocs.io/en/latest/', None),
210 210 }
211 211
212 212 # Options for LaTeX output
@@ -19,4 +19,4 b" Developer's guide for third party tools and libraries"
19 19 lexer
20 20 pycompat
21 21 config
22 inputhook_app No newline at end of file
22 inputhook_app
@@ -7,7 +7,7 b' You can now re-use the kernel machinery in IPython to easily make new kernels.'
7 7 This is useful for languages that have Python bindings, such as `Octave
8 8 <http://www.gnu.org/software/octave/>`_ (via
9 9 `Oct2Py <http://blink1073.github.io/oct2py/docs/index.html>`_), or languages
10 where the REPL can be controlled in a tty using `pexpect <http://pexpect.readthedocs.org/en/latest/>`_,
10 where the REPL can be controlled in a tty using `pexpect <http://pexpect.readthedocs.io/en/latest/>`_,
11 11 such as bash.
12 12
13 13 .. seealso::
@@ -27,10 +27,10 b' Contents'
27 27
28 28 .. seealso::
29 29
30 `Jupyter documentation <http://jupyter.readthedocs.org/en/latest/>`__
30 `Jupyter documentation <http://jupyter.readthedocs.io/en/latest/>`__
31 31 The Notebook code and many other pieces formerly in IPython are now parts
32 32 of Project Jupyter.
33 `ipyparallel documentation <http://ipyparallel.readthedocs.org/en/latest/>`__
33 `ipyparallel documentation <http://ipyparallel.readthedocs.io/en/latest/>`__
34 34 Formerly ``IPython.parallel``.
35 35
36 36
@@ -2,7 +2,7 b' IPython requires Python 2.7 or \xe2\x89\xa5 3.3.'
2 2
3 3 .. seealso::
4 4
5 `Installing Jupyter <http://jupyter.readthedocs.org/en/latest/install.html>`__
5 `Installing Jupyter <http://jupyter.readthedocs.io/en/latest/install.html>`__
6 6 The Notebook, nbconvert, and many other former pieces of IPython are now
7 7 part of Project Jupyter.
8 8
@@ -15,4 +15,4 b' Using IPython for interactive work'
15 15 .. seealso::
16 16
17 17 `A Qt Console for Jupyter <http://jupyter.org/qtconsole/>`__
18 `The Jupyter Notebook <http://jupyter-notebook.readthedocs.org/en/latest/>`__
18 `The Jupyter Notebook <http://jupyter-notebook.readthedocs.io/en/latest/>`__
@@ -219,7 +219,7 b' different numbers which correspond to the Process ID of the kernel.'
219 219
220 220 You can read more about using `ipython qtconsole
221 221 <http://jupyter.org/qtconsole/>`_, and
222 `ipython notebook <http://jupyter-notebook.readthedocs.org/en/latest/>`_. There
222 `ipython notebook <http://jupyter-notebook.readthedocs.io/en/latest/>`_. There
223 223 is also a :ref:`message spec <messaging>` which documents the protocol for
224 224 communication between kernels
225 225 and clients.
@@ -1000,7 +1000,7 b' Pull Requests (793):'
1000 1000 * :ghpull:`2274`: CLN: Use name to id mapping of notebooks instead of searching.
1001 1001 * :ghpull:`2270`: SSHLauncher tweaks
1002 1002 * :ghpull:`2269`: add missing location when disambiguating controller IP
1003 * :ghpull:`2263`: Allow docs to build on http://readthedocs.org/
1003 * :ghpull:`2263`: Allow docs to build on http://readthedocs.io/
1004 1004 * :ghpull:`2256`: Adding data publication example notebook.
1005 1005 * :ghpull:`2255`: better flush iopub with AsyncResults
1006 1006 * :ghpull:`2261`: Fix: longest_substr([]) -> ''
@@ -3,9 +3,33 b''
3 3 Issues closed in the 4.x development cycle
4 4 ==========================================
5 5
6 Issues closed in 4.1
6
7 Issues closed in 4.2
7 8 --------------------
8 9
10 GitHub stats for 2015/02/02 - 2016/04/20 (since 4.1)
11
12 These lists are automatically generated, and may be incomplete or contain duplicates.
13
14 We closed 10 issues and merged 22 pull requests.
15 The full list can be seen `on GitHub <https://github.com/ipython/ipython/issues?q=milestone%3A4.2+>`__
16
17 The following 10 authors contributed 27 commits.
18
19 * Benjamin Ragan-Kelley
20 * Carlos Cordoba
21 * Gökhan Karabulut
22 * Jonas Rauber
23 * Matthias Bussonnier
24 * Paul Ivanov
25 * Sebastian Bank
26 * Thomas A Caswell
27 * Thomas Kluyver
28 * Vincent Woo
29
30
31 Issues closed in 4.1
32 --------------------
9 33
10 34 GitHub stats for 2015/08/12 - 2016/02/02 (since 4.0.0)
11 35
@@ -2,6 +2,19 b''
2 2 4.x Series
3 3 ============
4 4
5 IPython 4.2
6 ===========
7
8 IPython 4.2 (April, 2016) includes various bugfixes and improvements over 4.1.
9
10 - Fix ``ipython -i`` on errors, which was broken in 4.1.
11 - The delay meant to highlight deprecated commands that have moved to jupyter has been removed.
12 - Improve compatibility with future versions of traitlets and matplotlib.
13 - Use stdlib :func:`python:shutil.get_terminal_size` to measure terminal width when displaying tracebacks
14 (provided by ``backports.shutil_get_terminal_size`` on Python 2).
15
16 You can see the rest `on GitHub <https://github.com/ipython/ipython/issues?q=milestone%3A4.2>`__.
17
5 18
6 19 IPython 4.1
7 20 ===========
@@ -34,8 +47,8 b' Released August, 2015'
34 47
35 48 IPython 4.0 is the first major release after the Big Split.
36 49 IPython no longer contains the notebook, qtconsole, etc. which have moved to
37 `jupyter <https://jupyter.readthedocs.org>`_.
38 IPython subprojects, such as `IPython.parallel <https://ipyparallel.readthedocs.org>`_ and `widgets <https://ipywidgets.readthedocs.org>`_ have moved to their own repos as well.
50 `jupyter <https://jupyter.readthedocs.io>`_.
51 IPython subprojects, such as `IPython.parallel <https://ipyparallel.readthedocs.io>`_ and `widgets <https://ipywidgets.readthedocs.io>`_ have moved to their own repos as well.
39 52
40 53 The following subpackages are deprecated:
41 54
@@ -354,7 +354,7 b''
354 354 "cell_type": "markdown",
355 355 "metadata": {},
356 356 "source": [
357 "[Vincent](https://vincent.readthedocs.org/en/latest/) is a visualization library that uses the [Vega](http://trifacta.github.io/vega/) visualization grammar to build [d3.js](http://d3js.org/) based visualizations in the Notebook and on http://nbviewer.ipython.org. `Visualization` objects in Vincetn have rich HTML and JavaSrcript representations."
357 "[Vincent](https://vincent.readthedocs.io/en/latest/) is a visualization library that uses the [Vega](http://trifacta.github.io/vega/) visualization grammar to build [d3.js](http://d3js.org/) based visualizations in the Notebook and on http://nbviewer.ipython.org. `Visualization` objects in Vincetn have rich HTML and JavaSrcript representations."
358 358 ]
359 359 },
360 360 {
@@ -198,7 +198,6 b' install_requires = ['
198 198 'traitlets',
199 199 'prompt_toolkit>=0.60',
200 200 'pygments',
201 'backports.shutil_get_terminal_size',
202 201 ]
203 202
204 203 # Platform-specific dependencies:
@@ -206,6 +205,8 b' install_requires = ['
206 205 # but requires pip >= 6. pip < 6 ignores these.
207 206
208 207 extras_require.update({
208 ':python_version == "2.7"': ['backports.shutil_get_terminal_size'],
209 ':python_version == "2.7" or python_version == "3.3"': ['pathlib2'],
209 210 ':sys_platform != "win32"': ['pexpect'],
210 211 ':sys_platform == "darwin"': ['appnope'],
211 212 ':sys_platform == "win32"': ['colorama'],
@@ -168,7 +168,7 b' if __name__ == "__main__":'
168 168 state='closed',
169 169 auth=True,
170 170 )
171 issues, pulls = split_pulls(issues_and_pulls)
171 issues, pulls = split_pulls(issues_and_pulls, project=project)
172 172 else:
173 173 issues = issues_closed_since(since, project=project, pulls=False)
174 174 pulls = issues_closed_since(since, project=project, pulls=True)
General Comments 0
You need to be logged in to leave comments. Login now