##// END OF EJS Templates
use cd --foo instead of cd -foo. also cd --<TAB> works. changes.txt
Ville M. Vainio -
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,391 +1,394 b''
1 1
2 2 """ Implementations for various useful completers
3 3
4 4 See Extensions/ipy_stock_completers.py on examples of how to enable a completer,
5 5 but the basic idea is to do:
6 6
7 7 ip.set_hook('complete_command', svn_completer, str_key = 'svn')
8 8
9 9 """
10 10 import IPython.ipapi
11 11 import glob,os,shlex,sys
12 12 import inspect
13 13 from time import time
14 14 from zipimport import zipimporter
15 15 ip = IPython.ipapi.get()
16 16
17 17 try:
18 18 set
19 19 except:
20 20 from sets import Set as set
21 21
22 22 TIMEOUT_STORAGE = 3 #Time in seconds after which the rootmodules will be stored
23 23 TIMEOUT_GIVEUP = 20 #Time in seconds after which we give up
24 24
25 25 def quick_completer(cmd, completions):
26 26 """ Easily create a trivial completer for a command.
27 27
28 28 Takes either a list of completions, or all completions in string
29 29 (that will be split on whitespace)
30 30
31 31 Example::
32 32
33 33 [d:\ipython]|1> import ipy_completers
34 34 [d:\ipython]|2> ipy_completers.quick_completer('foo', ['bar','baz'])
35 35 [d:\ipython]|3> foo b<TAB>
36 36 bar baz
37 37 [d:\ipython]|3> foo ba
38 38 """
39 39 if isinstance(completions, basestring):
40 40
41 41 completions = completions.split()
42 42 def do_complete(self,event):
43 43 return completions
44 44
45 45 ip.set_hook('complete_command',do_complete, str_key = cmd)
46 46
47 47 def getRootModules():
48 48 """
49 49 Returns a list containing the names of all the modules available in the
50 50 folders of the pythonpath.
51 51 """
52 52 modules = []
53 53 if ip.db.has_key('rootmodules'):
54 54 return ip.db['rootmodules']
55 55 t = time()
56 56 store = False
57 57 for path in sys.path:
58 58 modules += moduleList(path)
59 59 if time() - t >= TIMEOUT_STORAGE and not store:
60 60 store = True
61 61 print "\nCaching the list of root modules, please wait!"
62 62 print "(This will only be done once - type '%rehashx' to " + \
63 63 "reset cache!)"
64 64 print
65 65 if time() - t > TIMEOUT_GIVEUP:
66 66 print "This is taking too long, we give up."
67 67 print
68 68 ip.db['rootmodules'] = []
69 69 return []
70 70
71 71 modules += sys.builtin_module_names
72 72
73 73 modules = list(set(modules))
74 74 if '__init__' in modules:
75 75 modules.remove('__init__')
76 76 modules = list(set(modules))
77 77 if store:
78 78 ip.db['rootmodules'] = modules
79 79 return modules
80 80
81 81 def moduleList(path):
82 82 """
83 83 Return the list containing the names of the modules available in the given
84 84 folder.
85 85 """
86 86
87 87 if os.path.isdir(path):
88 88 folder_list = os.listdir(path)
89 89 elif path.endswith('.egg'):
90 90 try:
91 91 folder_list = [f for f in zipimporter(path)._files]
92 92 except:
93 93 folder_list = []
94 94 else:
95 95 folder_list = []
96 96 #folder_list = glob.glob(os.path.join(path,'*'))
97 97 folder_list = [p for p in folder_list \
98 98 if os.path.exists(os.path.join(path, p,'__init__.py'))\
99 99 or p[-3:] in ('.py','.so')\
100 100 or p[-4:] in ('.pyc','.pyo','.pyd')]
101 101
102 102 folder_list = [os.path.basename(p).split('.')[0] for p in folder_list]
103 103 return folder_list
104 104
105 105 def moduleCompletion(line):
106 106 """
107 107 Returns a list containing the completion possibilities for an import line.
108 108 The line looks like this :
109 109 'import xml.d'
110 110 'from xml.dom import'
111 111 """
112 112 def tryImport(mod, only_modules=False):
113 113 def isImportable(module, attr):
114 114 if only_modules:
115 115 return inspect.ismodule(getattr(module, attr))
116 116 else:
117 117 return not(attr[:2] == '__' and attr[-2:] == '__')
118 118 try:
119 119 m = __import__(mod)
120 120 except:
121 121 return []
122 122 mods = mod.split('.')
123 123 for module in mods[1:]:
124 124 m = getattr(m,module)
125 125 if (not hasattr(m, '__file__')) or (not only_modules) or\
126 126 (hasattr(m, '__file__') and '__init__' in m.__file__):
127 127 completion_list = [attr for attr in dir(m) if isImportable(m, attr)]
128 128 completion_list.extend(getattr(m,'__all__',[]))
129 129 if hasattr(m, '__file__') and '__init__' in m.__file__:
130 130 completion_list.extend(moduleList(os.path.dirname(m.__file__)))
131 131 completion_list = list(set(completion_list))
132 132 if '__init__' in completion_list:
133 133 completion_list.remove('__init__')
134 134 return completion_list
135 135
136 136 words = line.split(' ')
137 137 if len(words) == 3 and words[0] == 'from':
138 138 return ['import ']
139 139 if len(words) < 3 and (words[0] in ['import','from']) :
140 140 if len(words) == 1:
141 141 return getRootModules()
142 142 mod = words[1].split('.')
143 143 if len(mod) < 2:
144 144 return getRootModules()
145 145 completion_list = tryImport('.'.join(mod[:-1]), True)
146 146 completion_list = ['.'.join(mod[:-1] + [el]) for el in completion_list]
147 147 return completion_list
148 148 if len(words) >= 3 and words[0] == 'from':
149 149 mod = words[1]
150 150 return tryImport(mod)
151 151
152 152 def vcs_completer(commands, event):
153 153 """ utility to make writing typical version control app completers easier
154 154
155 155 VCS command line apps typically have the format:
156 156
157 157 [sudo ]PROGNAME [help] [command] file file...
158 158
159 159 """
160 160
161 161
162 162 cmd_param = event.line.split()
163 163 if event.line.endswith(' '):
164 164 cmd_param.append('')
165 165
166 166 if cmd_param[0] == 'sudo':
167 167 cmd_param = cmd_param[1:]
168 168
169 169 if len(cmd_param) == 2 or 'help' in cmd_param:
170 170 return commands.split()
171 171
172 172 return ip.IP.Completer.file_matches(event.symbol)
173 173
174 174
175 175 pkg_cache = None
176 176
177 177 def module_completer(self,event):
178 178 """ Give completions after user has typed 'import ...' or 'from ...'"""
179 179
180 180 # This works in all versions of python. While 2.5 has
181 181 # pkgutil.walk_packages(), that particular routine is fairly dangerous,
182 182 # since it imports *EVERYTHING* on sys.path. That is: a) very slow b) full
183 183 # of possibly problematic side effects.
184 184 # This search the folders in the sys.path for available modules.
185 185
186 186 return moduleCompletion(event.line)
187 187
188 188
189 189 svn_commands = """\
190 190 add blame praise annotate ann cat checkout co cleanup commit ci copy
191 191 cp delete del remove rm diff di export help ? h import info list ls
192 192 lock log merge mkdir move mv rename ren propdel pdel pd propedit pedit
193 193 pe propget pget pg proplist plist pl propset pset ps resolved revert
194 194 status stat st switch sw unlock update
195 195 """
196 196
197 197 def svn_completer(self,event):
198 198 return vcs_completer(svn_commands, event)
199 199
200 200
201 201 hg_commands = """
202 202 add addremove annotate archive backout branch branches bundle cat
203 203 clone commit copy diff export grep heads help identify import incoming
204 204 init locate log manifest merge outgoing parents paths pull push
205 205 qapplied qclone qcommit qdelete qdiff qfold qguard qheader qimport
206 206 qinit qnew qnext qpop qprev qpush qrefresh qrename qrestore qsave
207 207 qselect qseries qtop qunapplied recover remove rename revert rollback
208 208 root serve showconfig status strip tag tags tip unbundle update verify
209 209 version
210 210 """
211 211
212 212 def hg_completer(self,event):
213 213 """ Completer for mercurial commands """
214 214
215 215 return vcs_completer(hg_commands, event)
216 216
217 217
218 218
219 219 __bzr_commands = None
220 220
221 221 def bzr_commands():
222 222 global __bzr_commands
223 223 if __bzr_commands is not None:
224 224 return __bzr_commands
225 225 out = os.popen('bzr help commands')
226 226 __bzr_commands = [l.split()[0] for l in out]
227 227 return __bzr_commands
228 228
229 229 def bzr_completer(self,event):
230 230 """ Completer for bazaar commands """
231 231 cmd_param = event.line.split()
232 232 if event.line.endswith(' '):
233 233 cmd_param.append('')
234 234
235 235 if len(cmd_param) > 2:
236 236 cmd = cmd_param[1]
237 237 param = cmd_param[-1]
238 238 output_file = (param == '--output=')
239 239 if cmd == 'help':
240 240 return bzr_commands()
241 241 elif cmd in ['bundle-revisions','conflicts',
242 242 'deleted','nick','register-branch',
243 243 'serve','unbind','upgrade','version',
244 244 'whoami'] and not output_file:
245 245 return []
246 246 else:
247 247 # the rest are probably file names
248 248 return ip.IP.Completer.file_matches(event.symbol)
249 249
250 250 return bzr_commands()
251 251
252 252
253 253 def shlex_split(x):
254 254 """Helper function to split lines into segments."""
255 255 #shlex.split raise exception if syntax error in sh syntax
256 256 #for example if no closing " is found. This function keeps dropping
257 257 #the last character of the line until shlex.split does not raise
258 258 #exception. Adds end of the line to the result of shlex.split
259 259 #example: %run "c:/python -> ['%run','"c:/python']
260 260 endofline=[]
261 261 while x!="":
262 262 try:
263 263 comps=shlex.split(x)
264 264 if len(endofline)>=1:
265 265 comps.append("".join(endofline))
266 266 return comps
267 267 except ValueError:
268 268 endofline=[x[-1:]]+endofline
269 269 x=x[:-1]
270 270 return ["".join(endofline)]
271 271
272 272 def runlistpy(self, event):
273 273 comps = shlex_split(event.line)
274 274 relpath = (len(comps) > 1 and comps[-1] or '').strip("'\"")
275 275
276 276 #print "\nev=",event # dbg
277 277 #print "rp=",relpath # dbg
278 278 #print 'comps=',comps # dbg
279 279
280 280 lglob = glob.glob
281 281 isdir = os.path.isdir
282 282 if relpath.startswith('~'):
283 283 relpath = os.path.expanduser(relpath)
284 284 dirs = [f.replace('\\','/') + "/" for f in lglob(relpath+'*')
285 285 if isdir(f)]
286 286
287 287 # Find if the user has already typed the first filename, after which we
288 288 # should complete on all files, since after the first one other files may
289 289 # be arguments to the input script.
290 290 #filter(
291 291 if filter(lambda f: f.endswith('.py') or f.endswith('.ipy') or
292 292 f.endswith('.pyw'),comps):
293 293 pys = [f.replace('\\','/') for f in lglob('*')]
294 294 else:
295 295 pys = [f.replace('\\','/')
296 296 for f in lglob(relpath+'*.py') + lglob(relpath+'*.ipy') +
297 297 lglob(relpath + '*.pyw')]
298 298 return dirs + pys
299 299
300 300
301 301 greedy_cd_completer = False
302 302
303 303 def cd_completer(self, event):
304 304 relpath = event.symbol
305 305 #print event # dbg
306 306 if '-b' in event.line:
307 307 # return only bookmark completions
308 308 bkms = self.db.get('bookmarks',{})
309 309 return bkms.keys()
310 310
311 311
312 312 if event.symbol == '-':
313 313 width_dh = str(len(str(len(ip.user_ns['_dh']) + 1)))
314 314 # jump in directory history by number
315 315 fmt = '-%0' + width_dh +'d [%s]'
316 316 ents = [ fmt % (i,s) for i,s in enumerate(ip.user_ns['_dh'])]
317 317 if len(ents) > 1:
318 318 return ents
319 319 return []
320 320
321 if event.symbol.startswith('--'):
322 return ["--" + os.path.basename(d) for d in ip.user_ns['_dh']]
323
321 324 if relpath.startswith('~'):
322 325 relpath = os.path.expanduser(relpath).replace('\\','/')
323 326 found = []
324 327 for d in [f.replace('\\','/') + '/' for f in glob.glob(relpath+'*')
325 328 if os.path.isdir(f)]:
326 329 if ' ' in d:
327 330 # we don't want to deal with any of that, complex code
328 331 # for this is elsewhere
329 332 raise IPython.ipapi.TryNext
330 333 found.append( d )
331 334
332 335 if not found:
333 336 if os.path.isdir(relpath):
334 337 return [relpath]
335 338 raise IPython.ipapi.TryNext
336 339
337 340
338 341 def single_dir_expand(matches):
339 342 "Recursively expand match lists containing a single dir."
340 343
341 344 if len(matches) == 1 and os.path.isdir(matches[0]):
342 345 # Takes care of links to directories also. Use '/'
343 346 # explicitly, even under Windows, so that name completions
344 347 # don't end up escaped.
345 348 d = matches[0]
346 349 if d[-1] in ['/','\\']:
347 350 d = d[:-1]
348 351
349 352 subdirs = [p for p in os.listdir(d) if os.path.isdir( d + '/' + p) and not p.startswith('.')]
350 353 if subdirs:
351 354 matches = [ (d + '/' + p) for p in subdirs ]
352 355 return single_dir_expand(matches)
353 356 else:
354 357 return matches
355 358 else:
356 359 return matches
357 360
358 361 if greedy_cd_completer:
359 362 return single_dir_expand(found)
360 363 else:
361 364 return found
362 365
363 366 def apt_get_packages(prefix):
364 367 out = os.popen('apt-cache pkgnames')
365 368 for p in out:
366 369 if p.startswith(prefix):
367 370 yield p.rstrip()
368 371
369 372
370 373 apt_commands = """\
371 374 update upgrade install remove purge source build-dep dist-upgrade
372 375 dselect-upgrade clean autoclean check"""
373 376
374 377 def apt_completer(self, event):
375 378 """ Completer for apt-get (uses apt-cache internally)
376 379
377 380 """
378 381
379 382
380 383 cmd_param = event.line.split()
381 384 if event.line.endswith(' '):
382 385 cmd_param.append('')
383 386
384 387 if cmd_param[0] == 'sudo':
385 388 cmd_param = cmd_param[1:]
386 389
387 390 if len(cmd_param) == 2 or 'help' in cmd_param:
388 391 return apt_commands.split()
389 392
390 393 return list(apt_get_packages(event.symbol))
391 394
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,195 +1,200 b''
1 1 .. _changes:
2 2
3 3 ==========
4 4 What's new
5 5 ==========
6 6
7 7 .. contents::
8 8
9 9 Release 0.9
10 10 ===========
11 11
12 12 New features
13 13 ------------
14 14
15 15 * The notion of a task has been completely reworked. An `ITask` interface has
16 16 been created. This interface defines the methods that tasks need to implement.
17 17 These methods are now responsible for things like submitting tasks and processing
18 18 results. There are two basic task types: :class:`IPython.kernel.task.StringTask`
19 19 (this is the old `Task` object, but renamed) and the new
20 20 :class:`IPython.kernel.task.MapTask`, which is based on a function.
21 21 * A new interface, :class:`IPython.kernel.mapper.IMapper` has been defined to
22 22 standardize the idea of a `map` method. This interface has a single
23 23 `map` method that has the same syntax as the built-in `map`. We have also defined
24 24 a `mapper` factory interface that creates objects that implement
25 25 :class:`IPython.kernel.mapper.IMapper` for different controllers. Both
26 26 the multiengine and task controller now have mapping capabilties.
27 27 * The parallel function capabilities have been reworks. The major changes are that
28 28 i) there is now an `@parallel` magic that creates parallel functions, ii)
29 29 the syntax for mulitple variable follows that of `map`, iii) both the
30 30 multiengine and task controller now have a parallel function implementation.
31 31 * All of the parallel computing capabilities from `ipython1-dev` have been merged into
32 32 IPython proper. This resulted in the following new subpackages:
33 33 :mod:`IPython.kernel`, :mod:`IPython.kernel.core`, :mod:`IPython.config`,
34 34 :mod:`IPython.tools` and :mod:`IPython.testing`.
35 35 * As part of merging in the `ipython1-dev` stuff, the `setup.py` script and friends
36 36 have been completely refactored. Now we are checking for dependencies using
37 37 the approach that matplotlib uses.
38 38 * The documentation has been completely reorganized to accept the documentation
39 39 from `ipython1-dev`.
40 40 * We have switched to using Foolscap for all of our network protocols in
41 41 :mod:`IPython.kernel`. This gives us secure connections that are both encrypted
42 42 and authenticated.
43 43 * We have a brand new `COPYING.txt` files that describes the IPython license
44 44 and copyright. The biggest change is that we are putting "The IPython
45 45 Development Team" as the copyright holder. We give more details about exactly
46 46 what this means in this file. All developer should read this and use the new
47 47 banner in all IPython source code files.
48 48 * sh profile: ./foo runs foo as system command, no need to do !./foo anymore
49 49 * String lists now support 'sort(field, nums = True)' method (to easily
50 50 sort system command output). Try it with 'a = !ls -l ; a.sort(1, nums=1)'
51 51 * '%cpaste foo' now assigns the pasted block as string list, instead of string
52 52 * The ipcluster script now run by default with no security. This is done because
53 53 the main usage of the script is for starting things on localhost. Eventually
54 54 when ipcluster is able to start things on other hosts, we will put security
55 55 back.
56 * 'cd --foo' searches directory history for string foo, and jumps to that dir.
57 Last part of dir name is checked first. If no matches for that are found,
58 look at the whole path.
56 59
57 60 Bug fixes
58 61 ---------
59 62
60 63 * The colors escapes in the multiengine client are now turned off on win32 as they
61 64 don't print correctly.
62 65 * The :mod:`IPython.kernel.scripts.ipengine` script was exec'ing mpi_import_statement
63 66 incorrectly, which was leading the engine to crash when mpi was enabled.
64 67 * A few subpackages has missing `__init__.py` files.
65 68 * The documentation is only created is Sphinx is found. Previously, the `setup.py`
66 69 script would fail if it was missing.
70 * Greedy 'cd' completion has been disabled again (it was enabled in 0.8.4)
71
67 72
68 73 Backwards incompatible changes
69 74 ------------------------------
70 75
71 76 * :class:`IPython.kernel.client.Task` has been renamed
72 77 :class:`IPython.kernel.client.StringTask` to make way for new task types.
73 78 * The keyword argument `style` has been renamed `dist` in `scatter`, `gather`
74 79 and `map`.
75 80 * Renamed the values that the rename `dist` keyword argument can have from
76 81 `'basic'` to `'b'`.
77 82 * IPython has a larger set of dependencies if you want all of its capabilities.
78 83 See the `setup.py` script for details.
79 84 * The constructors for :class:`IPython.kernel.client.MultiEngineClient` and
80 85 :class:`IPython.kernel.client.TaskClient` no longer take the (ip,port) tuple.
81 86 Instead they take the filename of a file that contains the FURL for that
82 87 client. If the FURL file is in your IPYTHONDIR, it will be found automatically
83 88 and the constructor can be left empty.
84 89 * The asynchronous clients in :mod:`IPython.kernel.asyncclient` are now created
85 90 using the factory functions :func:`get_multiengine_client` and
86 91 :func:`get_task_client`. These return a `Deferred` to the actual client.
87 92 * The command line options to `ipcontroller` and `ipengine` have changed to
88 93 reflect the new Foolscap network protocol and the FURL files. Please see the
89 94 help for these scripts for details.
90 95 * The configuration files for the kernel have changed because of the Foolscap stuff.
91 96 If you were using custom config files before, you should delete them and regenerate
92 97 new ones.
93 98
94 99 Changes merged in from IPython1
95 100 -------------------------------
96 101
97 102 New features
98 103 ............
99 104
100 105 * Much improved ``setup.py`` and ``setupegg.py`` scripts. Because Twisted
101 106 and zope.interface are now easy installable, we can declare them as dependencies
102 107 in our setupegg.py script.
103 108 * IPython is now compatible with Twisted 2.5.0 and 8.x.
104 109 * Added a new example of how to use :mod:`ipython1.kernel.asynclient`.
105 110 * Initial draft of a process daemon in :mod:`ipython1.daemon`. This has not
106 111 been merged into IPython and is still in `ipython1-dev`.
107 112 * The ``TaskController`` now has methods for getting the queue status.
108 113 * The ``TaskResult`` objects not have information about how long the task
109 114 took to run.
110 115 * We are attaching additional attributes to exceptions ``(_ipython_*)`` that
111 116 we use to carry additional info around.
112 117 * New top-level module :mod:`asyncclient` that has asynchronous versions (that
113 118 return deferreds) of the client classes. This is designed to users who want
114 119 to run their own Twisted reactor
115 120 * All the clients in :mod:`client` are now based on Twisted. This is done by
116 121 running the Twisted reactor in a separate thread and using the
117 122 :func:`blockingCallFromThread` function that is in recent versions of Twisted.
118 123 * Functions can now be pushed/pulled to/from engines using
119 124 :meth:`MultiEngineClient.push_function` and :meth:`MultiEngineClient.pull_function`.
120 125 * Gather/scatter are now implemented in the client to reduce the work load
121 126 of the controller and improve performance.
122 127 * Complete rewrite of the IPython docuementation. All of the documentation
123 128 from the IPython website has been moved into docs/source as restructured
124 129 text documents. PDF and HTML documentation are being generated using
125 130 Sphinx.
126 131 * New developer oriented documentation: development guidelines and roadmap.
127 132 * Traditional ``ChangeLog`` has been changed to a more useful ``changes.txt`` file
128 133 that is organized by release and is meant to provide something more relevant
129 134 for users.
130 135
131 136 Bug fixes
132 137 .........
133 138
134 139 * Created a proper ``MANIFEST.in`` file to create source distributions.
135 140 * Fixed a bug in the ``MultiEngine`` interface. Previously, multi-engine
136 141 actions were being collected with a :class:`DeferredList` with
137 142 ``fireononeerrback=1``. This meant that methods were returning
138 143 before all engines had given their results. This was causing extremely odd
139 144 bugs in certain cases. To fix this problem, we have 1) set
140 145 ``fireononeerrback=0`` to make sure all results (or exceptions) are in
141 146 before returning and 2) introduced a :exc:`CompositeError` exception
142 147 that wraps all of the engine exceptions. This is a huge change as it means
143 148 that users will have to catch :exc:`CompositeError` rather than the actual
144 149 exception.
145 150
146 151 Backwards incompatible changes
147 152 ..............................
148 153
149 154 * All names have been renamed to conform to the lowercase_with_underscore
150 155 convention. This will require users to change references to all names like
151 156 ``queueStatus`` to ``queue_status``.
152 157 * Previously, methods like :meth:`MultiEngineClient.push` and
153 158 :meth:`MultiEngineClient.push` used ``*args`` and ``**kwargs``. This was
154 159 becoming a problem as we weren't able to introduce new keyword arguments into
155 160 the API. Now these methods simple take a dict or sequence. This has also allowed
156 161 us to get rid of the ``*All`` methods like :meth:`pushAll` and :meth:`pullAll`.
157 162 These things are now handled with the ``targets`` keyword argument that defaults
158 163 to ``'all'``.
159 164 * The :attr:`MultiEngineClient.magicTargets` has been renamed to
160 165 :attr:`MultiEngineClient.targets`.
161 166 * All methods in the MultiEngine interface now accept the optional keyword argument
162 167 ``block``.
163 168 * Renamed :class:`RemoteController` to :class:`MultiEngineClient` and
164 169 :class:`TaskController` to :class:`TaskClient`.
165 170 * Renamed the top-level module from :mod:`api` to :mod:`client`.
166 171 * Most methods in the multiengine interface now raise a :exc:`CompositeError` exception
167 172 that wraps the user's exceptions, rather than just raising the raw user's exception.
168 173 * Changed the ``setupNS`` and ``resultNames`` in the ``Task`` class to ``push``
169 174 and ``pull``.
170 175
171 176 Release 0.8.4
172 177 =============
173 178
174 179 Someone needs to describe what went into 0.8.4.
175 180
176 181 Release 0.8.2
177 182 =============
178 183
179 184 * %pushd/%popd behave differently; now "pushd /foo" pushes CURRENT directory
180 185 and jumps to /foo. The current behaviour is closer to the documented
181 186 behaviour, and should not trip anyone.
182 187
183 188 Release 0.8.3
184 189 =============
185 190
186 191 * pydb is now disabled by default (due to %run -d problems). You can enable
187 192 it by passing -pydb command line argument to IPython. Note that setting
188 193 it in config file won't work.
189 194
190 195 Older releases
191 196 ==============
192 197
193 198 Changes in earlier releases of IPython are described in the older file ``ChangeLog``.
194 199 Please refer to this document for details.
195 200
General Comments 0
You need to be logged in to leave comments. Login now