##// END OF EJS Templates
Merging upstream
Brian Granger -
r2005:7eb8a846 merge
parent child Browse files
Show More

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

@@ -0,0 +1,37 b''
1 # encoding: utf-8
2 """
3 Test the LineFrontEnd
4 """
5
6 __docformat__ = "restructuredtext en"
7
8 #-------------------------------------------------------------------------------
9 # Copyright (C) 2008 The IPython Development Team
10 #
11 # Distributed under the terms of the BSD License. The full license is
12 # in the file COPYING, distributed as part of this software.
13 #-------------------------------------------------------------------------------
14
15 from IPython.frontend.linefrontendbase import LineFrontEndBase
16 from copy import deepcopy
17 import nose.tools as nt
18
19 class ConcreteLineFrontEnd(LineFrontEndBase):
20 """ A concrete class to test the LineFrontEndBase.
21 """
22 def capture_output(self):
23 pass
24
25 def release_output(self):
26 pass
27
28
29 def test_is_complete():
30 """ Tests line completion heuristic.
31 """
32 frontend = ConcreteLineFrontEnd()
33 yield nt.assert_true, not frontend.is_complete('for x in \\')
34 yield nt.assert_true, not frontend.is_complete('for x in (1, ):')
35 yield nt.assert_true, frontend.is_complete('for x in (1, ):\n pass')
36
37
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,2322 +1,2327 b''
1 1 # -*- coding: iso-8859-1 -*-
2 2
3 3 """
4 4 ``ipipe`` provides classes to be used in an interactive Python session. Doing a
5 5 ``from ipipe import *`` is the preferred way to do this. The name of all
6 6 objects imported this way starts with ``i`` to minimize collisions.
7 7
8 8 ``ipipe`` supports "pipeline expressions", which is something resembling Unix
9 9 pipes. An example is::
10 10
11 11 >>> ienv | isort("key.lower()")
12 12
13 13 This gives a listing of all environment variables sorted by name.
14 14
15 15
16 16 There are three types of objects in a pipeline expression:
17 17
18 18 * ``Table``s: These objects produce items. Examples are ``ils`` (listing the
19 19 current directory, ``ienv`` (listing environment variables), ``ipwd`` (listing
20 20 user accounts) and ``igrp`` (listing user groups). A ``Table`` must be the
21 21 first object in a pipe expression.
22 22
23 23 * ``Pipe``s: These objects sit in the middle of a pipe expression. They
24 24 transform the input in some way (e.g. filtering or sorting it). Examples are:
25 25 ``ifilter`` (which filters the input pipe), ``isort`` (which sorts the input
26 26 pipe) and ``ieval`` (which evaluates a function or expression for each object
27 27 in the input pipe).
28 28
29 29 * ``Display``s: These objects can be put as the last object in a pipeline
30 30 expression. There are responsible for displaying the result of the pipeline
31 31 expression. If a pipeline expression doesn't end in a display object a default
32 32 display objects will be used. One example is ``ibrowse`` which is a ``curses``
33 33 based browser.
34 34
35 35
36 36 Adding support for pipeline expressions to your own objects can be done through
37 37 three extensions points (all of them optional):
38 38
39 39 * An object that will be displayed as a row by a ``Display`` object should
40 40 implement the method ``__xattrs__(self, mode)`` method or register an
41 41 implementation of the generic function ``xattrs``. For more info see ``xattrs``.
42 42
43 43 * When an object ``foo`` is displayed by a ``Display`` object, the generic
44 44 function ``xrepr`` is used.
45 45
46 46 * Objects that can be iterated by ``Pipe``s must iterable. For special cases,
47 47 where iteration for display is different than the normal iteration a special
48 48 implementation can be registered with the generic function ``xiter``. This
49 49 makes it possible to use dictionaries and modules in pipeline expressions,
50 50 for example::
51 51
52 52 >>> import sys
53 53 >>> sys | ifilter("isinstance(value, int)") | idump
54 54 key |value
55 55 api_version| 1012
56 56 dllhandle | 503316480
57 57 hexversion | 33817328
58 58 maxint |2147483647
59 59 maxunicode | 65535
60 60 >>> sys.modules | ifilter("_.value is not None") | isort("_.key.lower()")
61 61 ...
62 62
63 63 Note: The expression strings passed to ``ifilter()`` and ``isort()`` can
64 64 refer to the object to be filtered or sorted via the variable ``_`` and to any
65 65 of the attributes of the object, i.e.::
66 66
67 67 >>> sys.modules | ifilter("_.value is not None") | isort("_.key.lower()")
68 68
69 69 does the same as::
70 70
71 71 >>> sys.modules | ifilter("value is not None") | isort("key.lower()")
72 72
73 73 In addition to expression strings, it's possible to pass callables (taking
74 74 the object as an argument) to ``ifilter()``, ``isort()`` and ``ieval()``::
75 75
76 76 >>> sys | ifilter(lambda _:isinstance(_.value, int)) \
77 77 ... | ieval(lambda _: (_.key, hex(_.value))) | idump
78 78 0 |1
79 79 api_version|0x3f4
80 80 dllhandle |0x1e000000
81 81 hexversion |0x20402f0
82 82 maxint |0x7fffffff
83 83 maxunicode |0xffff
84 84 """
85 85
86 86 skip_doctest = True # ignore top-level docstring as a doctest.
87 87
88 88 import sys, os, os.path, stat, glob, new, csv, datetime, types
89 89 import itertools, mimetypes, StringIO
90 90
91 91 try: # Python 2.3 compatibility
92 92 import collections
93 93 except ImportError:
94 94 deque = list
95 95 else:
96 96 deque = collections.deque
97 97
98 98 try: # Python 2.3 compatibility
99 99 set
100 100 except NameError:
101 101 import sets
102 102 set = sets.Set
103 103
104 104 try: # Python 2.3 compatibility
105 105 sorted
106 106 except NameError:
107 107 def sorted(iterator, key=None, reverse=False):
108 108 items = list(iterator)
109 109 if key is not None:
110 110 items.sort(lambda i1, i2: cmp(key(i1), key(i2)))
111 111 else:
112 112 items.sort()
113 113 if reverse:
114 114 items.reverse()
115 115 return items
116 116
117 try: # Python 2.4 compatibility
118 GeneratorExit
119 except NameError:
120 GeneratorExit = SystemExit
121
117 122 try:
118 123 import pwd
119 124 except ImportError:
120 125 pwd = None
121 126
122 127 try:
123 128 import grp
124 129 except ImportError:
125 130 grp = None
126 131
127 132 from IPython.external import simplegeneric
128 133 from IPython.external import path
129 134
130 135 try:
131 136 from IPython import genutils, generics
132 137 except ImportError:
133 138 genutils = None
134 139 generics = None
135 140
136 141 from IPython import ipapi
137 142
138 143
139 144 __all__ = [
140 145 "ifile", "ils", "iglob", "iwalk", "ipwdentry", "ipwd", "igrpentry", "igrp",
141 146 "icsv", "ix", "ichain", "isort", "ifilter", "ieval", "ienum",
142 147 "ienv", "ihist", "ialias", "icap", "idump", "iless"
143 148 ]
144 149
145 150
146 151 os.stat_float_times(True) # enable microseconds
147 152
148 153
149 154 class AttrNamespace(object):
150 155 """
151 156 Helper class that is used for providing a namespace for evaluating
152 157 expressions containing attribute names of an object.
153 158 """
154 159 def __init__(self, wrapped):
155 160 self.wrapped = wrapped
156 161
157 162 def __getitem__(self, name):
158 163 if name == "_":
159 164 return self.wrapped
160 165 try:
161 166 return getattr(self.wrapped, name)
162 167 except AttributeError:
163 168 raise KeyError(name)
164 169
165 170 # Python 2.3 compatibility
166 171 # use eval workaround to find out which names are used in the
167 172 # eval string and put them into the locals. This works for most
168 173 # normal uses case, bizarre ones like accessing the locals()
169 174 # will fail
170 175 try:
171 176 eval("_", None, AttrNamespace(None))
172 177 except TypeError:
173 178 real_eval = eval
174 179 def eval(codestring, _globals, _locals):
175 180 """
176 181 eval(source[, globals[, locals]]) -> value
177 182
178 183 Evaluate the source in the context of globals and locals.
179 184 The source may be a string representing a Python expression
180 185 or a code object as returned by compile().
181 186 The globals must be a dictionary and locals can be any mappping.
182 187
183 188 This function is a workaround for the shortcomings of
184 189 Python 2.3's eval.
185 190 """
186 191
187 192 if isinstance(codestring, basestring):
188 193 code = compile(codestring, "_eval", "eval")
189 194 else:
190 195 code = codestring
191 196 newlocals = {}
192 197 for name in code.co_names:
193 198 try:
194 199 newlocals[name] = _locals[name]
195 200 except KeyError:
196 201 pass
197 202 return real_eval(code, _globals, newlocals)
198 203
199 204
200 205 noitem = object()
201 206
202 207
203 208 def item(iterator, index, default=noitem):
204 209 """
205 210 Return the ``index``th item from the iterator ``iterator``.
206 211 ``index`` must be an integer (negative integers are relative to the
207 212 end (i.e. the last items produced by the iterator)).
208 213
209 214 If ``default`` is given, this will be the default value when
210 215 the iterator doesn't contain an item at this position. Otherwise an
211 216 ``IndexError`` will be raised.
212 217
213 218 Note that using this function will partially or totally exhaust the
214 219 iterator.
215 220 """
216 221 i = index
217 222 if i>=0:
218 223 for item in iterator:
219 224 if not i:
220 225 return item
221 226 i -= 1
222 227 else:
223 228 i = -index
224 229 cache = deque()
225 230 for item in iterator:
226 231 cache.append(item)
227 232 if len(cache)>i:
228 233 cache.popleft()
229 234 if len(cache)==i:
230 235 return cache.popleft()
231 236 if default is noitem:
232 237 raise IndexError(index)
233 238 else:
234 239 return default
235 240
236 241
237 242 def getglobals(g):
238 243 """
239 244 Return the global namespace that is used for expression strings in
240 245 ``ifilter`` and others. This is ``g`` or (if ``g`` is ``None``) IPython's
241 246 user namespace.
242 247 """
243 248 if g is None:
244 249 if ipapi is not None:
245 250 api = ipapi.get()
246 251 if api is not None:
247 252 return api.user_ns
248 253 return globals()
249 254 return g
250 255
251 256
252 257 class Descriptor(object):
253 258 """
254 259 A ``Descriptor`` object is used for describing the attributes of objects.
255 260 """
256 261 def __hash__(self):
257 262 return hash(self.__class__) ^ hash(self.key())
258 263
259 264 def __eq__(self, other):
260 265 return self.__class__ is other.__class__ and self.key() == other.key()
261 266
262 267 def __ne__(self, other):
263 268 return self.__class__ is not other.__class__ or self.key() != other.key()
264 269
265 270 def key(self):
266 271 pass
267 272
268 273 def name(self):
269 274 """
270 275 Return the name of this attribute for display by a ``Display`` object
271 276 (e.g. as a column title).
272 277 """
273 278 key = self.key()
274 279 if key is None:
275 280 return "_"
276 281 return str(key)
277 282
278 283 def attrtype(self, obj):
279 284 """
280 285 Return the type of this attribute (i.e. something like "attribute" or
281 286 "method").
282 287 """
283 288
284 289 def valuetype(self, obj):
285 290 """
286 291 Return the type of this attribute value of the object ``obj``.
287 292 """
288 293
289 294 def value(self, obj):
290 295 """
291 296 Return the value of this attribute of the object ``obj``.
292 297 """
293 298
294 299 def doc(self, obj):
295 300 """
296 301 Return the documentation for this attribute.
297 302 """
298 303
299 304 def shortdoc(self, obj):
300 305 """
301 306 Return a short documentation for this attribute (defaulting to the
302 307 first line).
303 308 """
304 309 doc = self.doc(obj)
305 310 if doc is not None:
306 311 doc = doc.strip().splitlines()[0].strip()
307 312 return doc
308 313
309 314 def iter(self, obj):
310 315 """
311 316 Return an iterator for this attribute of the object ``obj``.
312 317 """
313 318 return xiter(self.value(obj))
314 319
315 320
316 321 class SelfDescriptor(Descriptor):
317 322 """
318 323 A ``SelfDescriptor`` describes the object itself.
319 324 """
320 325 def key(self):
321 326 return None
322 327
323 328 def attrtype(self, obj):
324 329 return "self"
325 330
326 331 def valuetype(self, obj):
327 332 return type(obj)
328 333
329 334 def value(self, obj):
330 335 return obj
331 336
332 337 def __repr__(self):
333 338 return "Self"
334 339
335 340 selfdescriptor = SelfDescriptor() # there's no need for more than one
336 341
337 342
338 343 class AttributeDescriptor(Descriptor):
339 344 """
340 345 An ``AttributeDescriptor`` describes a simple attribute of an object.
341 346 """
342 347 __slots__ = ("_name", "_doc")
343 348
344 349 def __init__(self, name, doc=None):
345 350 self._name = name
346 351 self._doc = doc
347 352
348 353 def key(self):
349 354 return self._name
350 355
351 356 def doc(self, obj):
352 357 return self._doc
353 358
354 359 def attrtype(self, obj):
355 360 return "attr"
356 361
357 362 def valuetype(self, obj):
358 363 return type(getattr(obj, self._name))
359 364
360 365 def value(self, obj):
361 366 return getattr(obj, self._name)
362 367
363 368 def __repr__(self):
364 369 if self._doc is None:
365 370 return "Attribute(%r)" % self._name
366 371 else:
367 372 return "Attribute(%r, %r)" % (self._name, self._doc)
368 373
369 374
370 375 class IndexDescriptor(Descriptor):
371 376 """
372 377 An ``IndexDescriptor`` describes an "attribute" of an object that is fetched
373 378 via ``__getitem__``.
374 379 """
375 380 __slots__ = ("_index",)
376 381
377 382 def __init__(self, index):
378 383 self._index = index
379 384
380 385 def key(self):
381 386 return self._index
382 387
383 388 def attrtype(self, obj):
384 389 return "item"
385 390
386 391 def valuetype(self, obj):
387 392 return type(obj[self._index])
388 393
389 394 def value(self, obj):
390 395 return obj[self._index]
391 396
392 397 def __repr__(self):
393 398 return "Index(%r)" % self._index
394 399
395 400
396 401 class MethodDescriptor(Descriptor):
397 402 """
398 403 A ``MethodDescriptor`` describes a method of an object that can be called
399 404 without argument. Note that this method shouldn't change the object.
400 405 """
401 406 __slots__ = ("_name", "_doc")
402 407
403 408 def __init__(self, name, doc=None):
404 409 self._name = name
405 410 self._doc = doc
406 411
407 412 def key(self):
408 413 return self._name
409 414
410 415 def doc(self, obj):
411 416 if self._doc is None:
412 417 return getattr(obj, self._name).__doc__
413 418 return self._doc
414 419
415 420 def attrtype(self, obj):
416 421 return "method"
417 422
418 423 def valuetype(self, obj):
419 424 return type(self.value(obj))
420 425
421 426 def value(self, obj):
422 427 return getattr(obj, self._name)()
423 428
424 429 def __repr__(self):
425 430 if self._doc is None:
426 431 return "Method(%r)" % self._name
427 432 else:
428 433 return "Method(%r, %r)" % (self._name, self._doc)
429 434
430 435
431 436 class IterAttributeDescriptor(Descriptor):
432 437 """
433 438 An ``IterAttributeDescriptor`` works like an ``AttributeDescriptor`` but
434 439 doesn't return an attribute values (because this value might be e.g. a large
435 440 list).
436 441 """
437 442 __slots__ = ("_name", "_doc")
438 443
439 444 def __init__(self, name, doc=None):
440 445 self._name = name
441 446 self._doc = doc
442 447
443 448 def key(self):
444 449 return self._name
445 450
446 451 def doc(self, obj):
447 452 return self._doc
448 453
449 454 def attrtype(self, obj):
450 455 return "iter"
451 456
452 457 def valuetype(self, obj):
453 458 return noitem
454 459
455 460 def value(self, obj):
456 461 return noitem
457 462
458 463 def iter(self, obj):
459 464 return xiter(getattr(obj, self._name))
460 465
461 466 def __repr__(self):
462 467 if self._doc is None:
463 468 return "IterAttribute(%r)" % self._name
464 469 else:
465 470 return "IterAttribute(%r, %r)" % (self._name, self._doc)
466 471
467 472
468 473 class IterMethodDescriptor(Descriptor):
469 474 """
470 475 An ``IterMethodDescriptor`` works like an ``MethodDescriptor`` but doesn't
471 476 return an attribute values (because this value might be e.g. a large list).
472 477 """
473 478 __slots__ = ("_name", "_doc")
474 479
475 480 def __init__(self, name, doc=None):
476 481 self._name = name
477 482 self._doc = doc
478 483
479 484 def key(self):
480 485 return self._name
481 486
482 487 def doc(self, obj):
483 488 if self._doc is None:
484 489 return getattr(obj, self._name).__doc__
485 490 return self._doc
486 491
487 492 def attrtype(self, obj):
488 493 return "itermethod"
489 494
490 495 def valuetype(self, obj):
491 496 return noitem
492 497
493 498 def value(self, obj):
494 499 return noitem
495 500
496 501 def iter(self, obj):
497 502 return xiter(getattr(obj, self._name)())
498 503
499 504 def __repr__(self):
500 505 if self._doc is None:
501 506 return "IterMethod(%r)" % self._name
502 507 else:
503 508 return "IterMethod(%r, %r)" % (self._name, self._doc)
504 509
505 510
506 511 class FunctionDescriptor(Descriptor):
507 512 """
508 513 A ``FunctionDescriptor`` turns a function into a descriptor. The function
509 514 will be called with the object to get the type and value of the attribute.
510 515 """
511 516 __slots__ = ("_function", "_name", "_doc")
512 517
513 518 def __init__(self, function, name=None, doc=None):
514 519 self._function = function
515 520 self._name = name
516 521 self._doc = doc
517 522
518 523 def key(self):
519 524 return self._function
520 525
521 526 def name(self):
522 527 if self._name is not None:
523 528 return self._name
524 529 return getattr(self._function, "__xname__", self._function.__name__)
525 530
526 531 def doc(self, obj):
527 532 if self._doc is None:
528 533 return self._function.__doc__
529 534 return self._doc
530 535
531 536 def attrtype(self, obj):
532 537 return "function"
533 538
534 539 def valuetype(self, obj):
535 540 return type(self._function(obj))
536 541
537 542 def value(self, obj):
538 543 return self._function(obj)
539 544
540 545 def __repr__(self):
541 546 if self._doc is None:
542 547 return "Function(%r)" % self._name
543 548 else:
544 549 return "Function(%r, %r)" % (self._name, self._doc)
545 550
546 551
547 552 class Table(object):
548 553 """
549 554 A ``Table`` is an object that produces items (just like a normal Python
550 555 iterator/generator does) and can be used as the first object in a pipeline
551 556 expression. The displayhook will open the default browser for such an object
552 557 (instead of simply printing the ``repr()`` result).
553 558 """
554 559
555 560 # We want to support ``foo`` and ``foo()`` in pipeline expression:
556 561 # So we implement the required operators (``|`` and ``+``) in the metaclass,
557 562 # instantiate the class and forward the operator to the instance
558 563 class __metaclass__(type):
559 564 def __iter__(self):
560 565 return iter(self())
561 566
562 567 def __or__(self, other):
563 568 return self() | other
564 569
565 570 def __add__(self, other):
566 571 return self() + other
567 572
568 573 def __radd__(self, other):
569 574 return other + self()
570 575
571 576 def __getitem__(self, index):
572 577 return self()[index]
573 578
574 579 def __getitem__(self, index):
575 580 return item(self, index)
576 581
577 582 def __contains__(self, item):
578 583 for haveitem in self:
579 584 if item == haveitem:
580 585 return True
581 586 return False
582 587
583 588 def __or__(self, other):
584 589 # autoinstantiate right hand side
585 590 if isinstance(other, type) and issubclass(other, (Table, Display)):
586 591 other = other()
587 592 # treat simple strings and functions as ``ieval`` instances
588 593 elif not isinstance(other, Display) and not isinstance(other, Table):
589 594 other = ieval(other)
590 595 # forward operations to the right hand side
591 596 return other.__ror__(self)
592 597
593 598 def __add__(self, other):
594 599 # autoinstantiate right hand side
595 600 if isinstance(other, type) and issubclass(other, Table):
596 601 other = other()
597 602 return ichain(self, other)
598 603
599 604 def __radd__(self, other):
600 605 # autoinstantiate left hand side
601 606 if isinstance(other, type) and issubclass(other, Table):
602 607 other = other()
603 608 return ichain(other, self)
604 609
605 610
606 611 class Pipe(Table):
607 612 """
608 613 A ``Pipe`` is an object that can be used in a pipeline expression. It
609 614 processes the objects it gets from its input ``Table``/``Pipe``. Note that
610 615 a ``Pipe`` object can't be used as the first object in a pipeline
611 616 expression, as it doesn't produces items itself.
612 617 """
613 618 class __metaclass__(Table.__metaclass__):
614 619 def __ror__(self, input):
615 620 return input | self()
616 621
617 622 def __ror__(self, input):
618 623 # autoinstantiate left hand side
619 624 if isinstance(input, type) and issubclass(input, Table):
620 625 input = input()
621 626 self.input = input
622 627 return self
623 628
624 629
625 630 def xrepr(item, mode="default"):
626 631 """
627 632 Generic function that adds color output and different display modes to ``repr``.
628 633
629 634 The result of an ``xrepr`` call is iterable and consists of ``(style, string)``
630 635 tuples. The ``style`` in this tuple must be a ``Style`` object from the
631 636 ``astring`` module. To reconfigure the output the first yielded tuple can be
632 637 a ``(aligment, full)`` tuple instead of a ``(style, string)`` tuple.
633 638 ``alignment`` can be -1 for left aligned, 0 for centered and 1 for right
634 639 aligned (the default is left alignment). ``full`` is a boolean that specifies
635 640 whether the complete output must be displayed or the ``Display`` object is
636 641 allowed to stop output after enough text has been produced (e.g. a syntax
637 642 highlighted text line would use ``True``, but for a large data structure
638 643 (i.e. a nested list, tuple or dictionary) ``False`` would be used).
639 644 The default is full output.
640 645
641 646 There are four different possible values for ``mode`` depending on where
642 647 the ``Display`` object will display ``item``:
643 648
644 649 ``"header"``
645 650 ``item`` will be displayed in a header line (this is used by ``ibrowse``).
646 651
647 652 ``"footer"``
648 653 ``item`` will be displayed in a footer line (this is used by ``ibrowse``).
649 654
650 655 ``"cell"``
651 656 ``item`` will be displayed in a table cell/list.
652 657
653 658 ``"default"``
654 659 default mode. If an ``xrepr`` implementation recursively outputs objects,
655 660 ``"default"`` must be passed in the recursive calls to ``xrepr``.
656 661
657 662 If no implementation is registered for ``item``, ``xrepr`` will try the
658 663 ``__xrepr__`` method on ``item``. If ``item`` doesn't have an ``__xrepr__``
659 664 method it falls back to ``repr``/``__repr__`` for all modes.
660 665 """
661 666 try:
662 667 func = item.__xrepr__
663 668 except AttributeError:
664 669 yield (astyle.style_default, repr(item))
665 670 else:
666 671 try:
667 672 for x in func(mode):
668 673 yield x
669 except (KeyboardInterrupt, SystemExit):
674 except (KeyboardInterrupt, SystemExit, GeneratorExit):
670 675 raise
671 676 except Exception:
672 677 yield (astyle.style_default, repr(item))
673 678 xrepr = simplegeneric.generic(xrepr)
674 679
675 680
676 681 def xrepr_none(self, mode="default"):
677 682 yield (astyle.style_type_none, repr(self))
678 683 xrepr.when_object(None)(xrepr_none)
679 684
680 685
681 686 def xrepr_noitem(self, mode="default"):
682 687 yield (2, True)
683 688 yield (astyle.style_nodata, "<?>")
684 689 xrepr.when_object(noitem)(xrepr_noitem)
685 690
686 691
687 692 def xrepr_bool(self, mode="default"):
688 693 yield (astyle.style_type_bool, repr(self))
689 694 xrepr.when_type(bool)(xrepr_bool)
690 695
691 696
692 697 def xrepr_str(self, mode="default"):
693 698 if mode == "cell":
694 699 yield (astyle.style_default, repr(self.expandtabs(tab))[1:-1])
695 700 else:
696 701 yield (astyle.style_default, repr(self))
697 702 xrepr.when_type(str)(xrepr_str)
698 703
699 704
700 705 def xrepr_unicode(self, mode="default"):
701 706 if mode == "cell":
702 707 yield (astyle.style_default, repr(self.expandtabs(tab))[2:-1])
703 708 else:
704 709 yield (astyle.style_default, repr(self))
705 710 xrepr.when_type(unicode)(xrepr_unicode)
706 711
707 712
708 713 def xrepr_number(self, mode="default"):
709 714 yield (1, True)
710 715 yield (astyle.style_type_number, repr(self))
711 716 xrepr.when_type(int)(xrepr_number)
712 717 xrepr.when_type(long)(xrepr_number)
713 718 xrepr.when_type(float)(xrepr_number)
714 719
715 720
716 721 def xrepr_complex(self, mode="default"):
717 722 yield (astyle.style_type_number, repr(self))
718 723 xrepr.when_type(complex)(xrepr_number)
719 724
720 725
721 726 def xrepr_datetime(self, mode="default"):
722 727 if mode == "cell":
723 728 # Don't use strftime() here, as this requires year >= 1900
724 729 yield (astyle.style_type_datetime,
725 730 "%04d-%02d-%02d %02d:%02d:%02d.%06d" % \
726 731 (self.year, self.month, self.day,
727 732 self.hour, self.minute, self.second,
728 733 self.microsecond),
729 734 )
730 735 else:
731 736 yield (astyle.style_type_datetime, repr(self))
732 737 xrepr.when_type(datetime.datetime)(xrepr_datetime)
733 738
734 739
735 740 def xrepr_date(self, mode="default"):
736 741 if mode == "cell":
737 742 yield (astyle.style_type_datetime,
738 743 "%04d-%02d-%02d" % (self.year, self.month, self.day))
739 744 else:
740 745 yield (astyle.style_type_datetime, repr(self))
741 746 xrepr.when_type(datetime.date)(xrepr_date)
742 747
743 748
744 749 def xrepr_time(self, mode="default"):
745 750 if mode == "cell":
746 751 yield (astyle.style_type_datetime,
747 752 "%02d:%02d:%02d.%06d" % \
748 753 (self.hour, self.minute, self.second, self.microsecond))
749 754 else:
750 755 yield (astyle.style_type_datetime, repr(self))
751 756 xrepr.when_type(datetime.time)(xrepr_time)
752 757
753 758
754 759 def xrepr_timedelta(self, mode="default"):
755 760 yield (astyle.style_type_datetime, repr(self))
756 761 xrepr.when_type(datetime.timedelta)(xrepr_timedelta)
757 762
758 763
759 764 def xrepr_type(self, mode="default"):
760 765 if self.__module__ == "__builtin__":
761 766 yield (astyle.style_type_type, self.__name__)
762 767 else:
763 768 yield (astyle.style_type_type, "%s.%s" % (self.__module__, self.__name__))
764 769 xrepr.when_type(type)(xrepr_type)
765 770
766 771
767 772 def xrepr_exception(self, mode="default"):
768 773 if self.__class__.__module__ == "exceptions":
769 774 classname = self.__class__.__name__
770 775 else:
771 776 classname = "%s.%s" % \
772 777 (self.__class__.__module__, self.__class__.__name__)
773 778 if mode == "header" or mode == "footer":
774 779 yield (astyle.style_error, "%s: %s" % (classname, self))
775 780 else:
776 781 yield (astyle.style_error, classname)
777 782 xrepr.when_type(Exception)(xrepr_exception)
778 783
779 784
780 785 def xrepr_listtuple(self, mode="default"):
781 786 if mode == "header" or mode == "footer":
782 787 if self.__class__.__module__ == "__builtin__":
783 788 classname = self.__class__.__name__
784 789 else:
785 790 classname = "%s.%s" % \
786 791 (self.__class__.__module__,self.__class__.__name__)
787 792 yield (astyle.style_default,
788 793 "<%s object with %d items at 0x%x>" % \
789 794 (classname, len(self), id(self)))
790 795 else:
791 796 yield (-1, False)
792 797 if isinstance(self, list):
793 798 yield (astyle.style_default, "[")
794 799 end = "]"
795 800 else:
796 801 yield (astyle.style_default, "(")
797 802 end = ")"
798 803 for (i, subself) in enumerate(self):
799 804 if i:
800 805 yield (astyle.style_default, ", ")
801 806 for part in xrepr(subself, "default"):
802 807 yield part
803 808 yield (astyle.style_default, end)
804 809 xrepr.when_type(list)(xrepr_listtuple)
805 810 xrepr.when_type(tuple)(xrepr_listtuple)
806 811
807 812
808 813 def xrepr_dict(self, mode="default"):
809 814 if mode == "header" or mode == "footer":
810 815 if self.__class__.__module__ == "__builtin__":
811 816 classname = self.__class__.__name__
812 817 else:
813 818 classname = "%s.%s" % \
814 819 (self.__class__.__module__,self.__class__.__name__)
815 820 yield (astyle.style_default,
816 821 "<%s object with %d items at 0x%x>" % \
817 822 (classname, len(self), id(self)))
818 823 else:
819 824 yield (-1, False)
820 825 if isinstance(self, dict):
821 826 yield (astyle.style_default, "{")
822 827 end = "}"
823 828 else:
824 829 yield (astyle.style_default, "dictproxy((")
825 830 end = "})"
826 831 for (i, (key, value)) in enumerate(self.iteritems()):
827 832 if i:
828 833 yield (astyle.style_default, ", ")
829 834 for part in xrepr(key, "default"):
830 835 yield part
831 836 yield (astyle.style_default, ": ")
832 837 for part in xrepr(value, "default"):
833 838 yield part
834 839 yield (astyle.style_default, end)
835 840 xrepr.when_type(dict)(xrepr_dict)
836 841 xrepr.when_type(types.DictProxyType)(xrepr_dict)
837 842
838 843
839 844 def upgradexattr(attr):
840 845 """
841 846 Convert an attribute descriptor string to a real descriptor object.
842 847
843 If attr already is a descriptor object return if unmodified. A
848 If attr already is a descriptor object return it unmodified. A
844 849 ``SelfDescriptor`` will be returned if ``attr`` is ``None``. ``"foo"``
845 850 returns an ``AttributeDescriptor`` for the attribute named ``"foo"``.
846 851 ``"foo()"`` returns a ``MethodDescriptor`` for the method named ``"foo"``.
847 852 ``"-foo"`` will return an ``IterAttributeDescriptor`` for the attribute
848 853 named ``"foo"`` and ``"-foo()"`` will return an ``IterMethodDescriptor``
849 for the method named ``"foo"``. Furthermore integer will return the appropriate
854 for the method named ``"foo"``. Furthermore integers will return the appropriate
850 855 ``IndexDescriptor`` and callables will return a ``FunctionDescriptor``.
851 856 """
852 857 if attr is None:
853 858 return selfdescriptor
854 859 elif isinstance(attr, Descriptor):
855 860 return attr
856 elif isinstance(attr, str):
861 elif isinstance(attr, basestring):
857 862 if attr.endswith("()"):
858 863 if attr.startswith("-"):
859 864 return IterMethodDescriptor(attr[1:-2])
860 865 else:
861 866 return MethodDescriptor(attr[:-2])
862 867 else:
863 868 if attr.startswith("-"):
864 869 return IterAttributeDescriptor(attr[1:])
865 870 else:
866 871 return AttributeDescriptor(attr)
867 872 elif isinstance(attr, (int, long)):
868 873 return IndexDescriptor(attr)
869 874 elif callable(attr):
870 875 return FunctionDescriptor(attr)
871 876 else:
872 877 raise TypeError("can't handle descriptor %r" % attr)
873 878
874 879
875 880 def xattrs(item, mode="default"):
876 881 """
877 882 Generic function that returns an iterable of attribute descriptors
878 883 to be used for displaying the attributes ob the object ``item`` in display
879 884 mode ``mode``.
880 885
881 886 There are two possible modes:
882 887
883 888 ``"detail"``
884 889 The ``Display`` object wants to display a detailed list of the object
885 890 attributes.
886 891
887 892 ``"default"``
888 893 The ``Display`` object wants to display the object in a list view.
889 894
890 895 If no implementation is registered for the object ``item`` ``xattrs`` falls
891 896 back to trying the ``__xattrs__`` method of the object. If this doesn't
892 897 exist either, ``dir(item)`` is used for ``"detail"`` mode and ``(None,)``
893 898 for ``"default"`` mode.
894 899
895 900 The implementation must yield attribute descriptors (see the class
896 901 ``Descriptor`` for more info). The ``__xattrs__`` method may also return
897 902 attribute descriptor strings (and ``None``) which will be converted to real
898 903 descriptors by ``upgradexattr()``.
899 904 """
900 905 try:
901 906 func = item.__xattrs__
902 907 except AttributeError:
903 908 if mode == "detail":
904 909 for attrname in dir(item):
905 910 yield AttributeDescriptor(attrname)
906 911 else:
907 912 yield selfdescriptor
908 913 else:
909 914 for attr in func(mode):
910 915 yield upgradexattr(attr)
911 916 xattrs = simplegeneric.generic(xattrs)
912 917
913 918
914 919 def xattrs_complex(self, mode="default"):
915 920 if mode == "detail":
916 921 return (AttributeDescriptor("real"), AttributeDescriptor("imag"))
917 922 return (selfdescriptor,)
918 923 xattrs.when_type(complex)(xattrs_complex)
919 924
920 925
921 926 def _isdict(item):
922 927 try:
923 928 itermeth = item.__class__.__iter__
924 929 except (AttributeError, TypeError):
925 930 return False
926 931 return itermeth is dict.__iter__ or itermeth is types.DictProxyType.__iter__
927 932
928 933
929 934 def _isstr(item):
930 935 if not isinstance(item, basestring):
931 936 return False
932 937 try:
933 938 itermeth = item.__class__.__iter__
934 939 except AttributeError:
935 940 return True
936 941 return False # ``__iter__`` has been redefined
937 942
938 943
939 944 def xiter(item):
940 945 """
941 946 Generic function that implements iteration for pipeline expression. If no
942 947 implementation is registered for ``item`` ``xiter`` falls back to ``iter``.
943 948 """
944 949 try:
945 950 func = item.__xiter__
946 951 except AttributeError:
947 952 if _isdict(item):
948 953 def items(item):
949 954 fields = ("key", "value")
950 955 for (key, value) in item.iteritems():
951 956 yield Fields(fields, key=key, value=value)
952 957 return items(item)
953 958 elif isinstance(item, new.module):
954 959 def items(item):
955 960 fields = ("key", "value")
956 961 for key in sorted(item.__dict__):
957 962 yield Fields(fields, key=key, value=getattr(item, key))
958 963 return items(item)
959 964 elif _isstr(item):
960 965 if not item:
961 966 raise ValueError("can't enter empty string")
962 967 lines = item.splitlines()
963 968 if len(lines) == 1:
964 969 def iterone(item):
965 970 yield item
966 971 return iterone(item)
967 972 else:
968 973 return iter(lines)
969 974 return iter(item)
970 975 else:
971 976 return iter(func()) # iter() just to be safe
972 977 xiter = simplegeneric.generic(xiter)
973 978
974 979
975 980 class ichain(Pipe):
976 981 """
977 982 Chains multiple ``Table``s into one.
978 983 """
979 984
980 985 def __init__(self, *iters):
981 986 self.iters = iters
982 987
983 988 def __iter__(self):
984 989 return itertools.chain(*self.iters)
985 990
986 991 def __xrepr__(self, mode="default"):
987 992 if mode == "header" or mode == "footer":
988 993 for (i, item) in enumerate(self.iters):
989 994 if i:
990 995 yield (astyle.style_default, "+")
991 996 if isinstance(item, Pipe):
992 997 yield (astyle.style_default, "(")
993 998 for part in xrepr(item, mode):
994 999 yield part
995 1000 if isinstance(item, Pipe):
996 1001 yield (astyle.style_default, ")")
997 1002 else:
998 1003 yield (astyle.style_default, repr(self))
999 1004
1000 1005 def __repr__(self):
1001 1006 args = ", ".join([repr(it) for it in self.iters])
1002 1007 return "%s.%s(%s)" % \
1003 1008 (self.__class__.__module__, self.__class__.__name__, args)
1004 1009
1005 1010
1006 1011 class ifile(path.path):
1007 1012 """
1008 1013 file (or directory) object.
1009 1014 """
1010 1015
1011 1016 def getmode(self):
1012 1017 return self.stat().st_mode
1013 1018 mode = property(getmode, None, None, "Access mode")
1014 1019
1015 1020 def gettype(self):
1016 1021 data = [
1017 1022 (stat.S_ISREG, "file"),
1018 1023 (stat.S_ISDIR, "dir"),
1019 1024 (stat.S_ISCHR, "chardev"),
1020 1025 (stat.S_ISBLK, "blockdev"),
1021 1026 (stat.S_ISFIFO, "fifo"),
1022 1027 (stat.S_ISLNK, "symlink"),
1023 1028 (stat.S_ISSOCK,"socket"),
1024 1029 ]
1025 1030 lstat = self.lstat()
1026 1031 if lstat is not None:
1027 1032 types = set([text for (func, text) in data if func(lstat.st_mode)])
1028 1033 else:
1029 1034 types = set()
1030 1035 m = self.mode
1031 1036 types.update([text for (func, text) in data if func(m)])
1032 1037 return ", ".join(types)
1033 1038 type = property(gettype, None, None, "file type (file, directory, link, etc.)")
1034 1039
1035 1040 def getmodestr(self):
1036 1041 m = self.mode
1037 1042 data = [
1038 1043 (stat.S_IRUSR, "-r"),
1039 1044 (stat.S_IWUSR, "-w"),
1040 1045 (stat.S_IXUSR, "-x"),
1041 1046 (stat.S_IRGRP, "-r"),
1042 1047 (stat.S_IWGRP, "-w"),
1043 1048 (stat.S_IXGRP, "-x"),
1044 1049 (stat.S_IROTH, "-r"),
1045 1050 (stat.S_IWOTH, "-w"),
1046 1051 (stat.S_IXOTH, "-x"),
1047 1052 ]
1048 1053 return "".join([text[bool(m&bit)] for (bit, text) in data])
1049 1054
1050 1055 modestr = property(getmodestr, None, None, "Access mode as string")
1051 1056
1052 1057 def getblocks(self):
1053 1058 return self.stat().st_blocks
1054 1059 blocks = property(getblocks, None, None, "File size in blocks")
1055 1060
1056 1061 def getblksize(self):
1057 1062 return self.stat().st_blksize
1058 1063 blksize = property(getblksize, None, None, "Filesystem block size")
1059 1064
1060 1065 def getdev(self):
1061 1066 return self.stat().st_dev
1062 1067 dev = property(getdev)
1063 1068
1064 1069 def getnlink(self):
1065 1070 return self.stat().st_nlink
1066 1071 nlink = property(getnlink, None, None, "Number of links")
1067 1072
1068 1073 def getuid(self):
1069 1074 return self.stat().st_uid
1070 1075 uid = property(getuid, None, None, "User id of file owner")
1071 1076
1072 1077 def getgid(self):
1073 1078 return self.stat().st_gid
1074 1079 gid = property(getgid, None, None, "Group id of file owner")
1075 1080
1076 1081 def getowner(self):
1077 1082 stat = self.stat()
1078 1083 try:
1079 1084 return pwd.getpwuid(stat.st_uid).pw_name
1080 1085 except KeyError:
1081 1086 return stat.st_uid
1082 1087 owner = property(getowner, None, None, "Owner name (or id)")
1083 1088
1084 1089 def getgroup(self):
1085 1090 stat = self.stat()
1086 1091 try:
1087 1092 return grp.getgrgid(stat.st_gid).gr_name
1088 1093 except KeyError:
1089 1094 return stat.st_gid
1090 1095 group = property(getgroup, None, None, "Group name (or id)")
1091 1096
1092 1097 def getadate(self):
1093 1098 return datetime.datetime.utcfromtimestamp(self.atime)
1094 1099 adate = property(getadate, None, None, "Access date")
1095 1100
1096 1101 def getcdate(self):
1097 1102 return datetime.datetime.utcfromtimestamp(self.ctime)
1098 1103 cdate = property(getcdate, None, None, "Creation date")
1099 1104
1100 1105 def getmdate(self):
1101 1106 return datetime.datetime.utcfromtimestamp(self.mtime)
1102 1107 mdate = property(getmdate, None, None, "Modification date")
1103 1108
1104 1109 def mimetype(self):
1105 1110 """
1106 1111 Return MIME type guessed from the extension.
1107 1112 """
1108 1113 return mimetypes.guess_type(self.basename())[0]
1109 1114
1110 1115 def encoding(self):
1111 1116 """
1112 1117 Return guessed compression (like "compress" or "gzip").
1113 1118 """
1114 1119 return mimetypes.guess_type(self.basename())[1]
1115 1120
1116 1121 def __repr__(self):
1117 1122 return "ifile(%s)" % path._base.__repr__(self)
1118 1123
1119 1124 if sys.platform == "win32":
1120 1125 defaultattrs = (None, "type", "size", "modestr", "mdate")
1121 1126 else:
1122 1127 defaultattrs = (None, "type", "size", "modestr", "owner", "group", "mdate")
1123 1128
1124 1129 def __xattrs__(self, mode="default"):
1125 1130 if mode == "detail":
1126 1131 return (
1127 1132 "name",
1128 1133 "basename()",
1129 1134 "abspath()",
1130 1135 "realpath()",
1131 1136 "type",
1132 1137 "mode",
1133 1138 "modestr",
1134 1139 "stat()",
1135 1140 "lstat()",
1136 1141 "uid",
1137 1142 "gid",
1138 1143 "owner",
1139 1144 "group",
1140 1145 "dev",
1141 1146 "nlink",
1142 1147 "ctime",
1143 1148 "mtime",
1144 1149 "atime",
1145 1150 "cdate",
1146 1151 "mdate",
1147 1152 "adate",
1148 1153 "size",
1149 1154 "blocks",
1150 1155 "blksize",
1151 1156 "isdir()",
1152 1157 "islink()",
1153 1158 "mimetype()",
1154 1159 "encoding()",
1155 1160 "-listdir()",
1156 1161 "-dirs()",
1157 1162 "-files()",
1158 1163 "-walk()",
1159 1164 "-walkdirs()",
1160 1165 "-walkfiles()",
1161 1166 )
1162 1167 else:
1163 1168 return self.defaultattrs
1164 1169
1165 1170
1166 1171 def xiter_ifile(self):
1167 1172 if self.isdir():
1168 1173 yield (self / os.pardir).abspath()
1169 1174 for child in sorted(self.listdir()):
1170 1175 yield child
1171 1176 else:
1172 1177 f = self.open("rb")
1173 1178 for line in f:
1174 1179 yield line
1175 1180 f.close()
1176 1181 xiter.when_type(ifile)(xiter_ifile)
1177 1182
1178 1183
1179 1184 # We need to implement ``xrepr`` for ``ifile`` as a generic function, because
1180 1185 # otherwise ``xrepr_str`` would kick in.
1181 1186 def xrepr_ifile(self, mode="default"):
1182 1187 try:
1183 1188 if self.isdir():
1184 1189 name = "idir"
1185 1190 style = astyle.style_dir
1186 1191 else:
1187 1192 name = "ifile"
1188 1193 style = astyle.style_file
1189 1194 except IOError:
1190 1195 name = "ifile"
1191 1196 style = astyle.style_default
1192 1197 if mode in ("cell", "header", "footer"):
1193 1198 abspath = repr(path._base(self.normpath()))
1194 1199 if abspath.startswith("u"):
1195 1200 abspath = abspath[2:-1]
1196 1201 else:
1197 1202 abspath = abspath[1:-1]
1198 1203 if mode == "cell":
1199 1204 yield (style, abspath)
1200 1205 else:
1201 1206 yield (style, "%s(%s)" % (name, abspath))
1202 1207 else:
1203 1208 yield (style, repr(self))
1204 1209 xrepr.when_type(ifile)(xrepr_ifile)
1205 1210
1206 1211
1207 1212 class ils(Table):
1208 1213 """
1209 1214 List the current (or a specified) directory.
1210 1215
1211 1216 Examples::
1212 1217
1213 1218 >>> ils
1214 1219 <class 'IPython.Extensions.ipipe.ils'>
1215 1220 >>> ils("/usr/local/lib/python2.4")
1216 1221 IPython.Extensions.ipipe.ils('/usr/local/lib/python2.4')
1217 1222 >>> ils("~")
1218 1223 IPython.Extensions.ipipe.ils('/home/fperez')
1219 1224 # all-random
1220 1225 """
1221 1226 def __init__(self, base=os.curdir, dirs=True, files=True):
1222 1227 self.base = os.path.expanduser(base)
1223 1228 self.dirs = dirs
1224 1229 self.files = files
1225 1230
1226 1231 def __iter__(self):
1227 1232 base = ifile(self.base)
1228 1233 yield (base / os.pardir).abspath()
1229 1234 for child in sorted(base.listdir()):
1230 1235 if self.dirs:
1231 1236 if self.files:
1232 1237 yield child
1233 1238 else:
1234 1239 if child.isdir():
1235 1240 yield child
1236 1241 elif self.files:
1237 1242 if not child.isdir():
1238 1243 yield child
1239 1244
1240 1245 def __xrepr__(self, mode="default"):
1241 1246 return xrepr(ifile(self.base), mode)
1242 1247
1243 1248 def __repr__(self):
1244 1249 return "%s.%s(%r)" % \
1245 1250 (self.__class__.__module__, self.__class__.__name__, self.base)
1246 1251
1247 1252
1248 1253 class iglob(Table):
1249 1254 """
1250 1255 List all files and directories matching a specified pattern.
1251 1256 (See ``glob.glob()`` for more info.).
1252 1257
1253 1258 Examples::
1254 1259
1255 1260 >>> iglob("*.py")
1256 1261 IPython.Extensions.ipipe.iglob('*.py')
1257 1262 """
1258 1263 def __init__(self, glob):
1259 1264 self.glob = glob
1260 1265
1261 1266 def __iter__(self):
1262 1267 for name in glob.glob(self.glob):
1263 1268 yield ifile(name)
1264 1269
1265 1270 def __xrepr__(self, mode="default"):
1266 1271 if mode == "header" or mode == "footer" or mode == "cell":
1267 1272 yield (astyle.style_default,
1268 1273 "%s(%r)" % (self.__class__.__name__, self.glob))
1269 1274 else:
1270 1275 yield (astyle.style_default, repr(self))
1271 1276
1272 1277 def __repr__(self):
1273 1278 return "%s.%s(%r)" % \
1274 1279 (self.__class__.__module__, self.__class__.__name__, self.glob)
1275 1280
1276 1281
1277 1282 class iwalk(Table):
1278 1283 """
1279 1284 List all files and directories in a directory and it's subdirectory::
1280 1285
1281 1286 >>> iwalk
1282 1287 <class 'IPython.Extensions.ipipe.iwalk'>
1283 1288 >>> iwalk("/usr/lib")
1284 1289 IPython.Extensions.ipipe.iwalk('/usr/lib')
1285 1290 >>> iwalk("~")
1286 1291 IPython.Extensions.ipipe.iwalk('/home/fperez') # random
1287 1292
1288 1293 """
1289 1294 def __init__(self, base=os.curdir, dirs=True, files=True):
1290 1295 self.base = os.path.expanduser(base)
1291 1296 self.dirs = dirs
1292 1297 self.files = files
1293 1298
1294 1299 def __iter__(self):
1295 1300 for (dirpath, dirnames, filenames) in os.walk(self.base):
1296 1301 if self.dirs:
1297 1302 for name in sorted(dirnames):
1298 1303 yield ifile(os.path.join(dirpath, name))
1299 1304 if self.files:
1300 1305 for name in sorted(filenames):
1301 1306 yield ifile(os.path.join(dirpath, name))
1302 1307
1303 1308 def __xrepr__(self, mode="default"):
1304 1309 if mode == "header" or mode == "footer" or mode == "cell":
1305 1310 yield (astyle.style_default,
1306 1311 "%s(%r)" % (self.__class__.__name__, self.base))
1307 1312 else:
1308 1313 yield (astyle.style_default, repr(self))
1309 1314
1310 1315 def __repr__(self):
1311 1316 return "%s.%s(%r)" % \
1312 1317 (self.__class__.__module__, self.__class__.__name__, self.base)
1313 1318
1314 1319
1315 1320 class ipwdentry(object):
1316 1321 """
1317 1322 ``ipwdentry`` objects encapsulate entries in the Unix user account and
1318 1323 password database.
1319 1324 """
1320 1325 def __init__(self, id):
1321 1326 self._id = id
1322 1327 self._entry = None
1323 1328
1324 1329 def __eq__(self, other):
1325 1330 return self.__class__ is other.__class__ and self._id == other._id
1326 1331
1327 1332 def __ne__(self, other):
1328 1333 return self.__class__ is not other.__class__ or self._id != other._id
1329 1334
1330 1335 def _getentry(self):
1331 1336 if self._entry is None:
1332 1337 if isinstance(self._id, basestring):
1333 1338 self._entry = pwd.getpwnam(self._id)
1334 1339 else:
1335 1340 self._entry = pwd.getpwuid(self._id)
1336 1341 return self._entry
1337 1342
1338 1343 def getname(self):
1339 1344 if isinstance(self._id, basestring):
1340 1345 return self._id
1341 1346 else:
1342 1347 return self._getentry().pw_name
1343 1348 name = property(getname, None, None, "User name")
1344 1349
1345 1350 def getpasswd(self):
1346 1351 return self._getentry().pw_passwd
1347 1352 passwd = property(getpasswd, None, None, "Password")
1348 1353
1349 1354 def getuid(self):
1350 1355 if isinstance(self._id, basestring):
1351 1356 return self._getentry().pw_uid
1352 1357 else:
1353 1358 return self._id
1354 1359 uid = property(getuid, None, None, "User id")
1355 1360
1356 1361 def getgid(self):
1357 1362 return self._getentry().pw_gid
1358 1363 gid = property(getgid, None, None, "Primary group id")
1359 1364
1360 1365 def getgroup(self):
1361 1366 return igrpentry(self.gid)
1362 1367 group = property(getgroup, None, None, "Group")
1363 1368
1364 1369 def getgecos(self):
1365 1370 return self._getentry().pw_gecos
1366 1371 gecos = property(getgecos, None, None, "Information (e.g. full user name)")
1367 1372
1368 1373 def getdir(self):
1369 1374 return self._getentry().pw_dir
1370 1375 dir = property(getdir, None, None, "$HOME directory")
1371 1376
1372 1377 def getshell(self):
1373 1378 return self._getentry().pw_shell
1374 1379 shell = property(getshell, None, None, "Login shell")
1375 1380
1376 1381 def __xattrs__(self, mode="default"):
1377 1382 return ("name", "passwd", "uid", "gid", "gecos", "dir", "shell")
1378 1383
1379 1384 def __repr__(self):
1380 1385 return "%s.%s(%r)" % \
1381 1386 (self.__class__.__module__, self.__class__.__name__, self._id)
1382 1387
1383 1388
1384 1389 class ipwd(Table):
1385 1390 """
1386 1391 List all entries in the Unix user account and password database.
1387 1392
1388 1393 Example::
1389 1394
1390 1395 >>> ipwd | isort("uid")
1391 1396 <IPython.Extensions.ipipe.isort key='uid' reverse=False at 0x849efec>
1392 1397 # random
1393 1398 """
1394 1399 def __iter__(self):
1395 1400 for entry in pwd.getpwall():
1396 1401 yield ipwdentry(entry.pw_name)
1397 1402
1398 1403 def __xrepr__(self, mode="default"):
1399 1404 if mode == "header" or mode == "footer" or mode == "cell":
1400 1405 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1401 1406 else:
1402 1407 yield (astyle.style_default, repr(self))
1403 1408
1404 1409
1405 1410 class igrpentry(object):
1406 1411 """
1407 1412 ``igrpentry`` objects encapsulate entries in the Unix group database.
1408 1413 """
1409 1414 def __init__(self, id):
1410 1415 self._id = id
1411 1416 self._entry = None
1412 1417
1413 1418 def __eq__(self, other):
1414 1419 return self.__class__ is other.__class__ and self._id == other._id
1415 1420
1416 1421 def __ne__(self, other):
1417 1422 return self.__class__ is not other.__class__ or self._id != other._id
1418 1423
1419 1424 def _getentry(self):
1420 1425 if self._entry is None:
1421 1426 if isinstance(self._id, basestring):
1422 1427 self._entry = grp.getgrnam(self._id)
1423 1428 else:
1424 1429 self._entry = grp.getgrgid(self._id)
1425 1430 return self._entry
1426 1431
1427 1432 def getname(self):
1428 1433 if isinstance(self._id, basestring):
1429 1434 return self._id
1430 1435 else:
1431 1436 return self._getentry().gr_name
1432 1437 name = property(getname, None, None, "Group name")
1433 1438
1434 1439 def getpasswd(self):
1435 1440 return self._getentry().gr_passwd
1436 1441 passwd = property(getpasswd, None, None, "Password")
1437 1442
1438 1443 def getgid(self):
1439 1444 if isinstance(self._id, basestring):
1440 1445 return self._getentry().gr_gid
1441 1446 else:
1442 1447 return self._id
1443 1448 gid = property(getgid, None, None, "Group id")
1444 1449
1445 1450 def getmem(self):
1446 1451 return self._getentry().gr_mem
1447 1452 mem = property(getmem, None, None, "Members")
1448 1453
1449 1454 def __xattrs__(self, mode="default"):
1450 1455 return ("name", "passwd", "gid", "mem")
1451 1456
1452 1457 def __xrepr__(self, mode="default"):
1453 1458 if mode == "header" or mode == "footer" or mode == "cell":
1454 1459 yield (astyle.style_default, "group ")
1455 1460 try:
1456 1461 yield (astyle.style_default, self.name)
1457 1462 except KeyError:
1458 1463 if isinstance(self._id, basestring):
1459 1464 yield (astyle.style_default, self.name_id)
1460 1465 else:
1461 1466 yield (astyle.style_type_number, str(self._id))
1462 1467 else:
1463 1468 yield (astyle.style_default, repr(self))
1464 1469
1465 1470 def __iter__(self):
1466 1471 for member in self.mem:
1467 1472 yield ipwdentry(member)
1468 1473
1469 1474 def __repr__(self):
1470 1475 return "%s.%s(%r)" % \
1471 1476 (self.__class__.__module__, self.__class__.__name__, self._id)
1472 1477
1473 1478
1474 1479 class igrp(Table):
1475 1480 """
1476 1481 This ``Table`` lists all entries in the Unix group database.
1477 1482 """
1478 1483 def __iter__(self):
1479 1484 for entry in grp.getgrall():
1480 1485 yield igrpentry(entry.gr_name)
1481 1486
1482 1487 def __xrepr__(self, mode="default"):
1483 1488 if mode == "header" or mode == "footer":
1484 1489 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1485 1490 else:
1486 1491 yield (astyle.style_default, repr(self))
1487 1492
1488 1493
1489 1494 class Fields(object):
1490 1495 def __init__(self, fieldnames, **fields):
1491 1496 self.__fieldnames = [upgradexattr(fieldname) for fieldname in fieldnames]
1492 1497 for (key, value) in fields.iteritems():
1493 1498 setattr(self, key, value)
1494 1499
1495 1500 def __xattrs__(self, mode="default"):
1496 1501 return self.__fieldnames
1497 1502
1498 1503 def __xrepr__(self, mode="default"):
1499 1504 yield (-1, False)
1500 1505 if mode == "header" or mode == "cell":
1501 1506 yield (astyle.style_default, self.__class__.__name__)
1502 1507 yield (astyle.style_default, "(")
1503 1508 for (i, f) in enumerate(self.__fieldnames):
1504 1509 if i:
1505 1510 yield (astyle.style_default, ", ")
1506 1511 yield (astyle.style_default, f.name())
1507 1512 yield (astyle.style_default, "=")
1508 1513 for part in xrepr(getattr(self, f), "default"):
1509 1514 yield part
1510 1515 yield (astyle.style_default, ")")
1511 1516 elif mode == "footer":
1512 1517 yield (astyle.style_default, self.__class__.__name__)
1513 1518 yield (astyle.style_default, "(")
1514 1519 for (i, f) in enumerate(self.__fieldnames):
1515 1520 if i:
1516 1521 yield (astyle.style_default, ", ")
1517 1522 yield (astyle.style_default, f.name())
1518 1523 yield (astyle.style_default, ")")
1519 1524 else:
1520 1525 yield (astyle.style_default, repr(self))
1521 1526
1522 1527
1523 1528 class FieldTable(Table, list):
1524 1529 def __init__(self, *fields):
1525 1530 Table.__init__(self)
1526 1531 list.__init__(self)
1527 1532 self.fields = fields
1528 1533
1529 1534 def add(self, **fields):
1530 1535 self.append(Fields(self.fields, **fields))
1531 1536
1532 1537 def __xrepr__(self, mode="default"):
1533 1538 yield (-1, False)
1534 1539 if mode == "header" or mode == "footer":
1535 1540 yield (astyle.style_default, self.__class__.__name__)
1536 1541 yield (astyle.style_default, "(")
1537 1542 for (i, f) in enumerate(self.__fieldnames):
1538 1543 if i:
1539 1544 yield (astyle.style_default, ", ")
1540 1545 yield (astyle.style_default, f)
1541 1546 yield (astyle.style_default, ")")
1542 1547 else:
1543 1548 yield (astyle.style_default, repr(self))
1544 1549
1545 1550 def __repr__(self):
1546 1551 return "<%s.%s object with fields=%r at 0x%x>" % \
1547 1552 (self.__class__.__module__, self.__class__.__name__,
1548 1553 ", ".join(map(repr, self.fields)), id(self))
1549 1554
1550 1555
1551 1556 class List(list):
1552 1557 def __xattrs__(self, mode="default"):
1553 1558 return xrange(len(self))
1554 1559
1555 1560 def __xrepr__(self, mode="default"):
1556 1561 yield (-1, False)
1557 1562 if mode == "header" or mode == "cell" or mode == "footer" or mode == "default":
1558 1563 yield (astyle.style_default, self.__class__.__name__)
1559 1564 yield (astyle.style_default, "(")
1560 1565 for (i, item) in enumerate(self):
1561 1566 if i:
1562 1567 yield (astyle.style_default, ", ")
1563 1568 for part in xrepr(item, "default"):
1564 1569 yield part
1565 1570 yield (astyle.style_default, ")")
1566 1571 else:
1567 1572 yield (astyle.style_default, repr(self))
1568 1573
1569 1574
1570 1575 class ienv(Table):
1571 1576 """
1572 1577 List environment variables.
1573 1578
1574 1579 Example::
1575 1580
1576 1581 >>> ienv
1577 1582 <class 'IPython.Extensions.ipipe.ienv'>
1578 1583 """
1579 1584
1580 1585 def __iter__(self):
1581 1586 fields = ("key", "value")
1582 1587 for (key, value) in os.environ.iteritems():
1583 1588 yield Fields(fields, key=key, value=value)
1584 1589
1585 1590 def __xrepr__(self, mode="default"):
1586 1591 if mode == "header" or mode == "cell":
1587 1592 yield (astyle.style_default, "%s()" % self.__class__.__name__)
1588 1593 else:
1589 1594 yield (astyle.style_default, repr(self))
1590 1595
1591 1596
1592 1597 class ihist(Table):
1593 1598 """
1594 1599 IPython input history
1595 1600
1596 1601 Example::
1597 1602
1598 1603 >>> ihist
1599 1604 <class 'IPython.Extensions.ipipe.ihist'>
1600 1605 >>> ihist(True) # raw mode
1601 1606 <IPython.Extensions.ipipe.ihist object at 0x849602c> # random
1602 1607 """
1603 1608 def __init__(self, raw=True):
1604 1609 self.raw = raw
1605 1610
1606 1611 def __iter__(self):
1607 1612 api = ipapi.get()
1608 1613 if self.raw:
1609 1614 for line in api.IP.input_hist_raw:
1610 1615 yield line.rstrip("\n")
1611 1616 else:
1612 1617 for line in api.IP.input_hist:
1613 1618 yield line.rstrip("\n")
1614 1619
1615 1620
1616 1621 class Alias(object):
1617 1622 """
1618 1623 Entry in the alias table
1619 1624 """
1620 1625 def __init__(self, name, args, command):
1621 1626 self.name = name
1622 1627 self.args = args
1623 1628 self.command = command
1624 1629
1625 1630 def __xattrs__(self, mode="default"):
1626 1631 return ("name", "args", "command")
1627 1632
1628 1633
1629 1634 class ialias(Table):
1630 1635 """
1631 1636 IPython alias list
1632 1637
1633 1638 Example::
1634 1639
1635 1640 >>> ialias
1636 1641 <class 'IPython.Extensions.ipipe.ialias'>
1637 1642 """
1638 1643 def __iter__(self):
1639 1644 api = ipapi.get()
1640 1645
1641 1646 for (name, (args, command)) in api.IP.alias_table.iteritems():
1642 1647 yield Alias(name, args, command)
1643 1648
1644 1649
1645 1650 class icsv(Pipe):
1646 1651 """
1647 1652 This ``Pipe`` turns the input (with must be a pipe outputting lines
1648 1653 or an ``ifile``) into lines of CVS columns.
1649 1654 """
1650 1655 def __init__(self, **csvargs):
1651 1656 """
1652 1657 Create an ``icsv`` object. ``cvsargs`` will be passed through as
1653 1658 keyword arguments to ``cvs.reader()``.
1654 1659 """
1655 1660 self.csvargs = csvargs
1656 1661
1657 1662 def __iter__(self):
1658 1663 input = self.input
1659 1664 if isinstance(input, ifile):
1660 1665 input = input.open("rb")
1661 1666 reader = csv.reader(input, **self.csvargs)
1662 1667 for line in reader:
1663 1668 yield List(line)
1664 1669
1665 1670 def __xrepr__(self, mode="default"):
1666 1671 yield (-1, False)
1667 1672 if mode == "header" or mode == "footer":
1668 1673 input = getattr(self, "input", None)
1669 1674 if input is not None:
1670 1675 for part in xrepr(input, mode):
1671 1676 yield part
1672 1677 yield (astyle.style_default, " | ")
1673 1678 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1674 1679 for (i, (name, value)) in enumerate(self.csvargs.iteritems()):
1675 1680 if i:
1676 1681 yield (astyle.style_default, ", ")
1677 1682 yield (astyle.style_default, name)
1678 1683 yield (astyle.style_default, "=")
1679 1684 for part in xrepr(value, "default"):
1680 1685 yield part
1681 1686 yield (astyle.style_default, ")")
1682 1687 else:
1683 1688 yield (astyle.style_default, repr(self))
1684 1689
1685 1690 def __repr__(self):
1686 1691 args = ", ".join(["%s=%r" % item for item in self.csvargs.iteritems()])
1687 1692 return "<%s.%s %s at 0x%x>" % \
1688 1693 (self.__class__.__module__, self.__class__.__name__, args, id(self))
1689 1694
1690 1695
1691 1696 class ix(Table):
1692 1697 """
1693 1698 Execute a system command and list its output as lines
1694 1699 (similar to ``os.popen()``).
1695 1700
1696 1701 Examples::
1697 1702
1698 1703 >>> ix("ps x")
1699 1704 IPython.Extensions.ipipe.ix('ps x')
1700 1705
1701 1706 >>> ix("find .") | ifile
1702 1707 <IPython.Extensions.ipipe.ieval expr=<class 'IPython.Extensions.ipipe.ifile'> at 0x8509d2c>
1703 1708 # random
1704 1709 """
1705 1710 def __init__(self, cmd):
1706 1711 self.cmd = cmd
1707 1712 self._pipeout = None
1708 1713
1709 1714 def __iter__(self):
1710 1715 (_pipein, self._pipeout) = os.popen4(self.cmd)
1711 1716 _pipein.close()
1712 1717 for l in self._pipeout:
1713 1718 yield l.rstrip("\r\n")
1714 1719 self._pipeout.close()
1715 1720 self._pipeout = None
1716 1721
1717 1722 def __del__(self):
1718 1723 if self._pipeout is not None and not self._pipeout.closed:
1719 1724 self._pipeout.close()
1720 1725 self._pipeout = None
1721 1726
1722 1727 def __xrepr__(self, mode="default"):
1723 1728 if mode == "header" or mode == "footer":
1724 1729 yield (astyle.style_default,
1725 1730 "%s(%r)" % (self.__class__.__name__, self.cmd))
1726 1731 else:
1727 1732 yield (astyle.style_default, repr(self))
1728 1733
1729 1734 def __repr__(self):
1730 1735 return "%s.%s(%r)" % \
1731 1736 (self.__class__.__module__, self.__class__.__name__, self.cmd)
1732 1737
1733 1738
1734 1739 class ifilter(Pipe):
1735 1740 """
1736 1741 Filter an input pipe. Only objects where an expression evaluates to true
1737 1742 (and doesn't raise an exception) are listed.
1738 1743
1739 1744 Examples::
1740 1745
1741 1746 >>> ils | ifilter("_.isfile() and size>1000")
1742 1747 >>> igrp | ifilter("len(mem)")
1743 1748 >>> sys.modules | ifilter(lambda _:_.value is not None)
1744 1749 # all-random
1745 1750 """
1746 1751
1747 1752 def __init__(self, expr, globals=None, errors="raiseifallfail"):
1748 1753 """
1749 1754 Create an ``ifilter`` object. ``expr`` can be a callable or a string
1750 1755 containing an expression. ``globals`` will be used as the global
1751 1756 namespace for calling string expressions (defaulting to IPython's
1752 1757 user namespace). ``errors`` specifies how exception during evaluation
1753 1758 of ``expr`` are handled:
1754 1759
1755 1760 ``"drop"``
1756 1761 drop all items that have errors;
1757 1762
1758 1763 ``"keep"``
1759 1764 keep all items that have errors;
1760 1765
1761 1766 ``"keeperror"``
1762 1767 keep the exception of all items that have errors;
1763 1768
1764 1769 ``"raise"``
1765 1770 raise the exception;
1766 1771
1767 1772 ``"raiseifallfail"``
1768 1773 raise the first exception if all items have errors; otherwise drop
1769 1774 those with errors (this is the default).
1770 1775 """
1771 1776 self.expr = expr
1772 1777 self.globals = globals
1773 1778 self.errors = errors
1774 1779
1775 1780 def __iter__(self):
1776 1781 if callable(self.expr):
1777 1782 test = self.expr
1778 1783 else:
1779 1784 g = getglobals(self.globals)
1780 1785 expr = compile(self.expr, "ipipe-expression", "eval")
1781 1786 def test(item):
1782 1787 return eval(expr, g, AttrNamespace(item))
1783 1788
1784 1789 ok = 0
1785 1790 exc_info = None
1786 1791 for item in xiter(self.input):
1787 1792 try:
1788 1793 if test(item):
1789 1794 yield item
1790 1795 ok += 1
1791 1796 except (KeyboardInterrupt, SystemExit):
1792 1797 raise
1793 1798 except Exception, exc:
1794 1799 if self.errors == "drop":
1795 1800 pass # Ignore errors
1796 1801 elif self.errors == "keep":
1797 1802 yield item
1798 1803 elif self.errors == "keeperror":
1799 1804 yield exc
1800 1805 elif self.errors == "raise":
1801 1806 raise
1802 1807 elif self.errors == "raiseifallfail":
1803 1808 if exc_info is None:
1804 1809 exc_info = sys.exc_info()
1805 1810 if not ok and exc_info is not None:
1806 1811 raise exc_info[0], exc_info[1], exc_info[2]
1807 1812
1808 1813 def __xrepr__(self, mode="default"):
1809 1814 if mode == "header" or mode == "footer":
1810 1815 input = getattr(self, "input", None)
1811 1816 if input is not None:
1812 1817 for part in xrepr(input, mode):
1813 1818 yield part
1814 1819 yield (astyle.style_default, " | ")
1815 1820 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1816 1821 for part in xrepr(self.expr, "default"):
1817 1822 yield part
1818 1823 yield (astyle.style_default, ")")
1819 1824 else:
1820 1825 yield (astyle.style_default, repr(self))
1821 1826
1822 1827 def __repr__(self):
1823 1828 return "<%s.%s expr=%r at 0x%x>" % \
1824 1829 (self.__class__.__module__, self.__class__.__name__,
1825 1830 self.expr, id(self))
1826 1831
1827 1832
1828 1833 class ieval(Pipe):
1829 1834 """
1830 1835 Evaluate an expression for each object in the input pipe.
1831 1836
1832 1837 Examples::
1833 1838
1834 1839 >>> ils | ieval("_.abspath()")
1835 1840 # random
1836 1841 >>> sys.path | ieval(ifile)
1837 1842 # random
1838 1843 """
1839 1844
1840 1845 def __init__(self, expr, globals=None, errors="raiseifallfail"):
1841 1846 """
1842 1847 Create an ``ieval`` object. ``expr`` can be a callable or a string
1843 1848 containing an expression. For the meaning of ``globals`` and
1844 1849 ``errors`` see ``ifilter``.
1845 1850 """
1846 1851 self.expr = expr
1847 1852 self.globals = globals
1848 1853 self.errors = errors
1849 1854
1850 1855 def __iter__(self):
1851 1856 if callable(self.expr):
1852 1857 do = self.expr
1853 1858 else:
1854 1859 g = getglobals(self.globals)
1855 1860 expr = compile(self.expr, "ipipe-expression", "eval")
1856 1861 def do(item):
1857 1862 return eval(expr, g, AttrNamespace(item))
1858 1863
1859 1864 ok = 0
1860 1865 exc_info = None
1861 1866 for item in xiter(self.input):
1862 1867 try:
1863 1868 yield do(item)
1864 1869 except (KeyboardInterrupt, SystemExit):
1865 1870 raise
1866 1871 except Exception, exc:
1867 1872 if self.errors == "drop":
1868 1873 pass # Ignore errors
1869 1874 elif self.errors == "keep":
1870 1875 yield item
1871 1876 elif self.errors == "keeperror":
1872 1877 yield exc
1873 1878 elif self.errors == "raise":
1874 1879 raise
1875 1880 elif self.errors == "raiseifallfail":
1876 1881 if exc_info is None:
1877 1882 exc_info = sys.exc_info()
1878 1883 if not ok and exc_info is not None:
1879 1884 raise exc_info[0], exc_info[1], exc_info[2]
1880 1885
1881 1886 def __xrepr__(self, mode="default"):
1882 1887 if mode == "header" or mode == "footer":
1883 1888 input = getattr(self, "input", None)
1884 1889 if input is not None:
1885 1890 for part in xrepr(input, mode):
1886 1891 yield part
1887 1892 yield (astyle.style_default, " | ")
1888 1893 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1889 1894 for part in xrepr(self.expr, "default"):
1890 1895 yield part
1891 1896 yield (astyle.style_default, ")")
1892 1897 else:
1893 1898 yield (astyle.style_default, repr(self))
1894 1899
1895 1900 def __repr__(self):
1896 1901 return "<%s.%s expr=%r at 0x%x>" % \
1897 1902 (self.__class__.__module__, self.__class__.__name__,
1898 1903 self.expr, id(self))
1899 1904
1900 1905
1901 1906 class ienum(Pipe):
1902 1907 """
1903 1908 Enumerate the input pipe (i.e. wrap each input object in an object
1904 1909 with ``index`` and ``object`` attributes).
1905 1910
1906 1911 Examples::
1907 1912
1908 1913 >>> xrange(20) | ieval("_,_*_") | ienum | ifilter("index % 2 == 0") | ieval("object")
1909 1914 """
1910 1915 skip_doctest = True
1911 1916
1912 1917 def __iter__(self):
1913 1918 fields = ("index", "object")
1914 1919 for (index, object) in enumerate(xiter(self.input)):
1915 1920 yield Fields(fields, index=index, object=object)
1916 1921
1917 1922
1918 1923 class isort(Pipe):
1919 1924 """
1920 1925 Sorts the input pipe.
1921 1926
1922 1927 Examples::
1923 1928
1924 1929 >>> ils | isort("size")
1925 1930 <IPython.Extensions.ipipe.isort key='size' reverse=False at 0x849ec2c>
1926 1931 >>> ils | isort("_.isdir(), _.lower()", reverse=True)
1927 1932 <IPython.Extensions.ipipe.isort key='_.isdir(), _.lower()' reverse=True at 0x849eacc>
1928 1933 # all-random
1929 1934 """
1930 1935
1931 1936 def __init__(self, key=None, globals=None, reverse=False):
1932 1937 """
1933 1938 Create an ``isort`` object. ``key`` can be a callable or a string
1934 1939 containing an expression (or ``None`` in which case the items
1935 1940 themselves will be sorted). If ``reverse`` is true the sort order
1936 1941 will be reversed. For the meaning of ``globals`` see ``ifilter``.
1937 1942 """
1938 1943 self.key = key
1939 1944 self.globals = globals
1940 1945 self.reverse = reverse
1941 1946
1942 1947 def __iter__(self):
1943 1948 if self.key is None:
1944 1949 items = sorted(xiter(self.input), reverse=self.reverse)
1945 1950 elif callable(self.key):
1946 1951 items = sorted(xiter(self.input), key=self.key, reverse=self.reverse)
1947 1952 else:
1948 1953 g = getglobals(self.globals)
1949 1954 key = compile(self.key, "ipipe-expression", "eval")
1950 1955 def realkey(item):
1951 1956 return eval(key, g, AttrNamespace(item))
1952 1957 items = sorted(xiter(self.input), key=realkey, reverse=self.reverse)
1953 1958 for item in items:
1954 1959 yield item
1955 1960
1956 1961 def __xrepr__(self, mode="default"):
1957 1962 if mode == "header" or mode == "footer":
1958 1963 input = getattr(self, "input", None)
1959 1964 if input is not None:
1960 1965 for part in xrepr(input, mode):
1961 1966 yield part
1962 1967 yield (astyle.style_default, " | ")
1963 1968 yield (astyle.style_default, "%s(" % self.__class__.__name__)
1964 1969 for part in xrepr(self.key, "default"):
1965 1970 yield part
1966 1971 if self.reverse:
1967 1972 yield (astyle.style_default, ", ")
1968 1973 for part in xrepr(True, "default"):
1969 1974 yield part
1970 1975 yield (astyle.style_default, ")")
1971 1976 else:
1972 1977 yield (astyle.style_default, repr(self))
1973 1978
1974 1979 def __repr__(self):
1975 1980 return "<%s.%s key=%r reverse=%r at 0x%x>" % \
1976 1981 (self.__class__.__module__, self.__class__.__name__,
1977 1982 self.key, self.reverse, id(self))
1978 1983
1979 1984
1980 1985 tab = 3 # for expandtabs()
1981 1986
1982 1987 def _format(field):
1983 1988 if isinstance(field, str):
1984 1989 text = repr(field.expandtabs(tab))[1:-1]
1985 1990 elif isinstance(field, unicode):
1986 1991 text = repr(field.expandtabs(tab))[2:-1]
1987 1992 elif isinstance(field, datetime.datetime):
1988 1993 # Don't use strftime() here, as this requires year >= 1900
1989 1994 text = "%04d-%02d-%02d %02d:%02d:%02d.%06d" % \
1990 1995 (field.year, field.month, field.day,
1991 1996 field.hour, field.minute, field.second, field.microsecond)
1992 1997 elif isinstance(field, datetime.date):
1993 1998 text = "%04d-%02d-%02d" % (field.year, field.month, field.day)
1994 1999 else:
1995 2000 text = repr(field)
1996 2001 return text
1997 2002
1998 2003
1999 2004 class Display(object):
2000 2005 class __metaclass__(type):
2001 2006 def __ror__(self, input):
2002 2007 return input | self()
2003 2008
2004 2009 def __init__(self, input=None):
2005 2010 self.input = input
2006 2011
2007 2012 def __ror__(self, input):
2008 2013 self.input = input
2009 2014 return self
2010 2015
2011 2016 def display(self):
2012 2017 pass
2013 2018
2014 2019
2015 2020 class iless(Display):
2016 2021 cmd = "less --quit-if-one-screen --LONG-PROMPT --LINE-NUMBERS --chop-long-lines --shift=8 --RAW-CONTROL-CHARS"
2017 2022
2018 2023 def display(self):
2019 2024 try:
2020 2025 pager = os.popen(self.cmd, "w")
2021 2026 try:
2022 2027 for item in xiter(self.input):
2023 2028 first = False
2024 2029 for attr in xattrs(item, "default"):
2025 2030 if first:
2026 2031 first = False
2027 2032 else:
2028 2033 pager.write(" ")
2029 2034 attr = upgradexattr(attr)
2030 2035 if not isinstance(attr, SelfDescriptor):
2031 2036 pager.write(attr.name())
2032 2037 pager.write("=")
2033 2038 pager.write(str(attr.value(item)))
2034 2039 pager.write("\n")
2035 2040 finally:
2036 2041 pager.close()
2037 2042 except Exception, exc:
2038 2043 print "%s: %s" % (exc.__class__.__name__, str(exc))
2039 2044
2040 2045
2041 2046 class _RedirectIO(object):
2042 2047 def __init__(self,*args,**kwargs):
2043 2048 """
2044 2049 Map the system output streams to self.
2045 2050 """
2046 2051 self.stream = StringIO.StringIO()
2047 2052 self.stdout = sys.stdout
2048 2053 sys.stdout = self
2049 2054 self.stderr = sys.stderr
2050 2055 sys.stderr = self
2051 2056
2052 2057 def write(self, text):
2053 2058 """
2054 2059 Write both to screen and to self.
2055 2060 """
2056 2061 self.stream.write(text)
2057 2062 self.stdout.write(text)
2058 2063 if "\n" in text:
2059 2064 self.stdout.flush()
2060 2065
2061 2066 def writelines(self, lines):
2062 2067 """
2063 2068 Write lines both to screen and to self.
2064 2069 """
2065 2070 self.stream.writelines(lines)
2066 2071 self.stdout.writelines(lines)
2067 2072 self.stdout.flush()
2068 2073
2069 2074 def restore(self):
2070 2075 """
2071 2076 Restore the default system streams.
2072 2077 """
2073 2078 self.stdout.flush()
2074 2079 self.stderr.flush()
2075 2080 sys.stdout = self.stdout
2076 2081 sys.stderr = self.stderr
2077 2082
2078 2083
2079 2084 class icap(Table):
2080 2085 """
2081 2086 Execute a python string and capture any output to stderr/stdout.
2082 2087
2083 2088 Examples::
2084 2089
2085 2090 >>> import time
2086 2091 >>> icap("for i in range(10): print i, time.sleep(0.1)")
2087 2092
2088 2093 """
2089 2094 skip_doctest = True
2090 2095
2091 2096 def __init__(self, expr, globals=None):
2092 2097 self.expr = expr
2093 2098 self.globals = globals
2094 2099 log = _RedirectIO()
2095 2100 try:
2096 2101 exec(expr, getglobals(globals))
2097 2102 finally:
2098 2103 log.restore()
2099 2104 self.stream = log.stream
2100 2105
2101 2106 def __iter__(self):
2102 2107 self.stream.seek(0)
2103 2108 for line in self.stream:
2104 2109 yield line.rstrip("\r\n")
2105 2110
2106 2111 def __xrepr__(self, mode="default"):
2107 2112 if mode == "header" or mode == "footer":
2108 2113 yield (astyle.style_default,
2109 2114 "%s(%r)" % (self.__class__.__name__, self.expr))
2110 2115 else:
2111 2116 yield (astyle.style_default, repr(self))
2112 2117
2113 2118 def __repr__(self):
2114 2119 return "%s.%s(%r)" % \
2115 2120 (self.__class__.__module__, self.__class__.__name__, self.expr)
2116 2121
2117 2122
2118 2123 def xformat(value, mode, maxlength):
2119 2124 align = None
2120 2125 full = True
2121 2126 width = 0
2122 2127 text = astyle.Text()
2123 2128 for (style, part) in xrepr(value, mode):
2124 2129 # only consider the first result
2125 2130 if align is None:
2126 2131 if isinstance(style, int):
2127 2132 # (style, text) really is (alignment, stop)
2128 2133 align = style
2129 2134 full = part
2130 2135 continue
2131 2136 else:
2132 2137 align = -1
2133 2138 full = True
2134 2139 if not isinstance(style, int):
2135 2140 text.append((style, part))
2136 2141 width += len(part)
2137 2142 if width >= maxlength and not full:
2138 2143 text.append((astyle.style_ellisis, "..."))
2139 2144 width += 3
2140 2145 break
2141 2146 if align is None: # default to left alignment
2142 2147 align = -1
2143 2148 return (align, width, text)
2144 2149
2145 2150
2146 2151
2147 2152 import astyle
2148 2153
2149 2154 class idump(Display):
2150 2155 # The approximate maximum length of a column entry
2151 2156 maxattrlength = 200
2152 2157
2153 2158 # Style for column names
2154 2159 style_header = astyle.Style.fromstr("white:black:bold")
2155 2160
2156 2161 def __init__(self, input=None, *attrs):
2157 2162 Display.__init__(self, input)
2158 2163 self.attrs = [upgradexattr(attr) for attr in attrs]
2159 2164 self.headerpadchar = " "
2160 2165 self.headersepchar = "|"
2161 2166 self.datapadchar = " "
2162 2167 self.datasepchar = "|"
2163 2168
2164 2169 def display(self):
2165 2170 stream = genutils.Term.cout
2166 2171 allattrs = []
2167 2172 attrset = set()
2168 2173 colwidths = {}
2169 2174 rows = []
2170 2175 for item in xiter(self.input):
2171 2176 row = {}
2172 2177 attrs = self.attrs
2173 2178 if not attrs:
2174 2179 attrs = xattrs(item, "default")
2175 2180 for attr in attrs:
2176 2181 if attr not in attrset:
2177 2182 allattrs.append(attr)
2178 2183 attrset.add(attr)
2179 2184 colwidths[attr] = len(attr.name())
2180 2185 try:
2181 2186 value = attr.value(item)
2182 2187 except (KeyboardInterrupt, SystemExit):
2183 2188 raise
2184 2189 except Exception, exc:
2185 2190 value = exc
2186 2191 (align, width, text) = xformat(value, "cell", self.maxattrlength)
2187 2192 colwidths[attr] = max(colwidths[attr], width)
2188 2193 # remember alignment, length and colored parts
2189 2194 row[attr] = (align, width, text)
2190 2195 rows.append(row)
2191 2196
2192 2197 stream.write("\n")
2193 2198 for (i, attr) in enumerate(allattrs):
2194 2199 attrname = attr.name()
2195 2200 self.style_header(attrname).write(stream)
2196 2201 spc = colwidths[attr] - len(attrname)
2197 2202 if i < len(colwidths)-1:
2198 2203 stream.write(self.headerpadchar*spc)
2199 2204 stream.write(self.headersepchar)
2200 2205 stream.write("\n")
2201 2206
2202 2207 for row in rows:
2203 2208 for (i, attr) in enumerate(allattrs):
2204 2209 (align, width, text) = row[attr]
2205 2210 spc = colwidths[attr] - width
2206 2211 if align == -1:
2207 2212 text.write(stream)
2208 2213 if i < len(colwidths)-1:
2209 2214 stream.write(self.datapadchar*spc)
2210 2215 elif align == 0:
2211 2216 spc = colwidths[attr] - width
2212 2217 spc1 = spc//2
2213 2218 spc2 = spc-spc1
2214 2219 stream.write(self.datapadchar*spc1)
2215 2220 text.write(stream)
2216 2221 if i < len(colwidths)-1:
2217 2222 stream.write(self.datapadchar*spc2)
2218 2223 else:
2219 2224 stream.write(self.datapadchar*spc)
2220 2225 text.write(stream)
2221 2226 if i < len(colwidths)-1:
2222 2227 stream.write(self.datasepchar)
2223 2228 stream.write("\n")
2224 2229
2225 2230
2226 2231 class AttributeDetail(Table):
2227 2232 """
2228 2233 ``AttributeDetail`` objects are use for displaying a detailed list of object
2229 2234 attributes.
2230 2235 """
2231 2236 def __init__(self, object, descriptor):
2232 2237 self.object = object
2233 2238 self.descriptor = descriptor
2234 2239
2235 2240 def __iter__(self):
2236 2241 return self.descriptor.iter(self.object)
2237 2242
2238 2243 def name(self):
2239 2244 return self.descriptor.name()
2240 2245
2241 2246 def attrtype(self):
2242 2247 return self.descriptor.attrtype(self.object)
2243 2248
2244 2249 def valuetype(self):
2245 2250 return self.descriptor.valuetype(self.object)
2246 2251
2247 2252 def doc(self):
2248 2253 return self.descriptor.doc(self.object)
2249 2254
2250 2255 def shortdoc(self):
2251 2256 return self.descriptor.shortdoc(self.object)
2252 2257
2253 2258 def value(self):
2254 2259 return self.descriptor.value(self.object)
2255 2260
2256 2261 def __xattrs__(self, mode="default"):
2257 2262 attrs = ("name()", "attrtype()", "valuetype()", "value()", "shortdoc()")
2258 2263 if mode == "detail":
2259 2264 attrs += ("doc()",)
2260 2265 return attrs
2261 2266
2262 2267 def __xrepr__(self, mode="default"):
2263 2268 yield (-1, True)
2264 2269 valuetype = self.valuetype()
2265 2270 if valuetype is not noitem:
2266 2271 for part in xrepr(valuetype):
2267 2272 yield part
2268 2273 yield (astyle.style_default, " ")
2269 2274 yield (astyle.style_default, self.attrtype())
2270 2275 yield (astyle.style_default, " ")
2271 2276 yield (astyle.style_default, self.name())
2272 2277 yield (astyle.style_default, " of ")
2273 2278 for part in xrepr(self.object):
2274 2279 yield part
2275 2280
2276 2281
2277 2282 try:
2278 2283 from ibrowse import ibrowse
2279 2284 except ImportError:
2280 2285 # No curses (probably Windows) => try igrid
2281 2286 try:
2282 2287 from igrid import igrid
2283 2288 except ImportError:
2284 2289 # no wx either => use ``idump`` as the default display.
2285 2290 defaultdisplay = idump
2286 2291 else:
2287 2292 defaultdisplay = igrid
2288 2293 __all__.append("igrid")
2289 2294 else:
2290 2295 defaultdisplay = ibrowse
2291 2296 __all__.append("ibrowse")
2292 2297
2293 2298
2294 2299 # If we're running under IPython, register our objects with IPython's
2295 2300 # generic function ``result_display``, else install a displayhook
2296 2301 # directly as sys.displayhook
2297 2302 if generics is not None:
2298 2303 def display_display(obj):
2299 2304 return obj.display()
2300 2305 generics.result_display.when_type(Display)(display_display)
2301 2306
2302 2307 def display_tableobject(obj):
2303 2308 return display_display(defaultdisplay(obj))
2304 2309 generics.result_display.when_type(Table)(display_tableobject)
2305 2310
2306 2311 def display_tableclass(obj):
2307 2312 return display_tableobject(obj())
2308 2313 generics.result_display.when_type(Table.__metaclass__)(display_tableclass)
2309 2314 else:
2310 2315 def installdisplayhook():
2311 2316 _originalhook = sys.displayhook
2312 2317 def displayhook(obj):
2313 2318 if isinstance(obj, type) and issubclass(obj, Table):
2314 2319 obj = obj()
2315 2320 if isinstance(obj, Table):
2316 2321 obj = defaultdisplay(obj)
2317 2322 if isinstance(obj, Display):
2318 2323 return obj.display()
2319 2324 else:
2320 2325 _originalhook(obj)
2321 2326 sys.displayhook = displayhook
2322 2327 installdisplayhook()
@@ -1,75 +1,75 b''
1 1 """ Greedy completer extension for IPython
2 2
3 3 Normal tab completer refuses to evaluate nonsafe stuff. This will evaluate
4 4 everything, so you need to consider the consequences of pressing tab
5 5 yourself!
6 6
7 7 Note that this extension simplifies readline interaction by setting
8 8 only whitespace as completer delimiter. If this works well, we will
9 9 do the same in default completer.
10 10
11 11 """
12 12 from IPython import generics,ipapi
13 13 from IPython.genutils import dir2
14 14
15 15 def attr_matches(self, text):
16 16 """Compute matches when text contains a dot.
17 17
18 18 MONKEYPATCHED VERSION (ipy_greedycompleter.py)
19 19
20 20 Assuming the text is of the form NAME.NAME....[NAME], and is
21 21 evaluatable in self.namespace or self.global_namespace, it will be
22 22 evaluated and its attributes (as revealed by dir()) are used as
23 23 possible completions. (For class instances, class members are are
24 24 also considered.)
25 25
26 26 WARNING: this can still invoke arbitrary C code, if an object
27 27 with a __getattr__ hook is evaluated.
28 28
29 29 """
30 30 import re
31 31
32 32 force_complete = 1
33 33 # Another option, seems to work great. Catches things like ''.<tab>
34 34 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
35 35
36 36 if m:
37 37 expr, attr = m.group(1, 3)
38 38 else:
39 39 # force match - eval anything that ends with colon
40 40 if not force_complete:
41 41 return []
42 42
43 43 m2 = re.match(r"(.+)\.(\w*)$", self.lbuf)
44 44 if not m2:
45 45 return []
46 46 expr, attr = m2.group(1,2)
47 47
48 48
49 49 try:
50 50 obj = eval(expr, self.namespace)
51 51 except:
52 52 try:
53 53 obj = eval(expr, self.global_namespace)
54 54 except:
55 55 return []
56 56
57 57 words = dir2(obj)
58 58
59 59 try:
60 60 words = generics.complete_object(obj, words)
61 61 except ipapi.TryNext:
62 62 pass
63 63 # Build match list to return
64 64 n = len(attr)
65 65 res = ["%s.%s" % (expr, w) for w in words if w[:n] == attr ]
66 66 return res
67 67
68 68 def main():
69 import readline
69 import IPython.rlineimpl as readline
70 70 readline.set_completer_delims(" \n\t")
71 71 # monkeypatch - the code will be folded to normal completer later on
72 72 import IPython.completer
73 73 IPython.completer.Completer.attr_matches = attr_matches
74 74
75 75 main() No newline at end of file
@@ -1,42 +1,66 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 Class which mimics a module.
4 4
5 5 Needed to allow pickle to correctly resolve namespaces during IPython
6 6 sessions.
7 7 """
8 8
9 9 #*****************************************************************************
10 10 # Copyright (C) 2002-2004 Fernando Perez. <fperez@colorado.edu>
11 11 #
12 12 # Distributed under the terms of the BSD License. The full license is in
13 13 # the file COPYING, distributed as part of this software.
14 14 #*****************************************************************************
15 15
16 16 import types
17 17
18 def init_fakemod_dict(fm,adict=None):
19 """Initialize a FakeModule instance __dict__.
20
21 Kept as a standalone function and not a method so the FakeModule API can
22 remain basically empty.
23
24 This should be considered for private IPython use, used in managing
25 namespaces for %run.
26
27 Parameters
28 ----------
29
30 fm : FakeModule instance
31
32 adict : dict, optional
33 """
34
35 dct = {}
36 # It seems pydoc (and perhaps others) needs any module instance to
37 # implement a __nonzero__ method, so we add it if missing:
38 dct.setdefault('__nonzero__',lambda : True)
39 dct.setdefault('__file__',__file__)
40
41 if adict is not None:
42 dct.update(adict)
43
44 # Hard assignment of the object's __dict__. This is nasty but deliberate.
45 fm.__dict__.clear()
46 fm.__dict__.update(dct)
47
48
18 49 class FakeModule(types.ModuleType):
19 50 """Simple class with attribute access to fake a module.
20 51
21 52 This is not meant to replace a module, but to allow inserting a fake
22 53 module in sys.modules so that systems which rely on run-time module
23 54 importing (like shelve and pickle) work correctly in interactive IPython
24 55 sessions.
25 56
26 57 Do NOT use this code for anything other than this IPython private hack."""
27 58
28 59 def __init__(self,adict=None):
29 60
30 61 # tmp to force __dict__ instance creation, else self.__dict__ fails
31 62 self.__iptmp = None
32
33 # It seems pydoc (and perhaps others) needs any module instance to
34 # implement a __nonzero__ method, so we add it if missing:
35 self.__dict__.setdefault('__nonzero__',lambda : True)
36 self.__dict__.setdefault('__file__',__file__)
37
38 63 # cleanup our temp trick
39 64 del self.__iptmp
40
41 if adict is not None:
42 self.__dict__.update(adict)
65 # Now, initialize the actual data in the instance dict.
66 init_fakemod_dict(self,adict)
@@ -1,3425 +1,3456 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Magic functions for InteractiveShell.
3 3 """
4 4
5 5 #*****************************************************************************
6 6 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
7 7 # Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu>
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #*****************************************************************************
12 12
13 13 #****************************************************************************
14 14 # Modules and globals
15 15
16 16 # Python standard modules
17 17 import __builtin__
18 18 import bdb
19 19 import inspect
20 20 import os
21 21 import pdb
22 22 import pydoc
23 23 import sys
24 24 import re
25 25 import tempfile
26 26 import time
27 27 import cPickle as pickle
28 28 import textwrap
29 29 from cStringIO import StringIO
30 30 from getopt import getopt,GetoptError
31 31 from pprint import pprint, pformat
32 32
33 33 # cProfile was added in Python2.5
34 34 try:
35 35 import cProfile as profile
36 36 import pstats
37 37 except ImportError:
38 38 # profile isn't bundled by default in Debian for license reasons
39 39 try:
40 40 import profile,pstats
41 41 except ImportError:
42 42 profile = pstats = None
43 43
44 44 # Homebrewed
45 45 import IPython
46 46 from IPython import Debugger, OInspect, wildcard
47 47 from IPython.FakeModule import FakeModule
48 48 from IPython.Itpl import Itpl, itpl, printpl,itplns
49 49 from IPython.PyColorize import Parser
50 50 from IPython.ipstruct import Struct
51 51 from IPython.macro import Macro
52 52 from IPython.genutils import *
53 53 from IPython import platutils
54 54 import IPython.generics
55 55 import IPython.ipapi
56 56 from IPython.ipapi import UsageError
57 57 from IPython.testing import decorators as testdec
58 58
59 59 #***************************************************************************
60 60 # Utility functions
61 61 def on_off(tag):
62 62 """Return an ON/OFF string for a 1/0 input. Simple utility function."""
63 63 return ['OFF','ON'][tag]
64 64
65 65 class Bunch: pass
66 66
67 67 def compress_dhist(dh):
68 68 head, tail = dh[:-10], dh[-10:]
69 69
70 70 newhead = []
71 71 done = set()
72 72 for h in head:
73 73 if h in done:
74 74 continue
75 75 newhead.append(h)
76 76 done.add(h)
77 77
78 78 return newhead + tail
79 79
80 80
81 81 #***************************************************************************
82 82 # Main class implementing Magic functionality
83 83 class Magic:
84 84 """Magic functions for InteractiveShell.
85 85
86 86 Shell functions which can be reached as %function_name. All magic
87 87 functions should accept a string, which they can parse for their own
88 88 needs. This can make some functions easier to type, eg `%cd ../`
89 89 vs. `%cd("../")`
90 90
91 91 ALL definitions MUST begin with the prefix magic_. The user won't need it
92 92 at the command line, but it is is needed in the definition. """
93 93
94 94 # class globals
95 95 auto_status = ['Automagic is OFF, % prefix IS needed for magic functions.',
96 96 'Automagic is ON, % prefix NOT needed for magic functions.']
97 97
98 98 #......................................................................
99 99 # some utility functions
100 100
101 101 def __init__(self,shell):
102 102
103 103 self.options_table = {}
104 104 if profile is None:
105 105 self.magic_prun = self.profile_missing_notice
106 106 self.shell = shell
107 107
108 108 # namespace for holding state we may need
109 109 self._magic_state = Bunch()
110 110
111 111 def profile_missing_notice(self, *args, **kwargs):
112 112 error("""\
113 113 The profile module could not be found. It has been removed from the standard
114 114 python packages because of its non-free license. To use profiling, install the
115 115 python-profiler package from non-free.""")
116 116
117 117 def default_option(self,fn,optstr):
118 118 """Make an entry in the options_table for fn, with value optstr"""
119 119
120 120 if fn not in self.lsmagic():
121 121 error("%s is not a magic function" % fn)
122 122 self.options_table[fn] = optstr
123 123
124 124 def lsmagic(self):
125 125 """Return a list of currently available magic functions.
126 126
127 127 Gives a list of the bare names after mangling (['ls','cd', ...], not
128 128 ['magic_ls','magic_cd',...]"""
129 129
130 130 # FIXME. This needs a cleanup, in the way the magics list is built.
131 131
132 132 # magics in class definition
133 133 class_magic = lambda fn: fn.startswith('magic_') and \
134 134 callable(Magic.__dict__[fn])
135 135 # in instance namespace (run-time user additions)
136 136 inst_magic = lambda fn: fn.startswith('magic_') and \
137 137 callable(self.__dict__[fn])
138 138 # and bound magics by user (so they can access self):
139 139 inst_bound_magic = lambda fn: fn.startswith('magic_') and \
140 140 callable(self.__class__.__dict__[fn])
141 141 magics = filter(class_magic,Magic.__dict__.keys()) + \
142 142 filter(inst_magic,self.__dict__.keys()) + \
143 143 filter(inst_bound_magic,self.__class__.__dict__.keys())
144 144 out = []
145 145 for fn in set(magics):
146 146 out.append(fn.replace('magic_','',1))
147 147 out.sort()
148 148 return out
149 149
150 150 def extract_input_slices(self,slices,raw=False):
151 151 """Return as a string a set of input history slices.
152 152
153 153 Inputs:
154 154
155 155 - slices: the set of slices is given as a list of strings (like
156 156 ['1','4:8','9'], since this function is for use by magic functions
157 157 which get their arguments as strings.
158 158
159 159 Optional inputs:
160 160
161 161 - raw(False): by default, the processed input is used. If this is
162 162 true, the raw input history is used instead.
163 163
164 164 Note that slices can be called with two notations:
165 165
166 166 N:M -> standard python form, means including items N...(M-1).
167 167
168 168 N-M -> include items N..M (closed endpoint)."""
169 169
170 170 if raw:
171 171 hist = self.shell.input_hist_raw
172 172 else:
173 173 hist = self.shell.input_hist
174 174
175 175 cmds = []
176 176 for chunk in slices:
177 177 if ':' in chunk:
178 178 ini,fin = map(int,chunk.split(':'))
179 179 elif '-' in chunk:
180 180 ini,fin = map(int,chunk.split('-'))
181 181 fin += 1
182 182 else:
183 183 ini = int(chunk)
184 184 fin = ini+1
185 185 cmds.append(hist[ini:fin])
186 186 return cmds
187 187
188 188 def _ofind(self, oname, namespaces=None):
189 189 """Find an object in the available namespaces.
190 190
191 191 self._ofind(oname) -> dict with keys: found,obj,ospace,ismagic
192 192
193 193 Has special code to detect magic functions.
194 194 """
195 195
196 196 oname = oname.strip()
197 197
198 198 alias_ns = None
199 199 if namespaces is None:
200 200 # Namespaces to search in:
201 201 # Put them in a list. The order is important so that we
202 202 # find things in the same order that Python finds them.
203 203 namespaces = [ ('Interactive', self.shell.user_ns),
204 204 ('IPython internal', self.shell.internal_ns),
205 205 ('Python builtin', __builtin__.__dict__),
206 206 ('Alias', self.shell.alias_table),
207 207 ]
208 208 alias_ns = self.shell.alias_table
209 209
210 210 # initialize results to 'null'
211 211 found = 0; obj = None; ospace = None; ds = None;
212 212 ismagic = 0; isalias = 0; parent = None
213 213
214 214 # Look for the given name by splitting it in parts. If the head is
215 215 # found, then we look for all the remaining parts as members, and only
216 216 # declare success if we can find them all.
217 217 oname_parts = oname.split('.')
218 218 oname_head, oname_rest = oname_parts[0],oname_parts[1:]
219 219 for nsname,ns in namespaces:
220 220 try:
221 221 obj = ns[oname_head]
222 222 except KeyError:
223 223 continue
224 224 else:
225 225 #print 'oname_rest:', oname_rest # dbg
226 226 for part in oname_rest:
227 227 try:
228 228 parent = obj
229 229 obj = getattr(obj,part)
230 230 except:
231 231 # Blanket except b/c some badly implemented objects
232 232 # allow __getattr__ to raise exceptions other than
233 233 # AttributeError, which then crashes IPython.
234 234 break
235 235 else:
236 236 # If we finish the for loop (no break), we got all members
237 237 found = 1
238 238 ospace = nsname
239 239 if ns == alias_ns:
240 240 isalias = 1
241 241 break # namespace loop
242 242
243 243 # Try to see if it's magic
244 244 if not found:
245 245 if oname.startswith(self.shell.ESC_MAGIC):
246 246 oname = oname[1:]
247 247 obj = getattr(self,'magic_'+oname,None)
248 248 if obj is not None:
249 249 found = 1
250 250 ospace = 'IPython internal'
251 251 ismagic = 1
252 252
253 253 # Last try: special-case some literals like '', [], {}, etc:
254 254 if not found and oname_head in ["''",'""','[]','{}','()']:
255 255 obj = eval(oname_head)
256 256 found = 1
257 257 ospace = 'Interactive'
258 258
259 259 return {'found':found, 'obj':obj, 'namespace':ospace,
260 260 'ismagic':ismagic, 'isalias':isalias, 'parent':parent}
261 261
262 262 def arg_err(self,func):
263 263 """Print docstring if incorrect arguments were passed"""
264 264 print 'Error in arguments:'
265 265 print OInspect.getdoc(func)
266 266
267 267 def format_latex(self,strng):
268 268 """Format a string for latex inclusion."""
269 269
270 270 # Characters that need to be escaped for latex:
271 271 escape_re = re.compile(r'(%|_|\$|#|&)',re.MULTILINE)
272 272 # Magic command names as headers:
273 273 cmd_name_re = re.compile(r'^(%s.*?):' % self.shell.ESC_MAGIC,
274 274 re.MULTILINE)
275 275 # Magic commands
276 276 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % self.shell.ESC_MAGIC,
277 277 re.MULTILINE)
278 278 # Paragraph continue
279 279 par_re = re.compile(r'\\$',re.MULTILINE)
280 280
281 281 # The "\n" symbol
282 282 newline_re = re.compile(r'\\n')
283 283
284 284 # Now build the string for output:
285 285 #strng = cmd_name_re.sub(r'\n\\texttt{\\textsl{\\large \1}}:',strng)
286 286 strng = cmd_name_re.sub(r'\n\\bigskip\n\\texttt{\\textbf{ \1}}:',
287 287 strng)
288 288 strng = cmd_re.sub(r'\\texttt{\g<cmd>}',strng)
289 289 strng = par_re.sub(r'\\\\',strng)
290 290 strng = escape_re.sub(r'\\\1',strng)
291 291 strng = newline_re.sub(r'\\textbackslash{}n',strng)
292 292 return strng
293 293
294 294 def format_screen(self,strng):
295 295 """Format a string for screen printing.
296 296
297 297 This removes some latex-type format codes."""
298 298 # Paragraph continue
299 299 par_re = re.compile(r'\\$',re.MULTILINE)
300 300 strng = par_re.sub('',strng)
301 301 return strng
302 302
303 303 def parse_options(self,arg_str,opt_str,*long_opts,**kw):
304 304 """Parse options passed to an argument string.
305 305
306 306 The interface is similar to that of getopt(), but it returns back a
307 307 Struct with the options as keys and the stripped argument string still
308 308 as a string.
309 309
310 310 arg_str is quoted as a true sys.argv vector by using shlex.split.
311 311 This allows us to easily expand variables, glob files, quote
312 312 arguments, etc.
313 313
314 314 Options:
315 315 -mode: default 'string'. If given as 'list', the argument string is
316 316 returned as a list (split on whitespace) instead of a string.
317 317
318 318 -list_all: put all option values in lists. Normally only options
319 319 appearing more than once are put in a list.
320 320
321 321 -posix (True): whether to split the input line in POSIX mode or not,
322 322 as per the conventions outlined in the shlex module from the
323 323 standard library."""
324 324
325 325 # inject default options at the beginning of the input line
326 326 caller = sys._getframe(1).f_code.co_name.replace('magic_','')
327 327 arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
328 328
329 329 mode = kw.get('mode','string')
330 330 if mode not in ['string','list']:
331 331 raise ValueError,'incorrect mode given: %s' % mode
332 332 # Get options
333 333 list_all = kw.get('list_all',0)
334 334 posix = kw.get('posix',True)
335 335
336 336 # Check if we have more than one argument to warrant extra processing:
337 337 odict = {} # Dictionary with options
338 338 args = arg_str.split()
339 339 if len(args) >= 1:
340 340 # If the list of inputs only has 0 or 1 thing in it, there's no
341 341 # need to look for options
342 342 argv = arg_split(arg_str,posix)
343 343 # Do regular option processing
344 344 try:
345 345 opts,args = getopt(argv,opt_str,*long_opts)
346 346 except GetoptError,e:
347 347 raise UsageError('%s ( allowed: "%s" %s)' % (e.msg,opt_str,
348 348 " ".join(long_opts)))
349 349 for o,a in opts:
350 350 if o.startswith('--'):
351 351 o = o[2:]
352 352 else:
353 353 o = o[1:]
354 354 try:
355 355 odict[o].append(a)
356 356 except AttributeError:
357 357 odict[o] = [odict[o],a]
358 358 except KeyError:
359 359 if list_all:
360 360 odict[o] = [a]
361 361 else:
362 362 odict[o] = a
363 363
364 364 # Prepare opts,args for return
365 365 opts = Struct(odict)
366 366 if mode == 'string':
367 367 args = ' '.join(args)
368 368
369 369 return opts,args
370 370
371 371 #......................................................................
372 372 # And now the actual magic functions
373 373
374 374 # Functions for IPython shell work (vars,funcs, config, etc)
375 375 def magic_lsmagic(self, parameter_s = ''):
376 376 """List currently available magic functions."""
377 377 mesc = self.shell.ESC_MAGIC
378 378 print 'Available magic functions:\n'+mesc+\
379 379 (' '+mesc).join(self.lsmagic())
380 380 print '\n' + Magic.auto_status[self.shell.rc.automagic]
381 381 return None
382 382
383 383 def magic_magic(self, parameter_s = ''):
384 384 """Print information about the magic function system.
385 385
386 386 Supported formats: -latex, -brief, -rest
387 387 """
388 388
389 389 mode = ''
390 390 try:
391 391 if parameter_s.split()[0] == '-latex':
392 392 mode = 'latex'
393 393 if parameter_s.split()[0] == '-brief':
394 394 mode = 'brief'
395 395 if parameter_s.split()[0] == '-rest':
396 396 mode = 'rest'
397 397 rest_docs = []
398 398 except:
399 399 pass
400 400
401 401 magic_docs = []
402 402 for fname in self.lsmagic():
403 403 mname = 'magic_' + fname
404 404 for space in (Magic,self,self.__class__):
405 405 try:
406 406 fn = space.__dict__[mname]
407 407 except KeyError:
408 408 pass
409 409 else:
410 410 break
411 411 if mode == 'brief':
412 412 # only first line
413 413 if fn.__doc__:
414 414 fndoc = fn.__doc__.split('\n',1)[0]
415 415 else:
416 416 fndoc = 'No documentation'
417 417 else:
418 418 if fn.__doc__:
419 419 fndoc = fn.__doc__.rstrip()
420 420 else:
421 421 fndoc = 'No documentation'
422 422
423 423
424 424 if mode == 'rest':
425 425 rest_docs.append('**%s%s**::\n\n\t%s\n\n' %(self.shell.ESC_MAGIC,
426 426 fname,fndoc))
427 427
428 428 else:
429 429 magic_docs.append('%s%s:\n\t%s\n' %(self.shell.ESC_MAGIC,
430 430 fname,fndoc))
431 431
432 432 magic_docs = ''.join(magic_docs)
433 433
434 434 if mode == 'rest':
435 435 return "".join(rest_docs)
436 436
437 437 if mode == 'latex':
438 438 print self.format_latex(magic_docs)
439 439 return
440 440 else:
441 441 magic_docs = self.format_screen(magic_docs)
442 442 if mode == 'brief':
443 443 return magic_docs
444 444
445 445 outmsg = """
446 446 IPython's 'magic' functions
447 447 ===========================
448 448
449 449 The magic function system provides a series of functions which allow you to
450 450 control the behavior of IPython itself, plus a lot of system-type
451 451 features. All these functions are prefixed with a % character, but parameters
452 452 are given without parentheses or quotes.
453 453
454 454 NOTE: If you have 'automagic' enabled (via the command line option or with the
455 455 %automagic function), you don't need to type in the % explicitly. By default,
456 456 IPython ships with automagic on, so you should only rarely need the % escape.
457 457
458 458 Example: typing '%cd mydir' (without the quotes) changes you working directory
459 459 to 'mydir', if it exists.
460 460
461 461 You can define your own magic functions to extend the system. See the supplied
462 462 ipythonrc and example-magic.py files for details (in your ipython
463 463 configuration directory, typically $HOME/.ipython/).
464 464
465 465 You can also define your own aliased names for magic functions. In your
466 466 ipythonrc file, placing a line like:
467 467
468 468 execute __IPYTHON__.magic_pf = __IPYTHON__.magic_profile
469 469
470 470 will define %pf as a new name for %profile.
471 471
472 472 You can also call magics in code using the ipmagic() function, which IPython
473 473 automatically adds to the builtin namespace. Type 'ipmagic?' for details.
474 474
475 475 For a list of the available magic functions, use %lsmagic. For a description
476 476 of any of them, type %magic_name?, e.g. '%cd?'.
477 477
478 478 Currently the magic system has the following functions:\n"""
479 479
480 480 mesc = self.shell.ESC_MAGIC
481 481 outmsg = ("%s\n%s\n\nSummary of magic functions (from %slsmagic):"
482 482 "\n\n%s%s\n\n%s" % (outmsg,
483 483 magic_docs,mesc,mesc,
484 484 (' '+mesc).join(self.lsmagic()),
485 485 Magic.auto_status[self.shell.rc.automagic] ) )
486 486
487 487 page(outmsg,screen_lines=self.shell.rc.screen_length)
488 488
489 489
490 490 def magic_autoindent(self, parameter_s = ''):
491 491 """Toggle autoindent on/off (if available)."""
492 492
493 493 self.shell.set_autoindent()
494 494 print "Automatic indentation is:",['OFF','ON'][self.shell.autoindent]
495 495
496 496
497 497 def magic_automagic(self, parameter_s = ''):
498 498 """Make magic functions callable without having to type the initial %.
499 499
500 500 Without argumentsl toggles on/off (when off, you must call it as
501 501 %automagic, of course). With arguments it sets the value, and you can
502 502 use any of (case insensitive):
503 503
504 504 - on,1,True: to activate
505 505
506 506 - off,0,False: to deactivate.
507 507
508 508 Note that magic functions have lowest priority, so if there's a
509 509 variable whose name collides with that of a magic fn, automagic won't
510 510 work for that function (you get the variable instead). However, if you
511 511 delete the variable (del var), the previously shadowed magic function
512 512 becomes visible to automagic again."""
513 513
514 514 rc = self.shell.rc
515 515 arg = parameter_s.lower()
516 516 if parameter_s in ('on','1','true'):
517 517 rc.automagic = True
518 518 elif parameter_s in ('off','0','false'):
519 519 rc.automagic = False
520 520 else:
521 521 rc.automagic = not rc.automagic
522 522 print '\n' + Magic.auto_status[rc.automagic]
523 523
524 524 @testdec.skip_doctest
525 525 def magic_autocall(self, parameter_s = ''):
526 526 """Make functions callable without having to type parentheses.
527 527
528 528 Usage:
529 529
530 530 %autocall [mode]
531 531
532 532 The mode can be one of: 0->Off, 1->Smart, 2->Full. If not given, the
533 533 value is toggled on and off (remembering the previous state).
534 534
535 535 In more detail, these values mean:
536 536
537 537 0 -> fully disabled
538 538
539 539 1 -> active, but do not apply if there are no arguments on the line.
540 540
541 541 In this mode, you get:
542 542
543 543 In [1]: callable
544 544 Out[1]: <built-in function callable>
545 545
546 546 In [2]: callable 'hello'
547 547 ------> callable('hello')
548 548 Out[2]: False
549 549
550 550 2 -> Active always. Even if no arguments are present, the callable
551 551 object is called:
552 552
553 553 In [2]: float
554 554 ------> float()
555 555 Out[2]: 0.0
556 556
557 557 Note that even with autocall off, you can still use '/' at the start of
558 558 a line to treat the first argument on the command line as a function
559 559 and add parentheses to it:
560 560
561 561 In [8]: /str 43
562 562 ------> str(43)
563 563 Out[8]: '43'
564 564
565 565 # all-random (note for auto-testing)
566 566 """
567 567
568 568 rc = self.shell.rc
569 569
570 570 if parameter_s:
571 571 arg = int(parameter_s)
572 572 else:
573 573 arg = 'toggle'
574 574
575 575 if not arg in (0,1,2,'toggle'):
576 576 error('Valid modes: (0->Off, 1->Smart, 2->Full')
577 577 return
578 578
579 579 if arg in (0,1,2):
580 580 rc.autocall = arg
581 581 else: # toggle
582 582 if rc.autocall:
583 583 self._magic_state.autocall_save = rc.autocall
584 584 rc.autocall = 0
585 585 else:
586 586 try:
587 587 rc.autocall = self._magic_state.autocall_save
588 588 except AttributeError:
589 589 rc.autocall = self._magic_state.autocall_save = 1
590 590
591 591 print "Automatic calling is:",['OFF','Smart','Full'][rc.autocall]
592 592
593 593 def magic_system_verbose(self, parameter_s = ''):
594 594 """Set verbose printing of system calls.
595 595
596 596 If called without an argument, act as a toggle"""
597 597
598 598 if parameter_s:
599 599 val = bool(eval(parameter_s))
600 600 else:
601 601 val = None
602 602
603 603 self.shell.rc_set_toggle('system_verbose',val)
604 604 print "System verbose printing is:",\
605 605 ['OFF','ON'][self.shell.rc.system_verbose]
606 606
607 607
608 608 def magic_page(self, parameter_s=''):
609 609 """Pretty print the object and display it through a pager.
610 610
611 611 %page [options] OBJECT
612 612
613 613 If no object is given, use _ (last output).
614 614
615 615 Options:
616 616
617 617 -r: page str(object), don't pretty-print it."""
618 618
619 619 # After a function contributed by Olivier Aubert, slightly modified.
620 620
621 621 # Process options/args
622 622 opts,args = self.parse_options(parameter_s,'r')
623 623 raw = 'r' in opts
624 624
625 625 oname = args and args or '_'
626 626 info = self._ofind(oname)
627 627 if info['found']:
628 628 txt = (raw and str or pformat)( info['obj'] )
629 629 page(txt)
630 630 else:
631 631 print 'Object `%s` not found' % oname
632 632
633 633 def magic_profile(self, parameter_s=''):
634 634 """Print your currently active IPyhton profile."""
635 635 if self.shell.rc.profile:
636 636 printpl('Current IPython profile: $self.shell.rc.profile.')
637 637 else:
638 638 print 'No profile active.'
639 639
640 640 def magic_pinfo(self, parameter_s='', namespaces=None):
641 641 """Provide detailed information about an object.
642 642
643 643 '%pinfo object' is just a synonym for object? or ?object."""
644 644
645 645 #print 'pinfo par: <%s>' % parameter_s # dbg
646 646
647 647
648 648 # detail_level: 0 -> obj? , 1 -> obj??
649 649 detail_level = 0
650 650 # We need to detect if we got called as 'pinfo pinfo foo', which can
651 651 # happen if the user types 'pinfo foo?' at the cmd line.
652 652 pinfo,qmark1,oname,qmark2 = \
653 653 re.match('(pinfo )?(\?*)(.*?)(\??$)',parameter_s).groups()
654 654 if pinfo or qmark1 or qmark2:
655 655 detail_level = 1
656 656 if "*" in oname:
657 657 self.magic_psearch(oname)
658 658 else:
659 659 self._inspect('pinfo', oname, detail_level=detail_level,
660 660 namespaces=namespaces)
661 661
662 662 def magic_pdef(self, parameter_s='', namespaces=None):
663 663 """Print the definition header for any callable object.
664 664
665 665 If the object is a class, print the constructor information."""
666 666 self._inspect('pdef',parameter_s, namespaces)
667 667
668 668 def magic_pdoc(self, parameter_s='', namespaces=None):
669 669 """Print the docstring for an object.
670 670
671 671 If the given object is a class, it will print both the class and the
672 672 constructor docstrings."""
673 673 self._inspect('pdoc',parameter_s, namespaces)
674 674
675 675 def magic_psource(self, parameter_s='', namespaces=None):
676 676 """Print (or run through pager) the source code for an object."""
677 677 self._inspect('psource',parameter_s, namespaces)
678 678
679 679 def magic_pfile(self, parameter_s=''):
680 680 """Print (or run through pager) the file where an object is defined.
681 681
682 682 The file opens at the line where the object definition begins. IPython
683 683 will honor the environment variable PAGER if set, and otherwise will
684 684 do its best to print the file in a convenient form.
685 685
686 686 If the given argument is not an object currently defined, IPython will
687 687 try to interpret it as a filename (automatically adding a .py extension
688 688 if needed). You can thus use %pfile as a syntax highlighting code
689 689 viewer."""
690 690
691 691 # first interpret argument as an object name
692 692 out = self._inspect('pfile',parameter_s)
693 693 # if not, try the input as a filename
694 694 if out == 'not found':
695 695 try:
696 696 filename = get_py_filename(parameter_s)
697 697 except IOError,msg:
698 698 print msg
699 699 return
700 700 page(self.shell.inspector.format(file(filename).read()))
701 701
702 702 def _inspect(self,meth,oname,namespaces=None,**kw):
703 703 """Generic interface to the inspector system.
704 704
705 705 This function is meant to be called by pdef, pdoc & friends."""
706 706
707 707 #oname = oname.strip()
708 708 #print '1- oname: <%r>' % oname # dbg
709 709 try:
710 710 oname = oname.strip().encode('ascii')
711 711 #print '2- oname: <%r>' % oname # dbg
712 712 except UnicodeEncodeError:
713 713 print 'Python identifiers can only contain ascii characters.'
714 714 return 'not found'
715 715
716 716 info = Struct(self._ofind(oname, namespaces))
717 717
718 718 if info.found:
719 719 try:
720 720 IPython.generics.inspect_object(info.obj)
721 721 return
722 722 except IPython.ipapi.TryNext:
723 723 pass
724 724 # Get the docstring of the class property if it exists.
725 725 path = oname.split('.')
726 726 root = '.'.join(path[:-1])
727 727 if info.parent is not None:
728 728 try:
729 729 target = getattr(info.parent, '__class__')
730 730 # The object belongs to a class instance.
731 731 try:
732 732 target = getattr(target, path[-1])
733 733 # The class defines the object.
734 734 if isinstance(target, property):
735 735 oname = root + '.__class__.' + path[-1]
736 736 info = Struct(self._ofind(oname))
737 737 except AttributeError: pass
738 738 except AttributeError: pass
739 739
740 740 pmethod = getattr(self.shell.inspector,meth)
741 741 formatter = info.ismagic and self.format_screen or None
742 742 if meth == 'pdoc':
743 743 pmethod(info.obj,oname,formatter)
744 744 elif meth == 'pinfo':
745 745 pmethod(info.obj,oname,formatter,info,**kw)
746 746 else:
747 747 pmethod(info.obj,oname)
748 748 else:
749 749 print 'Object `%s` not found.' % oname
750 750 return 'not found' # so callers can take other action
751 751
752 752 def magic_psearch(self, parameter_s=''):
753 753 """Search for object in namespaces by wildcard.
754 754
755 755 %psearch [options] PATTERN [OBJECT TYPE]
756 756
757 757 Note: ? can be used as a synonym for %psearch, at the beginning or at
758 758 the end: both a*? and ?a* are equivalent to '%psearch a*'. Still, the
759 759 rest of the command line must be unchanged (options come first), so
760 760 for example the following forms are equivalent
761 761
762 762 %psearch -i a* function
763 763 -i a* function?
764 764 ?-i a* function
765 765
766 766 Arguments:
767 767
768 768 PATTERN
769 769
770 770 where PATTERN is a string containing * as a wildcard similar to its
771 771 use in a shell. The pattern is matched in all namespaces on the
772 772 search path. By default objects starting with a single _ are not
773 773 matched, many IPython generated objects have a single
774 774 underscore. The default is case insensitive matching. Matching is
775 775 also done on the attributes of objects and not only on the objects
776 776 in a module.
777 777
778 778 [OBJECT TYPE]
779 779
780 780 Is the name of a python type from the types module. The name is
781 781 given in lowercase without the ending type, ex. StringType is
782 782 written string. By adding a type here only objects matching the
783 783 given type are matched. Using all here makes the pattern match all
784 784 types (this is the default).
785 785
786 786 Options:
787 787
788 788 -a: makes the pattern match even objects whose names start with a
789 789 single underscore. These names are normally ommitted from the
790 790 search.
791 791
792 792 -i/-c: make the pattern case insensitive/sensitive. If neither of
793 793 these options is given, the default is read from your ipythonrc
794 794 file. The option name which sets this value is
795 795 'wildcards_case_sensitive'. If this option is not specified in your
796 796 ipythonrc file, IPython's internal default is to do a case sensitive
797 797 search.
798 798
799 799 -e/-s NAMESPACE: exclude/search a given namespace. The pattern you
800 800 specifiy can be searched in any of the following namespaces:
801 801 'builtin', 'user', 'user_global','internal', 'alias', where
802 802 'builtin' and 'user' are the search defaults. Note that you should
803 803 not use quotes when specifying namespaces.
804 804
805 805 'Builtin' contains the python module builtin, 'user' contains all
806 806 user data, 'alias' only contain the shell aliases and no python
807 807 objects, 'internal' contains objects used by IPython. The
808 808 'user_global' namespace is only used by embedded IPython instances,
809 809 and it contains module-level globals. You can add namespaces to the
810 810 search with -s or exclude them with -e (these options can be given
811 811 more than once).
812 812
813 813 Examples:
814 814
815 815 %psearch a* -> objects beginning with an a
816 816 %psearch -e builtin a* -> objects NOT in the builtin space starting in a
817 817 %psearch a* function -> all functions beginning with an a
818 818 %psearch re.e* -> objects beginning with an e in module re
819 819 %psearch r*.e* -> objects that start with e in modules starting in r
820 820 %psearch r*.* string -> all strings in modules beginning with r
821 821
822 822 Case sensitve search:
823 823
824 824 %psearch -c a* list all object beginning with lower case a
825 825
826 826 Show objects beginning with a single _:
827 827
828 828 %psearch -a _* list objects beginning with a single underscore"""
829 829 try:
830 830 parameter_s = parameter_s.encode('ascii')
831 831 except UnicodeEncodeError:
832 832 print 'Python identifiers can only contain ascii characters.'
833 833 return
834 834
835 835 # default namespaces to be searched
836 836 def_search = ['user','builtin']
837 837
838 838 # Process options/args
839 839 opts,args = self.parse_options(parameter_s,'cias:e:',list_all=True)
840 840 opt = opts.get
841 841 shell = self.shell
842 842 psearch = shell.inspector.psearch
843 843
844 844 # select case options
845 845 if opts.has_key('i'):
846 846 ignore_case = True
847 847 elif opts.has_key('c'):
848 848 ignore_case = False
849 849 else:
850 850 ignore_case = not shell.rc.wildcards_case_sensitive
851 851
852 852 # Build list of namespaces to search from user options
853 853 def_search.extend(opt('s',[]))
854 854 ns_exclude = ns_exclude=opt('e',[])
855 855 ns_search = [nm for nm in def_search if nm not in ns_exclude]
856 856
857 857 # Call the actual search
858 858 try:
859 859 psearch(args,shell.ns_table,ns_search,
860 860 show_all=opt('a'),ignore_case=ignore_case)
861 861 except:
862 862 shell.showtraceback()
863 863
864 864 def magic_who_ls(self, parameter_s=''):
865 865 """Return a sorted list of all interactive variables.
866 866
867 867 If arguments are given, only variables of types matching these
868 868 arguments are returned."""
869 869
870 870 user_ns = self.shell.user_ns
871 871 internal_ns = self.shell.internal_ns
872 872 user_config_ns = self.shell.user_config_ns
873 873 out = []
874 874 typelist = parameter_s.split()
875 875
876 876 for i in user_ns:
877 877 if not (i.startswith('_') or i.startswith('_i')) \
878 878 and not (i in internal_ns or i in user_config_ns):
879 879 if typelist:
880 880 if type(user_ns[i]).__name__ in typelist:
881 881 out.append(i)
882 882 else:
883 883 out.append(i)
884 884 out.sort()
885 885 return out
886 886
887 887 def magic_who(self, parameter_s=''):
888 888 """Print all interactive variables, with some minimal formatting.
889 889
890 890 If any arguments are given, only variables whose type matches one of
891 891 these are printed. For example:
892 892
893 893 %who function str
894 894
895 895 will only list functions and strings, excluding all other types of
896 896 variables. To find the proper type names, simply use type(var) at a
897 897 command line to see how python prints type names. For example:
898 898
899 899 In [1]: type('hello')\\
900 900 Out[1]: <type 'str'>
901 901
902 902 indicates that the type name for strings is 'str'.
903 903
904 904 %who always excludes executed names loaded through your configuration
905 905 file and things which are internal to IPython.
906 906
907 907 This is deliberate, as typically you may load many modules and the
908 908 purpose of %who is to show you only what you've manually defined."""
909 909
910 910 varlist = self.magic_who_ls(parameter_s)
911 911 if not varlist:
912 912 if parameter_s:
913 913 print 'No variables match your requested type.'
914 914 else:
915 915 print 'Interactive namespace is empty.'
916 916 return
917 917
918 918 # if we have variables, move on...
919 919 count = 0
920 920 for i in varlist:
921 921 print i+'\t',
922 922 count += 1
923 923 if count > 8:
924 924 count = 0
925 925 print
926 926 print
927 927
928 928 def magic_whos(self, parameter_s=''):
929 929 """Like %who, but gives some extra information about each variable.
930 930
931 931 The same type filtering of %who can be applied here.
932 932
933 933 For all variables, the type is printed. Additionally it prints:
934 934
935 935 - For {},[],(): their length.
936 936
937 937 - For numpy and Numeric arrays, a summary with shape, number of
938 938 elements, typecode and size in memory.
939 939
940 940 - Everything else: a string representation, snipping their middle if
941 941 too long."""
942 942
943 943 varnames = self.magic_who_ls(parameter_s)
944 944 if not varnames:
945 945 if parameter_s:
946 946 print 'No variables match your requested type.'
947 947 else:
948 948 print 'Interactive namespace is empty.'
949 949 return
950 950
951 951 # if we have variables, move on...
952 952
953 953 # for these types, show len() instead of data:
954 954 seq_types = [types.DictType,types.ListType,types.TupleType]
955 955
956 956 # for numpy/Numeric arrays, display summary info
957 957 try:
958 958 import numpy
959 959 except ImportError:
960 960 ndarray_type = None
961 961 else:
962 962 ndarray_type = numpy.ndarray.__name__
963 963 try:
964 964 import Numeric
965 965 except ImportError:
966 966 array_type = None
967 967 else:
968 968 array_type = Numeric.ArrayType.__name__
969 969
970 970 # Find all variable names and types so we can figure out column sizes
971 971 def get_vars(i):
972 972 return self.shell.user_ns[i]
973 973
974 974 # some types are well known and can be shorter
975 975 abbrevs = {'IPython.macro.Macro' : 'Macro'}
976 976 def type_name(v):
977 977 tn = type(v).__name__
978 978 return abbrevs.get(tn,tn)
979 979
980 980 varlist = map(get_vars,varnames)
981 981
982 982 typelist = []
983 983 for vv in varlist:
984 984 tt = type_name(vv)
985 985
986 986 if tt=='instance':
987 987 typelist.append( abbrevs.get(str(vv.__class__),
988 988 str(vv.__class__)))
989 989 else:
990 990 typelist.append(tt)
991 991
992 992 # column labels and # of spaces as separator
993 993 varlabel = 'Variable'
994 994 typelabel = 'Type'
995 995 datalabel = 'Data/Info'
996 996 colsep = 3
997 997 # variable format strings
998 998 vformat = "$vname.ljust(varwidth)$vtype.ljust(typewidth)"
999 999 vfmt_short = '$vstr[:25]<...>$vstr[-25:]'
1000 1000 aformat = "%s: %s elems, type `%s`, %s bytes"
1001 1001 # find the size of the columns to format the output nicely
1002 1002 varwidth = max(max(map(len,varnames)), len(varlabel)) + colsep
1003 1003 typewidth = max(max(map(len,typelist)), len(typelabel)) + colsep
1004 1004 # table header
1005 1005 print varlabel.ljust(varwidth) + typelabel.ljust(typewidth) + \
1006 1006 ' '+datalabel+'\n' + '-'*(varwidth+typewidth+len(datalabel)+1)
1007 1007 # and the table itself
1008 1008 kb = 1024
1009 1009 Mb = 1048576 # kb**2
1010 1010 for vname,var,vtype in zip(varnames,varlist,typelist):
1011 1011 print itpl(vformat),
1012 1012 if vtype in seq_types:
1013 1013 print len(var)
1014 1014 elif vtype in [array_type,ndarray_type]:
1015 1015 vshape = str(var.shape).replace(',','').replace(' ','x')[1:-1]
1016 1016 if vtype==ndarray_type:
1017 1017 # numpy
1018 1018 vsize = var.size
1019 1019 vbytes = vsize*var.itemsize
1020 1020 vdtype = var.dtype
1021 1021 else:
1022 1022 # Numeric
1023 1023 vsize = Numeric.size(var)
1024 1024 vbytes = vsize*var.itemsize()
1025 1025 vdtype = var.typecode()
1026 1026
1027 1027 if vbytes < 100000:
1028 1028 print aformat % (vshape,vsize,vdtype,vbytes)
1029 1029 else:
1030 1030 print aformat % (vshape,vsize,vdtype,vbytes),
1031 1031 if vbytes < Mb:
1032 1032 print '(%s kb)' % (vbytes/kb,)
1033 1033 else:
1034 1034 print '(%s Mb)' % (vbytes/Mb,)
1035 1035 else:
1036 1036 try:
1037 1037 vstr = str(var)
1038 1038 except UnicodeEncodeError:
1039 1039 vstr = unicode(var).encode(sys.getdefaultencoding(),
1040 1040 'backslashreplace')
1041 1041 vstr = vstr.replace('\n','\\n')
1042 1042 if len(vstr) < 50:
1043 1043 print vstr
1044 1044 else:
1045 1045 printpl(vfmt_short)
1046 1046
1047 1047 def magic_reset(self, parameter_s=''):
1048 1048 """Resets the namespace by removing all names defined by the user.
1049 1049
1050 1050 Input/Output history are left around in case you need them.
1051 1051
1052 1052 Parameters
1053 1053 ----------
1054 1054 -y : force reset without asking for confirmation.
1055 1055
1056 1056 Examples
1057 1057 --------
1058 1058 In [6]: a = 1
1059 1059
1060 1060 In [7]: a
1061 1061 Out[7]: 1
1062 1062
1063 1063 In [8]: 'a' in _ip.user_ns
1064 1064 Out[8]: True
1065 1065
1066 1066 In [9]: %reset -f
1067 1067
1068 1068 In [10]: 'a' in _ip.user_ns
1069 1069 Out[10]: False
1070 1070 """
1071 1071
1072 1072 if parameter_s == '-f':
1073 1073 ans = True
1074 1074 else:
1075 1075 ans = self.shell.ask_yes_no(
1076 1076 "Once deleted, variables cannot be recovered. Proceed (y/[n])? ")
1077 1077 if not ans:
1078 1078 print 'Nothing done.'
1079 1079 return
1080 1080 user_ns = self.shell.user_ns
1081 1081 for i in self.magic_who_ls():
1082 1082 del(user_ns[i])
1083 1083
1084 1084 # Also flush the private list of module references kept for script
1085 1085 # execution protection
1086 1086 self.shell.clear_main_mod_cache()
1087 1087
1088 1088 def magic_logstart(self,parameter_s=''):
1089 1089 """Start logging anywhere in a session.
1090 1090
1091 1091 %logstart [-o|-r|-t] [log_name [log_mode]]
1092 1092
1093 1093 If no name is given, it defaults to a file named 'ipython_log.py' in your
1094 1094 current directory, in 'rotate' mode (see below).
1095 1095
1096 1096 '%logstart name' saves to file 'name' in 'backup' mode. It saves your
1097 1097 history up to that point and then continues logging.
1098 1098
1099 1099 %logstart takes a second optional parameter: logging mode. This can be one
1100 1100 of (note that the modes are given unquoted):\\
1101 1101 append: well, that says it.\\
1102 1102 backup: rename (if exists) to name~ and start name.\\
1103 1103 global: single logfile in your home dir, appended to.\\
1104 1104 over : overwrite existing log.\\
1105 1105 rotate: create rotating logs name.1~, name.2~, etc.
1106 1106
1107 1107 Options:
1108 1108
1109 1109 -o: log also IPython's output. In this mode, all commands which
1110 1110 generate an Out[NN] prompt are recorded to the logfile, right after
1111 1111 their corresponding input line. The output lines are always
1112 1112 prepended with a '#[Out]# ' marker, so that the log remains valid
1113 1113 Python code.
1114 1114
1115 1115 Since this marker is always the same, filtering only the output from
1116 1116 a log is very easy, using for example a simple awk call:
1117 1117
1118 1118 awk -F'#\\[Out\\]# ' '{if($2) {print $2}}' ipython_log.py
1119 1119
1120 1120 -r: log 'raw' input. Normally, IPython's logs contain the processed
1121 1121 input, so that user lines are logged in their final form, converted
1122 1122 into valid Python. For example, %Exit is logged as
1123 1123 '_ip.magic("Exit"). If the -r flag is given, all input is logged
1124 1124 exactly as typed, with no transformations applied.
1125 1125
1126 1126 -t: put timestamps before each input line logged (these are put in
1127 1127 comments)."""
1128 1128
1129 1129 opts,par = self.parse_options(parameter_s,'ort')
1130 1130 log_output = 'o' in opts
1131 1131 log_raw_input = 'r' in opts
1132 1132 timestamp = 't' in opts
1133 1133
1134 1134 rc = self.shell.rc
1135 1135 logger = self.shell.logger
1136 1136
1137 1137 # if no args are given, the defaults set in the logger constructor by
1138 1138 # ipytohn remain valid
1139 1139 if par:
1140 1140 try:
1141 1141 logfname,logmode = par.split()
1142 1142 except:
1143 1143 logfname = par
1144 1144 logmode = 'backup'
1145 1145 else:
1146 1146 logfname = logger.logfname
1147 1147 logmode = logger.logmode
1148 1148 # put logfname into rc struct as if it had been called on the command
1149 1149 # line, so it ends up saved in the log header Save it in case we need
1150 1150 # to restore it...
1151 1151 old_logfile = rc.opts.get('logfile','')
1152 1152 if logfname:
1153 1153 logfname = os.path.expanduser(logfname)
1154 1154 rc.opts.logfile = logfname
1155 1155 loghead = self.shell.loghead_tpl % (rc.opts,rc.args)
1156 1156 try:
1157 1157 started = logger.logstart(logfname,loghead,logmode,
1158 1158 log_output,timestamp,log_raw_input)
1159 1159 except:
1160 1160 rc.opts.logfile = old_logfile
1161 1161 warn("Couldn't start log: %s" % sys.exc_info()[1])
1162 1162 else:
1163 1163 # log input history up to this point, optionally interleaving
1164 1164 # output if requested
1165 1165
1166 1166 if timestamp:
1167 1167 # disable timestamping for the previous history, since we've
1168 1168 # lost those already (no time machine here).
1169 1169 logger.timestamp = False
1170 1170
1171 1171 if log_raw_input:
1172 1172 input_hist = self.shell.input_hist_raw
1173 1173 else:
1174 1174 input_hist = self.shell.input_hist
1175 1175
1176 1176 if log_output:
1177 1177 log_write = logger.log_write
1178 1178 output_hist = self.shell.output_hist
1179 1179 for n in range(1,len(input_hist)-1):
1180 1180 log_write(input_hist[n].rstrip())
1181 1181 if n in output_hist:
1182 1182 log_write(repr(output_hist[n]),'output')
1183 1183 else:
1184 1184 logger.log_write(input_hist[1:])
1185 1185 if timestamp:
1186 1186 # re-enable timestamping
1187 1187 logger.timestamp = True
1188 1188
1189 1189 print ('Activating auto-logging. '
1190 1190 'Current session state plus future input saved.')
1191 1191 logger.logstate()
1192 1192
1193 1193 def magic_logstop(self,parameter_s=''):
1194 1194 """Fully stop logging and close log file.
1195 1195
1196 1196 In order to start logging again, a new %logstart call needs to be made,
1197 1197 possibly (though not necessarily) with a new filename, mode and other
1198 1198 options."""
1199 1199 self.logger.logstop()
1200 1200
1201 1201 def magic_logoff(self,parameter_s=''):
1202 1202 """Temporarily stop logging.
1203 1203
1204 1204 You must have previously started logging."""
1205 1205 self.shell.logger.switch_log(0)
1206 1206
1207 1207 def magic_logon(self,parameter_s=''):
1208 1208 """Restart logging.
1209 1209
1210 1210 This function is for restarting logging which you've temporarily
1211 1211 stopped with %logoff. For starting logging for the first time, you
1212 1212 must use the %logstart function, which allows you to specify an
1213 1213 optional log filename."""
1214 1214
1215 1215 self.shell.logger.switch_log(1)
1216 1216
1217 1217 def magic_logstate(self,parameter_s=''):
1218 1218 """Print the status of the logging system."""
1219 1219
1220 1220 self.shell.logger.logstate()
1221 1221
1222 1222 def magic_pdb(self, parameter_s=''):
1223 1223 """Control the automatic calling of the pdb interactive debugger.
1224 1224
1225 1225 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
1226 1226 argument it works as a toggle.
1227 1227
1228 1228 When an exception is triggered, IPython can optionally call the
1229 1229 interactive pdb debugger after the traceback printout. %pdb toggles
1230 1230 this feature on and off.
1231 1231
1232 1232 The initial state of this feature is set in your ipythonrc
1233 1233 configuration file (the variable is called 'pdb').
1234 1234
1235 1235 If you want to just activate the debugger AFTER an exception has fired,
1236 1236 without having to type '%pdb on' and rerunning your code, you can use
1237 1237 the %debug magic."""
1238 1238
1239 1239 par = parameter_s.strip().lower()
1240 1240
1241 1241 if par:
1242 1242 try:
1243 1243 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
1244 1244 except KeyError:
1245 1245 print ('Incorrect argument. Use on/1, off/0, '
1246 1246 'or nothing for a toggle.')
1247 1247 return
1248 1248 else:
1249 1249 # toggle
1250 1250 new_pdb = not self.shell.call_pdb
1251 1251
1252 1252 # set on the shell
1253 1253 self.shell.call_pdb = new_pdb
1254 1254 print 'Automatic pdb calling has been turned',on_off(new_pdb)
1255 1255
1256 1256 def magic_debug(self, parameter_s=''):
1257 1257 """Activate the interactive debugger in post-mortem mode.
1258 1258
1259 1259 If an exception has just occurred, this lets you inspect its stack
1260 1260 frames interactively. Note that this will always work only on the last
1261 1261 traceback that occurred, so you must call this quickly after an
1262 1262 exception that you wish to inspect has fired, because if another one
1263 1263 occurs, it clobbers the previous one.
1264 1264
1265 1265 If you want IPython to automatically do this on every exception, see
1266 1266 the %pdb magic for more details.
1267 1267 """
1268 1268
1269 1269 self.shell.debugger(force=True)
1270 1270
1271 1271 @testdec.skip_doctest
1272 1272 def magic_prun(self, parameter_s ='',user_mode=1,
1273 1273 opts=None,arg_lst=None,prog_ns=None):
1274 1274
1275 1275 """Run a statement through the python code profiler.
1276 1276
1277 1277 Usage:
1278 1278 %prun [options] statement
1279 1279
1280 1280 The given statement (which doesn't require quote marks) is run via the
1281 1281 python profiler in a manner similar to the profile.run() function.
1282 1282 Namespaces are internally managed to work correctly; profile.run
1283 1283 cannot be used in IPython because it makes certain assumptions about
1284 1284 namespaces which do not hold under IPython.
1285 1285
1286 1286 Options:
1287 1287
1288 1288 -l <limit>: you can place restrictions on what or how much of the
1289 1289 profile gets printed. The limit value can be:
1290 1290
1291 1291 * A string: only information for function names containing this string
1292 1292 is printed.
1293 1293
1294 1294 * An integer: only these many lines are printed.
1295 1295
1296 1296 * A float (between 0 and 1): this fraction of the report is printed
1297 1297 (for example, use a limit of 0.4 to see the topmost 40% only).
1298 1298
1299 1299 You can combine several limits with repeated use of the option. For
1300 1300 example, '-l __init__ -l 5' will print only the topmost 5 lines of
1301 1301 information about class constructors.
1302 1302
1303 1303 -r: return the pstats.Stats object generated by the profiling. This
1304 1304 object has all the information about the profile in it, and you can
1305 1305 later use it for further analysis or in other functions.
1306 1306
1307 1307 -s <key>: sort profile by given key. You can provide more than one key
1308 1308 by using the option several times: '-s key1 -s key2 -s key3...'. The
1309 1309 default sorting key is 'time'.
1310 1310
1311 1311 The following is copied verbatim from the profile documentation
1312 1312 referenced below:
1313 1313
1314 1314 When more than one key is provided, additional keys are used as
1315 1315 secondary criteria when the there is equality in all keys selected
1316 1316 before them.
1317 1317
1318 1318 Abbreviations can be used for any key names, as long as the
1319 1319 abbreviation is unambiguous. The following are the keys currently
1320 1320 defined:
1321 1321
1322 1322 Valid Arg Meaning
1323 1323 "calls" call count
1324 1324 "cumulative" cumulative time
1325 1325 "file" file name
1326 1326 "module" file name
1327 1327 "pcalls" primitive call count
1328 1328 "line" line number
1329 1329 "name" function name
1330 1330 "nfl" name/file/line
1331 1331 "stdname" standard name
1332 1332 "time" internal time
1333 1333
1334 1334 Note that all sorts on statistics are in descending order (placing
1335 1335 most time consuming items first), where as name, file, and line number
1336 1336 searches are in ascending order (i.e., alphabetical). The subtle
1337 1337 distinction between "nfl" and "stdname" is that the standard name is a
1338 1338 sort of the name as printed, which means that the embedded line
1339 1339 numbers get compared in an odd way. For example, lines 3, 20, and 40
1340 1340 would (if the file names were the same) appear in the string order
1341 1341 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
1342 1342 line numbers. In fact, sort_stats("nfl") is the same as
1343 1343 sort_stats("name", "file", "line").
1344 1344
1345 1345 -T <filename>: save profile results as shown on screen to a text
1346 1346 file. The profile is still shown on screen.
1347 1347
1348 1348 -D <filename>: save (via dump_stats) profile statistics to given
1349 1349 filename. This data is in a format understod by the pstats module, and
1350 1350 is generated by a call to the dump_stats() method of profile
1351 1351 objects. The profile is still shown on screen.
1352 1352
1353 1353 If you want to run complete programs under the profiler's control, use
1354 1354 '%run -p [prof_opts] filename.py [args to program]' where prof_opts
1355 1355 contains profiler specific options as described here.
1356 1356
1357 1357 You can read the complete documentation for the profile module with::
1358 1358
1359 1359 In [1]: import profile; profile.help()
1360 1360 """
1361 1361
1362 1362 opts_def = Struct(D=[''],l=[],s=['time'],T=[''])
1363 1363 # protect user quote marks
1364 1364 parameter_s = parameter_s.replace('"',r'\"').replace("'",r"\'")
1365 1365
1366 1366 if user_mode: # regular user call
1367 1367 opts,arg_str = self.parse_options(parameter_s,'D:l:rs:T:',
1368 1368 list_all=1)
1369 1369 namespace = self.shell.user_ns
1370 1370 else: # called to run a program by %run -p
1371 1371 try:
1372 1372 filename = get_py_filename(arg_lst[0])
1373 1373 except IOError,msg:
1374 1374 error(msg)
1375 1375 return
1376 1376
1377 1377 arg_str = 'execfile(filename,prog_ns)'
1378 1378 namespace = locals()
1379 1379
1380 1380 opts.merge(opts_def)
1381 1381
1382 1382 prof = profile.Profile()
1383 1383 try:
1384 1384 prof = prof.runctx(arg_str,namespace,namespace)
1385 1385 sys_exit = ''
1386 1386 except SystemExit:
1387 1387 sys_exit = """*** SystemExit exception caught in code being profiled."""
1388 1388
1389 1389 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
1390 1390
1391 1391 lims = opts.l
1392 1392 if lims:
1393 1393 lims = [] # rebuild lims with ints/floats/strings
1394 1394 for lim in opts.l:
1395 1395 try:
1396 1396 lims.append(int(lim))
1397 1397 except ValueError:
1398 1398 try:
1399 1399 lims.append(float(lim))
1400 1400 except ValueError:
1401 1401 lims.append(lim)
1402 1402
1403 1403 # Trap output.
1404 1404 stdout_trap = StringIO()
1405 1405
1406 1406 if hasattr(stats,'stream'):
1407 1407 # In newer versions of python, the stats object has a 'stream'
1408 1408 # attribute to write into.
1409 1409 stats.stream = stdout_trap
1410 1410 stats.print_stats(*lims)
1411 1411 else:
1412 1412 # For older versions, we manually redirect stdout during printing
1413 1413 sys_stdout = sys.stdout
1414 1414 try:
1415 1415 sys.stdout = stdout_trap
1416 1416 stats.print_stats(*lims)
1417 1417 finally:
1418 1418 sys.stdout = sys_stdout
1419 1419
1420 1420 output = stdout_trap.getvalue()
1421 1421 output = output.rstrip()
1422 1422
1423 1423 page(output,screen_lines=self.shell.rc.screen_length)
1424 1424 print sys_exit,
1425 1425
1426 1426 dump_file = opts.D[0]
1427 1427 text_file = opts.T[0]
1428 1428 if dump_file:
1429 1429 prof.dump_stats(dump_file)
1430 1430 print '\n*** Profile stats marshalled to file',\
1431 1431 `dump_file`+'.',sys_exit
1432 1432 if text_file:
1433 1433 pfile = file(text_file,'w')
1434 1434 pfile.write(output)
1435 1435 pfile.close()
1436 1436 print '\n*** Profile printout saved to text file',\
1437 1437 `text_file`+'.',sys_exit
1438 1438
1439 1439 if opts.has_key('r'):
1440 1440 return stats
1441 1441 else:
1442 1442 return None
1443 1443
1444 1444 @testdec.skip_doctest
1445 1445 def magic_run(self, parameter_s ='',runner=None,
1446 1446 file_finder=get_py_filename):
1447 1447 """Run the named file inside IPython as a program.
1448 1448
1449 1449 Usage:\\
1450 1450 %run [-n -i -t [-N<N>] -d [-b<N>] -p [profile options]] file [args]
1451 1451
1452 1452 Parameters after the filename are passed as command-line arguments to
1453 1453 the program (put in sys.argv). Then, control returns to IPython's
1454 1454 prompt.
1455 1455
1456 1456 This is similar to running at a system prompt:\\
1457 1457 $ python file args\\
1458 1458 but with the advantage of giving you IPython's tracebacks, and of
1459 1459 loading all variables into your interactive namespace for further use
1460 1460 (unless -p is used, see below).
1461 1461
1462 1462 The file is executed in a namespace initially consisting only of
1463 1463 __name__=='__main__' and sys.argv constructed as indicated. It thus
1464 1464 sees its environment as if it were being run as a stand-alone program
1465 1465 (except for sharing global objects such as previously imported
1466 1466 modules). But after execution, the IPython interactive namespace gets
1467 1467 updated with all variables defined in the program (except for __name__
1468 1468 and sys.argv). This allows for very convenient loading of code for
1469 1469 interactive work, while giving each program a 'clean sheet' to run in.
1470 1470
1471 1471 Options:
1472 1472
1473 1473 -n: __name__ is NOT set to '__main__', but to the running file's name
1474 1474 without extension (as python does under import). This allows running
1475 1475 scripts and reloading the definitions in them without calling code
1476 1476 protected by an ' if __name__ == "__main__" ' clause.
1477 1477
1478 1478 -i: run the file in IPython's namespace instead of an empty one. This
1479 1479 is useful if you are experimenting with code written in a text editor
1480 1480 which depends on variables defined interactively.
1481 1481
1482 1482 -e: ignore sys.exit() calls or SystemExit exceptions in the script
1483 1483 being run. This is particularly useful if IPython is being used to
1484 1484 run unittests, which always exit with a sys.exit() call. In such
1485 1485 cases you are interested in the output of the test results, not in
1486 1486 seeing a traceback of the unittest module.
1487 1487
1488 1488 -t: print timing information at the end of the run. IPython will give
1489 1489 you an estimated CPU time consumption for your script, which under
1490 1490 Unix uses the resource module to avoid the wraparound problems of
1491 1491 time.clock(). Under Unix, an estimate of time spent on system tasks
1492 1492 is also given (for Windows platforms this is reported as 0.0).
1493 1493
1494 1494 If -t is given, an additional -N<N> option can be given, where <N>
1495 1495 must be an integer indicating how many times you want the script to
1496 1496 run. The final timing report will include total and per run results.
1497 1497
1498 1498 For example (testing the script uniq_stable.py):
1499 1499
1500 1500 In [1]: run -t uniq_stable
1501 1501
1502 1502 IPython CPU timings (estimated):\\
1503 1503 User : 0.19597 s.\\
1504 1504 System: 0.0 s.\\
1505 1505
1506 1506 In [2]: run -t -N5 uniq_stable
1507 1507
1508 1508 IPython CPU timings (estimated):\\
1509 1509 Total runs performed: 5\\
1510 1510 Times : Total Per run\\
1511 1511 User : 0.910862 s, 0.1821724 s.\\
1512 1512 System: 0.0 s, 0.0 s.
1513 1513
1514 1514 -d: run your program under the control of pdb, the Python debugger.
1515 1515 This allows you to execute your program step by step, watch variables,
1516 1516 etc. Internally, what IPython does is similar to calling:
1517 1517
1518 1518 pdb.run('execfile("YOURFILENAME")')
1519 1519
1520 1520 with a breakpoint set on line 1 of your file. You can change the line
1521 1521 number for this automatic breakpoint to be <N> by using the -bN option
1522 1522 (where N must be an integer). For example:
1523 1523
1524 1524 %run -d -b40 myscript
1525 1525
1526 1526 will set the first breakpoint at line 40 in myscript.py. Note that
1527 1527 the first breakpoint must be set on a line which actually does
1528 1528 something (not a comment or docstring) for it to stop execution.
1529 1529
1530 1530 When the pdb debugger starts, you will see a (Pdb) prompt. You must
1531 1531 first enter 'c' (without qoutes) to start execution up to the first
1532 1532 breakpoint.
1533 1533
1534 1534 Entering 'help' gives information about the use of the debugger. You
1535 1535 can easily see pdb's full documentation with "import pdb;pdb.help()"
1536 1536 at a prompt.
1537 1537
1538 1538 -p: run program under the control of the Python profiler module (which
1539 1539 prints a detailed report of execution times, function calls, etc).
1540 1540
1541 1541 You can pass other options after -p which affect the behavior of the
1542 1542 profiler itself. See the docs for %prun for details.
1543 1543
1544 1544 In this mode, the program's variables do NOT propagate back to the
1545 1545 IPython interactive namespace (because they remain in the namespace
1546 1546 where the profiler executes them).
1547 1547
1548 1548 Internally this triggers a call to %prun, see its documentation for
1549 1549 details on the options available specifically for profiling.
1550 1550
1551 1551 There is one special usage for which the text above doesn't apply:
1552 1552 if the filename ends with .ipy, the file is run as ipython script,
1553 1553 just as if the commands were written on IPython prompt.
1554 1554 """
1555 1555
1556 1556 # get arguments and set sys.argv for program to be run.
1557 1557 opts,arg_lst = self.parse_options(parameter_s,'nidtN:b:pD:l:rs:T:e',
1558 1558 mode='list',list_all=1)
1559 1559
1560 1560 try:
1561 1561 filename = file_finder(arg_lst[0])
1562 1562 except IndexError:
1563 1563 warn('you must provide at least a filename.')
1564 1564 print '\n%run:\n',OInspect.getdoc(self.magic_run)
1565 1565 return
1566 1566 except IOError,msg:
1567 1567 error(msg)
1568 1568 return
1569 1569
1570 1570 if filename.lower().endswith('.ipy'):
1571 1571 self.api.runlines(open(filename).read())
1572 1572 return
1573 1573
1574 1574 # Control the response to exit() calls made by the script being run
1575 1575 exit_ignore = opts.has_key('e')
1576 1576
1577 1577 # Make sure that the running script gets a proper sys.argv as if it
1578 1578 # were run from a system shell.
1579 1579 save_argv = sys.argv # save it for later restoring
1580 1580 sys.argv = [filename]+ arg_lst[1:] # put in the proper filename
1581 1581
1582 1582 if opts.has_key('i'):
1583 1583 # Run in user's interactive namespace
1584 1584 prog_ns = self.shell.user_ns
1585 1585 __name__save = self.shell.user_ns['__name__']
1586 1586 prog_ns['__name__'] = '__main__'
1587 main_mod = FakeModule(prog_ns)
1587 main_mod = self.shell.new_main_mod(prog_ns)
1588 1588 else:
1589 1589 # Run in a fresh, empty namespace
1590 1590 if opts.has_key('n'):
1591 1591 name = os.path.splitext(os.path.basename(filename))[0]
1592 1592 else:
1593 1593 name = '__main__'
1594 main_mod = FakeModule()
1594
1595 main_mod = self.shell.new_main_mod()
1595 1596 prog_ns = main_mod.__dict__
1596 1597 prog_ns['__name__'] = name
1597
1598 # The shell MUST hold a reference to main_mod so after %run exits,
1599 # the python deletion mechanism doesn't zero it out (leaving
1600 # dangling references). However, we should drop old versions of
1601 # main_mod. There is now a proper API to manage this caching in
1602 # the main shell object, we use that.
1603 self.shell.cache_main_mod(main_mod)
1604 1598
1605 1599 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
1606 1600 # set the __file__ global in the script's namespace
1607 1601 prog_ns['__file__'] = filename
1608 1602
1609 1603 # pickle fix. See iplib for an explanation. But we need to make sure
1610 1604 # that, if we overwrite __main__, we replace it at the end
1611 1605 main_mod_name = prog_ns['__name__']
1612 1606
1613 1607 if main_mod_name == '__main__':
1614 1608 restore_main = sys.modules['__main__']
1615 1609 else:
1616 1610 restore_main = False
1617 1611
1618 1612 # This needs to be undone at the end to prevent holding references to
1619 1613 # every single object ever created.
1620 1614 sys.modules[main_mod_name] = main_mod
1621 1615
1622 1616 stats = None
1623 1617 try:
1624 1618 self.shell.savehist()
1625 1619
1626 1620 if opts.has_key('p'):
1627 1621 stats = self.magic_prun('',0,opts,arg_lst,prog_ns)
1628 1622 else:
1629 1623 if opts.has_key('d'):
1630 1624 deb = Debugger.Pdb(self.shell.rc.colors)
1631 1625 # reset Breakpoint state, which is moronically kept
1632 1626 # in a class
1633 1627 bdb.Breakpoint.next = 1
1634 1628 bdb.Breakpoint.bplist = {}
1635 1629 bdb.Breakpoint.bpbynumber = [None]
1636 1630 # Set an initial breakpoint to stop execution
1637 1631 maxtries = 10
1638 1632 bp = int(opts.get('b',[1])[0])
1639 1633 checkline = deb.checkline(filename,bp)
1640 1634 if not checkline:
1641 1635 for bp in range(bp+1,bp+maxtries+1):
1642 1636 if deb.checkline(filename,bp):
1643 1637 break
1644 1638 else:
1645 1639 msg = ("\nI failed to find a valid line to set "
1646 1640 "a breakpoint\n"
1647 1641 "after trying up to line: %s.\n"
1648 1642 "Please set a valid breakpoint manually "
1649 1643 "with the -b option." % bp)
1650 1644 error(msg)
1651 1645 return
1652 1646 # if we find a good linenumber, set the breakpoint
1653 1647 deb.do_break('%s:%s' % (filename,bp))
1654 1648 # Start file run
1655 1649 print "NOTE: Enter 'c' at the",
1656 1650 print "%s prompt to start your script." % deb.prompt
1657 1651 try:
1658 1652 deb.run('execfile("%s")' % filename,prog_ns)
1659 1653
1660 1654 except:
1661 1655 etype, value, tb = sys.exc_info()
1662 1656 # Skip three frames in the traceback: the %run one,
1663 1657 # one inside bdb.py, and the command-line typed by the
1664 1658 # user (run by exec in pdb itself).
1665 1659 self.shell.InteractiveTB(etype,value,tb,tb_offset=3)
1666 1660 else:
1667 1661 if runner is None:
1668 1662 runner = self.shell.safe_execfile
1669 1663 if opts.has_key('t'):
1670 1664 # timed execution
1671 1665 try:
1672 1666 nruns = int(opts['N'][0])
1673 1667 if nruns < 1:
1674 1668 error('Number of runs must be >=1')
1675 1669 return
1676 1670 except (KeyError):
1677 1671 nruns = 1
1678 1672 if nruns == 1:
1679 1673 t0 = clock2()
1680 1674 runner(filename,prog_ns,prog_ns,
1681 1675 exit_ignore=exit_ignore)
1682 1676 t1 = clock2()
1683 1677 t_usr = t1[0]-t0[0]
1684 t_sys = t1[1]-t1[1]
1678 t_sys = t1[1]-t0[1]
1685 1679 print "\nIPython CPU timings (estimated):"
1686 1680 print " User : %10s s." % t_usr
1687 1681 print " System: %10s s." % t_sys
1688 1682 else:
1689 1683 runs = range(nruns)
1690 1684 t0 = clock2()
1691 1685 for nr in runs:
1692 1686 runner(filename,prog_ns,prog_ns,
1693 1687 exit_ignore=exit_ignore)
1694 1688 t1 = clock2()
1695 1689 t_usr = t1[0]-t0[0]
1696 t_sys = t1[1]-t1[1]
1690 t_sys = t1[1]-t0[1]
1697 1691 print "\nIPython CPU timings (estimated):"
1698 1692 print "Total runs performed:",nruns
1699 1693 print " Times : %10s %10s" % ('Total','Per run')
1700 1694 print " User : %10s s, %10s s." % (t_usr,t_usr/nruns)
1701 1695 print " System: %10s s, %10s s." % (t_sys,t_sys/nruns)
1702 1696
1703 1697 else:
1704 1698 # regular execution
1705 1699 runner(filename,prog_ns,prog_ns,exit_ignore=exit_ignore)
1700
1706 1701 if opts.has_key('i'):
1707 1702 self.shell.user_ns['__name__'] = __name__save
1708 1703 else:
1704 # The shell MUST hold a reference to prog_ns so after %run
1705 # exits, the python deletion mechanism doesn't zero it out
1706 # (leaving dangling references).
1707 self.shell.cache_main_mod(prog_ns,filename)
1709 1708 # update IPython interactive namespace
1710 1709 del prog_ns['__name__']
1711 1710 self.shell.user_ns.update(prog_ns)
1712 1711 finally:
1712 # It's a bit of a mystery why, but __builtins__ can change from
1713 # being a module to becoming a dict missing some key data after
1714 # %run. As best I can see, this is NOT something IPython is doing
1715 # at all, and similar problems have been reported before:
1716 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
1717 # Since this seems to be done by the interpreter itself, the best
1718 # we can do is to at least restore __builtins__ for the user on
1719 # exit.
1720 self.shell.user_ns['__builtins__'] = __builtin__
1721
1713 1722 # Ensure key global structures are restored
1714 1723 sys.argv = save_argv
1715 1724 if restore_main:
1716 1725 sys.modules['__main__'] = restore_main
1717 1726 else:
1718 1727 # Remove from sys.modules the reference to main_mod we'd
1719 1728 # added. Otherwise it will trap references to objects
1720 1729 # contained therein.
1721 1730 del sys.modules[main_mod_name]
1731
1722 1732 self.shell.reloadhist()
1723 1733
1724 1734 return stats
1725 1735
1726 1736 def magic_runlog(self, parameter_s =''):
1727 1737 """Run files as logs.
1728 1738
1729 1739 Usage:\\
1730 1740 %runlog file1 file2 ...
1731 1741
1732 1742 Run the named files (treating them as log files) in sequence inside
1733 1743 the interpreter, and return to the prompt. This is much slower than
1734 1744 %run because each line is executed in a try/except block, but it
1735 1745 allows running files with syntax errors in them.
1736 1746
1737 1747 Normally IPython will guess when a file is one of its own logfiles, so
1738 1748 you can typically use %run even for logs. This shorthand allows you to
1739 1749 force any file to be treated as a log file."""
1740 1750
1741 1751 for f in parameter_s.split():
1742 1752 self.shell.safe_execfile(f,self.shell.user_ns,
1743 1753 self.shell.user_ns,islog=1)
1744 1754
1745 1755 @testdec.skip_doctest
1746 1756 def magic_timeit(self, parameter_s =''):
1747 1757 """Time execution of a Python statement or expression
1748 1758
1749 1759 Usage:\\
1750 1760 %timeit [-n<N> -r<R> [-t|-c]] statement
1751 1761
1752 1762 Time execution of a Python statement or expression using the timeit
1753 1763 module.
1754 1764
1755 1765 Options:
1756 1766 -n<N>: execute the given statement <N> times in a loop. If this value
1757 1767 is not given, a fitting value is chosen.
1758 1768
1759 1769 -r<R>: repeat the loop iteration <R> times and take the best result.
1760 1770 Default: 3
1761 1771
1762 1772 -t: use time.time to measure the time, which is the default on Unix.
1763 1773 This function measures wall time.
1764 1774
1765 1775 -c: use time.clock to measure the time, which is the default on
1766 1776 Windows and measures wall time. On Unix, resource.getrusage is used
1767 1777 instead and returns the CPU user time.
1768 1778
1769 1779 -p<P>: use a precision of <P> digits to display the timing result.
1770 1780 Default: 3
1771 1781
1772 1782
1773 1783 Examples:
1774 1784
1775 1785 In [1]: %timeit pass
1776 1786 10000000 loops, best of 3: 53.3 ns per loop
1777 1787
1778 1788 In [2]: u = None
1779 1789
1780 1790 In [3]: %timeit u is None
1781 1791 10000000 loops, best of 3: 184 ns per loop
1782 1792
1783 1793 In [4]: %timeit -r 4 u == None
1784 1794 1000000 loops, best of 4: 242 ns per loop
1785 1795
1786 1796 In [5]: import time
1787 1797
1788 1798 In [6]: %timeit -n1 time.sleep(2)
1789 1799 1 loops, best of 3: 2 s per loop
1790 1800
1791 1801
1792 1802 The times reported by %timeit will be slightly higher than those
1793 1803 reported by the timeit.py script when variables are accessed. This is
1794 1804 due to the fact that %timeit executes the statement in the namespace
1795 1805 of the shell, compared with timeit.py, which uses a single setup
1796 1806 statement to import function or create variables. Generally, the bias
1797 1807 does not matter as long as results from timeit.py are not mixed with
1798 1808 those from %timeit."""
1799 1809
1800 1810 import timeit
1801 1811 import math
1802 1812
1803 units = [u"s", u"ms", u"\xb5s", u"ns"]
1813 # XXX: Unfortunately the unicode 'micro' symbol can cause problems in
1814 # certain terminals. Until we figure out a robust way of
1815 # auto-detecting if the terminal can deal with it, use plain 'us' for
1816 # microseconds. I am really NOT happy about disabling the proper
1817 # 'micro' prefix, but crashing is worse... If anyone knows what the
1818 # right solution for this is, I'm all ears...
1819 #
1820 # Note: using
1821 #
1822 # s = u'\xb5'
1823 # s.encode(sys.getdefaultencoding())
1824 #
1825 # is not sufficient, as I've seen terminals where that fails but
1826 # print s
1827 #
1828 # succeeds
1829 #
1830 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1831
1832 #units = [u"s", u"ms",u'\xb5',"ns"]
1833 units = [u"s", u"ms",u'us',"ns"]
1834
1804 1835 scaling = [1, 1e3, 1e6, 1e9]
1805 1836
1806 1837 opts, stmt = self.parse_options(parameter_s,'n:r:tcp:',
1807 1838 posix=False)
1808 1839 if stmt == "":
1809 1840 return
1810 1841 timefunc = timeit.default_timer
1811 1842 number = int(getattr(opts, "n", 0))
1812 1843 repeat = int(getattr(opts, "r", timeit.default_repeat))
1813 1844 precision = int(getattr(opts, "p", 3))
1814 1845 if hasattr(opts, "t"):
1815 1846 timefunc = time.time
1816 1847 if hasattr(opts, "c"):
1817 1848 timefunc = clock
1818 1849
1819 1850 timer = timeit.Timer(timer=timefunc)
1820 1851 # this code has tight coupling to the inner workings of timeit.Timer,
1821 1852 # but is there a better way to achieve that the code stmt has access
1822 1853 # to the shell namespace?
1823 1854
1824 1855 src = timeit.template % {'stmt': timeit.reindent(stmt, 8),
1825 1856 'setup': "pass"}
1826 1857 # Track compilation time so it can be reported if too long
1827 1858 # Minimum time above which compilation time will be reported
1828 1859 tc_min = 0.1
1829 1860
1830 1861 t0 = clock()
1831 1862 code = compile(src, "<magic-timeit>", "exec")
1832 1863 tc = clock()-t0
1833 1864
1834 1865 ns = {}
1835 1866 exec code in self.shell.user_ns, ns
1836 1867 timer.inner = ns["inner"]
1837 1868
1838 1869 if number == 0:
1839 1870 # determine number so that 0.2 <= total time < 2.0
1840 1871 number = 1
1841 1872 for i in range(1, 10):
1842 number *= 10
1843 1873 if timer.timeit(number) >= 0.2:
1844 1874 break
1875 number *= 10
1845 1876
1846 1877 best = min(timer.repeat(repeat, number)) / number
1847 1878
1848 1879 if best > 0.0:
1849 1880 order = min(-int(math.floor(math.log10(best)) // 3), 3)
1850 1881 else:
1851 1882 order = 3
1852 1883 print u"%d loops, best of %d: %.*g %s per loop" % (number, repeat,
1853 1884 precision,
1854 1885 best * scaling[order],
1855 1886 units[order])
1856 1887 if tc > tc_min:
1857 1888 print "Compiler time: %.2f s" % tc
1858 1889
1859 1890 @testdec.skip_doctest
1860 1891 def magic_time(self,parameter_s = ''):
1861 1892 """Time execution of a Python statement or expression.
1862 1893
1863 1894 The CPU and wall clock times are printed, and the value of the
1864 1895 expression (if any) is returned. Note that under Win32, system time
1865 1896 is always reported as 0, since it can not be measured.
1866 1897
1867 1898 This function provides very basic timing functionality. In Python
1868 1899 2.3, the timeit module offers more control and sophistication, so this
1869 1900 could be rewritten to use it (patches welcome).
1870 1901
1871 1902 Some examples:
1872 1903
1873 1904 In [1]: time 2**128
1874 1905 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1875 1906 Wall time: 0.00
1876 1907 Out[1]: 340282366920938463463374607431768211456L
1877 1908
1878 1909 In [2]: n = 1000000
1879 1910
1880 1911 In [3]: time sum(range(n))
1881 1912 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1882 1913 Wall time: 1.37
1883 1914 Out[3]: 499999500000L
1884 1915
1885 1916 In [4]: time print 'hello world'
1886 1917 hello world
1887 1918 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1888 1919 Wall time: 0.00
1889 1920
1890 1921 Note that the time needed by Python to compile the given expression
1891 1922 will be reported if it is more than 0.1s. In this example, the
1892 1923 actual exponentiation is done by Python at compilation time, so while
1893 1924 the expression can take a noticeable amount of time to compute, that
1894 1925 time is purely due to the compilation:
1895 1926
1896 1927 In [5]: time 3**9999;
1897 1928 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1898 1929 Wall time: 0.00 s
1899 1930
1900 1931 In [6]: time 3**999999;
1901 1932 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1902 1933 Wall time: 0.00 s
1903 1934 Compiler : 0.78 s
1904 1935 """
1905 1936
1906 1937 # fail immediately if the given expression can't be compiled
1907 1938
1908 1939 expr = self.shell.prefilter(parameter_s,False)
1909 1940
1910 1941 # Minimum time above which compilation time will be reported
1911 1942 tc_min = 0.1
1912 1943
1913 1944 try:
1914 1945 mode = 'eval'
1915 1946 t0 = clock()
1916 1947 code = compile(expr,'<timed eval>',mode)
1917 1948 tc = clock()-t0
1918 1949 except SyntaxError:
1919 1950 mode = 'exec'
1920 1951 t0 = clock()
1921 1952 code = compile(expr,'<timed exec>',mode)
1922 1953 tc = clock()-t0
1923 1954 # skew measurement as little as possible
1924 1955 glob = self.shell.user_ns
1925 1956 clk = clock2
1926 1957 wtime = time.time
1927 1958 # time execution
1928 1959 wall_st = wtime()
1929 1960 if mode=='eval':
1930 1961 st = clk()
1931 1962 out = eval(code,glob)
1932 1963 end = clk()
1933 1964 else:
1934 1965 st = clk()
1935 1966 exec code in glob
1936 1967 end = clk()
1937 1968 out = None
1938 1969 wall_end = wtime()
1939 1970 # Compute actual times and report
1940 1971 wall_time = wall_end-wall_st
1941 1972 cpu_user = end[0]-st[0]
1942 1973 cpu_sys = end[1]-st[1]
1943 1974 cpu_tot = cpu_user+cpu_sys
1944 1975 print "CPU times: user %.2f s, sys: %.2f s, total: %.2f s" % \
1945 1976 (cpu_user,cpu_sys,cpu_tot)
1946 1977 print "Wall time: %.2f s" % wall_time
1947 1978 if tc > tc_min:
1948 1979 print "Compiler : %.2f s" % tc
1949 1980 return out
1950 1981
1951 1982 @testdec.skip_doctest
1952 1983 def magic_macro(self,parameter_s = ''):
1953 1984 """Define a set of input lines as a macro for future re-execution.
1954 1985
1955 1986 Usage:\\
1956 1987 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1957 1988
1958 1989 Options:
1959 1990
1960 1991 -r: use 'raw' input. By default, the 'processed' history is used,
1961 1992 so that magics are loaded in their transformed version to valid
1962 1993 Python. If this option is given, the raw input as typed as the
1963 1994 command line is used instead.
1964 1995
1965 1996 This will define a global variable called `name` which is a string
1966 1997 made of joining the slices and lines you specify (n1,n2,... numbers
1967 1998 above) from your input history into a single string. This variable
1968 1999 acts like an automatic function which re-executes those lines as if
1969 2000 you had typed them. You just type 'name' at the prompt and the code
1970 2001 executes.
1971 2002
1972 2003 The notation for indicating number ranges is: n1-n2 means 'use line
1973 2004 numbers n1,...n2' (the endpoint is included). That is, '5-7' means
1974 2005 using the lines numbered 5,6 and 7.
1975 2006
1976 2007 Note: as a 'hidden' feature, you can also use traditional python slice
1977 2008 notation, where N:M means numbers N through M-1.
1978 2009
1979 2010 For example, if your history contains (%hist prints it):
1980 2011
1981 2012 44: x=1
1982 2013 45: y=3
1983 2014 46: z=x+y
1984 2015 47: print x
1985 2016 48: a=5
1986 2017 49: print 'x',x,'y',y
1987 2018
1988 2019 you can create a macro with lines 44 through 47 (included) and line 49
1989 2020 called my_macro with:
1990 2021
1991 2022 In [55]: %macro my_macro 44-47 49
1992 2023
1993 2024 Now, typing `my_macro` (without quotes) will re-execute all this code
1994 2025 in one pass.
1995 2026
1996 2027 You don't need to give the line-numbers in order, and any given line
1997 2028 number can appear multiple times. You can assemble macros with any
1998 2029 lines from your input history in any order.
1999 2030
2000 2031 The macro is a simple object which holds its value in an attribute,
2001 2032 but IPython's display system checks for macros and executes them as
2002 2033 code instead of printing them when you type their name.
2003 2034
2004 2035 You can view a macro's contents by explicitly printing it with:
2005 2036
2006 2037 'print macro_name'.
2007 2038
2008 2039 For one-off cases which DON'T contain magic function calls in them you
2009 2040 can obtain similar results by explicitly executing slices from your
2010 2041 input history with:
2011 2042
2012 2043 In [60]: exec In[44:48]+In[49]"""
2013 2044
2014 2045 opts,args = self.parse_options(parameter_s,'r',mode='list')
2015 2046 if not args:
2016 2047 macs = [k for k,v in self.shell.user_ns.items() if isinstance(v, Macro)]
2017 2048 macs.sort()
2018 2049 return macs
2019 2050 if len(args) == 1:
2020 2051 raise UsageError(
2021 2052 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
2022 2053 name,ranges = args[0], args[1:]
2023 2054
2024 2055 #print 'rng',ranges # dbg
2025 2056 lines = self.extract_input_slices(ranges,opts.has_key('r'))
2026 2057 macro = Macro(lines)
2027 2058 self.shell.user_ns.update({name:macro})
2028 2059 print 'Macro `%s` created. To execute, type its name (without quotes).' % name
2029 2060 print 'Macro contents:'
2030 2061 print macro,
2031 2062
2032 2063 def magic_save(self,parameter_s = ''):
2033 2064 """Save a set of lines to a given filename.
2034 2065
2035 2066 Usage:\\
2036 2067 %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ...
2037 2068
2038 2069 Options:
2039 2070
2040 2071 -r: use 'raw' input. By default, the 'processed' history is used,
2041 2072 so that magics are loaded in their transformed version to valid
2042 2073 Python. If this option is given, the raw input as typed as the
2043 2074 command line is used instead.
2044 2075
2045 2076 This function uses the same syntax as %macro for line extraction, but
2046 2077 instead of creating a macro it saves the resulting string to the
2047 2078 filename you specify.
2048 2079
2049 2080 It adds a '.py' extension to the file if you don't do so yourself, and
2050 2081 it asks for confirmation before overwriting existing files."""
2051 2082
2052 2083 opts,args = self.parse_options(parameter_s,'r',mode='list')
2053 2084 fname,ranges = args[0], args[1:]
2054 2085 if not fname.endswith('.py'):
2055 2086 fname += '.py'
2056 2087 if os.path.isfile(fname):
2057 2088 ans = raw_input('File `%s` exists. Overwrite (y/[N])? ' % fname)
2058 2089 if ans.lower() not in ['y','yes']:
2059 2090 print 'Operation cancelled.'
2060 2091 return
2061 2092 cmds = ''.join(self.extract_input_slices(ranges,opts.has_key('r')))
2062 2093 f = file(fname,'w')
2063 2094 f.write(cmds)
2064 2095 f.close()
2065 2096 print 'The following commands were written to file `%s`:' % fname
2066 2097 print cmds
2067 2098
2068 2099 def _edit_macro(self,mname,macro):
2069 2100 """open an editor with the macro data in a file"""
2070 2101 filename = self.shell.mktempfile(macro.value)
2071 2102 self.shell.hooks.editor(filename)
2072 2103
2073 2104 # and make a new macro object, to replace the old one
2074 2105 mfile = open(filename)
2075 2106 mvalue = mfile.read()
2076 2107 mfile.close()
2077 2108 self.shell.user_ns[mname] = Macro(mvalue)
2078 2109
2079 2110 def magic_ed(self,parameter_s=''):
2080 2111 """Alias to %edit."""
2081 2112 return self.magic_edit(parameter_s)
2082 2113
2083 2114 @testdec.skip_doctest
2084 2115 def magic_edit(self,parameter_s='',last_call=['','']):
2085 2116 """Bring up an editor and execute the resulting code.
2086 2117
2087 2118 Usage:
2088 2119 %edit [options] [args]
2089 2120
2090 2121 %edit runs IPython's editor hook. The default version of this hook is
2091 2122 set to call the __IPYTHON__.rc.editor command. This is read from your
2092 2123 environment variable $EDITOR. If this isn't found, it will default to
2093 2124 vi under Linux/Unix and to notepad under Windows. See the end of this
2094 2125 docstring for how to change the editor hook.
2095 2126
2096 2127 You can also set the value of this editor via the command line option
2097 2128 '-editor' or in your ipythonrc file. This is useful if you wish to use
2098 2129 specifically for IPython an editor different from your typical default
2099 2130 (and for Windows users who typically don't set environment variables).
2100 2131
2101 2132 This command allows you to conveniently edit multi-line code right in
2102 2133 your IPython session.
2103 2134
2104 2135 If called without arguments, %edit opens up an empty editor with a
2105 2136 temporary file and will execute the contents of this file when you
2106 2137 close it (don't forget to save it!).
2107 2138
2108 2139
2109 2140 Options:
2110 2141
2111 2142 -n <number>: open the editor at a specified line number. By default,
2112 2143 the IPython editor hook uses the unix syntax 'editor +N filename', but
2113 2144 you can configure this by providing your own modified hook if your
2114 2145 favorite editor supports line-number specifications with a different
2115 2146 syntax.
2116 2147
2117 2148 -p: this will call the editor with the same data as the previous time
2118 2149 it was used, regardless of how long ago (in your current session) it
2119 2150 was.
2120 2151
2121 2152 -r: use 'raw' input. This option only applies to input taken from the
2122 2153 user's history. By default, the 'processed' history is used, so that
2123 2154 magics are loaded in their transformed version to valid Python. If
2124 2155 this option is given, the raw input as typed as the command line is
2125 2156 used instead. When you exit the editor, it will be executed by
2126 2157 IPython's own processor.
2127 2158
2128 2159 -x: do not execute the edited code immediately upon exit. This is
2129 2160 mainly useful if you are editing programs which need to be called with
2130 2161 command line arguments, which you can then do using %run.
2131 2162
2132 2163
2133 2164 Arguments:
2134 2165
2135 2166 If arguments are given, the following possibilites exist:
2136 2167
2137 2168 - The arguments are numbers or pairs of colon-separated numbers (like
2138 2169 1 4:8 9). These are interpreted as lines of previous input to be
2139 2170 loaded into the editor. The syntax is the same of the %macro command.
2140 2171
2141 2172 - If the argument doesn't start with a number, it is evaluated as a
2142 2173 variable and its contents loaded into the editor. You can thus edit
2143 2174 any string which contains python code (including the result of
2144 2175 previous edits).
2145 2176
2146 2177 - If the argument is the name of an object (other than a string),
2147 2178 IPython will try to locate the file where it was defined and open the
2148 2179 editor at the point where it is defined. You can use `%edit function`
2149 2180 to load an editor exactly at the point where 'function' is defined,
2150 2181 edit it and have the file be executed automatically.
2151 2182
2152 2183 If the object is a macro (see %macro for details), this opens up your
2153 2184 specified editor with a temporary file containing the macro's data.
2154 2185 Upon exit, the macro is reloaded with the contents of the file.
2155 2186
2156 2187 Note: opening at an exact line is only supported under Unix, and some
2157 2188 editors (like kedit and gedit up to Gnome 2.8) do not understand the
2158 2189 '+NUMBER' parameter necessary for this feature. Good editors like
2159 2190 (X)Emacs, vi, jed, pico and joe all do.
2160 2191
2161 2192 - If the argument is not found as a variable, IPython will look for a
2162 2193 file with that name (adding .py if necessary) and load it into the
2163 2194 editor. It will execute its contents with execfile() when you exit,
2164 2195 loading any code in the file into your interactive namespace.
2165 2196
2166 2197 After executing your code, %edit will return as output the code you
2167 2198 typed in the editor (except when it was an existing file). This way
2168 2199 you can reload the code in further invocations of %edit as a variable,
2169 2200 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
2170 2201 the output.
2171 2202
2172 2203 Note that %edit is also available through the alias %ed.
2173 2204
2174 2205 This is an example of creating a simple function inside the editor and
2175 2206 then modifying it. First, start up the editor:
2176 2207
2177 2208 In [1]: ed
2178 2209 Editing... done. Executing edited code...
2179 2210 Out[1]: 'def foo():n print "foo() was defined in an editing session"n'
2180 2211
2181 2212 We can then call the function foo():
2182 2213
2183 2214 In [2]: foo()
2184 2215 foo() was defined in an editing session
2185 2216
2186 2217 Now we edit foo. IPython automatically loads the editor with the
2187 2218 (temporary) file where foo() was previously defined:
2188 2219
2189 2220 In [3]: ed foo
2190 2221 Editing... done. Executing edited code...
2191 2222
2192 2223 And if we call foo() again we get the modified version:
2193 2224
2194 2225 In [4]: foo()
2195 2226 foo() has now been changed!
2196 2227
2197 2228 Here is an example of how to edit a code snippet successive
2198 2229 times. First we call the editor:
2199 2230
2200 2231 In [5]: ed
2201 2232 Editing... done. Executing edited code...
2202 2233 hello
2203 2234 Out[5]: "print 'hello'n"
2204 2235
2205 2236 Now we call it again with the previous output (stored in _):
2206 2237
2207 2238 In [6]: ed _
2208 2239 Editing... done. Executing edited code...
2209 2240 hello world
2210 2241 Out[6]: "print 'hello world'n"
2211 2242
2212 2243 Now we call it with the output #8 (stored in _8, also as Out[8]):
2213 2244
2214 2245 In [7]: ed _8
2215 2246 Editing... done. Executing edited code...
2216 2247 hello again
2217 2248 Out[7]: "print 'hello again'n"
2218 2249
2219 2250
2220 2251 Changing the default editor hook:
2221 2252
2222 2253 If you wish to write your own editor hook, you can put it in a
2223 2254 configuration file which you load at startup time. The default hook
2224 2255 is defined in the IPython.hooks module, and you can use that as a
2225 2256 starting example for further modifications. That file also has
2226 2257 general instructions on how to set a new hook for use once you've
2227 2258 defined it."""
2228 2259
2229 2260 # FIXME: This function has become a convoluted mess. It needs a
2230 2261 # ground-up rewrite with clean, simple logic.
2231 2262
2232 2263 def make_filename(arg):
2233 2264 "Make a filename from the given args"
2234 2265 try:
2235 2266 filename = get_py_filename(arg)
2236 2267 except IOError:
2237 2268 if args.endswith('.py'):
2238 2269 filename = arg
2239 2270 else:
2240 2271 filename = None
2241 2272 return filename
2242 2273
2243 2274 # custom exceptions
2244 2275 class DataIsObject(Exception): pass
2245 2276
2246 2277 opts,args = self.parse_options(parameter_s,'prxn:')
2247 2278 # Set a few locals from the options for convenience:
2248 2279 opts_p = opts.has_key('p')
2249 2280 opts_r = opts.has_key('r')
2250 2281
2251 2282 # Default line number value
2252 2283 lineno = opts.get('n',None)
2253 2284
2254 2285 if opts_p:
2255 2286 args = '_%s' % last_call[0]
2256 2287 if not self.shell.user_ns.has_key(args):
2257 2288 args = last_call[1]
2258 2289
2259 2290 # use last_call to remember the state of the previous call, but don't
2260 2291 # let it be clobbered by successive '-p' calls.
2261 2292 try:
2262 2293 last_call[0] = self.shell.outputcache.prompt_count
2263 2294 if not opts_p:
2264 2295 last_call[1] = parameter_s
2265 2296 except:
2266 2297 pass
2267 2298
2268 2299 # by default this is done with temp files, except when the given
2269 2300 # arg is a filename
2270 2301 use_temp = 1
2271 2302
2272 2303 if re.match(r'\d',args):
2273 2304 # Mode where user specifies ranges of lines, like in %macro.
2274 2305 # This means that you can't edit files whose names begin with
2275 2306 # numbers this way. Tough.
2276 2307 ranges = args.split()
2277 2308 data = ''.join(self.extract_input_slices(ranges,opts_r))
2278 2309 elif args.endswith('.py'):
2279 2310 filename = make_filename(args)
2280 2311 data = ''
2281 2312 use_temp = 0
2282 2313 elif args:
2283 2314 try:
2284 2315 # Load the parameter given as a variable. If not a string,
2285 2316 # process it as an object instead (below)
2286 2317
2287 2318 #print '*** args',args,'type',type(args) # dbg
2288 2319 data = eval(args,self.shell.user_ns)
2289 2320 if not type(data) in StringTypes:
2290 2321 raise DataIsObject
2291 2322
2292 2323 except (NameError,SyntaxError):
2293 2324 # given argument is not a variable, try as a filename
2294 2325 filename = make_filename(args)
2295 2326 if filename is None:
2296 2327 warn("Argument given (%s) can't be found as a variable "
2297 2328 "or as a filename." % args)
2298 2329 return
2299 2330
2300 2331 data = ''
2301 2332 use_temp = 0
2302 2333 except DataIsObject:
2303 2334
2304 2335 # macros have a special edit function
2305 2336 if isinstance(data,Macro):
2306 2337 self._edit_macro(args,data)
2307 2338 return
2308 2339
2309 2340 # For objects, try to edit the file where they are defined
2310 2341 try:
2311 2342 filename = inspect.getabsfile(data)
2312 2343 if 'fakemodule' in filename.lower() and inspect.isclass(data):
2313 2344 # class created by %edit? Try to find source
2314 2345 # by looking for method definitions instead, the
2315 2346 # __module__ in those classes is FakeModule.
2316 2347 attrs = [getattr(data, aname) for aname in dir(data)]
2317 2348 for attr in attrs:
2318 2349 if not inspect.ismethod(attr):
2319 2350 continue
2320 2351 filename = inspect.getabsfile(attr)
2321 2352 if filename and 'fakemodule' not in filename.lower():
2322 2353 # change the attribute to be the edit target instead
2323 2354 data = attr
2324 2355 break
2325 2356
2326 2357 datafile = 1
2327 2358 except TypeError:
2328 2359 filename = make_filename(args)
2329 2360 datafile = 1
2330 2361 warn('Could not find file where `%s` is defined.\n'
2331 2362 'Opening a file named `%s`' % (args,filename))
2332 2363 # Now, make sure we can actually read the source (if it was in
2333 2364 # a temp file it's gone by now).
2334 2365 if datafile:
2335 2366 try:
2336 2367 if lineno is None:
2337 2368 lineno = inspect.getsourcelines(data)[1]
2338 2369 except IOError:
2339 2370 filename = make_filename(args)
2340 2371 if filename is None:
2341 2372 warn('The file `%s` where `%s` was defined cannot '
2342 2373 'be read.' % (filename,data))
2343 2374 return
2344 2375 use_temp = 0
2345 2376 else:
2346 2377 data = ''
2347 2378
2348 2379 if use_temp:
2349 2380 filename = self.shell.mktempfile(data)
2350 2381 print 'IPython will make a temporary file named:',filename
2351 2382
2352 2383 # do actual editing here
2353 2384 print 'Editing...',
2354 2385 sys.stdout.flush()
2355 2386 try:
2356 2387 self.shell.hooks.editor(filename,lineno)
2357 2388 except IPython.ipapi.TryNext:
2358 2389 warn('Could not open editor')
2359 2390 return
2360 2391
2361 2392 # XXX TODO: should this be generalized for all string vars?
2362 2393 # For now, this is special-cased to blocks created by cpaste
2363 2394 if args.strip() == 'pasted_block':
2364 2395 self.shell.user_ns['pasted_block'] = file_read(filename)
2365 2396
2366 2397 if opts.has_key('x'): # -x prevents actual execution
2367 2398 print
2368 2399 else:
2369 2400 print 'done. Executing edited code...'
2370 2401 if opts_r:
2371 2402 self.shell.runlines(file_read(filename))
2372 2403 else:
2373 2404 self.shell.safe_execfile(filename,self.shell.user_ns,
2374 2405 self.shell.user_ns)
2375 2406
2376 2407
2377 2408 if use_temp:
2378 2409 try:
2379 2410 return open(filename).read()
2380 2411 except IOError,msg:
2381 2412 if msg.filename == filename:
2382 2413 warn('File not found. Did you forget to save?')
2383 2414 return
2384 2415 else:
2385 2416 self.shell.showtraceback()
2386 2417
2387 2418 def magic_xmode(self,parameter_s = ''):
2388 2419 """Switch modes for the exception handlers.
2389 2420
2390 2421 Valid modes: Plain, Context and Verbose.
2391 2422
2392 2423 If called without arguments, acts as a toggle."""
2393 2424
2394 2425 def xmode_switch_err(name):
2395 2426 warn('Error changing %s exception modes.\n%s' %
2396 2427 (name,sys.exc_info()[1]))
2397 2428
2398 2429 shell = self.shell
2399 2430 new_mode = parameter_s.strip().capitalize()
2400 2431 try:
2401 2432 shell.InteractiveTB.set_mode(mode=new_mode)
2402 2433 print 'Exception reporting mode:',shell.InteractiveTB.mode
2403 2434 except:
2404 2435 xmode_switch_err('user')
2405 2436
2406 2437 # threaded shells use a special handler in sys.excepthook
2407 2438 if shell.isthreaded:
2408 2439 try:
2409 2440 shell.sys_excepthook.set_mode(mode=new_mode)
2410 2441 except:
2411 2442 xmode_switch_err('threaded')
2412 2443
2413 2444 def magic_colors(self,parameter_s = ''):
2414 2445 """Switch color scheme for prompts, info system and exception handlers.
2415 2446
2416 2447 Currently implemented schemes: NoColor, Linux, LightBG.
2417 2448
2418 2449 Color scheme names are not case-sensitive."""
2419 2450
2420 2451 def color_switch_err(name):
2421 2452 warn('Error changing %s color schemes.\n%s' %
2422 2453 (name,sys.exc_info()[1]))
2423 2454
2424 2455
2425 2456 new_scheme = parameter_s.strip()
2426 2457 if not new_scheme:
2427 2458 raise UsageError(
2428 2459 "%colors: you must specify a color scheme. See '%colors?'")
2429 2460 return
2430 2461 # local shortcut
2431 2462 shell = self.shell
2432 2463
2433 2464 import IPython.rlineimpl as readline
2434 2465
2435 2466 if not readline.have_readline and sys.platform == "win32":
2436 2467 msg = """\
2437 2468 Proper color support under MS Windows requires the pyreadline library.
2438 2469 You can find it at:
2439 2470 http://ipython.scipy.org/moin/PyReadline/Intro
2440 2471 Gary's readline needs the ctypes module, from:
2441 2472 http://starship.python.net/crew/theller/ctypes
2442 2473 (Note that ctypes is already part of Python versions 2.5 and newer).
2443 2474
2444 2475 Defaulting color scheme to 'NoColor'"""
2445 2476 new_scheme = 'NoColor'
2446 2477 warn(msg)
2447 2478
2448 2479 # readline option is 0
2449 2480 if not shell.has_readline:
2450 2481 new_scheme = 'NoColor'
2451 2482
2452 2483 # Set prompt colors
2453 2484 try:
2454 2485 shell.outputcache.set_colors(new_scheme)
2455 2486 except:
2456 2487 color_switch_err('prompt')
2457 2488 else:
2458 2489 shell.rc.colors = \
2459 2490 shell.outputcache.color_table.active_scheme_name
2460 2491 # Set exception colors
2461 2492 try:
2462 2493 shell.InteractiveTB.set_colors(scheme = new_scheme)
2463 2494 shell.SyntaxTB.set_colors(scheme = new_scheme)
2464 2495 except:
2465 2496 color_switch_err('exception')
2466 2497
2467 2498 # threaded shells use a verbose traceback in sys.excepthook
2468 2499 if shell.isthreaded:
2469 2500 try:
2470 2501 shell.sys_excepthook.set_colors(scheme=new_scheme)
2471 2502 except:
2472 2503 color_switch_err('system exception handler')
2473 2504
2474 2505 # Set info (for 'object?') colors
2475 2506 if shell.rc.color_info:
2476 2507 try:
2477 2508 shell.inspector.set_active_scheme(new_scheme)
2478 2509 except:
2479 2510 color_switch_err('object inspector')
2480 2511 else:
2481 2512 shell.inspector.set_active_scheme('NoColor')
2482 2513
2483 2514 def magic_color_info(self,parameter_s = ''):
2484 2515 """Toggle color_info.
2485 2516
2486 2517 The color_info configuration parameter controls whether colors are
2487 2518 used for displaying object details (by things like %psource, %pfile or
2488 2519 the '?' system). This function toggles this value with each call.
2489 2520
2490 2521 Note that unless you have a fairly recent pager (less works better
2491 2522 than more) in your system, using colored object information displays
2492 2523 will not work properly. Test it and see."""
2493 2524
2494 2525 self.shell.rc.color_info = 1 - self.shell.rc.color_info
2495 2526 self.magic_colors(self.shell.rc.colors)
2496 2527 print 'Object introspection functions have now coloring:',
2497 2528 print ['OFF','ON'][self.shell.rc.color_info]
2498 2529
2499 2530 def magic_Pprint(self, parameter_s=''):
2500 2531 """Toggle pretty printing on/off."""
2501 2532
2502 2533 self.shell.rc.pprint = 1 - self.shell.rc.pprint
2503 2534 print 'Pretty printing has been turned', \
2504 2535 ['OFF','ON'][self.shell.rc.pprint]
2505 2536
2506 2537 def magic_exit(self, parameter_s=''):
2507 2538 """Exit IPython, confirming if configured to do so.
2508 2539
2509 2540 You can configure whether IPython asks for confirmation upon exit by
2510 2541 setting the confirm_exit flag in the ipythonrc file."""
2511 2542
2512 2543 self.shell.exit()
2513 2544
2514 2545 def magic_quit(self, parameter_s=''):
2515 2546 """Exit IPython, confirming if configured to do so (like %exit)"""
2516 2547
2517 2548 self.shell.exit()
2518 2549
2519 2550 def magic_Exit(self, parameter_s=''):
2520 2551 """Exit IPython without confirmation."""
2521 2552
2522 2553 self.shell.ask_exit()
2523 2554
2524 2555 #......................................................................
2525 2556 # Functions to implement unix shell-type things
2526 2557
2527 2558 @testdec.skip_doctest
2528 2559 def magic_alias(self, parameter_s = ''):
2529 2560 """Define an alias for a system command.
2530 2561
2531 2562 '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd'
2532 2563
2533 2564 Then, typing 'alias_name params' will execute the system command 'cmd
2534 2565 params' (from your underlying operating system).
2535 2566
2536 2567 Aliases have lower precedence than magic functions and Python normal
2537 2568 variables, so if 'foo' is both a Python variable and an alias, the
2538 2569 alias can not be executed until 'del foo' removes the Python variable.
2539 2570
2540 2571 You can use the %l specifier in an alias definition to represent the
2541 2572 whole line when the alias is called. For example:
2542 2573
2543 2574 In [2]: alias all echo "Input in brackets: <%l>"
2544 2575 In [3]: all hello world
2545 2576 Input in brackets: <hello world>
2546 2577
2547 2578 You can also define aliases with parameters using %s specifiers (one
2548 2579 per parameter):
2549 2580
2550 2581 In [1]: alias parts echo first %s second %s
2551 2582 In [2]: %parts A B
2552 2583 first A second B
2553 2584 In [3]: %parts A
2554 2585 Incorrect number of arguments: 2 expected.
2555 2586 parts is an alias to: 'echo first %s second %s'
2556 2587
2557 2588 Note that %l and %s are mutually exclusive. You can only use one or
2558 2589 the other in your aliases.
2559 2590
2560 2591 Aliases expand Python variables just like system calls using ! or !!
2561 2592 do: all expressions prefixed with '$' get expanded. For details of
2562 2593 the semantic rules, see PEP-215:
2563 2594 http://www.python.org/peps/pep-0215.html. This is the library used by
2564 2595 IPython for variable expansion. If you want to access a true shell
2565 2596 variable, an extra $ is necessary to prevent its expansion by IPython:
2566 2597
2567 2598 In [6]: alias show echo
2568 2599 In [7]: PATH='A Python string'
2569 2600 In [8]: show $PATH
2570 2601 A Python string
2571 2602 In [9]: show $$PATH
2572 2603 /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
2573 2604
2574 2605 You can use the alias facility to acess all of $PATH. See the %rehash
2575 2606 and %rehashx functions, which automatically create aliases for the
2576 2607 contents of your $PATH.
2577 2608
2578 2609 If called with no parameters, %alias prints the current alias table."""
2579 2610
2580 2611 par = parameter_s.strip()
2581 2612 if not par:
2582 2613 stored = self.db.get('stored_aliases', {} )
2583 2614 atab = self.shell.alias_table
2584 2615 aliases = atab.keys()
2585 2616 aliases.sort()
2586 2617 res = []
2587 2618 showlast = []
2588 2619 for alias in aliases:
2589 2620 special = False
2590 2621 try:
2591 2622 tgt = atab[alias][1]
2592 2623 except (TypeError, AttributeError):
2593 2624 # unsubscriptable? probably a callable
2594 2625 tgt = atab[alias]
2595 2626 special = True
2596 2627 # 'interesting' aliases
2597 2628 if (alias in stored or
2598 2629 special or
2599 2630 alias.lower() != os.path.splitext(tgt)[0].lower() or
2600 2631 ' ' in tgt):
2601 2632 showlast.append((alias, tgt))
2602 2633 else:
2603 2634 res.append((alias, tgt ))
2604 2635
2605 2636 # show most interesting aliases last
2606 2637 res.extend(showlast)
2607 2638 print "Total number of aliases:",len(aliases)
2608 2639 return res
2609 2640 try:
2610 2641 alias,cmd = par.split(None,1)
2611 2642 except:
2612 2643 print OInspect.getdoc(self.magic_alias)
2613 2644 else:
2614 2645 nargs = cmd.count('%s')
2615 2646 if nargs>0 and cmd.find('%l')>=0:
2616 2647 error('The %s and %l specifiers are mutually exclusive '
2617 2648 'in alias definitions.')
2618 2649 else: # all looks OK
2619 2650 self.shell.alias_table[alias] = (nargs,cmd)
2620 2651 self.shell.alias_table_validate(verbose=0)
2621 2652 # end magic_alias
2622 2653
2623 2654 def magic_unalias(self, parameter_s = ''):
2624 2655 """Remove an alias"""
2625 2656
2626 2657 aname = parameter_s.strip()
2627 2658 if aname in self.shell.alias_table:
2628 2659 del self.shell.alias_table[aname]
2629 2660 stored = self.db.get('stored_aliases', {} )
2630 2661 if aname in stored:
2631 2662 print "Removing %stored alias",aname
2632 2663 del stored[aname]
2633 2664 self.db['stored_aliases'] = stored
2634 2665
2635 2666
2636 2667 def magic_rehashx(self, parameter_s = ''):
2637 2668 """Update the alias table with all executable files in $PATH.
2638 2669
2639 2670 This version explicitly checks that every entry in $PATH is a file
2640 2671 with execute access (os.X_OK), so it is much slower than %rehash.
2641 2672
2642 2673 Under Windows, it checks executability as a match agains a
2643 2674 '|'-separated string of extensions, stored in the IPython config
2644 2675 variable win_exec_ext. This defaults to 'exe|com|bat'.
2645 2676
2646 2677 This function also resets the root module cache of module completer,
2647 2678 used on slow filesystems.
2648 2679 """
2649 2680
2650 2681
2651 2682 ip = self.api
2652 2683
2653 2684 # for the benefit of module completer in ipy_completers.py
2654 2685 del ip.db['rootmodules']
2655 2686
2656 2687 path = [os.path.abspath(os.path.expanduser(p)) for p in
2657 2688 os.environ.get('PATH','').split(os.pathsep)]
2658 2689 path = filter(os.path.isdir,path)
2659 2690
2660 2691 alias_table = self.shell.alias_table
2661 2692 syscmdlist = []
2662 2693 if os.name == 'posix':
2663 2694 isexec = lambda fname:os.path.isfile(fname) and \
2664 2695 os.access(fname,os.X_OK)
2665 2696 else:
2666 2697
2667 2698 try:
2668 2699 winext = os.environ['pathext'].replace(';','|').replace('.','')
2669 2700 except KeyError:
2670 2701 winext = 'exe|com|bat|py'
2671 2702 if 'py' not in winext:
2672 2703 winext += '|py'
2673 2704 execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
2674 2705 isexec = lambda fname:os.path.isfile(fname) and execre.match(fname)
2675 2706 savedir = os.getcwd()
2676 2707 try:
2677 2708 # write the whole loop for posix/Windows so we don't have an if in
2678 2709 # the innermost part
2679 2710 if os.name == 'posix':
2680 2711 for pdir in path:
2681 2712 os.chdir(pdir)
2682 2713 for ff in os.listdir(pdir):
2683 2714 if isexec(ff) and ff not in self.shell.no_alias:
2684 2715 # each entry in the alias table must be (N,name),
2685 2716 # where N is the number of positional arguments of the
2686 2717 # alias.
2687 2718 # Dots will be removed from alias names, since ipython
2688 2719 # assumes names with dots to be python code
2689 2720 alias_table[ff.replace('.','')] = (0,ff)
2690 2721 syscmdlist.append(ff)
2691 2722 else:
2692 2723 for pdir in path:
2693 2724 os.chdir(pdir)
2694 2725 for ff in os.listdir(pdir):
2695 2726 base, ext = os.path.splitext(ff)
2696 2727 if isexec(ff) and base.lower() not in self.shell.no_alias:
2697 2728 if ext.lower() == '.exe':
2698 2729 ff = base
2699 2730 alias_table[base.lower().replace('.','')] = (0,ff)
2700 2731 syscmdlist.append(ff)
2701 2732 # Make sure the alias table doesn't contain keywords or builtins
2702 2733 self.shell.alias_table_validate()
2703 2734 # Call again init_auto_alias() so we get 'rm -i' and other
2704 2735 # modified aliases since %rehashx will probably clobber them
2705 2736
2706 2737 # no, we don't want them. if %rehashx clobbers them, good,
2707 2738 # we'll probably get better versions
2708 2739 # self.shell.init_auto_alias()
2709 2740 db = ip.db
2710 2741 db['syscmdlist'] = syscmdlist
2711 2742 finally:
2712 2743 os.chdir(savedir)
2713 2744
2714 2745 def magic_pwd(self, parameter_s = ''):
2715 2746 """Return the current working directory path."""
2716 2747 return os.getcwd()
2717 2748
2718 2749 def magic_cd(self, parameter_s=''):
2719 2750 """Change the current working directory.
2720 2751
2721 2752 This command automatically maintains an internal list of directories
2722 2753 you visit during your IPython session, in the variable _dh. The
2723 2754 command %dhist shows this history nicely formatted. You can also
2724 2755 do 'cd -<tab>' to see directory history conveniently.
2725 2756
2726 2757 Usage:
2727 2758
2728 2759 cd 'dir': changes to directory 'dir'.
2729 2760
2730 2761 cd -: changes to the last visited directory.
2731 2762
2732 2763 cd -<n>: changes to the n-th directory in the directory history.
2733 2764
2734 2765 cd --foo: change to directory that matches 'foo' in history
2735 2766
2736 2767 cd -b <bookmark_name>: jump to a bookmark set by %bookmark
2737 2768 (note: cd <bookmark_name> is enough if there is no
2738 2769 directory <bookmark_name>, but a bookmark with the name exists.)
2739 2770 'cd -b <tab>' allows you to tab-complete bookmark names.
2740 2771
2741 2772 Options:
2742 2773
2743 2774 -q: quiet. Do not print the working directory after the cd command is
2744 2775 executed. By default IPython's cd command does print this directory,
2745 2776 since the default prompts do not display path information.
2746 2777
2747 2778 Note that !cd doesn't work for this purpose because the shell where
2748 2779 !command runs is immediately discarded after executing 'command'."""
2749 2780
2750 2781 parameter_s = parameter_s.strip()
2751 2782 #bkms = self.shell.persist.get("bookmarks",{})
2752 2783
2753 2784 oldcwd = os.getcwd()
2754 2785 numcd = re.match(r'(-)(\d+)$',parameter_s)
2755 2786 # jump in directory history by number
2756 2787 if numcd:
2757 2788 nn = int(numcd.group(2))
2758 2789 try:
2759 2790 ps = self.shell.user_ns['_dh'][nn]
2760 2791 except IndexError:
2761 2792 print 'The requested directory does not exist in history.'
2762 2793 return
2763 2794 else:
2764 2795 opts = {}
2765 2796 elif parameter_s.startswith('--'):
2766 2797 ps = None
2767 2798 fallback = None
2768 2799 pat = parameter_s[2:]
2769 2800 dh = self.shell.user_ns['_dh']
2770 2801 # first search only by basename (last component)
2771 2802 for ent in reversed(dh):
2772 2803 if pat in os.path.basename(ent) and os.path.isdir(ent):
2773 2804 ps = ent
2774 2805 break
2775 2806
2776 2807 if fallback is None and pat in ent and os.path.isdir(ent):
2777 2808 fallback = ent
2778 2809
2779 2810 # if we have no last part match, pick the first full path match
2780 2811 if ps is None:
2781 2812 ps = fallback
2782 2813
2783 2814 if ps is None:
2784 2815 print "No matching entry in directory history"
2785 2816 return
2786 2817 else:
2787 2818 opts = {}
2788 2819
2789 2820
2790 2821 else:
2791 2822 #turn all non-space-escaping backslashes to slashes,
2792 2823 # for c:\windows\directory\names\
2793 2824 parameter_s = re.sub(r'\\(?! )','/', parameter_s)
2794 2825 opts,ps = self.parse_options(parameter_s,'qb',mode='string')
2795 2826 # jump to previous
2796 2827 if ps == '-':
2797 2828 try:
2798 2829 ps = self.shell.user_ns['_dh'][-2]
2799 2830 except IndexError:
2800 2831 raise UsageError('%cd -: No previous directory to change to.')
2801 2832 # jump to bookmark if needed
2802 2833 else:
2803 2834 if not os.path.isdir(ps) or opts.has_key('b'):
2804 2835 bkms = self.db.get('bookmarks', {})
2805 2836
2806 2837 if bkms.has_key(ps):
2807 2838 target = bkms[ps]
2808 2839 print '(bookmark:%s) -> %s' % (ps,target)
2809 2840 ps = target
2810 2841 else:
2811 2842 if opts.has_key('b'):
2812 2843 raise UsageError("Bookmark '%s' not found. "
2813 2844 "Use '%%bookmark -l' to see your bookmarks." % ps)
2814 2845
2815 2846 # at this point ps should point to the target dir
2816 2847 if ps:
2817 2848 try:
2818 2849 os.chdir(os.path.expanduser(ps))
2819 2850 if self.shell.rc.term_title:
2820 2851 #print 'set term title:',self.shell.rc.term_title # dbg
2821 2852 platutils.set_term_title('IPy ' + abbrev_cwd())
2822 2853 except OSError:
2823 2854 print sys.exc_info()[1]
2824 2855 else:
2825 2856 cwd = os.getcwd()
2826 2857 dhist = self.shell.user_ns['_dh']
2827 2858 if oldcwd != cwd:
2828 2859 dhist.append(cwd)
2829 2860 self.db['dhist'] = compress_dhist(dhist)[-100:]
2830 2861
2831 2862 else:
2832 2863 os.chdir(self.shell.home_dir)
2833 2864 if self.shell.rc.term_title:
2834 2865 platutils.set_term_title("IPy ~")
2835 2866 cwd = os.getcwd()
2836 2867 dhist = self.shell.user_ns['_dh']
2837 2868
2838 2869 if oldcwd != cwd:
2839 2870 dhist.append(cwd)
2840 2871 self.db['dhist'] = compress_dhist(dhist)[-100:]
2841 2872 if not 'q' in opts and self.shell.user_ns['_dh']:
2842 2873 print self.shell.user_ns['_dh'][-1]
2843 2874
2844 2875
2845 2876 def magic_env(self, parameter_s=''):
2846 2877 """List environment variables."""
2847 2878
2848 2879 return os.environ.data
2849 2880
2850 2881 def magic_pushd(self, parameter_s=''):
2851 2882 """Place the current dir on stack and change directory.
2852 2883
2853 2884 Usage:\\
2854 2885 %pushd ['dirname']
2855 2886 """
2856 2887
2857 2888 dir_s = self.shell.dir_stack
2858 2889 tgt = os.path.expanduser(parameter_s)
2859 2890 cwd = os.getcwd().replace(self.home_dir,'~')
2860 2891 if tgt:
2861 2892 self.magic_cd(parameter_s)
2862 2893 dir_s.insert(0,cwd)
2863 2894 return self.magic_dirs()
2864 2895
2865 2896 def magic_popd(self, parameter_s=''):
2866 2897 """Change to directory popped off the top of the stack.
2867 2898 """
2868 2899 if not self.shell.dir_stack:
2869 2900 raise UsageError("%popd on empty stack")
2870 2901 top = self.shell.dir_stack.pop(0)
2871 2902 self.magic_cd(top)
2872 2903 print "popd ->",top
2873 2904
2874 2905 def magic_dirs(self, parameter_s=''):
2875 2906 """Return the current directory stack."""
2876 2907
2877 2908 return self.shell.dir_stack
2878 2909
2879 2910 def magic_dhist(self, parameter_s=''):
2880 2911 """Print your history of visited directories.
2881 2912
2882 2913 %dhist -> print full history\\
2883 2914 %dhist n -> print last n entries only\\
2884 2915 %dhist n1 n2 -> print entries between n1 and n2 (n1 not included)\\
2885 2916
2886 2917 This history is automatically maintained by the %cd command, and
2887 2918 always available as the global list variable _dh. You can use %cd -<n>
2888 2919 to go to directory number <n>.
2889 2920
2890 2921 Note that most of time, you should view directory history by entering
2891 2922 cd -<TAB>.
2892 2923
2893 2924 """
2894 2925
2895 2926 dh = self.shell.user_ns['_dh']
2896 2927 if parameter_s:
2897 2928 try:
2898 2929 args = map(int,parameter_s.split())
2899 2930 except:
2900 2931 self.arg_err(Magic.magic_dhist)
2901 2932 return
2902 2933 if len(args) == 1:
2903 2934 ini,fin = max(len(dh)-(args[0]),0),len(dh)
2904 2935 elif len(args) == 2:
2905 2936 ini,fin = args
2906 2937 else:
2907 2938 self.arg_err(Magic.magic_dhist)
2908 2939 return
2909 2940 else:
2910 2941 ini,fin = 0,len(dh)
2911 2942 nlprint(dh,
2912 2943 header = 'Directory history (kept in _dh)',
2913 2944 start=ini,stop=fin)
2914 2945
2915 2946 @testdec.skip_doctest
2916 2947 def magic_sc(self, parameter_s=''):
2917 2948 """Shell capture - execute a shell command and capture its output.
2918 2949
2919 2950 DEPRECATED. Suboptimal, retained for backwards compatibility.
2920 2951
2921 2952 You should use the form 'var = !command' instead. Example:
2922 2953
2923 2954 "%sc -l myfiles = ls ~" should now be written as
2924 2955
2925 2956 "myfiles = !ls ~"
2926 2957
2927 2958 myfiles.s, myfiles.l and myfiles.n still apply as documented
2928 2959 below.
2929 2960
2930 2961 --
2931 2962 %sc [options] varname=command
2932 2963
2933 2964 IPython will run the given command using commands.getoutput(), and
2934 2965 will then update the user's interactive namespace with a variable
2935 2966 called varname, containing the value of the call. Your command can
2936 2967 contain shell wildcards, pipes, etc.
2937 2968
2938 2969 The '=' sign in the syntax is mandatory, and the variable name you
2939 2970 supply must follow Python's standard conventions for valid names.
2940 2971
2941 2972 (A special format without variable name exists for internal use)
2942 2973
2943 2974 Options:
2944 2975
2945 2976 -l: list output. Split the output on newlines into a list before
2946 2977 assigning it to the given variable. By default the output is stored
2947 2978 as a single string.
2948 2979
2949 2980 -v: verbose. Print the contents of the variable.
2950 2981
2951 2982 In most cases you should not need to split as a list, because the
2952 2983 returned value is a special type of string which can automatically
2953 2984 provide its contents either as a list (split on newlines) or as a
2954 2985 space-separated string. These are convenient, respectively, either
2955 2986 for sequential processing or to be passed to a shell command.
2956 2987
2957 2988 For example:
2958 2989
2959 2990 # all-random
2960 2991
2961 2992 # Capture into variable a
2962 2993 In [1]: sc a=ls *py
2963 2994
2964 2995 # a is a string with embedded newlines
2965 2996 In [2]: a
2966 2997 Out[2]: 'setup.py\\nwin32_manual_post_install.py'
2967 2998
2968 2999 # which can be seen as a list:
2969 3000 In [3]: a.l
2970 3001 Out[3]: ['setup.py', 'win32_manual_post_install.py']
2971 3002
2972 3003 # or as a whitespace-separated string:
2973 3004 In [4]: a.s
2974 3005 Out[4]: 'setup.py win32_manual_post_install.py'
2975 3006
2976 3007 # a.s is useful to pass as a single command line:
2977 3008 In [5]: !wc -l $a.s
2978 3009 146 setup.py
2979 3010 130 win32_manual_post_install.py
2980 3011 276 total
2981 3012
2982 3013 # while the list form is useful to loop over:
2983 3014 In [6]: for f in a.l:
2984 3015 ...: !wc -l $f
2985 3016 ...:
2986 3017 146 setup.py
2987 3018 130 win32_manual_post_install.py
2988 3019
2989 3020 Similiarly, the lists returned by the -l option are also special, in
2990 3021 the sense that you can equally invoke the .s attribute on them to
2991 3022 automatically get a whitespace-separated string from their contents:
2992 3023
2993 3024 In [7]: sc -l b=ls *py
2994 3025
2995 3026 In [8]: b
2996 3027 Out[8]: ['setup.py', 'win32_manual_post_install.py']
2997 3028
2998 3029 In [9]: b.s
2999 3030 Out[9]: 'setup.py win32_manual_post_install.py'
3000 3031
3001 3032 In summary, both the lists and strings used for ouptut capture have
3002 3033 the following special attributes:
3003 3034
3004 3035 .l (or .list) : value as list.
3005 3036 .n (or .nlstr): value as newline-separated string.
3006 3037 .s (or .spstr): value as space-separated string.
3007 3038 """
3008 3039
3009 3040 opts,args = self.parse_options(parameter_s,'lv')
3010 3041 # Try to get a variable name and command to run
3011 3042 try:
3012 3043 # the variable name must be obtained from the parse_options
3013 3044 # output, which uses shlex.split to strip options out.
3014 3045 var,_ = args.split('=',1)
3015 3046 var = var.strip()
3016 3047 # But the the command has to be extracted from the original input
3017 3048 # parameter_s, not on what parse_options returns, to avoid the
3018 3049 # quote stripping which shlex.split performs on it.
3019 3050 _,cmd = parameter_s.split('=',1)
3020 3051 except ValueError:
3021 3052 var,cmd = '',''
3022 3053 # If all looks ok, proceed
3023 3054 out,err = self.shell.getoutputerror(cmd)
3024 3055 if err:
3025 3056 print >> Term.cerr,err
3026 3057 if opts.has_key('l'):
3027 3058 out = SList(out.split('\n'))
3028 3059 else:
3029 3060 out = LSString(out)
3030 3061 if opts.has_key('v'):
3031 3062 print '%s ==\n%s' % (var,pformat(out))
3032 3063 if var:
3033 3064 self.shell.user_ns.update({var:out})
3034 3065 else:
3035 3066 return out
3036 3067
3037 3068 def magic_sx(self, parameter_s=''):
3038 3069 """Shell execute - run a shell command and capture its output.
3039 3070
3040 3071 %sx command
3041 3072
3042 3073 IPython will run the given command using commands.getoutput(), and
3043 3074 return the result formatted as a list (split on '\\n'). Since the
3044 3075 output is _returned_, it will be stored in ipython's regular output
3045 3076 cache Out[N] and in the '_N' automatic variables.
3046 3077
3047 3078 Notes:
3048 3079
3049 3080 1) If an input line begins with '!!', then %sx is automatically
3050 3081 invoked. That is, while:
3051 3082 !ls
3052 3083 causes ipython to simply issue system('ls'), typing
3053 3084 !!ls
3054 3085 is a shorthand equivalent to:
3055 3086 %sx ls
3056 3087
3057 3088 2) %sx differs from %sc in that %sx automatically splits into a list,
3058 3089 like '%sc -l'. The reason for this is to make it as easy as possible
3059 3090 to process line-oriented shell output via further python commands.
3060 3091 %sc is meant to provide much finer control, but requires more
3061 3092 typing.
3062 3093
3063 3094 3) Just like %sc -l, this is a list with special attributes:
3064 3095
3065 3096 .l (or .list) : value as list.
3066 3097 .n (or .nlstr): value as newline-separated string.
3067 3098 .s (or .spstr): value as whitespace-separated string.
3068 3099
3069 3100 This is very useful when trying to use such lists as arguments to
3070 3101 system commands."""
3071 3102
3072 3103 if parameter_s:
3073 3104 out,err = self.shell.getoutputerror(parameter_s)
3074 3105 if err:
3075 3106 print >> Term.cerr,err
3076 3107 return SList(out.split('\n'))
3077 3108
3078 3109 def magic_bg(self, parameter_s=''):
3079 3110 """Run a job in the background, in a separate thread.
3080 3111
3081 3112 For example,
3082 3113
3083 3114 %bg myfunc(x,y,z=1)
3084 3115
3085 3116 will execute 'myfunc(x,y,z=1)' in a background thread. As soon as the
3086 3117 execution starts, a message will be printed indicating the job
3087 3118 number. If your job number is 5, you can use
3088 3119
3089 3120 myvar = jobs.result(5) or myvar = jobs[5].result
3090 3121
3091 3122 to assign this result to variable 'myvar'.
3092 3123
3093 3124 IPython has a job manager, accessible via the 'jobs' object. You can
3094 3125 type jobs? to get more information about it, and use jobs.<TAB> to see
3095 3126 its attributes. All attributes not starting with an underscore are
3096 3127 meant for public use.
3097 3128
3098 3129 In particular, look at the jobs.new() method, which is used to create
3099 3130 new jobs. This magic %bg function is just a convenience wrapper
3100 3131 around jobs.new(), for expression-based jobs. If you want to create a
3101 3132 new job with an explicit function object and arguments, you must call
3102 3133 jobs.new() directly.
3103 3134
3104 3135 The jobs.new docstring also describes in detail several important
3105 3136 caveats associated with a thread-based model for background job
3106 3137 execution. Type jobs.new? for details.
3107 3138
3108 3139 You can check the status of all jobs with jobs.status().
3109 3140
3110 3141 The jobs variable is set by IPython into the Python builtin namespace.
3111 3142 If you ever declare a variable named 'jobs', you will shadow this
3112 3143 name. You can either delete your global jobs variable to regain
3113 3144 access to the job manager, or make a new name and assign it manually
3114 3145 to the manager (stored in IPython's namespace). For example, to
3115 3146 assign the job manager to the Jobs name, use:
3116 3147
3117 3148 Jobs = __builtins__.jobs"""
3118 3149
3119 3150 self.shell.jobs.new(parameter_s,self.shell.user_ns)
3120 3151
3121 3152 def magic_r(self, parameter_s=''):
3122 3153 """Repeat previous input.
3123 3154
3124 3155 Note: Consider using the more powerfull %rep instead!
3125 3156
3126 3157 If given an argument, repeats the previous command which starts with
3127 3158 the same string, otherwise it just repeats the previous input.
3128 3159
3129 3160 Shell escaped commands (with ! as first character) are not recognized
3130 3161 by this system, only pure python code and magic commands.
3131 3162 """
3132 3163
3133 3164 start = parameter_s.strip()
3134 3165 esc_magic = self.shell.ESC_MAGIC
3135 3166 # Identify magic commands even if automagic is on (which means
3136 3167 # the in-memory version is different from that typed by the user).
3137 3168 if self.shell.rc.automagic:
3138 3169 start_magic = esc_magic+start
3139 3170 else:
3140 3171 start_magic = start
3141 3172 # Look through the input history in reverse
3142 3173 for n in range(len(self.shell.input_hist)-2,0,-1):
3143 3174 input = self.shell.input_hist[n]
3144 3175 # skip plain 'r' lines so we don't recurse to infinity
3145 3176 if input != '_ip.magic("r")\n' and \
3146 3177 (input.startswith(start) or input.startswith(start_magic)):
3147 3178 #print 'match',`input` # dbg
3148 3179 print 'Executing:',input,
3149 3180 self.shell.runlines(input)
3150 3181 return
3151 3182 print 'No previous input matching `%s` found.' % start
3152 3183
3153 3184
3154 3185 def magic_bookmark(self, parameter_s=''):
3155 3186 """Manage IPython's bookmark system.
3156 3187
3157 3188 %bookmark <name> - set bookmark to current dir
3158 3189 %bookmark <name> <dir> - set bookmark to <dir>
3159 3190 %bookmark -l - list all bookmarks
3160 3191 %bookmark -d <name> - remove bookmark
3161 3192 %bookmark -r - remove all bookmarks
3162 3193
3163 3194 You can later on access a bookmarked folder with:
3164 3195 %cd -b <name>
3165 3196 or simply '%cd <name>' if there is no directory called <name> AND
3166 3197 there is such a bookmark defined.
3167 3198
3168 3199 Your bookmarks persist through IPython sessions, but they are
3169 3200 associated with each profile."""
3170 3201
3171 3202 opts,args = self.parse_options(parameter_s,'drl',mode='list')
3172 3203 if len(args) > 2:
3173 3204 raise UsageError("%bookmark: too many arguments")
3174 3205
3175 3206 bkms = self.db.get('bookmarks',{})
3176 3207
3177 3208 if opts.has_key('d'):
3178 3209 try:
3179 3210 todel = args[0]
3180 3211 except IndexError:
3181 3212 raise UsageError(
3182 3213 "%bookmark -d: must provide a bookmark to delete")
3183 3214 else:
3184 3215 try:
3185 3216 del bkms[todel]
3186 3217 except KeyError:
3187 3218 raise UsageError(
3188 3219 "%%bookmark -d: Can't delete bookmark '%s'" % todel)
3189 3220
3190 3221 elif opts.has_key('r'):
3191 3222 bkms = {}
3192 3223 elif opts.has_key('l'):
3193 3224 bks = bkms.keys()
3194 3225 bks.sort()
3195 3226 if bks:
3196 3227 size = max(map(len,bks))
3197 3228 else:
3198 3229 size = 0
3199 3230 fmt = '%-'+str(size)+'s -> %s'
3200 3231 print 'Current bookmarks:'
3201 3232 for bk in bks:
3202 3233 print fmt % (bk,bkms[bk])
3203 3234 else:
3204 3235 if not args:
3205 3236 raise UsageError("%bookmark: You must specify the bookmark name")
3206 3237 elif len(args)==1:
3207 3238 bkms[args[0]] = os.getcwd()
3208 3239 elif len(args)==2:
3209 3240 bkms[args[0]] = args[1]
3210 3241 self.db['bookmarks'] = bkms
3211 3242
3212 3243 def magic_pycat(self, parameter_s=''):
3213 3244 """Show a syntax-highlighted file through a pager.
3214 3245
3215 3246 This magic is similar to the cat utility, but it will assume the file
3216 3247 to be Python source and will show it with syntax highlighting. """
3217 3248
3218 3249 try:
3219 3250 filename = get_py_filename(parameter_s)
3220 3251 cont = file_read(filename)
3221 3252 except IOError:
3222 3253 try:
3223 3254 cont = eval(parameter_s,self.user_ns)
3224 3255 except NameError:
3225 3256 cont = None
3226 3257 if cont is None:
3227 3258 print "Error: no such file or variable"
3228 3259 return
3229 3260
3230 3261 page(self.shell.pycolorize(cont),
3231 3262 screen_lines=self.shell.rc.screen_length)
3232 3263
3233 3264 def magic_cpaste(self, parameter_s=''):
3234 3265 """Allows you to paste & execute a pre-formatted code block from clipboard.
3235 3266
3236 3267 You must terminate the block with '--' (two minus-signs) alone on the
3237 3268 line. You can also provide your own sentinel with '%paste -s %%' ('%%'
3238 3269 is the new sentinel for this operation)
3239 3270
3240 3271 The block is dedented prior to execution to enable execution of method
3241 3272 definitions. '>' and '+' characters at the beginning of a line are
3242 3273 ignored, to allow pasting directly from e-mails, diff files and
3243 3274 doctests (the '...' continuation prompt is also stripped). The
3244 3275 executed block is also assigned to variable named 'pasted_block' for
3245 3276 later editing with '%edit pasted_block'.
3246 3277
3247 3278 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
3248 3279 This assigns the pasted block to variable 'foo' as string, without
3249 3280 dedenting or executing it (preceding >>> and + is still stripped)
3250 3281
3251 3282 '%cpaste -r' re-executes the block previously entered by cpaste.
3252 3283
3253 3284 Do not be alarmed by garbled output on Windows (it's a readline bug).
3254 3285 Just press enter and type -- (and press enter again) and the block
3255 3286 will be what was just pasted.
3256 3287
3257 3288 IPython statements (magics, shell escapes) are not supported (yet).
3258 3289 """
3259 3290 opts,args = self.parse_options(parameter_s,'rs:',mode='string')
3260 3291 par = args.strip()
3261 3292 if opts.has_key('r'):
3262 3293 b = self.user_ns.get('pasted_block', None)
3263 3294 if b is None:
3264 3295 raise UsageError('No previous pasted block available')
3265 3296 print "Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b))
3266 3297 exec b in self.user_ns
3267 3298 return
3268 3299
3269 3300 sentinel = opts.get('s','--')
3270 3301
3271 3302 # Regular expressions that declare text we strip from the input:
3272 3303 strip_re = [r'^\s*In \[\d+\]:', # IPython input prompt
3273 3304 r'^\s*(\s?>)+', # Python input prompt
3274 3305 r'^\s*\.{3,}', # Continuation prompts
3275 3306 r'^\++',
3276 3307 ]
3277 3308
3278 3309 strip_from_start = map(re.compile,strip_re)
3279 3310
3280 3311 from IPython import iplib
3281 3312 lines = []
3282 3313 print "Pasting code; enter '%s' alone on the line to stop." % sentinel
3283 3314 while 1:
3284 3315 l = iplib.raw_input_original(':')
3285 3316 if l ==sentinel:
3286 3317 break
3287 3318
3288 3319 for pat in strip_from_start:
3289 3320 l = pat.sub('',l)
3290 3321 lines.append(l)
3291 3322
3292 3323 block = "\n".join(lines) + '\n'
3293 3324 #print "block:\n",block
3294 3325 if not par:
3295 3326 b = textwrap.dedent(block)
3296 3327 self.user_ns['pasted_block'] = b
3297 3328 exec b in self.user_ns
3298 3329 else:
3299 3330 self.user_ns[par] = SList(block.splitlines())
3300 3331 print "Block assigned to '%s'" % par
3301 3332
3302 3333 def magic_quickref(self,arg):
3303 3334 """ Show a quick reference sheet """
3304 3335 import IPython.usage
3305 3336 qr = IPython.usage.quick_reference + self.magic_magic('-brief')
3306 3337
3307 3338 page(qr)
3308 3339
3309 3340 def magic_upgrade(self,arg):
3310 3341 """ Upgrade your IPython installation
3311 3342
3312 3343 This will copy the config files that don't yet exist in your
3313 3344 ipython dir from the system config dir. Use this after upgrading
3314 3345 IPython if you don't wish to delete your .ipython dir.
3315 3346
3316 3347 Call with -nolegacy to get rid of ipythonrc* files (recommended for
3317 3348 new users)
3318 3349
3319 3350 """
3320 3351 ip = self.getapi()
3321 3352 ipinstallation = path(IPython.__file__).dirname()
3322 3353 upgrade_script = '%s "%s"' % (sys.executable,ipinstallation / 'upgrade_dir.py')
3323 3354 src_config = ipinstallation / 'UserConfig'
3324 3355 userdir = path(ip.options.ipythondir)
3325 3356 cmd = '%s "%s" "%s"' % (upgrade_script, src_config, userdir)
3326 3357 print ">",cmd
3327 3358 shell(cmd)
3328 3359 if arg == '-nolegacy':
3329 3360 legacy = userdir.files('ipythonrc*')
3330 3361 print "Nuking legacy files:",legacy
3331 3362
3332 3363 [p.remove() for p in legacy]
3333 3364 suffix = (sys.platform == 'win32' and '.ini' or '')
3334 3365 (userdir / ('ipythonrc' + suffix)).write_text('# Empty, see ipy_user_conf.py\n')
3335 3366
3336 3367
3337 3368 def magic_doctest_mode(self,parameter_s=''):
3338 3369 """Toggle doctest mode on and off.
3339 3370
3340 3371 This mode allows you to toggle the prompt behavior between normal
3341 3372 IPython prompts and ones that are as similar to the default IPython
3342 3373 interpreter as possible.
3343 3374
3344 3375 It also supports the pasting of code snippets that have leading '>>>'
3345 3376 and '...' prompts in them. This means that you can paste doctests from
3346 3377 files or docstrings (even if they have leading whitespace), and the
3347 3378 code will execute correctly. You can then use '%history -tn' to see
3348 3379 the translated history without line numbers; this will give you the
3349 3380 input after removal of all the leading prompts and whitespace, which
3350 3381 can be pasted back into an editor.
3351 3382
3352 3383 With these features, you can switch into this mode easily whenever you
3353 3384 need to do testing and changes to doctests, without having to leave
3354 3385 your existing IPython session.
3355 3386 """
3356 3387
3357 3388 # XXX - Fix this to have cleaner activate/deactivate calls.
3358 3389 from IPython.Extensions import InterpreterPasteInput as ipaste
3359 3390 from IPython.ipstruct import Struct
3360 3391
3361 3392 # Shorthands
3362 3393 shell = self.shell
3363 3394 oc = shell.outputcache
3364 3395 rc = shell.rc
3365 3396 meta = shell.meta
3366 3397 # dstore is a data store kept in the instance metadata bag to track any
3367 3398 # changes we make, so we can undo them later.
3368 3399 dstore = meta.setdefault('doctest_mode',Struct())
3369 3400 save_dstore = dstore.setdefault
3370 3401
3371 3402 # save a few values we'll need to recover later
3372 3403 mode = save_dstore('mode',False)
3373 3404 save_dstore('rc_pprint',rc.pprint)
3374 3405 save_dstore('xmode',shell.InteractiveTB.mode)
3375 3406 save_dstore('rc_separate_out',rc.separate_out)
3376 3407 save_dstore('rc_separate_out2',rc.separate_out2)
3377 3408 save_dstore('rc_prompts_pad_left',rc.prompts_pad_left)
3378 3409 save_dstore('rc_separate_in',rc.separate_in)
3379 3410
3380 3411 if mode == False:
3381 3412 # turn on
3382 3413 ipaste.activate_prefilter()
3383 3414
3384 3415 oc.prompt1.p_template = '>>> '
3385 3416 oc.prompt2.p_template = '... '
3386 3417 oc.prompt_out.p_template = ''
3387 3418
3388 3419 # Prompt separators like plain python
3389 3420 oc.input_sep = oc.prompt1.sep = ''
3390 3421 oc.output_sep = ''
3391 3422 oc.output_sep2 = ''
3392 3423
3393 3424 oc.prompt1.pad_left = oc.prompt2.pad_left = \
3394 3425 oc.prompt_out.pad_left = False
3395 3426
3396 3427 rc.pprint = False
3397 3428
3398 3429 shell.magic_xmode('Plain')
3399 3430
3400 3431 else:
3401 3432 # turn off
3402 3433 ipaste.deactivate_prefilter()
3403 3434
3404 3435 oc.prompt1.p_template = rc.prompt_in1
3405 3436 oc.prompt2.p_template = rc.prompt_in2
3406 3437 oc.prompt_out.p_template = rc.prompt_out
3407 3438
3408 3439 oc.input_sep = oc.prompt1.sep = dstore.rc_separate_in
3409 3440
3410 3441 oc.output_sep = dstore.rc_separate_out
3411 3442 oc.output_sep2 = dstore.rc_separate_out2
3412 3443
3413 3444 oc.prompt1.pad_left = oc.prompt2.pad_left = \
3414 3445 oc.prompt_out.pad_left = dstore.rc_prompts_pad_left
3415 3446
3416 3447 rc.pprint = dstore.rc_pprint
3417 3448
3418 3449 shell.magic_xmode(dstore.xmode)
3419 3450
3420 3451 # Store new mode and inform
3421 3452 dstore.mode = bool(1-int(mode))
3422 3453 print 'Doctest mode is:',
3423 3454 print ['OFF','ON'][dstore.mode]
3424 3455
3425 3456 # end Magic
@@ -1,622 +1,626 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 Classes for handling input/output prompts.
4 4 """
5 5
6 6 #*****************************************************************************
7 7 # Copyright (C) 2008-2009 The IPython Development Team
8 8 # Copyright (C) 2001-2007 Fernando Perez <fperez@colorado.edu>
9 9 #
10 10 # Distributed under the terms of the BSD License. The full license is in
11 11 # the file COPYING, distributed as part of this software.
12 12 #*****************************************************************************
13 13
14 14 #****************************************************************************
15 15 # Required modules
16 16 import __builtin__
17 17 import os
18 18 import socket
19 19 import sys
20 20 import time
21 21
22 22 # IPython's own
23 23 from IPython import ColorANSI
24 24 from IPython import Release
25 25 from IPython.external.Itpl import ItplNS
26 26 from IPython.ipapi import TryNext
27 27 from IPython.ipstruct import Struct
28 28 from IPython.macro import Macro
29 29
30 30 from IPython.genutils import *
31 31
32 32 #****************************************************************************
33 33 #Color schemes for Prompts.
34 34
35 35 PromptColors = ColorANSI.ColorSchemeTable()
36 36 InputColors = ColorANSI.InputTermColors # just a shorthand
37 37 Colors = ColorANSI.TermColors # just a shorthand
38 38
39 39 PromptColors.add_scheme(ColorANSI.ColorScheme(
40 40 'NoColor',
41 41 in_prompt = InputColors.NoColor, # Input prompt
42 42 in_number = InputColors.NoColor, # Input prompt number
43 43 in_prompt2 = InputColors.NoColor, # Continuation prompt
44 44 in_normal = InputColors.NoColor, # color off (usu. Colors.Normal)
45 45
46 46 out_prompt = Colors.NoColor, # Output prompt
47 47 out_number = Colors.NoColor, # Output prompt number
48 48
49 49 normal = Colors.NoColor # color off (usu. Colors.Normal)
50 50 ))
51 51
52 52 # make some schemes as instances so we can copy them for modification easily:
53 53 __PColLinux = ColorANSI.ColorScheme(
54 54 'Linux',
55 55 in_prompt = InputColors.Green,
56 56 in_number = InputColors.LightGreen,
57 57 in_prompt2 = InputColors.Green,
58 58 in_normal = InputColors.Normal, # color off (usu. Colors.Normal)
59 59
60 60 out_prompt = Colors.Red,
61 61 out_number = Colors.LightRed,
62 62
63 63 normal = Colors.Normal
64 64 )
65 65 # Don't forget to enter it into the table!
66 66 PromptColors.add_scheme(__PColLinux)
67 67
68 68 # Slightly modified Linux for light backgrounds
69 69 __PColLightBG = __PColLinux.copy('LightBG')
70 70
71 71 __PColLightBG.colors.update(
72 72 in_prompt = InputColors.Blue,
73 73 in_number = InputColors.LightBlue,
74 74 in_prompt2 = InputColors.Blue
75 75 )
76 76 PromptColors.add_scheme(__PColLightBG)
77 77
78 78 del Colors,InputColors
79 79
80 80 #-----------------------------------------------------------------------------
81 81 def multiple_replace(dict, text):
82 82 """ Replace in 'text' all occurences of any key in the given
83 83 dictionary by its corresponding value. Returns the new string."""
84 84
85 85 # Function by Xavier Defrang, originally found at:
86 86 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81330
87 87
88 88 # Create a regular expression from the dictionary keys
89 89 regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys())))
90 90 # For each match, look-up corresponding value in dictionary
91 91 return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text)
92 92
93 93 #-----------------------------------------------------------------------------
94 94 # Special characters that can be used in prompt templates, mainly bash-like
95 95
96 96 # If $HOME isn't defined (Windows), make it an absurd string so that it can
97 97 # never be expanded out into '~'. Basically anything which can never be a
98 98 # reasonable directory name will do, we just want the $HOME -> '~' operation
99 99 # to become a no-op. We pre-compute $HOME here so it's not done on every
100 100 # prompt call.
101 101
102 102 # FIXME:
103 103
104 104 # - This should be turned into a class which does proper namespace management,
105 105 # since the prompt specials need to be evaluated in a certain namespace.
106 106 # Currently it's just globals, which need to be managed manually by code
107 107 # below.
108 108
109 109 # - I also need to split up the color schemes from the prompt specials
110 110 # somehow. I don't have a clean design for that quite yet.
111 111
112 112 HOME = os.environ.get("HOME","//////:::::ZZZZZ,,,~~~")
113 113
114 114 # We precompute a few more strings here for the prompt_specials, which are
115 115 # fixed once ipython starts. This reduces the runtime overhead of computing
116 116 # prompt strings.
117 117 USER = os.environ.get("USER")
118 118 HOSTNAME = socket.gethostname()
119 119 HOSTNAME_SHORT = HOSTNAME.split(".")[0]
120 120 ROOT_SYMBOL = "$#"[os.name=='nt' or os.getuid()==0]
121 121
122 122 prompt_specials_color = {
123 123 # Prompt/history count
124 124 '%n' : '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
125 125 r'\#': '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
126 126 # Just the prompt counter number, WITHOUT any coloring wrappers, so users
127 127 # can get numbers displayed in whatever color they want.
128 128 r'\N': '${self.cache.prompt_count}',
129
129 130 # Prompt/history count, with the actual digits replaced by dots. Used
130 131 # mainly in continuation prompts (prompt_in2)
131 r'\D': '${"."*len(str(self.cache.prompt_count))}',
132 #r'\D': '${"."*len(str(self.cache.prompt_count))}',
133 # More robust form of the above expression, that uses __builtins__
134 r'\D': '${"."*__builtins__.len(__builtins__.str(self.cache.prompt_count))}',
135
132 136 # Current working directory
133 137 r'\w': '${os.getcwd()}',
134 138 # Current time
135 139 r'\t' : '${time.strftime("%H:%M:%S")}',
136 140 # Basename of current working directory.
137 141 # (use os.sep to make this portable across OSes)
138 142 r'\W' : '${os.getcwd().split("%s")[-1]}' % os.sep,
139 143 # These X<N> are an extension to the normal bash prompts. They return
140 144 # N terms of the path, after replacing $HOME with '~'
141 145 r'\X0': '${os.getcwd().replace("%s","~")}' % HOME,
142 146 r'\X1': '${self.cwd_filt(1)}',
143 147 r'\X2': '${self.cwd_filt(2)}',
144 148 r'\X3': '${self.cwd_filt(3)}',
145 149 r'\X4': '${self.cwd_filt(4)}',
146 150 r'\X5': '${self.cwd_filt(5)}',
147 151 # Y<N> are similar to X<N>, but they show '~' if it's the directory
148 152 # N+1 in the list. Somewhat like %cN in tcsh.
149 153 r'\Y0': '${self.cwd_filt2(0)}',
150 154 r'\Y1': '${self.cwd_filt2(1)}',
151 155 r'\Y2': '${self.cwd_filt2(2)}',
152 156 r'\Y3': '${self.cwd_filt2(3)}',
153 157 r'\Y4': '${self.cwd_filt2(4)}',
154 158 r'\Y5': '${self.cwd_filt2(5)}',
155 159 # Hostname up to first .
156 160 r'\h': HOSTNAME_SHORT,
157 161 # Full hostname
158 162 r'\H': HOSTNAME,
159 163 # Username of current user
160 164 r'\u': USER,
161 165 # Escaped '\'
162 166 '\\\\': '\\',
163 167 # Newline
164 168 r'\n': '\n',
165 169 # Carriage return
166 170 r'\r': '\r',
167 171 # Release version
168 172 r'\v': Release.version,
169 173 # Root symbol ($ or #)
170 174 r'\$': ROOT_SYMBOL,
171 175 }
172 176
173 177 # A copy of the prompt_specials dictionary but with all color escapes removed,
174 178 # so we can correctly compute the prompt length for the auto_rewrite method.
175 179 prompt_specials_nocolor = prompt_specials_color.copy()
176 180 prompt_specials_nocolor['%n'] = '${self.cache.prompt_count}'
177 181 prompt_specials_nocolor[r'\#'] = '${self.cache.prompt_count}'
178 182
179 183 # Add in all the InputTermColors color escapes as valid prompt characters.
180 184 # They all get added as \\C_COLORNAME, so that we don't have any conflicts
181 185 # with a color name which may begin with a letter used by any other of the
182 186 # allowed specials. This of course means that \\C will never be allowed for
183 187 # anything else.
184 188 input_colors = ColorANSI.InputTermColors
185 189 for _color in dir(input_colors):
186 190 if _color[0] != '_':
187 191 c_name = r'\C_'+_color
188 192 prompt_specials_color[c_name] = getattr(input_colors,_color)
189 193 prompt_specials_nocolor[c_name] = ''
190 194
191 195 # we default to no color for safety. Note that prompt_specials is a global
192 196 # variable used by all prompt objects.
193 197 prompt_specials = prompt_specials_nocolor
194 198
195 199 #-----------------------------------------------------------------------------
196 200 def str_safe(arg):
197 201 """Convert to a string, without ever raising an exception.
198 202
199 203 If str(arg) fails, <ERROR: ... > is returned, where ... is the exception
200 204 error message."""
201 205
202 206 try:
203 207 out = str(arg)
204 208 except UnicodeError:
205 209 try:
206 210 out = arg.encode('utf_8','replace')
207 211 except Exception,msg:
208 212 # let's keep this little duplication here, so that the most common
209 213 # case doesn't suffer from a double try wrapping.
210 214 out = '<ERROR: %s>' % msg
211 215 except Exception,msg:
212 216 out = '<ERROR: %s>' % msg
213 217 return out
214 218
215 219 class BasePrompt(object):
216 220 """Interactive prompt similar to Mathematica's."""
217 221
218 222 def _get_p_template(self):
219 223 return self._p_template
220 224
221 225 def _set_p_template(self,val):
222 226 self._p_template = val
223 227 self.set_p_str()
224 228
225 229 p_template = property(_get_p_template,_set_p_template,
226 230 doc='Template for prompt string creation')
227 231
228 232 def __init__(self,cache,sep,prompt,pad_left=False):
229 233
230 234 # Hack: we access information about the primary prompt through the
231 235 # cache argument. We need this, because we want the secondary prompt
232 236 # to be aligned with the primary one. Color table info is also shared
233 237 # by all prompt classes through the cache. Nice OO spaghetti code!
234 238 self.cache = cache
235 239 self.sep = sep
236 240
237 241 # regexp to count the number of spaces at the end of a prompt
238 242 # expression, useful for prompt auto-rewriting
239 243 self.rspace = re.compile(r'(\s*)$')
240 244 # Flag to left-pad prompt strings to match the length of the primary
241 245 # prompt
242 246 self.pad_left = pad_left
243 247
244 248 # Set template to create each actual prompt (where numbers change).
245 249 # Use a property
246 250 self.p_template = prompt
247 251 self.set_p_str()
248 252
249 253 def set_p_str(self):
250 254 """ Set the interpolating prompt strings.
251 255
252 256 This must be called every time the color settings change, because the
253 257 prompt_specials global may have changed."""
254 258
255 259 import os,time # needed in locals for prompt string handling
256 260 loc = locals()
257 261 try:
258 262 self.p_str = ItplNS('%s%s%s' %
259 263 ('${self.sep}${self.col_p}',
260 264 multiple_replace(prompt_specials, self.p_template),
261 265 '${self.col_norm}'),self.cache.user_ns,loc)
262 266
263 267 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
264 268 self.p_template),
265 269 self.cache.user_ns,loc)
266 270 except:
267 271 print "Illegal prompt template (check $ usage!):",self.p_template
268 272 self.p_str = self.p_template
269 273 self.p_str_nocolor = self.p_template
270 274
271 275 def write(self,msg): # dbg
272 276 sys.stdout.write(msg)
273 277 return ''
274 278
275 279 def __str__(self):
276 280 """Return a string form of the prompt.
277 281
278 282 This for is useful for continuation and output prompts, since it is
279 283 left-padded to match lengths with the primary one (if the
280 284 self.pad_left attribute is set)."""
281 285
282 286 out_str = str_safe(self.p_str)
283 287 if self.pad_left:
284 288 # We must find the amount of padding required to match lengths,
285 289 # taking the color escapes (which are invisible on-screen) into
286 290 # account.
287 291 esc_pad = len(out_str) - len(str_safe(self.p_str_nocolor))
288 292 format = '%%%ss' % (len(str(self.cache.last_prompt))+esc_pad)
289 293 return format % out_str
290 294 else:
291 295 return out_str
292 296
293 297 # these path filters are put in as methods so that we can control the
294 298 # namespace where the prompt strings get evaluated
295 299 def cwd_filt(self,depth):
296 300 """Return the last depth elements of the current working directory.
297 301
298 302 $HOME is always replaced with '~'.
299 303 If depth==0, the full path is returned."""
300 304
301 305 cwd = os.getcwd().replace(HOME,"~")
302 306 out = os.sep.join(cwd.split(os.sep)[-depth:])
303 307 if out:
304 308 return out
305 309 else:
306 310 return os.sep
307 311
308 312 def cwd_filt2(self,depth):
309 313 """Return the last depth elements of the current working directory.
310 314
311 315 $HOME is always replaced with '~'.
312 316 If depth==0, the full path is returned."""
313 317
314 318 full_cwd = os.getcwd()
315 319 cwd = full_cwd.replace(HOME,"~").split(os.sep)
316 320 if '~' in cwd and len(cwd) == depth+1:
317 321 depth += 1
318 322 drivepart = ''
319 323 if sys.platform == 'win32' and len(cwd) > depth:
320 324 drivepart = os.path.splitdrive(full_cwd)[0]
321 325 out = drivepart + '/'.join(cwd[-depth:])
322 326
323 327 if out:
324 328 return out
325 329 else:
326 330 return os.sep
327 331
328 332 def __nonzero__(self):
329 333 """Implement boolean behavior.
330 334
331 335 Checks whether the p_str attribute is non-empty"""
332 336
333 337 return bool(self.p_template)
334 338
335 339 class Prompt1(BasePrompt):
336 340 """Input interactive prompt similar to Mathematica's."""
337 341
338 342 def __init__(self,cache,sep='\n',prompt='In [\\#]: ',pad_left=True):
339 343 BasePrompt.__init__(self,cache,sep,prompt,pad_left)
340 344
341 345 def set_colors(self):
342 346 self.set_p_str()
343 347 Colors = self.cache.color_table.active_colors # shorthand
344 348 self.col_p = Colors.in_prompt
345 349 self.col_num = Colors.in_number
346 350 self.col_norm = Colors.in_normal
347 351 # We need a non-input version of these escapes for the '--->'
348 352 # auto-call prompts used in the auto_rewrite() method.
349 353 self.col_p_ni = self.col_p.replace('\001','').replace('\002','')
350 354 self.col_norm_ni = Colors.normal
351 355
352 356 def __str__(self):
353 357 self.cache.prompt_count += 1
354 358 self.cache.last_prompt = str_safe(self.p_str_nocolor).split('\n')[-1]
355 359 return str_safe(self.p_str)
356 360
357 361 def auto_rewrite(self):
358 362 """Print a string of the form '--->' which lines up with the previous
359 363 input string. Useful for systems which re-write the user input when
360 364 handling automatically special syntaxes."""
361 365
362 366 curr = str(self.cache.last_prompt)
363 367 nrspaces = len(self.rspace.search(curr).group())
364 368 return '%s%s>%s%s' % (self.col_p_ni,'-'*(len(curr)-nrspaces-1),
365 369 ' '*nrspaces,self.col_norm_ni)
366 370
367 371 class PromptOut(BasePrompt):
368 372 """Output interactive prompt similar to Mathematica's."""
369 373
370 374 def __init__(self,cache,sep='',prompt='Out[\\#]: ',pad_left=True):
371 375 BasePrompt.__init__(self,cache,sep,prompt,pad_left)
372 376 if not self.p_template:
373 377 self.__str__ = lambda: ''
374 378
375 379 def set_colors(self):
376 380 self.set_p_str()
377 381 Colors = self.cache.color_table.active_colors # shorthand
378 382 self.col_p = Colors.out_prompt
379 383 self.col_num = Colors.out_number
380 384 self.col_norm = Colors.normal
381 385
382 386 class Prompt2(BasePrompt):
383 387 """Interactive continuation prompt."""
384 388
385 389 def __init__(self,cache,prompt=' .\\D.: ',pad_left=True):
386 390 self.cache = cache
387 391 self.p_template = prompt
388 392 self.pad_left = pad_left
389 393 self.set_p_str()
390 394
391 395 def set_p_str(self):
392 396 import os,time # needed in locals for prompt string handling
393 397 loc = locals()
394 398 self.p_str = ItplNS('%s%s%s' %
395 399 ('${self.col_p2}',
396 400 multiple_replace(prompt_specials, self.p_template),
397 401 '$self.col_norm'),
398 402 self.cache.user_ns,loc)
399 403 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
400 404 self.p_template),
401 405 self.cache.user_ns,loc)
402 406
403 407 def set_colors(self):
404 408 self.set_p_str()
405 409 Colors = self.cache.color_table.active_colors
406 410 self.col_p2 = Colors.in_prompt2
407 411 self.col_norm = Colors.in_normal
408 412 # FIXME (2004-06-16) HACK: prevent crashes for users who haven't
409 413 # updated their prompt_in2 definitions. Remove eventually.
410 414 self.col_p = Colors.out_prompt
411 415 self.col_num = Colors.out_number
412 416
413 417
414 418 #-----------------------------------------------------------------------------
415 419 class CachedOutput:
416 420 """Class for printing output from calculations while keeping a cache of
417 421 reults. It dynamically creates global variables prefixed with _ which
418 422 contain these results.
419 423
420 424 Meant to be used as a sys.displayhook replacement, providing numbered
421 425 prompts and cache services.
422 426
423 427 Initialize with initial and final values for cache counter (this defines
424 428 the maximum size of the cache."""
425 429
426 430 def __init__(self,shell,cache_size,Pprint,
427 431 colors='NoColor',input_sep='\n',
428 432 output_sep='\n',output_sep2='',
429 433 ps1 = None, ps2 = None,ps_out = None,pad_left=True):
430 434
431 435 cache_size_min = 3
432 436 if cache_size <= 0:
433 437 self.do_full_cache = 0
434 438 cache_size = 0
435 439 elif cache_size < cache_size_min:
436 440 self.do_full_cache = 0
437 441 cache_size = 0
438 442 warn('caching was disabled (min value for cache size is %s).' %
439 443 cache_size_min,level=3)
440 444 else:
441 445 self.do_full_cache = 1
442 446
443 447 self.cache_size = cache_size
444 448 self.input_sep = input_sep
445 449
446 450 # we need a reference to the user-level namespace
447 451 self.shell = shell
448 452 self.user_ns = shell.user_ns
449 453 # and to the user's input
450 454 self.input_hist = shell.input_hist
451 455 # and to the user's logger, for logging output
452 456 self.logger = shell.logger
453 457
454 458 # Set input prompt strings and colors
455 459 if cache_size == 0:
456 460 if ps1.find('%n') > -1 or ps1.find(r'\#') > -1 \
457 461 or ps1.find(r'\N') > -1:
458 462 ps1 = '>>> '
459 463 if ps2.find('%n') > -1 or ps2.find(r'\#') > -1 \
460 464 or ps2.find(r'\N') > -1:
461 465 ps2 = '... '
462 466 self.ps1_str = self._set_prompt_str(ps1,'In [\\#]: ','>>> ')
463 467 self.ps2_str = self._set_prompt_str(ps2,' .\\D.: ','... ')
464 468 self.ps_out_str = self._set_prompt_str(ps_out,'Out[\\#]: ','')
465 469
466 470 self.color_table = PromptColors
467 471 self.prompt1 = Prompt1(self,sep=input_sep,prompt=self.ps1_str,
468 472 pad_left=pad_left)
469 473 self.prompt2 = Prompt2(self,prompt=self.ps2_str,pad_left=pad_left)
470 474 self.prompt_out = PromptOut(self,sep='',prompt=self.ps_out_str,
471 475 pad_left=pad_left)
472 476 self.set_colors(colors)
473 477
474 478 # other more normal stuff
475 479 # b/c each call to the In[] prompt raises it by 1, even the first.
476 480 self.prompt_count = 0
477 481 # Store the last prompt string each time, we need it for aligning
478 482 # continuation and auto-rewrite prompts
479 483 self.last_prompt = ''
480 484 self.Pprint = Pprint
481 485 self.output_sep = output_sep
482 486 self.output_sep2 = output_sep2
483 487 self._,self.__,self.___ = '','',''
484 488 self.pprint_types = map(type,[(),[],{}])
485 489
486 490 # these are deliberately global:
487 491 to_user_ns = {'_':self._,'__':self.__,'___':self.___}
488 492 self.user_ns.update(to_user_ns)
489 493
490 494 def _set_prompt_str(self,p_str,cache_def,no_cache_def):
491 495 if p_str is None:
492 496 if self.do_full_cache:
493 497 return cache_def
494 498 else:
495 499 return no_cache_def
496 500 else:
497 501 return p_str
498 502
499 503 def set_colors(self,colors):
500 504 """Set the active color scheme and configure colors for the three
501 505 prompt subsystems."""
502 506
503 507 # FIXME: the prompt_specials global should be gobbled inside this
504 508 # class instead. Do it when cleaning up the whole 3-prompt system.
505 509 global prompt_specials
506 510 if colors.lower()=='nocolor':
507 511 prompt_specials = prompt_specials_nocolor
508 512 else:
509 513 prompt_specials = prompt_specials_color
510 514
511 515 self.color_table.set_active_scheme(colors)
512 516 self.prompt1.set_colors()
513 517 self.prompt2.set_colors()
514 518 self.prompt_out.set_colors()
515 519
516 520 def __call__(self,arg=None):
517 521 """Printing with history cache management.
518 522
519 523 This is invoked everytime the interpreter needs to print, and is
520 524 activated by setting the variable sys.displayhook to it."""
521 525
522 526 # If something injected a '_' variable in __builtin__, delete
523 527 # ipython's automatic one so we don't clobber that. gettext() in
524 528 # particular uses _, so we need to stay away from it.
525 529 if '_' in __builtin__.__dict__:
526 530 try:
527 531 del self.user_ns['_']
528 532 except KeyError:
529 533 pass
530 534 if arg is not None:
531 535 cout_write = Term.cout.write # fast lookup
532 536 # first handle the cache and counters
533 537
534 538 # do not print output if input ends in ';'
535 539 try:
536 540 if self.input_hist[self.prompt_count].endswith(';\n'):
537 541 return
538 542 except IndexError:
539 543 # some uses of ipshellembed may fail here
540 544 pass
541 545 # don't use print, puts an extra space
542 546 cout_write(self.output_sep)
543 547 outprompt = self.shell.hooks.generate_output_prompt()
544 548 if self.do_full_cache:
545 549 cout_write(outprompt)
546 550
547 551 # and now call a possibly user-defined print mechanism
548 552 manipulated_val = self.display(arg)
549 553
550 554 # user display hooks can change the variable to be stored in
551 555 # output history
552 556
553 557 if manipulated_val is not None:
554 558 arg = manipulated_val
555 559
556 560 # avoid recursive reference when displaying _oh/Out
557 561 if arg is not self.user_ns['_oh']:
558 562 self.update(arg)
559 563
560 564 if self.logger.log_output:
561 565 self.logger.log_write(repr(arg),'output')
562 566 cout_write(self.output_sep2)
563 567 Term.cout.flush()
564 568
565 569 def _display(self,arg):
566 570 """Default printer method, uses pprint.
567 571
568 572 Do ip.set_hook("result_display", my_displayhook) for custom result
569 573 display, e.g. when your own objects need special formatting.
570 574 """
571 575 try:
572 576 return IPython.generics.result_display(arg)
573 577 except TryNext:
574 578 return self.shell.hooks.result_display(arg)
575 579
576 580 # Assign the default display method:
577 581 display = _display
578 582
579 583 def update(self,arg):
580 584 #print '***cache_count', self.cache_count # dbg
581 585 if len(self.user_ns['_oh']) >= self.cache_size and self.do_full_cache:
582 586 warn('Output cache limit (currently '+
583 587 `self.cache_size`+' entries) hit.\n'
584 588 'Flushing cache and resetting history counter...\n'
585 589 'The only history variables available will be _,__,___ and _1\n'
586 590 'with the current result.')
587 591
588 592 self.flush()
589 593 # Don't overwrite '_' and friends if '_' is in __builtin__ (otherwise
590 594 # we cause buggy behavior for things like gettext).
591 595 if '_' not in __builtin__.__dict__:
592 596 self.___ = self.__
593 597 self.__ = self._
594 598 self._ = arg
595 599 self.user_ns.update({'_':self._,'__':self.__,'___':self.___})
596 600
597 601 # hackish access to top-level namespace to create _1,_2... dynamically
598 602 to_main = {}
599 603 if self.do_full_cache:
600 604 new_result = '_'+`self.prompt_count`
601 605 to_main[new_result] = arg
602 606 self.user_ns.update(to_main)
603 607 self.user_ns['_oh'][self.prompt_count] = arg
604 608
605 609 def flush(self):
606 610 if not self.do_full_cache:
607 611 raise ValueError,"You shouldn't have reached the cache flush "\
608 612 "if full caching is not enabled!"
609 613 # delete auto-generated vars from global namespace
610 614
611 615 for n in range(1,self.prompt_count + 1):
612 616 key = '_'+`n`
613 617 try:
614 618 del self.user_ns[key]
615 619 except: pass
616 620 self.user_ns['_oh'].clear()
617 621
618 622 if '_' not in __builtin__.__dict__:
619 623 self.user_ns.update({'_':None,'__':None, '___':None})
620 624 import gc
621 625 gc.collect() # xxx needed?
622 626
@@ -1,121 +1,121 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Release data for the IPython project."""
3 3
4 4 #*****************************************************************************
5 5 # Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu>
6 6 #
7 7 # Copyright (c) 2001 Janko Hauser <jhauser@zscout.de> and Nathaniel Gray
8 8 # <n8gray@caltech.edu>
9 9 #
10 10 # Distributed under the terms of the BSD License. The full license is in
11 11 # the file COPYING, distributed as part of this software.
12 12 #*****************************************************************************
13 13
14 14 # Name of the package for release purposes. This is the name which labels
15 15 # the tarballs and RPMs made by distutils, so it's best to lowercase it.
16 16 name = 'ipython'
17 17
18 18 # For versions with substrings (like 0.6.16.svn), use an extra . to separate
19 19 # the new substring. We have to avoid using either dashes or underscores,
20 20 # because bdist_rpm does not accept dashes (an RPM) convention, and
21 21 # bdist_deb does not accept underscores (a Debian convention).
22 22
23 development = False # change this to False to do a release
24 version_base = '0.9.1'
23 development = True # change this to False to do a release
24 version_base = '0.10'
25 25 branch = 'ipython'
26 revision = '1143'
26 revision = '1163'
27 27
28 28 if development:
29 29 if branch == 'ipython':
30 30 version = '%s.bzr.r%s' % (version_base, revision)
31 31 else:
32 32 version = '%s.bzr.r%s.%s' % (version_base, revision, branch)
33 33 else:
34 34 version = version_base
35 35
36 36
37 37 description = "An interactive computing environment for Python"
38 38
39 39 long_description = \
40 40 """
41 41 The goal of IPython is to create a comprehensive environment for
42 42 interactive and exploratory computing. To support this goal, IPython
43 43 has two main components:
44 44
45 45 * An enhanced interactive Python shell.
46 46
47 47 * An architecture for interactive parallel computing.
48 48
49 49 The enhanced interactive Python shell has the following main features:
50 50
51 51 * Comprehensive object introspection.
52 52
53 53 * Input history, persistent across sessions.
54 54
55 55 * Caching of output results during a session with automatically generated
56 56 references.
57 57
58 58 * Readline based name completion.
59 59
60 60 * Extensible system of 'magic' commands for controlling the environment and
61 61 performing many tasks related either to IPython or the operating system.
62 62
63 63 * Configuration system with easy switching between different setups (simpler
64 64 than changing $PYTHONSTARTUP environment variables every time).
65 65
66 66 * Session logging and reloading.
67 67
68 68 * Extensible syntax processing for special purpose situations.
69 69
70 70 * Access to the system shell with user-extensible alias system.
71 71
72 72 * Easily embeddable in other Python programs and wxPython GUIs.
73 73
74 74 * Integrated access to the pdb debugger and the Python profiler.
75 75
76 76 The parallel computing architecture has the following main features:
77 77
78 78 * Quickly parallelize Python code from an interactive Python/IPython session.
79 79
80 80 * A flexible and dynamic process model that be deployed on anything from
81 81 multicore workstations to supercomputers.
82 82
83 83 * An architecture that supports many different styles of parallelism, from
84 84 message passing to task farming.
85 85
86 86 * Both blocking and fully asynchronous interfaces.
87 87
88 88 * High level APIs that enable many things to be parallelized in a few lines
89 89 of code.
90 90
91 91 * Share live parallel jobs with other users securely.
92 92
93 93 * Dynamically load balanced task farming system.
94 94
95 95 * Robust error handling in parallel code.
96 96
97 97 The latest development version is always available from IPython's `Launchpad
98 98 site <http://launchpad.net/ipython>`_.
99 99 """
100 100
101 101 license = 'BSD'
102 102
103 103 authors = {'Fernando' : ('Fernando Perez','fperez@colorado.edu'),
104 104 'Janko' : ('Janko Hauser','jhauser@zscout.de'),
105 105 'Nathan' : ('Nathaniel Gray','n8gray@caltech.edu'),
106 106 'Ville' : ('Ville Vainio','vivainio@gmail.com'),
107 107 'Brian' : ('Brian E Granger', 'ellisonbg@gmail.com'),
108 108 'Min' : ('Min Ragan-Kelley', 'benjaminrk@gmail.com')
109 109 }
110 110
111 111 author = 'The IPython Development Team'
112 112
113 113 author_email = 'ipython-dev@scipy.org'
114 114
115 115 url = 'http://ipython.scipy.org'
116 116
117 117 download_url = 'http://ipython.scipy.org/dist'
118 118
119 119 platforms = ['Linux','Mac OSX','Windows XP/2000/NT','Windows 95/98/ME']
120 120
121 121 keywords = ['Interactive','Interpreter','Shell','Parallel','Distributed']
@@ -1,1244 +1,1246 b''
1 1 # -*- coding: utf-8 -*-
2 2 """IPython Shell classes.
3 3
4 4 All the matplotlib support code was co-developed with John Hunter,
5 5 matplotlib's author.
6 6 """
7 7
8 8 #*****************************************************************************
9 9 # Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu>
10 10 #
11 11 # Distributed under the terms of the BSD License. The full license is in
12 12 # the file COPYING, distributed as part of this software.
13 13 #*****************************************************************************
14 14
15 15 # Code begins
16 16 # Stdlib imports
17 17 import __builtin__
18 18 import __main__
19 19 import Queue
20 20 import inspect
21 21 import os
22 22 import sys
23 23 import thread
24 24 import threading
25 25 import time
26 26
27 27 from signal import signal, SIGINT
28 28
29 29 try:
30 30 import ctypes
31 31 HAS_CTYPES = True
32 32 except ImportError:
33 33 HAS_CTYPES = False
34 34
35 35 # IPython imports
36 36 import IPython
37 37 from IPython import ultraTB, ipapi
38 38 from IPython.Magic import Magic
39 39 from IPython.genutils import Term,warn,error,flag_calls, ask_yes_no
40 40 from IPython.iplib import InteractiveShell
41 41 from IPython.ipmaker import make_IPython
42 42 from IPython.ipstruct import Struct
43 43 from IPython.testing import decorators as testdec
44 44
45 45 # Globals
46 46 # global flag to pass around information about Ctrl-C without exceptions
47 47 KBINT = False
48 48
49 49 # global flag to turn on/off Tk support.
50 50 USE_TK = False
51 51
52 52 # ID for the main thread, used for cross-thread exceptions
53 53 MAIN_THREAD_ID = thread.get_ident()
54 54
55 55 # Tag when runcode() is active, for exception handling
56 56 CODE_RUN = None
57 57
58 58 # Default timeout for waiting for multithreaded shells (in seconds)
59 59 GUI_TIMEOUT = 10
60 60
61 61 #-----------------------------------------------------------------------------
62 62 # This class is trivial now, but I want to have it in to publish a clean
63 63 # interface. Later when the internals are reorganized, code that uses this
64 64 # shouldn't have to change.
65 65
66 66 class IPShell:
67 67 """Create an IPython instance."""
68 68
69 69 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
70 70 debug=1,shell_class=InteractiveShell):
71 71 self.IP = make_IPython(argv,user_ns=user_ns,
72 72 user_global_ns=user_global_ns,
73 73 debug=debug,shell_class=shell_class)
74 74
75 75 def mainloop(self,sys_exit=0,banner=None):
76 76 self.IP.mainloop(banner)
77 77 if sys_exit:
78 78 sys.exit()
79 79
80 80 #-----------------------------------------------------------------------------
81 81 def kill_embedded(self,parameter_s=''):
82 82 """%kill_embedded : deactivate for good the current embedded IPython.
83 83
84 84 This function (after asking for confirmation) sets an internal flag so that
85 85 an embedded IPython will never activate again. This is useful to
86 86 permanently disable a shell that is being called inside a loop: once you've
87 87 figured out what you needed from it, you may then kill it and the program
88 88 will then continue to run without the interactive shell interfering again.
89 89 """
90 90
91 91 kill = ask_yes_no("Are you sure you want to kill this embedded instance "
92 92 "(y/n)? [y/N] ",'n')
93 93 if kill:
94 94 self.shell.embedded_active = False
95 95 print "This embedded IPython will not reactivate anymore once you exit."
96 96
97 97 class IPShellEmbed:
98 98 """Allow embedding an IPython shell into a running program.
99 99
100 100 Instances of this class are callable, with the __call__ method being an
101 101 alias to the embed() method of an InteractiveShell instance.
102 102
103 103 Usage (see also the example-embed.py file for a running example):
104 104
105 105 ipshell = IPShellEmbed([argv,banner,exit_msg,rc_override])
106 106
107 107 - argv: list containing valid command-line options for IPython, as they
108 108 would appear in sys.argv[1:].
109 109
110 110 For example, the following command-line options:
111 111
112 112 $ ipython -prompt_in1 'Input <\\#>' -colors LightBG
113 113
114 114 would be passed in the argv list as:
115 115
116 116 ['-prompt_in1','Input <\\#>','-colors','LightBG']
117 117
118 118 - banner: string which gets printed every time the interpreter starts.
119 119
120 120 - exit_msg: string which gets printed every time the interpreter exits.
121 121
122 122 - rc_override: a dict or Struct of configuration options such as those
123 123 used by IPython. These options are read from your ~/.ipython/ipythonrc
124 124 file when the Shell object is created. Passing an explicit rc_override
125 125 dict with any options you want allows you to override those values at
126 126 creation time without having to modify the file. This way you can create
127 127 embeddable instances configured in any way you want without editing any
128 128 global files (thus keeping your interactive IPython configuration
129 129 unchanged).
130 130
131 131 Then the ipshell instance can be called anywhere inside your code:
132 132
133 133 ipshell(header='') -> Opens up an IPython shell.
134 134
135 135 - header: string printed by the IPython shell upon startup. This can let
136 136 you know where in your code you are when dropping into the shell. Note
137 137 that 'banner' gets prepended to all calls, so header is used for
138 138 location-specific information.
139 139
140 140 For more details, see the __call__ method below.
141 141
142 142 When the IPython shell is exited with Ctrl-D, normal program execution
143 143 resumes.
144 144
145 145 This functionality was inspired by a posting on comp.lang.python by cmkl
146 146 <cmkleffner@gmx.de> on Dec. 06/01 concerning similar uses of pyrepl, and
147 147 by the IDL stop/continue commands."""
148 148
149 149 def __init__(self,argv=None,banner='',exit_msg=None,rc_override=None,
150 150 user_ns=None):
151 151 """Note that argv here is a string, NOT a list."""
152 152 self.set_banner(banner)
153 153 self.set_exit_msg(exit_msg)
154 154 self.set_dummy_mode(0)
155 155
156 156 # sys.displayhook is a global, we need to save the user's original
157 157 # Don't rely on __displayhook__, as the user may have changed that.
158 158 self.sys_displayhook_ori = sys.displayhook
159 159
160 160 # save readline completer status
161 161 try:
162 162 #print 'Save completer',sys.ipcompleter # dbg
163 163 self.sys_ipcompleter_ori = sys.ipcompleter
164 164 except:
165 165 pass # not nested with IPython
166 166
167 167 self.IP = make_IPython(argv,rc_override=rc_override,
168 168 embedded=True,
169 169 user_ns=user_ns)
170 170
171 171 ip = ipapi.IPApi(self.IP)
172 172 ip.expose_magic("kill_embedded",kill_embedded)
173 173
174 174 # copy our own displayhook also
175 175 self.sys_displayhook_embed = sys.displayhook
176 176 # and leave the system's display hook clean
177 177 sys.displayhook = self.sys_displayhook_ori
178 178 # don't use the ipython crash handler so that user exceptions aren't
179 179 # trapped
180 180 sys.excepthook = ultraTB.FormattedTB(color_scheme = self.IP.rc.colors,
181 181 mode = self.IP.rc.xmode,
182 182 call_pdb = self.IP.rc.pdb)
183 183 self.restore_system_completer()
184 184
185 185 def restore_system_completer(self):
186 186 """Restores the readline completer which was in place.
187 187
188 188 This allows embedded IPython within IPython not to disrupt the
189 189 parent's completion.
190 190 """
191 191
192 192 try:
193 193 self.IP.readline.set_completer(self.sys_ipcompleter_ori)
194 194 sys.ipcompleter = self.sys_ipcompleter_ori
195 195 except:
196 196 pass
197 197
198 198 def __call__(self,header='',local_ns=None,global_ns=None,dummy=None):
199 199 """Activate the interactive interpreter.
200 200
201 201 __call__(self,header='',local_ns=None,global_ns,dummy=None) -> Start
202 202 the interpreter shell with the given local and global namespaces, and
203 203 optionally print a header string at startup.
204 204
205 205 The shell can be globally activated/deactivated using the
206 206 set/get_dummy_mode methods. This allows you to turn off a shell used
207 207 for debugging globally.
208 208
209 209 However, *each* time you call the shell you can override the current
210 210 state of dummy_mode with the optional keyword parameter 'dummy'. For
211 211 example, if you set dummy mode on with IPShell.set_dummy_mode(1), you
212 212 can still have a specific call work by making it as IPShell(dummy=0).
213 213
214 214 The optional keyword parameter dummy controls whether the call
215 215 actually does anything. """
216 216
217 217 # If the user has turned it off, go away
218 218 if not self.IP.embedded_active:
219 219 return
220 220
221 221 # Normal exits from interactive mode set this flag, so the shell can't
222 222 # re-enter (it checks this variable at the start of interactive mode).
223 223 self.IP.exit_now = False
224 224
225 225 # Allow the dummy parameter to override the global __dummy_mode
226 226 if dummy or (dummy != 0 and self.__dummy_mode):
227 227 return
228 228
229 229 # Set global subsystems (display,completions) to our values
230 230 sys.displayhook = self.sys_displayhook_embed
231 231 if self.IP.has_readline:
232 232 self.IP.set_completer()
233 233
234 234 if self.banner and header:
235 235 format = '%s\n%s\n'
236 236 else:
237 237 format = '%s%s\n'
238 238 banner = format % (self.banner,header)
239 239
240 240 # Call the embedding code with a stack depth of 1 so it can skip over
241 241 # our call and get the original caller's namespaces.
242 242 self.IP.embed_mainloop(banner,local_ns,global_ns,stack_depth=1)
243 243
244 244 if self.exit_msg:
245 245 print self.exit_msg
246 246
247 247 # Restore global systems (display, completion)
248 248 sys.displayhook = self.sys_displayhook_ori
249 249 self.restore_system_completer()
250 250
251 251 def set_dummy_mode(self,dummy):
252 252 """Sets the embeddable shell's dummy mode parameter.
253 253
254 254 set_dummy_mode(dummy): dummy = 0 or 1.
255 255
256 256 This parameter is persistent and makes calls to the embeddable shell
257 257 silently return without performing any action. This allows you to
258 258 globally activate or deactivate a shell you're using with a single call.
259 259
260 260 If you need to manually"""
261 261
262 262 if dummy not in [0,1,False,True]:
263 263 raise ValueError,'dummy parameter must be boolean'
264 264 self.__dummy_mode = dummy
265 265
266 266 def get_dummy_mode(self):
267 267 """Return the current value of the dummy mode parameter.
268 268 """
269 269 return self.__dummy_mode
270 270
271 271 def set_banner(self,banner):
272 272 """Sets the global banner.
273 273
274 274 This banner gets prepended to every header printed when the shell
275 275 instance is called."""
276 276
277 277 self.banner = banner
278 278
279 279 def set_exit_msg(self,exit_msg):
280 280 """Sets the global exit_msg.
281 281
282 282 This exit message gets printed upon exiting every time the embedded
283 283 shell is called. It is None by default. """
284 284
285 285 self.exit_msg = exit_msg
286 286
287 287 #-----------------------------------------------------------------------------
288 288 if HAS_CTYPES:
289 289 # Add async exception support. Trick taken from:
290 290 # http://sebulba.wikispaces.com/recipe+thread2
291 291 def _async_raise(tid, exctype):
292 292 """raises the exception, performs cleanup if needed"""
293 293 if not inspect.isclass(exctype):
294 294 raise TypeError("Only types can be raised (not instances)")
295 res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid,
295 # Explicit cast to c_long is necessary for 64-bit support:
296 # See https://bugs.launchpad.net/ipython/+bug/237073
297 res = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid),
296 298 ctypes.py_object(exctype))
297 299 if res == 0:
298 300 raise ValueError("invalid thread id")
299 301 elif res != 1:
300 # """if it returns a number greater than one, you're in trouble,
301 # and you should call it again with exc=NULL to revert the effect"""
302 # If it returns a number greater than one, you're in trouble,
303 # and you should call it again with exc=NULL to revert the effect
302 304 ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0)
303 305 raise SystemError("PyThreadState_SetAsyncExc failed")
304 306
305 def sigint_handler (signum,stack_frame):
307 def sigint_handler(signum,stack_frame):
306 308 """Sigint handler for threaded apps.
307 309
308 310 This is a horrible hack to pass information about SIGINT _without_
309 311 using exceptions, since I haven't been able to properly manage
310 312 cross-thread exceptions in GTK/WX. In fact, I don't think it can be
311 313 done (or at least that's my understanding from a c.l.py thread where
312 314 this was discussed)."""
313 315
314 316 global KBINT
315 317
316 318 if CODE_RUN:
317 319 _async_raise(MAIN_THREAD_ID,KeyboardInterrupt)
318 320 else:
319 321 KBINT = True
320 322 print '\nKeyboardInterrupt - Press <Enter> to continue.',
321 323 Term.cout.flush()
322 324
323 325 else:
324 def sigint_handler (signum,stack_frame):
326 def sigint_handler(signum,stack_frame):
325 327 """Sigint handler for threaded apps.
326 328
327 329 This is a horrible hack to pass information about SIGINT _without_
328 330 using exceptions, since I haven't been able to properly manage
329 331 cross-thread exceptions in GTK/WX. In fact, I don't think it can be
330 332 done (or at least that's my understanding from a c.l.py thread where
331 333 this was discussed)."""
332 334
333 335 global KBINT
334 336
335 337 print '\nKeyboardInterrupt - Press <Enter> to continue.',
336 338 Term.cout.flush()
337 339 # Set global flag so that runsource can know that Ctrl-C was hit
338 340 KBINT = True
339 341
340 342
341 343 class MTInteractiveShell(InteractiveShell):
342 344 """Simple multi-threaded shell."""
343 345
344 346 # Threading strategy taken from:
345 347 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65109, by Brian
346 348 # McErlean and John Finlay. Modified with corrections by Antoon Pardon,
347 349 # from the pygtk mailing list, to avoid lockups with system calls.
348 350
349 351 # class attribute to indicate whether the class supports threads or not.
350 352 # Subclasses with thread support should override this as needed.
351 353 isthreaded = True
352 354
353 355 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
354 356 user_ns=None,user_global_ns=None,banner2='',
355 357 gui_timeout=GUI_TIMEOUT,**kw):
356 358 """Similar to the normal InteractiveShell, but with threading control"""
357 359
358 360 InteractiveShell.__init__(self,name,usage,rc,user_ns,
359 361 user_global_ns,banner2)
360 362
361 363 # Timeout we wait for GUI thread
362 364 self.gui_timeout = gui_timeout
363 365
364 366 # A queue to hold the code to be executed.
365 367 self.code_queue = Queue.Queue()
366 368
367 369 # Stuff to do at closing time
368 370 self._kill = None
369 371 on_kill = kw.get('on_kill', [])
370 372 # Check that all things to kill are callable:
371 373 for t in on_kill:
372 374 if not callable(t):
373 375 raise TypeError,'on_kill must be a list of callables'
374 376 self.on_kill = on_kill
375 377 # thread identity of the "worker thread" (that may execute code directly)
376 378 self.worker_ident = None
377 379
378 380 def runsource(self, source, filename="<input>", symbol="single"):
379 381 """Compile and run some source in the interpreter.
380 382
381 383 Modified version of code.py's runsource(), to handle threading issues.
382 384 See the original for full docstring details."""
383 385
384 386 global KBINT
385 387
386 388 # If Ctrl-C was typed, we reset the flag and return right away
387 389 if KBINT:
388 390 KBINT = False
389 391 return False
390 392
391 393 if self._kill:
392 394 # can't queue new code if we are being killed
393 395 return True
394 396
395 397 try:
396 398 code = self.compile(source, filename, symbol)
397 399 except (OverflowError, SyntaxError, ValueError):
398 400 # Case 1
399 401 self.showsyntaxerror(filename)
400 402 return False
401 403
402 404 if code is None:
403 405 # Case 2
404 406 return True
405 407
406 408 # shortcut - if we are in worker thread, or the worker thread is not
407 409 # running, execute directly (to allow recursion and prevent deadlock if
408 410 # code is run early in IPython construction)
409 411
410 412 if (self.worker_ident is None
411 413 or self.worker_ident == thread.get_ident() ):
412 414 InteractiveShell.runcode(self,code)
413 415 return False
414 416
415 417 # Case 3
416 418 # Store code in queue, so the execution thread can handle it.
417 419
418 420 completed_ev, received_ev = threading.Event(), threading.Event()
419 421
420 422 self.code_queue.put((code,completed_ev, received_ev))
421 423 # first make sure the message was received, with timeout
422 424 received_ev.wait(self.gui_timeout)
423 425 if not received_ev.isSet():
424 426 # the mainloop is dead, start executing code directly
425 427 print "Warning: Timeout for mainloop thread exceeded"
426 428 print "switching to nonthreaded mode (until mainloop wakes up again)"
427 429 self.worker_ident = None
428 430 else:
429 431 completed_ev.wait()
430 432 return False
431 433
432 434 def runcode(self):
433 435 """Execute a code object.
434 436
435 437 Multithreaded wrapper around IPython's runcode()."""
436 438
437 439 global CODE_RUN
438 440
439 441 # we are in worker thread, stash out the id for runsource()
440 442 self.worker_ident = thread.get_ident()
441 443
442 444 if self._kill:
443 445 print >>Term.cout, 'Closing threads...',
444 446 Term.cout.flush()
445 447 for tokill in self.on_kill:
446 448 tokill()
447 449 print >>Term.cout, 'Done.'
448 450 # allow kill() to return
449 451 self._kill.set()
450 452 return True
451 453
452 454 # Install sigint handler. We do it every time to ensure that if user
453 455 # code modifies it, we restore our own handling.
454 456 try:
455 457 signal(SIGINT,sigint_handler)
456 458 except SystemError:
457 459 # This happens under Windows, which seems to have all sorts
458 460 # of problems with signal handling. Oh well...
459 461 pass
460 462
461 463 # Flush queue of pending code by calling the run methood of the parent
462 464 # class with all items which may be in the queue.
463 465 code_to_run = None
464 466 while 1:
465 467 try:
466 468 code_to_run, completed_ev, received_ev = self.code_queue.get_nowait()
467 469 except Queue.Empty:
468 470 break
469 471 received_ev.set()
470 472
471 473 # Exceptions need to be raised differently depending on which
472 474 # thread is active. This convoluted try/except is only there to
473 475 # protect against asynchronous exceptions, to ensure that a KBINT
474 476 # at the wrong time doesn't deadlock everything. The global
475 477 # CODE_TO_RUN is set to true/false as close as possible to the
476 478 # runcode() call, so that the KBINT handler is correctly informed.
477 479 try:
478 480 try:
479 481 CODE_RUN = True
480 482 InteractiveShell.runcode(self,code_to_run)
481 483 except KeyboardInterrupt:
482 484 print "Keyboard interrupted in mainloop"
483 485 while not self.code_queue.empty():
484 486 code, ev1,ev2 = self.code_queue.get_nowait()
485 487 ev1.set()
486 488 ev2.set()
487 489 break
488 490 finally:
489 491 CODE_RUN = False
490 492 # allow runsource() return from wait
491 493 completed_ev.set()
492 494
493 495
494 496 # This MUST return true for gtk threading to work
495 497 return True
496 498
497 499 def kill(self):
498 500 """Kill the thread, returning when it has been shut down."""
499 501 self._kill = threading.Event()
500 502 self._kill.wait()
501 503
502 504 class MatplotlibShellBase:
503 505 """Mixin class to provide the necessary modifications to regular IPython
504 506 shell classes for matplotlib support.
505 507
506 508 Given Python's MRO, this should be used as the FIRST class in the
507 509 inheritance hierarchy, so that it overrides the relevant methods."""
508 510
509 511 def _matplotlib_config(self,name,user_ns,user_global_ns=None):
510 512 """Return items needed to setup the user's shell with matplotlib"""
511 513
512 514 # Initialize matplotlib to interactive mode always
513 515 import matplotlib
514 516 from matplotlib import backends
515 517 matplotlib.interactive(True)
516 518
517 519 def use(arg):
518 520 """IPython wrapper for matplotlib's backend switcher.
519 521
520 522 In interactive use, we can not allow switching to a different
521 523 interactive backend, since thread conflicts will most likely crash
522 524 the python interpreter. This routine does a safety check first,
523 525 and refuses to perform a dangerous switch. It still allows
524 526 switching to non-interactive backends."""
525 527
526 528 if arg in backends.interactive_bk and arg != self.mpl_backend:
527 529 m=('invalid matplotlib backend switch.\n'
528 530 'This script attempted to switch to the interactive '
529 531 'backend: `%s`\n'
530 532 'Your current choice of interactive backend is: `%s`\n\n'
531 533 'Switching interactive matplotlib backends at runtime\n'
532 534 'would crash the python interpreter, '
533 535 'and IPython has blocked it.\n\n'
534 536 'You need to either change your choice of matplotlib backend\n'
535 537 'by editing your .matplotlibrc file, or run this script as a \n'
536 538 'standalone file from the command line, not using IPython.\n' %
537 539 (arg,self.mpl_backend) )
538 540 raise RuntimeError, m
539 541 else:
540 542 self.mpl_use(arg)
541 543 self.mpl_use._called = True
542 544
543 545 self.matplotlib = matplotlib
544 546 self.mpl_backend = matplotlib.rcParams['backend']
545 547
546 548 # we also need to block switching of interactive backends by use()
547 549 self.mpl_use = matplotlib.use
548 550 self.mpl_use._called = False
549 551 # overwrite the original matplotlib.use with our wrapper
550 552 matplotlib.use = use
551 553
552 554 # This must be imported last in the matplotlib series, after
553 555 # backend/interactivity choices have been made
554 556 import matplotlib.pylab as pylab
555 557 self.pylab = pylab
556 558
557 559 self.pylab.show._needmain = False
558 560 # We need to detect at runtime whether show() is called by the user.
559 561 # For this, we wrap it into a decorator which adds a 'called' flag.
560 562 self.pylab.draw_if_interactive = flag_calls(self.pylab.draw_if_interactive)
561 563
562 564 # Build a user namespace initialized with matplotlib/matlab features.
563 565 user_ns, user_global_ns = IPython.ipapi.make_user_namespaces(user_ns,
564 566 user_global_ns)
565 567
566 568 # Import numpy as np/pyplot as plt are conventions we're trying to
567 569 # somewhat standardize on. Making them available to users by default
568 570 # will greatly help this.
569 571 exec ("import numpy\n"
570 572 "import numpy as np\n"
571 573 "import matplotlib\n"
572 574 "import matplotlib.pylab as pylab\n"
573 575 "try:\n"
574 576 " import matplotlib.pyplot as plt\n"
575 577 "except ImportError:\n"
576 578 " pass\n"
577 579 ) in user_ns
578 580
579 581 # Build matplotlib info banner
580 582 b="""
581 583 Welcome to pylab, a matplotlib-based Python environment.
582 584 For more information, type 'help(pylab)'.
583 585 """
584 586 return user_ns,user_global_ns,b
585 587
586 588 def mplot_exec(self,fname,*where,**kw):
587 589 """Execute a matplotlib script.
588 590
589 591 This is a call to execfile(), but wrapped in safeties to properly
590 592 handle interactive rendering and backend switching."""
591 593
592 594 #print '*** Matplotlib runner ***' # dbg
593 595 # turn off rendering until end of script
594 596 isInteractive = self.matplotlib.rcParams['interactive']
595 597 self.matplotlib.interactive(False)
596 598 self.safe_execfile(fname,*where,**kw)
597 599 self.matplotlib.interactive(isInteractive)
598 600 # make rendering call now, if the user tried to do it
599 601 if self.pylab.draw_if_interactive.called:
600 602 self.pylab.draw()
601 603 self.pylab.draw_if_interactive.called = False
602 604
603 605 # if a backend switch was performed, reverse it now
604 606 if self.mpl_use._called:
605 607 self.matplotlib.rcParams['backend'] = self.mpl_backend
606 608
607 609 @testdec.skip_doctest
608 610 def magic_run(self,parameter_s=''):
609 611 Magic.magic_run(self,parameter_s,runner=self.mplot_exec)
610 612
611 613 # Fix the docstring so users see the original as well
612 614 magic_run.__doc__ = "%s\n%s" % (Magic.magic_run.__doc__,
613 615 "\n *** Modified %run for Matplotlib,"
614 616 " with proper interactive handling ***")
615 617
616 618 # Now we provide 2 versions of a matplotlib-aware IPython base shells, single
617 619 # and multithreaded. Note that these are meant for internal use, the IPShell*
618 620 # classes below are the ones meant for public consumption.
619 621
620 622 class MatplotlibShell(MatplotlibShellBase,InteractiveShell):
621 623 """Single-threaded shell with matplotlib support."""
622 624
623 625 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
624 626 user_ns=None,user_global_ns=None,**kw):
625 627 user_ns,user_global_ns,b2 = self._matplotlib_config(name,user_ns,user_global_ns)
626 628 InteractiveShell.__init__(self,name,usage,rc,user_ns,user_global_ns,
627 629 banner2=b2,**kw)
628 630
629 631 class MatplotlibMTShell(MatplotlibShellBase,MTInteractiveShell):
630 632 """Multi-threaded shell with matplotlib support."""
631 633
632 634 def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
633 635 user_ns=None,user_global_ns=None, **kw):
634 636 user_ns,user_global_ns,b2 = self._matplotlib_config(name,user_ns,user_global_ns)
635 637 MTInteractiveShell.__init__(self,name,usage,rc,user_ns,user_global_ns,
636 638 banner2=b2,**kw)
637 639
638 640 #-----------------------------------------------------------------------------
639 641 # Utility functions for the different GUI enabled IPShell* classes.
640 642
641 643 def get_tk():
642 644 """Tries to import Tkinter and returns a withdrawn Tkinter root
643 645 window. If Tkinter is already imported or not available, this
644 646 returns None. This function calls `hijack_tk` underneath.
645 647 """
646 648 if not USE_TK or sys.modules.has_key('Tkinter'):
647 649 return None
648 650 else:
649 651 try:
650 652 import Tkinter
651 653 except ImportError:
652 654 return None
653 655 else:
654 656 hijack_tk()
655 657 r = Tkinter.Tk()
656 658 r.withdraw()
657 659 return r
658 660
659 661 def hijack_tk():
660 662 """Modifies Tkinter's mainloop with a dummy so when a module calls
661 663 mainloop, it does not block.
662 664
663 665 """
664 666 def misc_mainloop(self, n=0):
665 667 pass
666 668 def tkinter_mainloop(n=0):
667 669 pass
668 670
669 671 import Tkinter
670 672 Tkinter.Misc.mainloop = misc_mainloop
671 673 Tkinter.mainloop = tkinter_mainloop
672 674
673 675 def update_tk(tk):
674 676 """Updates the Tkinter event loop. This is typically called from
675 677 the respective WX or GTK mainloops.
676 678 """
677 679 if tk:
678 680 tk.update()
679 681
680 682 def hijack_wx():
681 683 """Modifies wxPython's MainLoop with a dummy so user code does not
682 684 block IPython. The hijacked mainloop function is returned.
683 685 """
684 686 def dummy_mainloop(*args, **kw):
685 687 pass
686 688
687 689 try:
688 690 import wx
689 691 except ImportError:
690 692 # For very old versions of WX
691 693 import wxPython as wx
692 694
693 695 ver = wx.__version__
694 696 orig_mainloop = None
695 697 if ver[:3] >= '2.5':
696 698 import wx
697 699 if hasattr(wx, '_core_'): core = getattr(wx, '_core_')
698 700 elif hasattr(wx, '_core'): core = getattr(wx, '_core')
699 701 else: raise AttributeError('Could not find wx core module')
700 702 orig_mainloop = core.PyApp_MainLoop
701 703 core.PyApp_MainLoop = dummy_mainloop
702 704 elif ver[:3] == '2.4':
703 705 orig_mainloop = wx.wxc.wxPyApp_MainLoop
704 706 wx.wxc.wxPyApp_MainLoop = dummy_mainloop
705 707 else:
706 708 warn("Unable to find either wxPython version 2.4 or >= 2.5.")
707 709 return orig_mainloop
708 710
709 711 def hijack_gtk():
710 712 """Modifies pyGTK's mainloop with a dummy so user code does not
711 713 block IPython. This function returns the original `gtk.mainloop`
712 714 function that has been hijacked.
713 715 """
714 716 def dummy_mainloop(*args, **kw):
715 717 pass
716 718 import gtk
717 719 if gtk.pygtk_version >= (2,4,0): orig_mainloop = gtk.main
718 720 else: orig_mainloop = gtk.mainloop
719 721 gtk.mainloop = dummy_mainloop
720 722 gtk.main = dummy_mainloop
721 723 return orig_mainloop
722 724
723 725 def hijack_qt():
724 726 """Modifies PyQt's mainloop with a dummy so user code does not
725 727 block IPython. This function returns the original
726 728 `qt.qApp.exec_loop` function that has been hijacked.
727 729 """
728 730 def dummy_mainloop(*args, **kw):
729 731 pass
730 732 import qt
731 733 orig_mainloop = qt.qApp.exec_loop
732 734 qt.qApp.exec_loop = dummy_mainloop
733 735 qt.QApplication.exec_loop = dummy_mainloop
734 736 return orig_mainloop
735 737
736 738 def hijack_qt4():
737 739 """Modifies PyQt4's mainloop with a dummy so user code does not
738 740 block IPython. This function returns the original
739 741 `QtGui.qApp.exec_` function that has been hijacked.
740 742 """
741 743 def dummy_mainloop(*args, **kw):
742 744 pass
743 745 from PyQt4 import QtGui, QtCore
744 746 orig_mainloop = QtGui.qApp.exec_
745 747 QtGui.qApp.exec_ = dummy_mainloop
746 748 QtGui.QApplication.exec_ = dummy_mainloop
747 749 QtCore.QCoreApplication.exec_ = dummy_mainloop
748 750 return orig_mainloop
749 751
750 752 #-----------------------------------------------------------------------------
751 753 # The IPShell* classes below are the ones meant to be run by external code as
752 754 # IPython instances. Note that unless a specific threading strategy is
753 755 # desired, the factory function start() below should be used instead (it
754 756 # selects the proper threaded class).
755 757
756 758 class IPThread(threading.Thread):
757 759 def run(self):
758 760 self.IP.mainloop(self._banner)
759 761 self.IP.kill()
760 762
761 763 class IPShellGTK(IPThread):
762 764 """Run a gtk mainloop() in a separate thread.
763 765
764 766 Python commands can be passed to the thread where they will be executed.
765 767 This is implemented by periodically checking for passed code using a
766 768 GTK timeout callback."""
767 769
768 770 TIMEOUT = 100 # Millisecond interval between timeouts.
769 771
770 772 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
771 773 debug=1,shell_class=MTInteractiveShell):
772 774
773 775 import gtk
774 776 # Check for set_interactive, coming up in new pygtk.
775 777 # Disable it so that this code works, but notify
776 778 # the user that he has a better option as well.
777 779 # XXX TODO better support when set_interactive is released
778 780 try:
779 781 gtk.set_interactive(False)
780 782 print "Your PyGtk has set_interactive(), so you can use the"
781 783 print "more stable single-threaded Gtk mode."
782 784 print "See https://bugs.launchpad.net/ipython/+bug/270856"
783 785 except AttributeError:
784 786 pass
785 787
786 788 self.gtk = gtk
787 789 self.gtk_mainloop = hijack_gtk()
788 790
789 791 # Allows us to use both Tk and GTK.
790 792 self.tk = get_tk()
791 793
792 794 if gtk.pygtk_version >= (2,4,0): mainquit = self.gtk.main_quit
793 795 else: mainquit = self.gtk.mainquit
794 796
795 797 self.IP = make_IPython(argv,user_ns=user_ns,
796 798 user_global_ns=user_global_ns,
797 799 debug=debug,
798 800 shell_class=shell_class,
799 801 on_kill=[mainquit])
800 802
801 803 # HACK: slot for banner in self; it will be passed to the mainloop
802 804 # method only and .run() needs it. The actual value will be set by
803 805 # .mainloop().
804 806 self._banner = None
805 807
806 808 threading.Thread.__init__(self)
807 809
808 810 def mainloop(self,sys_exit=0,banner=None):
809 811
810 812 self._banner = banner
811 813
812 814 if self.gtk.pygtk_version >= (2,4,0):
813 815 import gobject
814 816 gobject.idle_add(self.on_timer)
815 817 else:
816 818 self.gtk.idle_add(self.on_timer)
817 819
818 820 if sys.platform != 'win32':
819 821 try:
820 822 if self.gtk.gtk_version[0] >= 2:
821 823 self.gtk.gdk.threads_init()
822 824 except AttributeError:
823 825 pass
824 826 except RuntimeError:
825 827 error('Your pyGTK likely has not been compiled with '
826 828 'threading support.\n'
827 829 'The exception printout is below.\n'
828 830 'You can either rebuild pyGTK with threads, or '
829 831 'try using \n'
830 832 'matplotlib with a different backend (like Tk or WX).\n'
831 833 'Note that matplotlib will most likely not work in its '
832 834 'current state!')
833 835 self.IP.InteractiveTB()
834 836
835 837 self.start()
836 838 self.gtk.gdk.threads_enter()
837 839 self.gtk_mainloop()
838 840 self.gtk.gdk.threads_leave()
839 841 self.join()
840 842
841 843 def on_timer(self):
842 844 """Called when GTK is idle.
843 845
844 846 Must return True always, otherwise GTK stops calling it"""
845 847
846 848 update_tk(self.tk)
847 849 self.IP.runcode()
848 850 time.sleep(0.01)
849 851 return True
850 852
851 853
852 854 class IPShellWX(IPThread):
853 855 """Run a wx mainloop() in a separate thread.
854 856
855 857 Python commands can be passed to the thread where they will be executed.
856 858 This is implemented by periodically checking for passed code using a
857 859 GTK timeout callback."""
858 860
859 861 TIMEOUT = 100 # Millisecond interval between timeouts.
860 862
861 863 def __init__(self,argv=None,user_ns=None,user_global_ns=None,
862 864 debug=1,shell_class=MTInteractiveShell):
863 865
864 866 self.IP = make_IPython(argv,user_ns=user_ns,
865 867 user_global_ns=user_global_ns,
866 868 debug=debug,
867 869 shell_class=shell_class,
868 870 on_kill=[self.wxexit])
869 871
870 872 wantedwxversion=self.IP.rc.wxversion
871 873 if wantedwxversion!="0":
872 874 try:
873 875 import wxversion
874 876 except ImportError:
875 877 error('The wxversion module is needed for WX version selection')
876 878 else:
877 879 try:
878 880 wxversion.select(wantedwxversion)
879 881 except:
880 882 self.IP.InteractiveTB()
881 883 error('Requested wxPython version %s could not be loaded' %
882 884 wantedwxversion)
883 885
884 886 import wx
885 887
886 888 threading.Thread.__init__(self)
887 889 self.wx = wx
888 890 self.wx_mainloop = hijack_wx()
889 891
890 892 # Allows us to use both Tk and GTK.
891 893 self.tk = get_tk()
892 894
893 895 # HACK: slot for banner in self; it will be passed to the mainloop
894 896 # method only and .run() needs it. The actual value will be set by
895 897 # .mainloop().
896 898 self._banner = None
897 899
898 900 self.app = None
899 901
900 902 def wxexit(self, *args):
901 903 if self.app is not None:
902 904 self.app.agent.timer.Stop()
903 905 self.app.ExitMainLoop()
904 906
905 907 def mainloop(self,sys_exit=0,banner=None):
906 908
907 909 self._banner = banner
908 910
909 911 self.start()
910 912
911 913 class TimerAgent(self.wx.MiniFrame):
912 914 wx = self.wx
913 915 IP = self.IP
914 916 tk = self.tk
915 917 def __init__(self, parent, interval):
916 918 style = self.wx.DEFAULT_FRAME_STYLE | self.wx.TINY_CAPTION_HORIZ
917 919 self.wx.MiniFrame.__init__(self, parent, -1, ' ', pos=(200, 200),
918 920 size=(100, 100),style=style)
919 921 self.Show(False)
920 922 self.interval = interval
921 923 self.timerId = self.wx.NewId()
922 924
923 925 def StartWork(self):
924 926 self.timer = self.wx.Timer(self, self.timerId)
925 927 self.wx.EVT_TIMER(self, self.timerId, self.OnTimer)
926 928 self.timer.Start(self.interval)
927 929
928 930 def OnTimer(self, event):
929 931 update_tk(self.tk)
930 932 self.IP.runcode()
931 933
932 934 class App(self.wx.App):
933 935 wx = self.wx
934 936 TIMEOUT = self.TIMEOUT
935 937 def OnInit(self):
936 938 'Create the main window and insert the custom frame'
937 939 self.agent = TimerAgent(None, self.TIMEOUT)
938 940 self.agent.Show(False)
939 941 self.agent.StartWork()
940 942 return True
941 943
942 944 self.app = App(redirect=False)
943 945 self.wx_mainloop(self.app)
944 946 self.join()
945 947
946 948
947 949 class IPShellQt(IPThread):
948 950 """Run a Qt event loop in a separate thread.
949 951
950 952 Python commands can be passed to the thread where they will be executed.
951 953 This is implemented by periodically checking for passed code using a
952 954 Qt timer / slot."""
953 955
954 956 TIMEOUT = 100 # Millisecond interval between timeouts.
955 957
956 958 def __init__(self, argv=None, user_ns=None, user_global_ns=None,
957 959 debug=0, shell_class=MTInteractiveShell):
958 960
959 961 import qt
960 962
961 963 self.exec_loop = hijack_qt()
962 964
963 965 # Allows us to use both Tk and QT.
964 966 self.tk = get_tk()
965 967
966 968 self.IP = make_IPython(argv,
967 969 user_ns=user_ns,
968 970 user_global_ns=user_global_ns,
969 971 debug=debug,
970 972 shell_class=shell_class,
971 973 on_kill=[qt.qApp.exit])
972 974
973 975 # HACK: slot for banner in self; it will be passed to the mainloop
974 976 # method only and .run() needs it. The actual value will be set by
975 977 # .mainloop().
976 978 self._banner = None
977 979
978 980 threading.Thread.__init__(self)
979 981
980 982 def mainloop(self, sys_exit=0, banner=None):
981 983
982 984 import qt
983 985
984 986 self._banner = banner
985 987
986 988 if qt.QApplication.startingUp():
987 989 a = qt.QApplication(sys.argv)
988 990
989 991 self.timer = qt.QTimer()
990 992 qt.QObject.connect(self.timer,
991 993 qt.SIGNAL('timeout()'),
992 994 self.on_timer)
993 995
994 996 self.start()
995 997 self.timer.start(self.TIMEOUT, True)
996 998 while True:
997 999 if self.IP._kill: break
998 1000 self.exec_loop()
999 1001 self.join()
1000 1002
1001 1003 def on_timer(self):
1002 1004 update_tk(self.tk)
1003 1005 result = self.IP.runcode()
1004 1006 self.timer.start(self.TIMEOUT, True)
1005 1007 return result
1006 1008
1007 1009
1008 1010 class IPShellQt4(IPThread):
1009 1011 """Run a Qt event loop in a separate thread.
1010 1012
1011 1013 Python commands can be passed to the thread where they will be executed.
1012 1014 This is implemented by periodically checking for passed code using a
1013 1015 Qt timer / slot."""
1014 1016
1015 1017 TIMEOUT = 100 # Millisecond interval between timeouts.
1016 1018
1017 1019 def __init__(self, argv=None, user_ns=None, user_global_ns=None,
1018 1020 debug=0, shell_class=MTInteractiveShell):
1019 1021
1020 1022 from PyQt4 import QtCore, QtGui
1021 1023
1022 1024 try:
1023 1025 # present in PyQt4-4.2.1 or later
1024 1026 QtCore.pyqtRemoveInputHook()
1025 1027 except AttributeError:
1026 1028 pass
1027 1029
1028 1030 if QtCore.PYQT_VERSION_STR == '4.3':
1029 1031 warn('''PyQt4 version 4.3 detected.
1030 1032 If you experience repeated threading warnings, please update PyQt4.
1031 1033 ''')
1032 1034
1033 1035 self.exec_ = hijack_qt4()
1034 1036
1035 1037 # Allows us to use both Tk and QT.
1036 1038 self.tk = get_tk()
1037 1039
1038 1040 self.IP = make_IPython(argv,
1039 1041 user_ns=user_ns,
1040 1042 user_global_ns=user_global_ns,
1041 1043 debug=debug,
1042 1044 shell_class=shell_class,
1043 1045 on_kill=[QtGui.qApp.exit])
1044 1046
1045 1047 # HACK: slot for banner in self; it will be passed to the mainloop
1046 1048 # method only and .run() needs it. The actual value will be set by
1047 1049 # .mainloop().
1048 1050 self._banner = None
1049 1051
1050 1052 threading.Thread.__init__(self)
1051 1053
1052 1054 def mainloop(self, sys_exit=0, banner=None):
1053 1055
1054 1056 from PyQt4 import QtCore, QtGui
1055 1057
1056 1058 self._banner = banner
1057 1059
1058 1060 if QtGui.QApplication.startingUp():
1059 1061 a = QtGui.QApplication(sys.argv)
1060 1062
1061 1063 self.timer = QtCore.QTimer()
1062 1064 QtCore.QObject.connect(self.timer,
1063 1065 QtCore.SIGNAL('timeout()'),
1064 1066 self.on_timer)
1065 1067
1066 1068 self.start()
1067 1069 self.timer.start(self.TIMEOUT)
1068 1070 while True:
1069 1071 if self.IP._kill: break
1070 1072 self.exec_()
1071 1073 self.join()
1072 1074
1073 1075 def on_timer(self):
1074 1076 update_tk(self.tk)
1075 1077 result = self.IP.runcode()
1076 1078 self.timer.start(self.TIMEOUT)
1077 1079 return result
1078 1080
1079 1081
1080 1082 # A set of matplotlib public IPython shell classes, for single-threaded (Tk*
1081 1083 # and FLTK*) and multithreaded (GTK*, WX* and Qt*) backends to use.
1082 1084 def _load_pylab(user_ns):
1083 1085 """Allow users to disable pulling all of pylab into the top-level
1084 1086 namespace.
1085 1087
1086 1088 This little utility must be called AFTER the actual ipython instance is
1087 1089 running, since only then will the options file have been fully parsed."""
1088 1090
1089 1091 ip = IPython.ipapi.get()
1090 1092 if ip.options.pylab_import_all:
1091 1093 ip.ex("from matplotlib.pylab import *")
1092 1094 ip.IP.user_config_ns.update(ip.user_ns)
1093 1095
1094 1096
1095 1097 class IPShellMatplotlib(IPShell):
1096 1098 """Subclass IPShell with MatplotlibShell as the internal shell.
1097 1099
1098 1100 Single-threaded class, meant for the Tk* and FLTK* backends.
1099 1101
1100 1102 Having this on a separate class simplifies the external driver code."""
1101 1103
1102 1104 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1103 1105 IPShell.__init__(self,argv,user_ns,user_global_ns,debug,
1104 1106 shell_class=MatplotlibShell)
1105 1107 _load_pylab(self.IP.user_ns)
1106 1108
1107 1109 class IPShellMatplotlibGTK(IPShellGTK):
1108 1110 """Subclass IPShellGTK with MatplotlibMTShell as the internal shell.
1109 1111
1110 1112 Multi-threaded class, meant for the GTK* backends."""
1111 1113
1112 1114 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1113 1115 IPShellGTK.__init__(self,argv,user_ns,user_global_ns,debug,
1114 1116 shell_class=MatplotlibMTShell)
1115 1117 _load_pylab(self.IP.user_ns)
1116 1118
1117 1119 class IPShellMatplotlibWX(IPShellWX):
1118 1120 """Subclass IPShellWX with MatplotlibMTShell as the internal shell.
1119 1121
1120 1122 Multi-threaded class, meant for the WX* backends."""
1121 1123
1122 1124 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1123 1125 IPShellWX.__init__(self,argv,user_ns,user_global_ns,debug,
1124 1126 shell_class=MatplotlibMTShell)
1125 1127 _load_pylab(self.IP.user_ns)
1126 1128
1127 1129 class IPShellMatplotlibQt(IPShellQt):
1128 1130 """Subclass IPShellQt with MatplotlibMTShell as the internal shell.
1129 1131
1130 1132 Multi-threaded class, meant for the Qt* backends."""
1131 1133
1132 1134 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1133 1135 IPShellQt.__init__(self,argv,user_ns,user_global_ns,debug,
1134 1136 shell_class=MatplotlibMTShell)
1135 1137 _load_pylab(self.IP.user_ns)
1136 1138
1137 1139 class IPShellMatplotlibQt4(IPShellQt4):
1138 1140 """Subclass IPShellQt4 with MatplotlibMTShell as the internal shell.
1139 1141
1140 1142 Multi-threaded class, meant for the Qt4* backends."""
1141 1143
1142 1144 def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
1143 1145 IPShellQt4.__init__(self,argv,user_ns,user_global_ns,debug,
1144 1146 shell_class=MatplotlibMTShell)
1145 1147 _load_pylab(self.IP.user_ns)
1146 1148
1147 1149 #-----------------------------------------------------------------------------
1148 1150 # Factory functions to actually start the proper thread-aware shell
1149 1151
1150 1152 def _select_shell(argv):
1151 1153 """Select a shell from the given argv vector.
1152 1154
1153 1155 This function implements the threading selection policy, allowing runtime
1154 1156 control of the threading mode, both for general users and for matplotlib.
1155 1157
1156 1158 Return:
1157 1159 Shell class to be instantiated for runtime operation.
1158 1160 """
1159 1161
1160 1162 global USE_TK
1161 1163
1162 1164 mpl_shell = {'gthread' : IPShellMatplotlibGTK,
1163 1165 'wthread' : IPShellMatplotlibWX,
1164 1166 'qthread' : IPShellMatplotlibQt,
1165 1167 'q4thread' : IPShellMatplotlibQt4,
1166 1168 'tkthread' : IPShellMatplotlib, # Tk is built-in
1167 1169 }
1168 1170
1169 1171 th_shell = {'gthread' : IPShellGTK,
1170 1172 'wthread' : IPShellWX,
1171 1173 'qthread' : IPShellQt,
1172 1174 'q4thread' : IPShellQt4,
1173 1175 'tkthread' : IPShell, # Tk is built-in
1174 1176 }
1175 1177
1176 1178 backends = {'gthread' : 'GTKAgg',
1177 1179 'wthread' : 'WXAgg',
1178 1180 'qthread' : 'QtAgg',
1179 1181 'q4thread' :'Qt4Agg',
1180 1182 'tkthread' :'TkAgg',
1181 1183 }
1182 1184
1183 1185 all_opts = set(['tk','pylab','gthread','qthread','q4thread','wthread',
1184 1186 'tkthread'])
1185 1187 user_opts = set([s.replace('-','') for s in argv[:3]])
1186 1188 special_opts = user_opts & all_opts
1187 1189
1188 1190 if 'tk' in special_opts:
1189 1191 USE_TK = True
1190 1192 special_opts.remove('tk')
1191 1193
1192 1194 if 'pylab' in special_opts:
1193 1195
1194 1196 try:
1195 1197 import matplotlib
1196 1198 except ImportError:
1197 1199 error('matplotlib could NOT be imported! Starting normal IPython.')
1198 1200 return IPShell
1199 1201
1200 1202 special_opts.remove('pylab')
1201 1203 # If there's any option left, it means the user wants to force the
1202 1204 # threading backend, else it's auto-selected from the rc file
1203 1205 if special_opts:
1204 1206 th_mode = special_opts.pop()
1205 1207 matplotlib.rcParams['backend'] = backends[th_mode]
1206 1208 else:
1207 1209 backend = matplotlib.rcParams['backend']
1208 1210 if backend.startswith('GTK'):
1209 1211 th_mode = 'gthread'
1210 1212 elif backend.startswith('WX'):
1211 1213 th_mode = 'wthread'
1212 1214 elif backend.startswith('Qt4'):
1213 1215 th_mode = 'q4thread'
1214 1216 elif backend.startswith('Qt'):
1215 1217 th_mode = 'qthread'
1216 1218 else:
1217 1219 # Any other backend, use plain Tk
1218 1220 th_mode = 'tkthread'
1219 1221
1220 1222 return mpl_shell[th_mode]
1221 1223 else:
1222 1224 # No pylab requested, just plain threads
1223 1225 try:
1224 1226 th_mode = special_opts.pop()
1225 1227 except KeyError:
1226 1228 th_mode = 'tkthread'
1227 1229 return th_shell[th_mode]
1228 1230
1229 1231
1230 1232 # This is the one which should be called by external code.
1231 1233 def start(user_ns = None):
1232 1234 """Return a running shell instance, dealing with threading options.
1233 1235
1234 1236 This is a factory function which will instantiate the proper IPython shell
1235 1237 based on the user's threading choice. Such a selector is needed because
1236 1238 different GUI toolkits require different thread handling details."""
1237 1239
1238 1240 shell = _select_shell(sys.argv)
1239 1241 return shell(user_ns = user_ns)
1240 1242
1241 1243 # Some aliases for backwards compatibility
1242 1244 IPythonShell = IPShell
1243 1245 IPythonShellEmbed = IPShellEmbed
1244 1246 #************************ End of file <Shell.py> ***************************
@@ -1,116 +1,114 b''
1 1 """ User configuration file for IPython
2 2
3 3 This is a more flexible and safe way to configure ipython than *rc files
4 4 (ipythonrc, ipythonrc-pysh etc.)
5 5
6 6 This file is always imported on ipython startup. You can import the
7 7 ipython extensions you need here (see IPython/Extensions directory).
8 8
9 9 Feel free to edit this file to customize your ipython experience.
10 10
11 11 Note that as such this file does nothing, for backwards compatibility.
12 12 Consult e.g. file 'ipy_profile_sh.py' for an example of the things
13 13 you can do here.
14 14
15 15 See http://ipython.scipy.org/moin/IpythonExtensionApi for detailed
16 16 description on what you could do here.
17 17 """
18 18
19 19 # Most of your config files and extensions will probably start with this import
20 20
21 21 import IPython.ipapi
22 22 ip = IPython.ipapi.get()
23 23
24 24 # You probably want to uncomment this if you did %upgrade -nolegacy
25 25 # import ipy_defaults
26 26
27 27 import os
28 28
29 29 def main():
30 30
31 31 # uncomment if you want to get ipython -p sh behaviour
32 32 # without having to use command line switches
33 33 # import ipy_profile_sh
34 34
35 35 # Configure your favourite editor?
36 36 # Good idea e.g. for %edit os.path.isfile
37 37
38 38 #import ipy_editors
39 39
40 40 # Choose one of these:
41 41
42 42 #ipy_editors.scite()
43 43 #ipy_editors.scite('c:/opt/scite/scite.exe')
44 44 #ipy_editors.komodo()
45 45 #ipy_editors.idle()
46 46 # ... or many others, try 'ipy_editors??' after import to see them
47 47
48 48 # Or roll your own:
49 49 #ipy_editors.install_editor("c:/opt/jed +$line $file")
50 50
51 51
52 52 o = ip.options
53 53 # An example on how to set options
54 54 #o.autocall = 1
55 55 o.system_verbose = 0
56 56
57 57 #import_all("os sys")
58 58 #execf('~/_ipython/ns.py')
59 59
60 60
61 61 # -- prompt
62 62 # A different, more compact set of prompts from the default ones, that
63 63 # always show your current location in the filesystem:
64 64
65 65 #o.prompt_in1 = r'\C_LightBlue[\C_LightCyan\Y2\C_LightBlue]\C_Normal\n\C_Green|\#>'
66 66 #o.prompt_in2 = r'.\D: '
67 67 #o.prompt_out = r'[\#] '
68 68
69 69 # Try one of these color settings if you can't read the text easily
70 70 # autoexec is a list of IPython commands to execute on startup
71 71 #o.autoexec.append('%colors LightBG')
72 72 #o.autoexec.append('%colors NoColor')
73 73 #o.autoexec.append('%colors Linux')
74 74
75 75 # for sane integer division that converts to float (1/2 == 0.5)
76 76 #o.autoexec.append('from __future__ import division')
77 77
78 78 # For %tasks and %kill
79 79 #import jobctrl
80 80
81 81 # For autoreloading of modules (%autoreload, %aimport)
82 82 #import ipy_autoreload
83 83
84 84 # For winpdb support (%wdb)
85 85 #import ipy_winpdb
86 86
87 87 # For bzr completer, requires bzrlib (the python installation of bzr)
88 88 #ip.load('ipy_bzr')
89 89
90 90 # Tab completer that is not quite so picky (i.e.
91 91 # "foo".<TAB> and str(2).<TAB> will work). Complete
92 92 # at your own risk!
93 93 #import ipy_greedycompleter
94 94
95 95 # If you are on Linux, you may be annoyed by
96 96 # "Display all N possibilities? (y or n)" on tab completion,
97 97 # as well as the paging through "more". Uncomment the following
98 98 # lines to disable that behaviour
99 99 #import readline
100 100 #readline.parse_and_bind('set completion-query-items 1000')
101 101 #readline.parse_and_bind('set page-completions no')
102
103
104
105
102
103
106 104 # some config helper functions you can use
107 105 def import_all(modules):
108 106 """ Usage: import_all("os sys") """
109 107 for m in modules.split():
110 108 ip.ex("from %s import *" % m)
111
109
112 110 def execf(fname):
113 111 """ Execute a file in user namespace """
114 112 ip.ex('execfile("%s")' % os.path.expanduser(fname))
115 113
116 114 main()
@@ -1,490 +1,490 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Manage background (threaded) jobs conveniently from an interactive shell.
3 3
4 4 This module provides a BackgroundJobManager class. This is the main class
5 5 meant for public usage, it implements an object which can create and manage
6 6 new background jobs.
7 7
8 8 It also provides the actual job classes managed by these BackgroundJobManager
9 9 objects, see their docstrings below.
10 10
11 11
12 12 This system was inspired by discussions with B. Granger and the
13 13 BackgroundCommand class described in the book Python Scripting for
14 14 Computational Science, by H. P. Langtangen:
15 15
16 16 http://folk.uio.no/hpl/scripting
17 17
18 18 (although ultimately no code from this text was used, as IPython's system is a
19 19 separate implementation).
20 20 """
21 21
22 22 #*****************************************************************************
23 23 # Copyright (C) 2005-2006 Fernando Perez <fperez@colorado.edu>
24 24 #
25 25 # Distributed under the terms of the BSD License. The full license is in
26 26 # the file COPYING, distributed as part of this software.
27 27 #*****************************************************************************
28 28
29 29 # Code begins
30 30 import sys
31 31 import threading
32 32
33 33 from IPython.ultraTB import AutoFormattedTB
34 34 from IPython.genutils import warn,error
35 35
36 36 class BackgroundJobManager:
37 37 """Class to manage a pool of backgrounded threaded jobs.
38 38
39 39 Below, we assume that 'jobs' is a BackgroundJobManager instance.
40 40
41 41 Usage summary (see the method docstrings for details):
42 42
43 43 jobs.new(...) -> start a new job
44 44
45 45 jobs() or jobs.status() -> print status summary of all jobs
46 46
47 47 jobs[N] -> returns job number N.
48 48
49 49 foo = jobs[N].result -> assign to variable foo the result of job N
50 50
51 51 jobs[N].traceback() -> print the traceback of dead job N
52 52
53 53 jobs.remove(N) -> remove (finished) job N
54 54
55 55 jobs.flush_finished() -> remove all finished jobs
56 56
57 57 As a convenience feature, BackgroundJobManager instances provide the
58 58 utility result and traceback methods which retrieve the corresponding
59 59 information from the jobs list:
60 60
61 61 jobs.result(N) <--> jobs[N].result
62 62 jobs.traceback(N) <--> jobs[N].traceback()
63 63
64 64 While this appears minor, it allows you to use tab completion
65 65 interactively on the job manager instance.
66 66
67 67 In interactive mode, IPython provides the magic fuction %bg for quick
68 68 creation of backgrounded expression-based jobs. Type bg? for details."""
69 69
70 70 def __init__(self):
71 71 # Lists for job management
72 72 self.jobs_run = []
73 73 self.jobs_comp = []
74 74 self.jobs_dead = []
75 75 # A dict of all jobs, so users can easily access any of them
76 76 self.jobs_all = {}
77 77 # For reporting
78 78 self._comp_report = []
79 79 self._dead_report = []
80 80 # Store status codes locally for fast lookups
81 81 self._s_created = BackgroundJobBase.stat_created_c
82 82 self._s_running = BackgroundJobBase.stat_running_c
83 83 self._s_completed = BackgroundJobBase.stat_completed_c
84 84 self._s_dead = BackgroundJobBase.stat_dead_c
85 85
86 86 def new(self,func_or_exp,*args,**kwargs):
87 87 """Add a new background job and start it in a separate thread.
88 88
89 89 There are two types of jobs which can be created:
90 90
91 91 1. Jobs based on expressions which can be passed to an eval() call.
92 92 The expression must be given as a string. For example:
93 93
94 94 job_manager.new('myfunc(x,y,z=1)'[,glob[,loc]])
95 95
96 96 The given expression is passed to eval(), along with the optional
97 97 global/local dicts provided. If no dicts are given, they are
98 98 extracted automatically from the caller's frame.
99 99
100 100 A Python statement is NOT a valid eval() expression. Basically, you
101 101 can only use as an eval() argument something which can go on the right
102 102 of an '=' sign and be assigned to a variable.
103 103
104 104 For example,"print 'hello'" is not valid, but '2+3' is.
105 105
106 106 2. Jobs given a function object, optionally passing additional
107 107 positional arguments:
108 108
109 109 job_manager.new(myfunc,x,y)
110 110
111 111 The function is called with the given arguments.
112 112
113 113 If you need to pass keyword arguments to your function, you must
114 114 supply them as a dict named kw:
115 115
116 116 job_manager.new(myfunc,x,y,kw=dict(z=1))
117 117
118 118 The reason for this assymmetry is that the new() method needs to
119 119 maintain access to its own keywords, and this prevents name collisions
120 120 between arguments to new() and arguments to your own functions.
121 121
122 122 In both cases, the result is stored in the job.result field of the
123 123 background job object.
124 124
125 125
126 126 Notes and caveats:
127 127
128 128 1. All threads running share the same standard output. Thus, if your
129 129 background jobs generate output, it will come out on top of whatever
130 130 you are currently writing. For this reason, background jobs are best
131 131 used with silent functions which simply return their output.
132 132
133 133 2. Threads also all work within the same global namespace, and this
134 134 system does not lock interactive variables. So if you send job to the
135 135 background which operates on a mutable object for a long time, and
136 136 start modifying that same mutable object interactively (or in another
137 137 backgrounded job), all sorts of bizarre behaviour will occur.
138 138
139 139 3. If a background job is spending a lot of time inside a C extension
140 140 module which does not release the Python Global Interpreter Lock
141 141 (GIL), this will block the IPython prompt. This is simply because the
142 142 Python interpreter can only switch between threads at Python
143 143 bytecodes. While the execution is inside C code, the interpreter must
144 144 simply wait unless the extension module releases the GIL.
145 145
146 146 4. There is no way, due to limitations in the Python threads library,
147 147 to kill a thread once it has started."""
148 148
149 149 if callable(func_or_exp):
150 150 kw = kwargs.get('kw',{})
151 151 job = BackgroundJobFunc(func_or_exp,*args,**kw)
152 152 elif isinstance(func_or_exp,basestring):
153 153 if not args:
154 154 frame = sys._getframe(1)
155 155 glob, loc = frame.f_globals, frame.f_locals
156 156 elif len(args)==1:
157 157 glob = loc = args[0]
158 158 elif len(args)==2:
159 159 glob,loc = args
160 160 else:
161 161 raise ValueError,\
162 162 'Expression jobs take at most 2 args (globals,locals)'
163 163 job = BackgroundJobExpr(func_or_exp,glob,loc)
164 164 else:
165 165 raise
166 166 jkeys = self.jobs_all.keys()
167 167 if jkeys:
168 168 job.num = max(jkeys)+1
169 169 else:
170 170 job.num = 0
171 171 self.jobs_run.append(job)
172 172 self.jobs_all[job.num] = job
173 173 print 'Starting job # %s in a separate thread.' % job.num
174 174 job.start()
175 175 return job
176 176
177 177 def __getitem__(self,key):
178 178 return self.jobs_all[key]
179 179
180 180 def __call__(self):
181 181 """An alias to self.status(),
182 182
183 183 This allows you to simply call a job manager instance much like the
184 184 Unix jobs shell command."""
185 185
186 186 return self.status()
187 187
188 188 def _update_status(self):
189 189 """Update the status of the job lists.
190 190
191 191 This method moves finished jobs to one of two lists:
192 192 - self.jobs_comp: jobs which completed successfully
193 193 - self.jobs_dead: jobs which finished but died.
194 194
195 195 It also copies those jobs to corresponding _report lists. These lists
196 196 are used to report jobs completed/dead since the last update, and are
197 197 then cleared by the reporting function after each call."""
198 198
199 199 run,comp,dead = self._s_running,self._s_completed,self._s_dead
200 200 jobs_run = self.jobs_run
201 201 for num in range(len(jobs_run)):
202 202 job = jobs_run[num]
203 203 stat = job.stat_code
204 204 if stat == run:
205 205 continue
206 206 elif stat == comp:
207 207 self.jobs_comp.append(job)
208 208 self._comp_report.append(job)
209 209 jobs_run[num] = False
210 210 elif stat == dead:
211 211 self.jobs_dead.append(job)
212 212 self._dead_report.append(job)
213 213 jobs_run[num] = False
214 214 self.jobs_run = filter(None,self.jobs_run)
215 215
216 216 def _group_report(self,group,name):
217 217 """Report summary for a given job group.
218 218
219 219 Return True if the group had any elements."""
220 220
221 221 if group:
222 222 print '%s jobs:' % name
223 223 for job in group:
224 224 print '%s : %s' % (job.num,job)
225 225 print
226 226 return True
227 227
228 228 def _group_flush(self,group,name):
229 229 """Flush a given job group
230 230
231 231 Return True if the group had any elements."""
232 232
233 233 njobs = len(group)
234 234 if njobs:
235 235 plural = {1:''}.setdefault(njobs,'s')
236 236 print 'Flushing %s %s job%s.' % (njobs,name,plural)
237 237 group[:] = []
238 238 return True
239 239
240 240 def _status_new(self):
241 241 """Print the status of newly finished jobs.
242 242
243 243 Return True if any new jobs are reported.
244 244
245 245 This call resets its own state every time, so it only reports jobs
246 246 which have finished since the last time it was called."""
247 247
248 248 self._update_status()
249 249 new_comp = self._group_report(self._comp_report,'Completed')
250 250 new_dead = self._group_report(self._dead_report,
251 'Dead, call job.traceback() for details')
251 'Dead, call jobs.traceback() for details')
252 252 self._comp_report[:] = []
253 253 self._dead_report[:] = []
254 254 return new_comp or new_dead
255 255
256 256 def status(self,verbose=0):
257 257 """Print a status of all jobs currently being managed."""
258 258
259 259 self._update_status()
260 260 self._group_report(self.jobs_run,'Running')
261 261 self._group_report(self.jobs_comp,'Completed')
262 262 self._group_report(self.jobs_dead,'Dead')
263 263 # Also flush the report queues
264 264 self._comp_report[:] = []
265 265 self._dead_report[:] = []
266 266
267 267 def remove(self,num):
268 268 """Remove a finished (completed or dead) job."""
269 269
270 270 try:
271 271 job = self.jobs_all[num]
272 272 except KeyError:
273 273 error('Job #%s not found' % num)
274 274 else:
275 275 stat_code = job.stat_code
276 276 if stat_code == self._s_running:
277 277 error('Job #%s is still running, it can not be removed.' % num)
278 278 return
279 279 elif stat_code == self._s_completed:
280 280 self.jobs_comp.remove(job)
281 281 elif stat_code == self._s_dead:
282 282 self.jobs_dead.remove(job)
283 283
284 284 def flush_finished(self):
285 285 """Flush all jobs finished (completed and dead) from lists.
286 286
287 287 Running jobs are never flushed.
288 288
289 289 It first calls _status_new(), to update info. If any jobs have
290 290 completed since the last _status_new() call, the flush operation
291 291 aborts."""
292 292
293 293 if self._status_new():
294 294 error('New jobs completed since last '\
295 295 '_status_new(), aborting flush.')
296 296 return
297 297
298 298 # Remove the finished jobs from the master dict
299 299 jobs_all = self.jobs_all
300 300 for job in self.jobs_comp+self.jobs_dead:
301 301 del(jobs_all[job.num])
302 302
303 303 # Now flush these lists completely
304 304 fl_comp = self._group_flush(self.jobs_comp,'Completed')
305 305 fl_dead = self._group_flush(self.jobs_dead,'Dead')
306 306 if not (fl_comp or fl_dead):
307 307 print 'No jobs to flush.'
308 308
309 309 def result(self,num):
310 310 """result(N) -> return the result of job N."""
311 311 try:
312 312 return self.jobs_all[num].result
313 313 except KeyError:
314 314 error('Job #%s not found' % num)
315 315
316 316 def traceback(self,num):
317 317 try:
318 318 self.jobs_all[num].traceback()
319 319 except KeyError:
320 320 error('Job #%s not found' % num)
321 321
322 322
323 323 class BackgroundJobBase(threading.Thread):
324 324 """Base class to build BackgroundJob classes.
325 325
326 326 The derived classes must implement:
327 327
328 328 - Their own __init__, since the one here raises NotImplementedError. The
329 329 derived constructor must call self._init() at the end, to provide common
330 330 initialization.
331 331
332 332 - A strform attribute used in calls to __str__.
333 333
334 334 - A call() method, which will make the actual execution call and must
335 335 return a value to be held in the 'result' field of the job object."""
336 336
337 337 # Class constants for status, in string and as numerical codes (when
338 338 # updating jobs lists, we don't want to do string comparisons). This will
339 339 # be done at every user prompt, so it has to be as fast as possible
340 340 stat_created = 'Created'; stat_created_c = 0
341 341 stat_running = 'Running'; stat_running_c = 1
342 342 stat_completed = 'Completed'; stat_completed_c = 2
343 stat_dead = 'Dead (Exception), call job.traceback() for details'
343 stat_dead = 'Dead (Exception), call jobs.traceback() for details'
344 344 stat_dead_c = -1
345 345
346 346 def __init__(self):
347 347 raise NotImplementedError, \
348 348 "This class can not be instantiated directly."
349 349
350 350 def _init(self):
351 351 """Common initialization for all BackgroundJob objects"""
352 352
353 353 for attr in ['call','strform']:
354 354 assert hasattr(self,attr), "Missing attribute <%s>" % attr
355 355
356 356 # The num tag can be set by an external job manager
357 357 self.num = None
358 358
359 359 self.status = BackgroundJobBase.stat_created
360 360 self.stat_code = BackgroundJobBase.stat_created_c
361 361 self.finished = False
362 362 self.result = '<BackgroundJob has not completed>'
363 363 # reuse the ipython traceback handler if we can get to it, otherwise
364 364 # make a new one
365 365 try:
366 366 self._make_tb = __IPYTHON__.InteractiveTB.text
367 367 except:
368 368 self._make_tb = AutoFormattedTB(mode = 'Context',
369 369 color_scheme='NoColor',
370 370 tb_offset = 1).text
371 371 # Hold a formatted traceback if one is generated.
372 372 self._tb = None
373 373
374 374 threading.Thread.__init__(self)
375 375
376 376 def __str__(self):
377 377 return self.strform
378 378
379 379 def __repr__(self):
380 380 return '<BackgroundJob: %s>' % self.strform
381 381
382 382 def traceback(self):
383 383 print self._tb
384 384
385 385 def run(self):
386 386 try:
387 387 self.status = BackgroundJobBase.stat_running
388 388 self.stat_code = BackgroundJobBase.stat_running_c
389 389 self.result = self.call()
390 390 except:
391 391 self.status = BackgroundJobBase.stat_dead
392 392 self.stat_code = BackgroundJobBase.stat_dead_c
393 393 self.finished = None
394 self.result = ('<BackgroundJob died, call job.traceback() for details>')
394 self.result = ('<BackgroundJob died, call jobs.traceback() for details>')
395 395 self._tb = self._make_tb()
396 396 else:
397 397 self.status = BackgroundJobBase.stat_completed
398 398 self.stat_code = BackgroundJobBase.stat_completed_c
399 399 self.finished = True
400 400
401 401 class BackgroundJobExpr(BackgroundJobBase):
402 402 """Evaluate an expression as a background job (uses a separate thread)."""
403 403
404 404 def __init__(self,expression,glob=None,loc=None):
405 405 """Create a new job from a string which can be fed to eval().
406 406
407 407 global/locals dicts can be provided, which will be passed to the eval
408 408 call."""
409 409
410 410 # fail immediately if the given expression can't be compiled
411 411 self.code = compile(expression,'<BackgroundJob compilation>','eval')
412 412
413 413 if glob is None:
414 414 glob = {}
415 415 if loc is None:
416 416 loc = {}
417 417
418 418 self.expression = self.strform = expression
419 419 self.glob = glob
420 420 self.loc = loc
421 421 self._init()
422 422
423 423 def call(self):
424 424 return eval(self.code,self.glob,self.loc)
425 425
426 426 class BackgroundJobFunc(BackgroundJobBase):
427 427 """Run a function call as a background job (uses a separate thread)."""
428 428
429 429 def __init__(self,func,*args,**kwargs):
430 430 """Create a new job from a callable object.
431 431
432 432 Any positional arguments and keyword args given to this constructor
433 433 after the initial callable are passed directly to it."""
434 434
435 435 assert callable(func),'first argument must be callable'
436 436
437 437 if args is None:
438 438 args = []
439 439 if kwargs is None:
440 440 kwargs = {}
441 441
442 442 self.func = func
443 443 self.args = args
444 444 self.kwargs = kwargs
445 445 # The string form will only include the function passed, because
446 446 # generating string representations of the arguments is a potentially
447 447 # _very_ expensive operation (e.g. with large arrays).
448 448 self.strform = str(func)
449 449 self._init()
450 450
451 451 def call(self):
452 452 return self.func(*self.args,**self.kwargs)
453 453
454 454
455 455 if __name__=='__main__':
456 456
457 457 import time
458 458
459 459 def sleepfunc(interval=2,*a,**kw):
460 460 args = dict(interval=interval,
461 461 args=a,
462 462 kwargs=kw)
463 463 time.sleep(interval)
464 464 return args
465 465
466 466 def diefunc(interval=2,*a,**kw):
467 467 time.sleep(interval)
468 468 die
469 469
470 470 def printfunc(interval=1,reps=5):
471 471 for n in range(reps):
472 472 time.sleep(interval)
473 473 print 'In the background...'
474 474
475 475 jobs = BackgroundJobManager()
476 476 # first job will have # 0
477 477 jobs.new(sleepfunc,4)
478 478 jobs.new(sleepfunc,kw={'reps':2})
479 479 # This makes a job which will die
480 480 jobs.new(diefunc,1)
481 481 jobs.new('printfunc(1,3)')
482 482
483 483 # after a while, you can get the traceback of a dead job. Run the line
484 484 # below again interactively until it prints a traceback (check the status
485 485 # of the job):
486 486 print jobs[1].status
487 487 jobs[1].traceback()
488 488
489 489 # Run this line again until the printed result changes
490 490 print "The result of job #0 is:",jobs[0].result
@@ -1,76 +1,77 b''
1 1 """
2 2 Base front end class for all async frontends.
3 3 """
4 4 __docformat__ = "restructuredtext en"
5 5
6 6 #-------------------------------------------------------------------------------
7 7 # Copyright (C) 2008 The IPython Development Team
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #-------------------------------------------------------------------------------
12 12
13 13
14 14 #-------------------------------------------------------------------------------
15 15 # Imports
16 16 #-------------------------------------------------------------------------------
17 from IPython.external import guid
18 17
18 from IPython.external import guid
19 19
20 20 from zope.interface import Interface, Attribute, implements, classProvides
21 21 from twisted.python.failure import Failure
22 from IPython.frontend.frontendbase import FrontEndBase, IFrontEnd, IFrontEndFactory
22 from IPython.frontend.frontendbase import (
23 FrontEndBase, IFrontEnd, IFrontEndFactory)
23 24 from IPython.kernel.core.history import FrontEndHistory
24 25 from IPython.kernel.engineservice import IEngineCore
25 26
26 27
27 28 class AsyncFrontEndBase(FrontEndBase):
28 29 """
29 30 Overrides FrontEndBase to wrap execute in a deferred result.
30 31 All callbacks are made as callbacks on the deferred result.
31 32 """
32 33
33 34 implements(IFrontEnd)
34 35 classProvides(IFrontEndFactory)
35 36
36 37 def __init__(self, engine=None, history=None):
37 38 assert(engine==None or IEngineCore.providedBy(engine))
38 39 self.engine = IEngineCore(engine)
39 40 if history is None:
40 41 self.history = FrontEndHistory(input_cache=[''])
41 42 else:
42 43 self.history = history
43 44
44 45
45 46 def execute(self, block, blockID=None):
46 47 """Execute the block and return the deferred result.
47 48
48 49 Parameters:
49 50 block : {str, AST}
50 51 blockID : any
51 52 Caller may provide an ID to identify this block.
52 53 result['blockID'] := blockID
53 54
54 55 Result:
55 56 Deferred result of self.interpreter.execute
56 57 """
57 58
58 59 if(not self.is_complete(block)):
59 60 return Failure(Exception("Block is not compilable"))
60 61
61 62 if(blockID == None):
62 63 blockID = guid.generate()
63 64
64 65 d = self.engine.execute(block)
65 66 d.addCallback(self._add_history, block=block)
66 67 d.addCallbacks(self._add_block_id_for_result,
67 68 errback=self._add_block_id_for_failure,
68 69 callbackArgs=(blockID,),
69 70 errbackArgs=(blockID,))
70 71 d.addBoth(self.update_cell_prompt, blockID=blockID)
71 72 d.addCallbacks(self.render_result,
72 73 errback=self.render_error)
73 74
74 75 return d
75 76
76 77
@@ -1,94 +1,100 b''
1 1 # encoding: utf-8
2 2 """This file contains unittests for the
3 3 IPython.frontend.cocoa.cocoa_frontend module.
4 4 """
5 5 __docformat__ = "restructuredtext en"
6 6
7 7 #---------------------------------------------------------------------------
8 8 # Copyright (C) 2005 The IPython Development Team
9 9 #
10 10 # Distributed under the terms of the BSD License. The full license is in
11 11 # the file COPYING, distributed as part of this software.
12 12 #---------------------------------------------------------------------------
13 13
14 14 #---------------------------------------------------------------------------
15 15 # Imports
16 16 #---------------------------------------------------------------------------
17 17
18 # Tell nose to skip this module
19 __test__ = {}
20
21 from twisted.trial import unittest
22 from twisted.internet.defer import succeed
23
24 from IPython.kernel.core.interpreter import Interpreter
25 import IPython.kernel.engineservice as es
26
18 27 try:
19 from IPython.kernel.core.interpreter import Interpreter
20 import IPython.kernel.engineservice as es
21 from IPython.testing.util import DeferredTestCase
22 from twisted.internet.defer import succeed
23 from IPython.frontend.cocoa.cocoa_frontend import IPythonCocoaController
28 from IPython.frontend.cocoa.cocoa_frontend import IPythonCocoaController
24 29 from Foundation import NSMakeRect
25 from AppKit import NSTextView, NSScrollView
30 from AppKit import NSTextView, NSScrollView
26 31 except ImportError:
27 import nose
28 raise nose.SkipTest("This test requires zope.interface, Twisted, Foolscap and PyObjC")
32 # This tells twisted.trial to skip this module if PyObjC is not found
33 skip = True
29 34
30 class TestIPythonCocoaControler(DeferredTestCase):
35 #---------------------------------------------------------------------------
36 # Tests
37 #---------------------------------------------------------------------------
38 class TestIPythonCocoaControler(unittest.TestCase):
31 39 """Tests for IPythonCocoaController"""
32
40
33 41 def setUp(self):
34 42 self.controller = IPythonCocoaController.alloc().init()
35 43 self.engine = es.EngineService()
36 44 self.engine.startService()
37
45
38 46 def tearDown(self):
39 47 self.controller = None
40 48 self.engine.stopService()
41
49
42 50 def testControllerExecutesCode(self):
43 51 code ="""5+5"""
44 52 expected = Interpreter().execute(code)
45 53 del expected['number']
46 54 def removeNumberAndID(result):
47 55 del result['number']
48 56 del result['id']
49 57 return result
50 self.assertDeferredEquals(
51 self.controller.execute(code).addCallback(removeNumberAndID),
52 expected)
53
58 d = self.controller.execute(code)
59 d.addCallback(removeNumberAndID)
60 d.addCallback(lambda r: self.assertEquals(r, expected))
61
54 62 def testControllerMirrorsUserNSWithValuesAsStrings(self):
55 63 code = """userns1=1;userns2=2"""
56 64 def testControllerUserNS(result):
57 65 self.assertEquals(self.controller.userNS['userns1'], 1)
58 66 self.assertEquals(self.controller.userNS['userns2'], 2)
59
60 67 self.controller.execute(code).addCallback(testControllerUserNS)
61
62
68
63 69 def testControllerInstantiatesIEngine(self):
64 70 self.assert_(es.IEngineBase.providedBy(self.controller.engine))
65
71
66 72 def testControllerCompletesToken(self):
67 73 code = """longNameVariable=10"""
68 74 def testCompletes(result):
69 75 self.assert_("longNameVariable" in result)
70
76
71 77 def testCompleteToken(result):
72 78 self.controller.complete("longNa").addCallback(testCompletes)
73
79
74 80 self.controller.execute(code).addCallback(testCompletes)
75
76
81
82
77 83 def testCurrentIndent(self):
78 84 """test that current_indent_string returns current indent or None.
79 85 Uses _indent_for_block for direct unit testing.
80 86 """
81
87
82 88 self.controller.tabUsesSpaces = True
83 89 self.assert_(self.controller._indent_for_block("""a=3""") == None)
84 90 self.assert_(self.controller._indent_for_block("") == None)
85 91 block = """def test():\n a=3"""
86 92 self.assert_(self.controller._indent_for_block(block) == \
87 93 ' ' * self.controller.tabSpaces)
88
94
89 95 block = """if(True):\n%sif(False):\n%spass""" % \
90 96 (' '*self.controller.tabSpaces,
91 97 2*' '*self.controller.tabSpaces)
92 98 self.assert_(self.controller._indent_for_block(block) == \
93 99 2*(' '*self.controller.tabSpaces))
94
100
@@ -1,333 +1,372 b''
1 1 """
2 2 Base front end class for all line-oriented frontends, rather than
3 3 block-oriented.
4 4
5 5 Currently this focuses on synchronous frontends.
6 6 """
7 7 __docformat__ = "restructuredtext en"
8 8
9 9 #-------------------------------------------------------------------------------
10 10 # Copyright (C) 2008 The IPython Development Team
11 11 #
12 12 # Distributed under the terms of the BSD License. The full license is in
13 13 # the file COPYING, distributed as part of this software.
14 14 #-------------------------------------------------------------------------------
15 15
16 16 #-------------------------------------------------------------------------------
17 17 # Imports
18 18 #-------------------------------------------------------------------------------
19 19 import re
20 20
21 import IPython
22 21 import sys
23 22 import codeop
24 import traceback
25 23
26 24 from frontendbase import FrontEndBase
27 25 from IPython.kernel.core.interpreter import Interpreter
28 26
29 27 def common_prefix(strings):
30 28 """ Given a list of strings, return the common prefix between all
31 29 these strings.
32 30 """
33 31 ref = strings[0]
34 32 prefix = ''
35 33 for size in range(len(ref)):
36 34 test_prefix = ref[:size+1]
37 35 for string in strings[1:]:
38 36 if not string.startswith(test_prefix):
39 37 return prefix
40 38 prefix = test_prefix
41 39
42 40 return prefix
43 41
44 42 #-------------------------------------------------------------------------------
45 43 # Base class for the line-oriented front ends
46 44 #-------------------------------------------------------------------------------
47 45 class LineFrontEndBase(FrontEndBase):
48 46 """ Concrete implementation of the FrontEndBase class. This is meant
49 47 to be the base class behind all the frontend that are line-oriented,
50 48 rather than block-oriented.
51 49 """
52 50
53 51 # We need to keep the prompt number, to be able to increment
54 52 # it when there is an exception.
55 53 prompt_number = 1
56 54
57 55 # We keep a reference to the last result: it helps testing and
58 56 # programatic control of the frontend.
59 57 last_result = dict(number=0)
60 58
59 # The last prompt displayed. Useful for continuation prompts.
60 last_prompt = ''
61
61 62 # The input buffer being edited
62 63 input_buffer = ''
63 64
64 65 # Set to true for debug output
65 66 debug = False
66 67
67 68 # A banner to print at startup
68 69 banner = None
69 70
70 71 #--------------------------------------------------------------------------
71 72 # FrontEndBase interface
72 73 #--------------------------------------------------------------------------
73 74
74 75 def __init__(self, shell=None, history=None, banner=None, *args, **kwargs):
75 76 if shell is None:
76 77 shell = Interpreter()
77 78 FrontEndBase.__init__(self, shell=shell, history=history)
78 79
79 80 if banner is not None:
80 81 self.banner = banner
81 82
82 83 def start(self):
83 84 """ Put the frontend in a state where it is ready for user
84 85 interaction.
85 86 """
86 87 if self.banner is not None:
87 88 self.write(self.banner, refresh=False)
88 89
89 90 self.new_prompt(self.input_prompt_template.substitute(number=1))
90 91
91 92
92 93 def complete(self, line):
93 94 """Complete line in engine's user_ns
94 95
95 96 Parameters
96 97 ----------
97 98 line : string
98 99
99 100 Result
100 101 ------
101 102 The replacement for the line and the list of possible completions.
102 103 """
103 104 completions = self.shell.complete(line)
104 105 complete_sep = re.compile('[\s\{\}\[\]\(\)\=]')
105 106 if completions:
106 107 prefix = common_prefix(completions)
107 108 residual = complete_sep.split(line)[:-1]
108 109 line = line[:-len(residual)] + prefix
109 110 return line, completions
110 111
111 112
112 113 def render_result(self, result):
113 114 """ Frontend-specific rendering of the result of a calculation
114 115 that has been sent to an engine.
115 116 """
116 117 if 'stdout' in result and result['stdout']:
117 118 self.write('\n' + result['stdout'])
118 119 if 'display' in result and result['display']:
119 120 self.write("%s%s\n" % (
120 121 self.output_prompt_template.substitute(
121 122 number=result['number']),
122 123 result['display']['pprint']
123 124 ) )
124 125
125 126
126 127 def render_error(self, failure):
127 128 """ Frontend-specific rendering of error.
128 129 """
129 130 self.write('\n\n'+str(failure)+'\n\n')
130 131 return failure
131 132
132 133
133 134 def is_complete(self, string):
134 135 """ Check if a string forms a complete, executable set of
135 136 commands.
136 137
137 138 For the line-oriented frontend, multi-line code is not executed
138 139 as soon as it is complete: the users has to enter two line
139 140 returns.
140 141 """
141 142 if string in ('', '\n'):
142 143 # Prefiltering, eg through ipython0, may return an empty
143 144 # string although some operations have been accomplished. We
144 145 # thus want to consider an empty string as a complete
145 146 # statement.
146 147 return True
147 148 elif ( len(self.input_buffer.split('\n'))>2
148 149 and not re.findall(r"\n[\t ]*\n[\t ]*$", string)):
149 150 return False
150 151 else:
151 152 self.capture_output()
152 153 try:
153 154 # Add line returns here, to make sure that the statement is
154 # complete.
155 is_complete = codeop.compile_command(string.rstrip() + '\n\n',
155 # complete (except if '\' was used).
156 # This should probably be done in a different place (like
157 # maybe 'prefilter_input' method? For now, this works.
158 clean_string = string.rstrip('\n')
159 if not clean_string.endswith('\\'): clean_string +='\n\n'
160 is_complete = codeop.compile_command(clean_string,
156 161 "<string>", "exec")
157 162 self.release_output()
158 163 except Exception, e:
159 164 # XXX: Hack: return True so that the
160 165 # code gets executed and the error captured.
161 166 is_complete = True
162 167 return is_complete
163 168
164 169
165 170 def write(self, string, refresh=True):
166 171 """ Write some characters to the display.
167 172
168 173 Subclass should overide this method.
169 174
170 175 The refresh keyword argument is used in frontends with an
171 176 event loop, to choose whether the write should trigget an UI
172 177 refresh, and thus be syncrhonous, or not.
173 178 """
174 179 print >>sys.__stderr__, string
175 180
176 181
177 182 def execute(self, python_string, raw_string=None):
178 183 """ Stores the raw_string in the history, and sends the
179 184 python string to the interpreter.
180 185 """
181 186 if raw_string is None:
182 187 raw_string = python_string
183 188 # Create a false result, in case there is an exception
184 189 self.last_result = dict(number=self.prompt_number)
185 190
186 ## try:
187 ## self.history.input_cache[-1] = raw_string.rstrip()
188 ## result = self.shell.execute(python_string)
189 ## self.last_result = result
190 ## self.render_result(result)
191 ## except:
192 ## self.show_traceback()
193 ## finally:
194 ## self.after_execute()
195
196 191 try:
197 192 try:
198 193 self.history.input_cache[-1] = raw_string.rstrip()
199 194 result = self.shell.execute(python_string)
200 195 self.last_result = result
201 196 self.render_result(result)
202 197 except:
203 198 self.show_traceback()
204 199 finally:
205 200 self.after_execute()
206 201
207 202
208 203 #--------------------------------------------------------------------------
209 204 # LineFrontEndBase interface
210 205 #--------------------------------------------------------------------------
211 206
212 207 def prefilter_input(self, string):
213 208 """ Prefilter the input to turn it in valid python.
214 209 """
215 210 string = string.replace('\r\n', '\n')
216 211 string = string.replace('\t', 4*' ')
217 212 # Clean the trailing whitespace
218 213 string = '\n'.join(l.rstrip() for l in string.split('\n'))
219 214 return string
220 215
221 216
222 217 def after_execute(self):
223 218 """ All the operations required after an execution to put the
224 219 terminal back in a shape where it is usable.
225 220 """
226 221 self.prompt_number += 1
227 222 self.new_prompt(self.input_prompt_template.substitute(
228 223 number=(self.last_result['number'] + 1)))
229 224 # Start a new empty history entry
230 225 self._add_history(None, '')
231 226 self.history_cursor = len(self.history.input_cache) - 1
232 227
233 228
234 229 def complete_current_input(self):
235 230 """ Do code completion on current line.
236 231 """
237 232 if self.debug:
238 233 print >>sys.__stdout__, "complete_current_input",
239 234 line = self.input_buffer
240 235 new_line, completions = self.complete(line)
241 236 if len(completions)>1:
242 237 self.write_completion(completions, new_line=new_line)
243 238 elif not line == new_line:
244 239 self.input_buffer = new_line
245 240 if self.debug:
246 241 print >>sys.__stdout__, 'line', line
247 242 print >>sys.__stdout__, 'new_line', new_line
248 243 print >>sys.__stdout__, completions
249 244
250 245
251 246 def get_line_width(self):
252 247 """ Return the width of the line in characters.
253 248 """
254 249 return 80
255 250
256 251
257 252 def write_completion(self, possibilities, new_line=None):
258 253 """ Write the list of possible completions.
259 254
260 255 new_line is the completed input line that should be displayed
261 256 after the completion are writen. If None, the input_buffer
262 257 before the completion is used.
263 258 """
264 259 if new_line is None:
265 260 new_line = self.input_buffer
266 261
267 262 self.write('\n')
268 263 max_len = len(max(possibilities, key=len)) + 1
269 264
270 265 # Now we check how much symbol we can put on a line...
271 266 chars_per_line = self.get_line_width()
272 267 symbols_per_line = max(1, chars_per_line/max_len)
273 268
274 269 pos = 1
275 buf = []
270 completion_string = []
276 271 for symbol in possibilities:
277 272 if pos < symbols_per_line:
278 buf.append(symbol.ljust(max_len))
273 completion_string.append(symbol.ljust(max_len))
279 274 pos += 1
280 275 else:
281 buf.append(symbol.rstrip() + '\n')
276 completion_string.append(symbol.rstrip() + '\n')
282 277 pos = 1
283 self.write(''.join(buf))
278 self.write(''.join(completion_string))
284 279 self.new_prompt(self.input_prompt_template.substitute(
285 280 number=self.last_result['number'] + 1))
286 281 self.input_buffer = new_line
287 282
288 283
289 284 def new_prompt(self, prompt):
290 285 """ Prints a prompt and starts a new editing buffer.
291 286
292 287 Subclasses should use this method to make sure that the
293 288 terminal is put in a state favorable for a new line
294 289 input.
295 290 """
296 291 self.input_buffer = ''
297 292 self.write(prompt)
298 293
299 294
295 def continuation_prompt(self):
296 """Returns the current continuation prompt.
297 """
298 return ("."*(len(self.last_prompt)-2) + ': ')
299
300
301 def execute_command(self, command, hidden=False):
302 """ Execute a command, not only in the model, but also in the
303 view, if any.
304 """
305 return self.shell.execute(command)
306
300 307 #--------------------------------------------------------------------------
301 308 # Private API
302 309 #--------------------------------------------------------------------------
303 310
304 def _on_enter(self):
311 def _on_enter(self, new_line_pos=0):
305 312 """ Called when the return key is pressed in a line editing
306 313 buffer.
314
315 Parameters
316 ----------
317 new_line_pos : integer, optional
318 Position of the new line to add, starting from the
319 end (0 adds a new line after the last line, -1 before
320 the last line...)
321
322 Returns
323 -------
324 True if execution is triggered
307 325 """
308 326 current_buffer = self.input_buffer
309 cleaned_buffer = self.prefilter_input(current_buffer)
327 # XXX: This string replace is ugly, but there should be no way it
328 # fails.
329 prompt_less_buffer = re.sub('^' + self.continuation_prompt(),
330 '', current_buffer).replace('\n' + self.continuation_prompt(),
331 '\n')
332 cleaned_buffer = self.prefilter_input(prompt_less_buffer)
310 333 if self.is_complete(cleaned_buffer):
311 334 self.execute(cleaned_buffer, raw_string=current_buffer)
335 return True
312 336 else:
313 self.input_buffer += self._get_indent_string(
314 current_buffer[:-1])
315 if len(current_buffer.split('\n')) == 2:
316 self.input_buffer += '\t\t'
317 if current_buffer[:-1].split('\n')[-1].rstrip().endswith(':'):
318 self.input_buffer += '\t'
319
337 # Start a new line.
338 new_line_pos = -new_line_pos
339 lines = current_buffer.split('\n')[:-1]
340 prompt_less_lines = prompt_less_buffer.split('\n')
341 # Create the new line, with the continuation prompt, and the
342 # same amount of indent than the line above it.
343 new_line = self.continuation_prompt() + \
344 self._get_indent_string('\n'.join(
345 prompt_less_lines[:new_line_pos-1]))
346 if len(lines) == 1:
347 # We are starting a first continuation line. Indent it.
348 new_line += '\t'
349 elif current_buffer[:-1].split('\n')[-1].rstrip().endswith(':'):
350 # The last line ends with ":", autoindent the new line.
351 new_line += '\t'
352
353 if new_line_pos == 0:
354 lines.append(new_line)
355 else:
356 lines.insert(new_line_pos, new_line)
357 self.input_buffer = '\n'.join(lines)
358
320 359
321 360 def _get_indent_string(self, string):
322 361 """ Return the string of whitespace that prefixes a line. Used to
323 362 add the right amount of indendation when creating a new line.
324 363 """
325 364 string = string.replace('\t', ' '*4)
326 365 string = string.split('\n')[-1]
327 366 indent_chars = len(string) - len(string.lstrip())
328 367 indent_string = '\t'*(indent_chars // 4) + \
329 368 ' '*(indent_chars % 4)
330 369
331 370 return indent_string
332 371
333 372
@@ -1,246 +1,285 b''
1 1 """
2 2 Frontend class that uses IPython0 to prefilter the inputs.
3 3
4 4 Using the IPython0 mechanism gives us access to the magics.
5 5
6 6 This is a transitory class, used here to do the transition between
7 7 ipython0 and ipython1. This class is meant to be short-lived as more
8 8 functionnality is abstracted out of ipython0 in reusable functions and
9 9 is added on the interpreter. This class can be a used to guide this
10 10 refactoring.
11 11 """
12 12 __docformat__ = "restructuredtext en"
13 13
14 14 #-------------------------------------------------------------------------------
15 15 # Copyright (C) 2008 The IPython Development Team
16 16 #
17 17 # Distributed under the terms of the BSD License. The full license is in
18 18 # the file COPYING, distributed as part of this software.
19 19 #-------------------------------------------------------------------------------
20 20
21 21 #-------------------------------------------------------------------------------
22 22 # Imports
23 23 #-------------------------------------------------------------------------------
24 24 import sys
25
26 from linefrontendbase import LineFrontEndBase, common_prefix
27 from frontendbase import FrontEndBase
25 import pydoc
26 import os
27 import re
28 import __builtin__
28 29
29 30 from IPython.ipmaker import make_IPython
30 31 from IPython.ipapi import IPApi
31 32 from IPython.kernel.core.redirector_output_trap import RedirectorOutputTrap
32 33
33 34 from IPython.kernel.core.sync_traceback_trap import SyncTracebackTrap
34 35
35 36 from IPython.genutils import Term
36 import pydoc
37 import os
38 import sys
37
38 from linefrontendbase import LineFrontEndBase, common_prefix
39 39
40 40
41 41 def mk_system_call(system_call_function, command):
42 42 """ given a os.system replacement, and a leading string command,
43 43 returns a function that will execute the command with the given
44 44 argument string.
45 45 """
46 46 def my_system_call(args):
47 47 system_call_function("%s %s" % (command, args))
48
49 my_system_call.__doc__ = "Calls %s" % command
48 50 return my_system_call
49 51
50 52 #-------------------------------------------------------------------------------
51 53 # Frontend class using ipython0 to do the prefiltering.
52 54 #-------------------------------------------------------------------------------
53 55 class PrefilterFrontEnd(LineFrontEndBase):
54 56 """ Class that uses ipython0 to do prefilter the input, do the
55 57 completion and the magics.
56 58
57 59 The core trick is to use an ipython0 instance to prefilter the
58 60 input, and share the namespace between the interpreter instance used
59 61 to execute the statements and the ipython0 used for code
60 62 completion...
61 63 """
62 64
63 65 debug = False
64 66
65 def __init__(self, ipython0=None, *args, **kwargs):
67 def __init__(self, ipython0=None, argv=None, *args, **kwargs):
66 68 """ Parameters:
67 69 -----------
68 70
69 71 ipython0: an optional ipython0 instance to use for command
70 72 prefiltering and completion.
73
74 argv : list, optional
75 Used as the instance's argv value. If not given, [] is used.
71 76 """
77 if argv is None:
78 argv = []
79 # This is a hack to avoid the IPython exception hook to trigger
80 # on exceptions (https://bugs.launchpad.net/bugs/337105)
81 # XXX: This is horrible: module-leve monkey patching -> side
82 # effects.
83 from IPython import iplib
84 iplib.InteractiveShell.isthreaded = True
85
72 86 LineFrontEndBase.__init__(self, *args, **kwargs)
73 87 self.shell.output_trap = RedirectorOutputTrap(
74 88 out_callback=self.write,
75 89 err_callback=self.write,
76 90 )
77 91 self.shell.traceback_trap = SyncTracebackTrap(
78 92 formatters=self.shell.traceback_trap.formatters,
79 93 )
80 94
81 95 # Start the ipython0 instance:
82 96 self.save_output_hooks()
83 97 if ipython0 is None:
84 98 # Instanciate an IPython0 interpreter to be able to use the
85 99 # prefiltering.
100 # Suppress all key input, to avoid waiting
101 def my_rawinput(x=None):
102 return '\n'
103 old_rawinput = __builtin__.raw_input
104 __builtin__.raw_input = my_rawinput
86 105 # XXX: argv=[] is a bit bold.
87 ipython0 = make_IPython(argv=[],
106 ipython0 = make_IPython(argv=argv,
88 107 user_ns=self.shell.user_ns,
89 108 user_global_ns=self.shell.user_global_ns)
109 __builtin__.raw_input = old_rawinput
90 110 self.ipython0 = ipython0
91 111 # Set the pager:
92 112 self.ipython0.set_hook('show_in_pager',
93 113 lambda s, string: self.write("\n" + string))
94 114 self.ipython0.write = self.write
95 115 self._ip = _ip = IPApi(self.ipython0)
96 116 # Make sure the raw system call doesn't get called, as we don't
97 117 # have a stdin accessible.
98 118 self._ip.system = self.system_call
99 119 # XXX: Muck around with magics so that they work better
100 120 # in our environment
101 self.ipython0.magic_ls = mk_system_call(self.system_call,
102 'ls -CF')
121 if not sys.platform.startswith('win'):
122 self.ipython0.magic_ls = mk_system_call(self.system_call,
123 'ls -CF')
103 124 # And now clean up the mess created by ipython0
104 125 self.release_output()
105 126
106 127
107 128 if not 'banner' in kwargs and self.banner is None:
108 self.banner = self.ipython0.BANNER + """
109 This is the wx frontend, by Gael Varoquaux. This is EXPERIMENTAL code."""
129 self.banner = self.ipython0.BANNER
110 130
131 # FIXME: __init__ and start should be two different steps
111 132 self.start()
112 133
113 134 #--------------------------------------------------------------------------
114 135 # FrontEndBase interface
115 136 #--------------------------------------------------------------------------
116 137
117 138 def show_traceback(self):
118 139 """ Use ipython0 to capture the last traceback and display it.
119 140 """
120 self.capture_output()
141 # Don't do the capture; the except_hook has already done some
142 # modifications to the IO streams, if we store them, we'll be
143 # storing the wrong ones.
144 #self.capture_output()
121 145 self.ipython0.showtraceback(tb_offset=-1)
122 146 self.release_output()
123 147
124 148
125 149 def execute(self, python_string, raw_string=None):
126 150 if self.debug:
127 151 print 'Executing Python code:', repr(python_string)
128 152 self.capture_output()
129 153 LineFrontEndBase.execute(self, python_string,
130 154 raw_string=raw_string)
131 155 self.release_output()
132 156
133 157
134 158 def save_output_hooks(self):
135 159 """ Store all the output hooks we can think of, to be able to
136 160 restore them.
137 161
138 162 We need to do this early, as starting the ipython0 instance will
139 163 screw ouput hooks.
140 164 """
141 165 self.__old_cout_write = Term.cout.write
142 166 self.__old_cerr_write = Term.cerr.write
143 167 self.__old_stdout = sys.stdout
144 168 self.__old_stderr= sys.stderr
145 169 self.__old_help_output = pydoc.help.output
146 170 self.__old_display_hook = sys.displayhook
147 171
148 172
149 173 def capture_output(self):
150 174 """ Capture all the output mechanisms we can think of.
151 175 """
152 176 self.save_output_hooks()
153 177 Term.cout.write = self.write
154 178 Term.cerr.write = self.write
155 179 sys.stdout = Term.cout
156 180 sys.stderr = Term.cerr
157 181 pydoc.help.output = self.shell.output_trap.out
158 182
159 183
160 184 def release_output(self):
161 185 """ Release all the different captures we have made.
162 186 """
163 187 Term.cout.write = self.__old_cout_write
164 188 Term.cerr.write = self.__old_cerr_write
165 189 sys.stdout = self.__old_stdout
166 190 sys.stderr = self.__old_stderr
167 191 pydoc.help.output = self.__old_help_output
168 192 sys.displayhook = self.__old_display_hook
169 193
170 194
171 195 def complete(self, line):
172 196 # FIXME: This should be factored out in the linefrontendbase
173 197 # method.
174 word = line.split('\n')[-1].split(' ')[-1]
198 word = self._get_completion_text(line)
175 199 completions = self.ipython0.complete(word)
176 200 # FIXME: The proper sort should be done in the complete method.
177 201 key = lambda x: x.replace('_', '')
178 202 completions.sort(key=key)
179 203 if completions:
180 204 prefix = common_prefix(completions)
181 205 line = line[:-len(word)] + prefix
182 206 return line, completions
183 207
184 208
185 209 #--------------------------------------------------------------------------
186 210 # LineFrontEndBase interface
187 211 #--------------------------------------------------------------------------
188 212
189 213 def prefilter_input(self, input_string):
190 214 """ Using IPython0 to prefilter the commands to turn them
191 215 in executable statements that are valid Python strings.
192 216 """
193 217 input_string = LineFrontEndBase.prefilter_input(self, input_string)
194 218 filtered_lines = []
195 219 # The IPython0 prefilters sometime produce output. We need to
196 220 # capture it.
197 221 self.capture_output()
198 222 self.last_result = dict(number=self.prompt_number)
199 223
200 224 ## try:
201 225 ## for line in input_string.split('\n'):
202 226 ## filtered_lines.append(
203 227 ## self.ipython0.prefilter(line, False).rstrip())
204 228 ## except:
205 229 ## # XXX: probably not the right thing to do.
206 230 ## self.ipython0.showsyntaxerror()
207 231 ## self.after_execute()
208 232 ## finally:
209 233 ## self.release_output()
210 234
211 235
212 236 try:
213 237 try:
214 238 for line in input_string.split('\n'):
215 239 filtered_lines.append(
216 240 self.ipython0.prefilter(line, False).rstrip())
217 241 except:
218 242 # XXX: probably not the right thing to do.
219 243 self.ipython0.showsyntaxerror()
220 244 self.after_execute()
221 245 finally:
222 246 self.release_output()
223 247
224 248
225 249
226 250 # Clean up the trailing whitespace, to avoid indentation errors
227 251 filtered_string = '\n'.join(filtered_lines)
228 252 return filtered_string
229 253
230 254
231 255 #--------------------------------------------------------------------------
232 256 # PrefilterFrontEnd interface
233 257 #--------------------------------------------------------------------------
234 258
235 259 def system_call(self, command_string):
236 260 """ Allows for frontend to define their own system call, to be
237 261 able capture output and redirect input.
238 262 """
239 263 return os.system(command_string)
240 264
241 265
242 266 def do_exit(self):
243 267 """ Exit the shell, cleanup and save the history.
244 268 """
245 269 self.ipython0.atexit_operations()
246 270
271
272 def _get_completion_text(self, line):
273 """ Returns the text to be completed by breaking the line at specified
274 delimiters.
275 """
276 # Break at: spaces, '=', all parentheses (except if balanced).
277 # FIXME2: In the future, we need to make the implementation similar to
278 # that in the 'pyreadline' module (modes/basemode.py) where we break at
279 # each delimiter and try to complete the residual line, until we get a
280 # successful list of completions.
281 expression = '\s|=|,|:|\((?!.*\))|\[(?!.*\])|\{(?!.*\})'
282 complete_sep = re.compile(expression)
283 text = complete_sep.split(line)[-1]
284 return text
285
1 NO CONTENT: file renamed from IPython/frontend/_process/__init__.py to IPython/frontend/process/__init__.py
@@ -1,179 +1,184 b''
1 1 # Addapted from killableprocess.py.
2 2 #______________________________________________________________________________
3 3 #
4 4 # killableprocess - subprocesses which can be reliably killed
5 5 #
6 6 # Parts of this module are copied from the subprocess.py file contained
7 7 # in the Python distribution.
8 8 #
9 9 # Copyright (c) 2003-2004 by Peter Astrand <astrand@lysator.liu.se>
10 10 #
11 11 # Additions and modifications written by Benjamin Smedberg
12 12 # <benjamin@smedbergs.us> are Copyright (c) 2006 by the Mozilla Foundation
13 13 # <http://www.mozilla.org/>
14 14 #
15 15 # By obtaining, using, and/or copying this software and/or its
16 16 # associated documentation, you agree that you have read, understood,
17 17 # and will comply with the following terms and conditions:
18 18 #
19 19 # Permission to use, copy, modify, and distribute this software and
20 20 # its associated documentation for any purpose and without fee is
21 21 # hereby granted, provided that the above copyright notice appears in
22 22 # all copies, and that both that copyright notice and this permission
23 23 # notice appear in supporting documentation, and that the name of the
24 24 # author not be used in advertising or publicity pertaining to
25 25 # distribution of the software without specific, written prior
26 26 # permission.
27 27 #
28 28 # THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
29 29 # INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
30 30 # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
31 31 # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
32 32 # OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
33 33 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
34 34 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
35 35
36 36 r"""killableprocess - Subprocesses which can be reliably killed
37 37
38 38 This module is a subclass of the builtin "subprocess" module. It allows
39 39 processes that launch subprocesses to be reliably killed on Windows (via the Popen.kill() method.
40 40
41 41 It also adds a timeout argument to Wait() for a limited period of time before
42 42 forcefully killing the process.
43 43
44 44 Note: On Windows, this module requires Windows 2000 or higher (no support for
45 45 Windows 95, 98, or NT 4.0). It also requires ctypes, which is bundled with
46 46 Python 2.5+ or available from http://python.net/crew/theller/ctypes/
47 47 """
48 48
49 49 import subprocess
50 50 from subprocess import PIPE
51 51 import sys
52 52 import os
53 53 import types
54 54
55 55 try:
56 56 from subprocess import CalledProcessError
57 57 except ImportError:
58 58 # Python 2.4 doesn't implement CalledProcessError
59 59 class CalledProcessError(Exception):
60 60 """This exception is raised when a process run by check_call() returns
61 61 a non-zero exit status. The exit status will be stored in the
62 62 returncode attribute."""
63 63 def __init__(self, returncode, cmd):
64 64 self.returncode = returncode
65 65 self.cmd = cmd
66 66 def __str__(self):
67 67 return "Command '%s' returned non-zero exit status %d" % (self.cmd, self.returncode)
68 68
69 69 mswindows = (sys.platform == "win32")
70 70
71 71 skip = False
72 72
73 73 if mswindows:
74 74 import platform
75 75 if platform.uname()[3] == '' or platform.uname()[3] > '6.0.6000':
76 76 # Killable process does not work under vista when starting for
77 77 # something else than cmd.
78 78 skip = True
79 79 else:
80 80 import winprocess
81 81 else:
82 82 import signal
83 83
84 84 if not mswindows:
85 85 def DoNothing(*args):
86 86 pass
87 87
88 88
89 89 if skip:
90 90 Popen = subprocess.Popen
91 91 else:
92 92 class Popen(subprocess.Popen):
93 93 if not mswindows:
94 94 # Override __init__ to set a preexec_fn
95 95 def __init__(self, *args, **kwargs):
96 96 if len(args) >= 7:
97 97 raise Exception("Arguments preexec_fn and after must be passed by keyword.")
98 98
99 99 real_preexec_fn = kwargs.pop("preexec_fn", None)
100 100 def setpgid_preexec_fn():
101 101 os.setpgid(0, 0)
102 102 if real_preexec_fn:
103 103 apply(real_preexec_fn)
104 104
105 105 kwargs['preexec_fn'] = setpgid_preexec_fn
106 106
107 107 subprocess.Popen.__init__(self, *args, **kwargs)
108 108
109 109 if mswindows:
110 110 def _execute_child(self, args, executable, preexec_fn, close_fds,
111 111 cwd, env, universal_newlines, startupinfo,
112 112 creationflags, shell,
113 113 p2cread, p2cwrite,
114 114 c2pread, c2pwrite,
115 115 errread, errwrite):
116 116 if not isinstance(args, types.StringTypes):
117 117 args = subprocess.list2cmdline(args)
118 118
119 119 if startupinfo is None:
120 120 startupinfo = winprocess.STARTUPINFO()
121 121
122 122 if None not in (p2cread, c2pwrite, errwrite):
123 123 startupinfo.dwFlags |= winprocess.STARTF_USESTDHANDLES
124 124
125 125 startupinfo.hStdInput = int(p2cread)
126 126 startupinfo.hStdOutput = int(c2pwrite)
127 127 startupinfo.hStdError = int(errwrite)
128 128 if shell:
129 129 startupinfo.dwFlags |= winprocess.STARTF_USESHOWWINDOW
130 130 startupinfo.wShowWindow = winprocess.SW_HIDE
131 131 comspec = os.environ.get("COMSPEC", "cmd.exe")
132 132 args = comspec + " /c " + args
133 133
134 134 # We create a new job for this process, so that we can kill
135 135 # the process and any sub-processes
136 136 self._job = winprocess.CreateJobObject()
137 137
138 138 creationflags |= winprocess.CREATE_SUSPENDED
139 139 creationflags |= winprocess.CREATE_UNICODE_ENVIRONMENT
140 140
141 141 hp, ht, pid, tid = winprocess.CreateProcess(
142 142 executable, args,
143 143 None, None, # No special security
144 144 1, # Must inherit handles!
145 145 creationflags,
146 146 winprocess.EnvironmentBlock(env),
147 147 cwd, startupinfo)
148 148
149 149 self._child_created = True
150 150 self._handle = hp
151 151 self._thread = ht
152 152 self.pid = pid
153 153
154 winprocess.AssignProcessToJobObject(self._job, hp)
154 # XXX: A try/except to fix UAC-related problems under
155 # Windows Vista, when reparenting jobs.
156 try:
157 winprocess.AssignProcessToJobObject(self._job, hp)
158 except WindowsError:
159 pass
155 160 winprocess.ResumeThread(ht)
156 161
157 162 if p2cread is not None:
158 163 p2cread.Close()
159 164 if c2pwrite is not None:
160 165 c2pwrite.Close()
161 166 if errwrite is not None:
162 167 errwrite.Close()
163 168
164 169 def kill(self, group=True):
165 170 """Kill the process. If group=True, all sub-processes will also be killed."""
166 171 if mswindows:
167 172 if group:
168 173 winprocess.TerminateJobObject(self._job, 127)
169 174 else:
170 175 winprocess.TerminateProcess(self._handle, 127)
171 176 self.returncode = 127
172 177 else:
173 178 if group:
174 179 os.killpg(self.pid, signal.SIGKILL)
175 180 else:
176 181 os.kill(self.pid, signal.SIGKILL)
177 182 self.returncode = -9
178 183
179 184
1 NO CONTENT: file renamed from IPython/frontend/_process/pipedprocess.py to IPython/frontend/process/pipedprocess.py
1 NO CONTENT: file renamed from IPython/frontend/_process/winprocess.py to IPython/frontend/process/winprocess.py
@@ -1,155 +1,109 b''
1 1 # encoding: utf-8
2 2
3 """This file contains unittests for the frontendbase module."""
3 """This file contains unittests for the asyncfrontendbase module."""
4 4
5 5 __docformat__ = "restructuredtext en"
6 6
7 7 #---------------------------------------------------------------------------
8 8 # Copyright (C) 2008 The IPython Development Team
9 9 #
10 10 # Distributed under the terms of the BSD License. The full license is in
11 11 # the file COPYING, distributed as part of this software.
12 12 #---------------------------------------------------------------------------
13 13
14 14 #---------------------------------------------------------------------------
15 15 # Imports
16 16 #---------------------------------------------------------------------------
17 17
18 import unittest
18 # Tell nose to skip this module
19 __test__ = {}
19 20
20 try:
21 from IPython.frontend.asyncfrontendbase import AsyncFrontEndBase
22 from IPython.frontend import frontendbase
23 from IPython.kernel.engineservice import EngineService
24 except ImportError:
25 import nose
26 raise nose.SkipTest("This test requires zope.interface, Twisted and Foolscap")
21 from twisted.trial import unittest
22 from IPython.frontend.asyncfrontendbase import AsyncFrontEndBase
23 from IPython.frontend import frontendbase
24 from IPython.kernel.engineservice import EngineService
25 from IPython.testing.parametric import Parametric, parametric
27 26
28 from IPython.testing.decorators import skip
29 27
30 28 class FrontEndCallbackChecker(AsyncFrontEndBase):
31 29 """FrontEndBase subclass for checking callbacks"""
32 30 def __init__(self, engine=None, history=None):
33 31 super(FrontEndCallbackChecker, self).__init__(engine=engine,
34 32 history=history)
35 33 self.updateCalled = False
36 34 self.renderResultCalled = False
37 35 self.renderErrorCalled = False
38 36
39 37 def update_cell_prompt(self, result, blockID=None):
40 38 self.updateCalled = True
41 39 return result
42 40
43 41 def render_result(self, result):
44 42 self.renderResultCalled = True
45 43 return result
46 44
47
48 45 def render_error(self, failure):
49 46 self.renderErrorCalled = True
50 47 return failure
51
52 48
53 49
54
55 50 class TestAsyncFrontendBase(unittest.TestCase):
56 51 def setUp(self):
57 52 """Setup the EngineService and FrontEndBase"""
58 53
59 54 self.fb = FrontEndCallbackChecker(engine=EngineService())
60 55
61 56 def test_implements_IFrontEnd(self):
62 assert(frontendbase.IFrontEnd.implementedBy(
57 self.assert_(frontendbase.IFrontEnd.implementedBy(
63 58 AsyncFrontEndBase))
64 59
65 60 def test_is_complete_returns_False_for_incomplete_block(self):
66 """"""
67
68 61 block = """def test(a):"""
69
70 assert(self.fb.is_complete(block) == False)
62 self.assert_(self.fb.is_complete(block) == False)
71 63
72 64 def test_is_complete_returns_True_for_complete_block(self):
73 """"""
74
75 65 block = """def test(a): pass"""
76
77 assert(self.fb.is_complete(block))
78
66 self.assert_(self.fb.is_complete(block))
79 67 block = """a=3"""
80
81 assert(self.fb.is_complete(block))
68 self.assert_(self.fb.is_complete(block))
82 69
83 70 def test_blockID_added_to_result(self):
84 71 block = """3+3"""
85
86 72 d = self.fb.execute(block, blockID='TEST_ID')
87
88 d.addCallback(self.checkBlockID, expected='TEST_ID')
73 d.addCallback(lambda r: self.assert_(r['blockID']=='TEST_ID'))
74 return d
89 75
90 76 def test_blockID_added_to_failure(self):
91 77 block = "raise Exception()"
92
93 78 d = self.fb.execute(block,blockID='TEST_ID')
94 d.addErrback(self.checkFailureID, expected='TEST_ID')
95
96 def checkBlockID(self, result, expected=""):
97 assert(result['blockID'] == expected)
98
99
100 def checkFailureID(self, failure, expected=""):
101 assert(failure.blockID == expected)
102
79 d.addErrback(lambda f: self.assert_(f.blockID=='TEST_ID'))
80 return d
103 81
104 82 def test_callbacks_added_to_execute(self):
105 """test that
106 update_cell_prompt
107 render_result
108
109 are added to execute request
110 """
111
112 83 d = self.fb.execute("10+10")
113 d.addCallback(self.checkCallbacks)
84 d.addCallback(lambda r: self.assert_(self.fb.updateCalled and self.fb.renderResultCalled))
85 return d
114 86
115 def checkCallbacks(self, result):
116 assert(self.fb.updateCalled)
117 assert(self.fb.renderResultCalled)
118
119 @skip("This test fails and lead to an unhandled error in a Deferred.")
120 87 def test_error_callback_added_to_execute(self):
121 """test that render_error called on execution error"""
88 """Test that render_error called on execution error."""
122 89
123 90 d = self.fb.execute("raise Exception()")
124 d.addCallback(self.checkRenderError)
125
126 def checkRenderError(self, result):
127 assert(self.fb.renderErrorCalled)
91 d.addErrback(lambda f: self.assert_(self.fb.renderErrorCalled))
92 return d
128 93
129 94 def test_history_returns_expected_block(self):
130 """Make sure history browsing doesn't fail"""
95 """Make sure history browsing doesn't fail."""
131 96
132 97 blocks = ["a=1","a=2","a=3"]
133 for b in blocks:
134 d = self.fb.execute(b)
135
136 # d is now the deferred for the last executed block
137 d.addCallback(self.historyTests, blocks)
138
139
140 def historyTests(self, result, blocks):
141 """historyTests"""
142
143 assert(len(blocks) >= 3)
144 assert(self.fb.get_history_previous("") == blocks[-2])
145 assert(self.fb.get_history_previous("") == blocks[-3])
146 assert(self.fb.get_history_next() == blocks[-2])
147
148
149 def test_history_returns_none_at_startup(self):
150 """test_history_returns_none_at_startup"""
151
152 assert(self.fb.get_history_previous("")==None)
153 assert(self.fb.get_history_next()==None)
154
155
98 d = self.fb.execute(blocks[0])
99 d.addCallback(lambda _: self.fb.execute(blocks[1]))
100 d.addCallback(lambda _: self.fb.execute(blocks[2]))
101 d.addCallback(lambda _: self.assert_(self.fb.get_history_previous("")==blocks[-2]))
102 d.addCallback(lambda _: self.assert_(self.fb.get_history_previous("")==blocks[-3]))
103 d.addCallback(lambda _: self.assert_(self.fb.get_history_next()==blocks[-2]))
104 return d
105
106 def test_history_returns_none_at_startup(self):
107 self.assert_(self.fb.get_history_previous("")==None)
108 self.assert_(self.fb.get_history_next()==None)
109
@@ -1,180 +1,252 b''
1 1 # encoding: utf-8
2 2 """
3 3 Test process execution and IO redirection.
4 4 """
5 5
6 6 __docformat__ = "restructuredtext en"
7 7
8 8 #-------------------------------------------------------------------------------
9 9 # Copyright (C) 2008 The IPython Development Team
10 10 #
11 11 # Distributed under the terms of the BSD License. The full license is
12 12 # in the file COPYING, distributed as part of this software.
13 13 #-------------------------------------------------------------------------------
14 14
15 from copy import copy, deepcopy
15 16 from cStringIO import StringIO
16 17 import string
17 18
18 from IPython.ipapi import get as get_ipython0
19 from nose.tools import assert_equal
20
19 21 from IPython.frontend.prefilterfrontend import PrefilterFrontEnd
20 from copy import deepcopy
22 from IPython.ipapi import get as get_ipython0
23 from IPython.testing.plugin.ipdoctest import default_argv
24
25
26 def safe_deepcopy(d):
27 """ Deep copy every key of the given dict, when possible. Elsewhere
28 do a copy.
29 """
30 copied_d = dict()
31 for key, value in d.iteritems():
32 try:
33 copied_d[key] = deepcopy(value)
34 except:
35 try:
36 copied_d[key] = copy(value)
37 except:
38 copied_d[key] = value
39 return copied_d
40
21 41
22 42 class TestPrefilterFrontEnd(PrefilterFrontEnd):
23 43
24 44 input_prompt_template = string.Template('')
25 45 output_prompt_template = string.Template('')
26 46 banner = ''
27 47
28 48 def __init__(self):
29 ipython0 = get_ipython0().IP
30 49 self.out = StringIO()
31 PrefilterFrontEnd.__init__(self, ipython0=ipython0)
32 # Clean up the namespace for isolation between tests
33 user_ns = self.ipython0.user_ns
34 # We need to keep references to things so that they don't
35 # get garbage collected (this stinks).
36 self.shadow_ns = dict()
37 for i in self.ipython0.magic_who_ls():
38 self.shadow_ns[i] = user_ns.pop(i)
50 PrefilterFrontEnd.__init__(self,argv=default_argv())
39 51 # Some more code for isolation (yeah, crazy)
40 52 self._on_enter()
41 53 self.out.flush()
42 54 self.out.reset()
43 55 self.out.truncate()
44 56
45 57 def write(self, string, *args, **kwargs):
46 58 self.out.write(string)
47 59
48 60 def _on_enter(self):
49 61 self.input_buffer += '\n'
50 62 PrefilterFrontEnd._on_enter(self)
51 63
52 64
53 65 def isolate_ipython0(func):
54 66 """ Decorator to isolate execution that involves an iptyhon0.
67
68 Notes
69 -----
70
71 Apply only to functions with no arguments. Nose skips functions
72 with arguments.
55 73 """
56 def my_func(*args, **kwargs):
57 ipython0 = get_ipython0().IP
58 user_ns = deepcopy(ipython0.user_ns)
59 global_ns = deepcopy(ipython0.global_ns)
74 def my_func():
75 iplib = get_ipython0()
76 if iplib is None:
77 return func()
78 ipython0 = iplib.IP
79 global_ns = safe_deepcopy(ipython0.user_global_ns)
80 user_ns = safe_deepcopy(ipython0.user_ns)
60 81 try:
61 func(*args, **kwargs)
82 out = func()
62 83 finally:
63 84 ipython0.user_ns = user_ns
64 ipython0.global_ns = global_ns
85 ipython0.user_global_ns = global_ns
86 # Undo the hack at creation of PrefilterFrontEnd
87 from IPython import iplib
88 iplib.InteractiveShell.isthreaded = False
89 return out
65 90
91 my_func.__name__ = func.__name__
66 92 return my_func
67 93
68 94
69 95 @isolate_ipython0
70 96 def test_execution():
71 97 """ Test execution of a command.
72 98 """
73 99 f = TestPrefilterFrontEnd()
74 100 f.input_buffer = 'print 1'
75 101 f._on_enter()
76 102 out_value = f.out.getvalue()
77 assert out_value == '1\n'
103 assert_equal(out_value, '1\n')
78 104
79 105
80 106 @isolate_ipython0
81 107 def test_multiline():
82 108 """ Test execution of a multiline command.
83 109 """
84 110 f = TestPrefilterFrontEnd()
85 111 f.input_buffer = 'if True:'
86 112 f._on_enter()
87 113 f.input_buffer += 'print 1'
88 114 f._on_enter()
89 115 out_value = f.out.getvalue()
90 assert out_value == ''
116 yield assert_equal, out_value, ''
91 117 f._on_enter()
92 118 out_value = f.out.getvalue()
93 assert out_value == '1\n'
119 yield assert_equal, out_value, '1\n'
94 120 f = TestPrefilterFrontEnd()
95 121 f.input_buffer='(1 +'
96 122 f._on_enter()
97 123 f.input_buffer += '0)'
98 124 f._on_enter()
99 125 out_value = f.out.getvalue()
100 assert out_value == ''
126 yield assert_equal, out_value, ''
101 127 f._on_enter()
102 128 out_value = f.out.getvalue()
103 assert out_value == '1\n'
129 yield assert_equal, out_value, '1\n'
104 130
105 131
106 132 @isolate_ipython0
107 133 def test_capture():
108 134 """ Test the capture of output in different channels.
109 135 """
110 136 # Test on the OS-level stdout, stderr.
111 137 f = TestPrefilterFrontEnd()
112 138 f.input_buffer = \
113 139 'import os; out=os.fdopen(1, "w"); out.write("1") ; out.flush()'
114 140 f._on_enter()
115 141 out_value = f.out.getvalue()
116 assert out_value == '1'
142 yield assert_equal, out_value, '1'
117 143 f = TestPrefilterFrontEnd()
118 144 f.input_buffer = \
119 145 'import os; out=os.fdopen(2, "w"); out.write("1") ; out.flush()'
120 146 f._on_enter()
121 147 out_value = f.out.getvalue()
122 assert out_value == '1'
148 yield assert_equal, out_value, '1'
123 149
124 150
125 151 @isolate_ipython0
126 152 def test_magic():
127 153 """ Test the magic expansion and history.
128 154
129 155 This test is fairly fragile and will break when magics change.
130 156 """
131 157 f = TestPrefilterFrontEnd()
158 # Before checking the interactive namespace, make sure it's clear (it can
159 # otherwise pick up things stored in the user's local db)
160 f.input_buffer += '%reset -f'
161 f._on_enter()
162 f.complete_current_input()
163 # Now, run the %who magic and check output
132 164 f.input_buffer += '%who'
133 165 f._on_enter()
134 166 out_value = f.out.getvalue()
135 assert out_value == 'Interactive namespace is empty.\n'
167 assert_equal(out_value, 'Interactive namespace is empty.\n')
136 168
137 169
138 170 @isolate_ipython0
139 171 def test_help():
140 172 """ Test object inspection.
141 173 """
142 174 f = TestPrefilterFrontEnd()
143 175 f.input_buffer += "def f():"
144 176 f._on_enter()
145 177 f.input_buffer += "'foobar'"
146 178 f._on_enter()
147 179 f.input_buffer += "pass"
148 180 f._on_enter()
149 181 f._on_enter()
150 182 f.input_buffer += "f?"
151 183 f._on_enter()
152 184 assert 'traceback' not in f.last_result
153 185 ## XXX: ipython doctest magic breaks this. I have no clue why
154 186 #out_value = f.out.getvalue()
155 187 #assert out_value.split()[-1] == 'foobar'
156 188
157 189
158 190 @isolate_ipython0
159 def test_completion():
160 """ Test command-line completion.
191 def test_completion_simple():
192 """ Test command-line completion on trivial examples.
161 193 """
162 194 f = TestPrefilterFrontEnd()
163 195 f.input_buffer = 'zzza = 1'
164 196 f._on_enter()
165 197 f.input_buffer = 'zzzb = 2'
166 198 f._on_enter()
167 199 f.input_buffer = 'zz'
168 200 f.complete_current_input()
169 201 out_value = f.out.getvalue()
170 assert out_value == '\nzzza zzzb '
171 assert f.input_buffer == 'zzz'
202 yield assert_equal, out_value, '\nzzza zzzb '
203 yield assert_equal, f.input_buffer, 'zzz'
204
205
206 @isolate_ipython0
207 def test_completion_parenthesis():
208 """ Test command-line completion when a parenthesis is open.
209 """
210 f = TestPrefilterFrontEnd()
211 f.input_buffer = 'zzza = 1'
212 f._on_enter()
213 f.input_buffer = 'zzzb = 2'
214 f._on_enter()
215 f.input_buffer = 'map(zz'
216 f.complete_current_input()
217 out_value = f.out.getvalue()
218 yield assert_equal, out_value, '\nzzza zzzb '
219 yield assert_equal, f.input_buffer, 'map(zzz'
220
221
222 @isolate_ipython0
223 def test_completion_indexing():
224 """ Test command-line completion when indexing on objects.
225 """
226 f = TestPrefilterFrontEnd()
227 f.input_buffer = 'a = [0]'
228 f._on_enter()
229 f.input_buffer = 'a[0].'
230 f.complete_current_input()
231 assert_equal(f.input_buffer, 'a[0].__')
232
233
234 @isolate_ipython0
235 def test_completion_equal():
236 """ Test command-line completion when the delimiter is "=", not " ".
237 """
238 f = TestPrefilterFrontEnd()
239 f.input_buffer = 'a=1.'
240 f.complete_current_input()
241 assert_equal(f.input_buffer, 'a=1.__')
242
172 243
173 244
174 245 if __name__ == '__main__':
175 246 test_magic()
176 247 test_help()
177 248 test_execution()
178 249 test_multiline()
179 250 test_capture()
180 test_completion()
251 test_completion_simple()
252 test_completion_complex()
@@ -1,67 +1,67 b''
1 1 # encoding: utf-8
2 2 """
3 3 Test process execution and IO redirection.
4 4 """
5 5
6 6 __docformat__ = "restructuredtext en"
7 7
8 #-------------------------------------------------------------------------------
9 # Copyright (C) 2008 The IPython Development Team
8 #-----------------------------------------------------------------------------
9 # Copyright (C) 2008-2009 The IPython Development Team
10 10 #
11 11 # Distributed under the terms of the BSD License. The full license is
12 12 # in the file COPYING, distributed as part of this software.
13 #-------------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 14
15 15 from cStringIO import StringIO
16 16 from time import sleep
17 17 import sys
18 18
19 from IPython.frontend._process import PipedProcess
19 from IPython.frontend.process import PipedProcess
20 20 from IPython.testing import decorators as testdec
21 21
22 22
23 23 def test_capture_out():
24 24 """ A simple test to see if we can execute a process and get the output.
25 25 """
26 26 s = StringIO()
27 27 p = PipedProcess('echo 1', out_callback=s.write, )
28 28 p.start()
29 29 p.join()
30 30 result = s.getvalue().rstrip()
31 31 assert result == '1'
32 32
33 33
34 34 def test_io():
35 35 """ Checks that we can send characters on stdin to the process.
36 36 """
37 37 s = StringIO()
38 38 p = PipedProcess(sys.executable + ' -c "a = raw_input(); print a"',
39 39 out_callback=s.write, )
40 40 p.start()
41 41 test_string = '12345\n'
42 42 while not hasattr(p, 'process'):
43 43 sleep(0.1)
44 44 p.process.stdin.write(test_string)
45 45 p.join()
46 46 result = s.getvalue()
47 47 assert result == test_string
48 48
49 49
50 50 def test_kill():
51 51 """ Check that we can kill a process, and its subprocess.
52 52 """
53 53 s = StringIO()
54 54 p = PipedProcess(sys.executable + ' -c "a = raw_input();"',
55 55 out_callback=s.write, )
56 56 p.start()
57 57 while not hasattr(p, 'process'):
58 58 sleep(0.1)
59 59 p.process.kill()
60 60 assert p.process.poll() is not None
61 61
62 62
63 63 if __name__ == '__main__':
64 64 test_capture_out()
65 65 test_io()
66 66 test_kill()
67 67
@@ -1,436 +1,625 b''
1 1 # encoding: utf-8
2 2 """
3 3 A Wx widget to act as a console and input commands.
4 4
5 5 This widget deals with prompts and provides an edit buffer
6 6 restricted to after the last prompt.
7 7 """
8 8
9 9 __docformat__ = "restructuredtext en"
10 10
11 11 #-------------------------------------------------------------------------------
12 12 # Copyright (C) 2008 The IPython Development Team
13 13 #
14 14 # Distributed under the terms of the BSD License. The full license is
15 15 # in the file COPYING, distributed as part of this software.
16 16 #-------------------------------------------------------------------------------
17 17
18 18 #-------------------------------------------------------------------------------
19 19 # Imports
20 20 #-------------------------------------------------------------------------------
21 21
22 22 import wx
23 23 import wx.stc as stc
24 24
25 25 from wx.py import editwindow
26 26 import time
27 27 import sys
28 import string
29
28 30 LINESEP = '\n'
29 31 if sys.platform == 'win32':
30 32 LINESEP = '\n\r'
31 33
32 34 import re
33 35
34 36 # FIXME: Need to provide an API for non user-generated display on the
35 37 # screen: this should not be editable by the user.
38 #-------------------------------------------------------------------------------
39 # Constants
40 #-------------------------------------------------------------------------------
41 _COMPLETE_BUFFER_MARKER = 31
42 _ERROR_MARKER = 30
43 _INPUT_MARKER = 29
36 44
37 45 _DEFAULT_SIZE = 10
38 46 if sys.platform == 'darwin':
39 47 _DEFAULT_SIZE = 12
40 48
41 49 _DEFAULT_STYLE = {
42 'stdout' : 'fore:#0000FF',
43 'stderr' : 'fore:#007f00',
44 'trace' : 'fore:#FF0000',
45
50 #background definition
46 51 'default' : 'size:%d' % _DEFAULT_SIZE,
47 52 'bracegood' : 'fore:#00AA00,back:#000000,bold',
48 53 'bracebad' : 'fore:#FF0000,back:#000000,bold',
49 54
55 # Edge column: a number of None
56 'edge_column' : -1,
57
50 58 # properties for the various Python lexer styles
51 59 'comment' : 'fore:#007F00',
52 60 'number' : 'fore:#007F7F',
53 61 'string' : 'fore:#7F007F,italic',
54 62 'char' : 'fore:#7F007F,italic',
55 63 'keyword' : 'fore:#00007F,bold',
56 64 'triple' : 'fore:#7F0000',
57 65 'tripledouble' : 'fore:#7F0000',
58 66 'class' : 'fore:#0000FF,bold,underline',
59 67 'def' : 'fore:#007F7F,bold',
60 'operator' : 'bold'
68 'operator' : 'bold',
69
70 # Default colors
71 'trace' : '#FAFAF1', # Nice green
72 'stdout' : '#FDFFD3', # Nice yellow
73 'stderr' : '#FFF1F1', # Nice red
74
75 # Default scintilla settings
76 'antialiasing' : True,
77 'carret_color' : 'BLACK',
78 'background_color' :'WHITE',
79
80 #prompt definition
81 'prompt_in1' : \
82 '\n\x01\x1b[0;34m\x02In [\x01\x1b[1;34m\x02$number\x01\x1b[0;34m\x02]: \x01\x1b[0m\x02',
83
84 'prompt_out': \
85 '\x01\x1b[0;31m\x02Out[\x01\x1b[1;31m\x02$number\x01\x1b[0;31m\x02]: \x01\x1b[0m\x02',
61 86 }
62 87
63 88 # new style numbers
64 89 _STDOUT_STYLE = 15
65 90 _STDERR_STYLE = 16
66 91 _TRACE_STYLE = 17
67 92
68 93
69 94 # system colors
70 95 #SYS_COLOUR_BACKGROUND = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BACKGROUND)
71 96
97 # Translation table from ANSI escape sequences to color.
98 ANSI_STYLES = {'0;30': [0, 'BLACK'], '0;31': [1, 'RED'],
99 '0;32': [2, 'GREEN'], '0;33': [3, 'BROWN'],
100 '0;34': [4, 'BLUE'], '0;35': [5, 'PURPLE'],
101 '0;36': [6, 'CYAN'], '0;37': [7, 'LIGHT GREY'],
102 '1;30': [8, 'DARK GREY'], '1;31': [9, 'RED'],
103 '1;32': [10, 'SEA GREEN'], '1;33': [11, 'YELLOW'],
104 '1;34': [12, 'LIGHT BLUE'], '1;35':
105 [13, 'MEDIUM VIOLET RED'],
106 '1;36': [14, 'LIGHT STEEL BLUE'], '1;37': [15, 'YELLOW']}
107
108 # XXX: Maybe one day we should factor this code with ColorANSI. Right now
109 # ColorANSI is hard to reuse and makes our code more complex.
110
111 #we define platform specific fonts
112 if wx.Platform == '__WXMSW__':
113 FACES = { 'times': 'Times New Roman',
114 'mono' : 'Courier New',
115 'helv' : 'Arial',
116 'other': 'Comic Sans MS',
117 'size' : 10,
118 'size2': 8,
119 }
120 elif wx.Platform == '__WXMAC__':
121 FACES = { 'times': 'Times New Roman',
122 'mono' : 'Monaco',
123 'helv' : 'Arial',
124 'other': 'Comic Sans MS',
125 'size' : 10,
126 'size2': 8,
127 }
128 else:
129 FACES = { 'times': 'Times',
130 'mono' : 'Courier',
131 'helv' : 'Helvetica',
132 'other': 'new century schoolbook',
133 'size' : 10,
134 'size2': 8,
135 }
136
137
72 138 #-------------------------------------------------------------------------------
73 139 # The console widget class
74 140 #-------------------------------------------------------------------------------
75 141 class ConsoleWidget(editwindow.EditWindow):
76 142 """ Specialized styled text control view for console-like workflow.
77 143
78 144 This widget is mainly interested in dealing with the prompt and
79 145 keeping the cursor inside the editing line.
80 146 """
81 147
82 148 # This is where the title captured from the ANSI escape sequences are
83 149 # stored.
84 150 title = 'Console'
85 151
152 # Last prompt printed
153 last_prompt = ''
154
86 155 # The buffer being edited.
87 156 def _set_input_buffer(self, string):
88 157 self.SetSelection(self.current_prompt_pos, self.GetLength())
89 158 self.ReplaceSelection(string)
90 159 self.GotoPos(self.GetLength())
91 160
92 161 def _get_input_buffer(self):
93 162 """ Returns the text in current edit buffer.
94 163 """
95 164 input_buffer = self.GetTextRange(self.current_prompt_pos,
96 165 self.GetLength())
97 166 input_buffer = input_buffer.replace(LINESEP, '\n')
98 167 return input_buffer
99 168
100 169 input_buffer = property(_get_input_buffer, _set_input_buffer)
101 170
102 171 style = _DEFAULT_STYLE.copy()
103 172
104 173 # Translation table from ANSI escape sequences to color. Override
105 174 # this to specify your colors.
106 ANSI_STYLES = {'0;30': [0, 'BLACK'], '0;31': [1, 'RED'],
107 '0;32': [2, 'GREEN'], '0;33': [3, 'BROWN'],
108 '0;34': [4, 'BLUE'], '0;35': [5, 'PURPLE'],
109 '0;36': [6, 'CYAN'], '0;37': [7, 'LIGHT GREY'],
110 '1;30': [8, 'DARK GREY'], '1;31': [9, 'RED'],
111 '1;32': [10, 'SEA GREEN'], '1;33': [11, 'YELLOW'],
112 '1;34': [12, 'LIGHT BLUE'], '1;35':
113 [13, 'MEDIUM VIOLET RED'],
114 '1;36': [14, 'LIGHT STEEL BLUE'], '1;37': [15, 'YELLOW']}
115
116 # The color of the carret (call _apply_style() after setting)
117 carret_color = 'BLACK'
175 ANSI_STYLES = ANSI_STYLES.copy()
118 176
177 # Font faces
178 faces = FACES.copy()
179
119 180 # Store the last time a refresh was done
120 181 _last_refresh_time = 0
121 182
122 183 #--------------------------------------------------------------------------
123 184 # Public API
124 185 #--------------------------------------------------------------------------
125 186
126 187 def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition,
127 188 size=wx.DefaultSize, style=wx.WANTS_CHARS, ):
128 189 editwindow.EditWindow.__init__(self, parent, id, pos, size, style)
129 self._configure_scintilla()
190 self.configure_scintilla()
191 # Track if 'enter' key as ever been processed
192 # This variable will only be reallowed until key goes up
193 self.enter_catched = False
194 self.current_prompt_pos = 0
130 195
131 196 self.Bind(wx.EVT_KEY_DOWN, self._on_key_down)
132 197 self.Bind(wx.EVT_KEY_UP, self._on_key_up)
133 198
134 199
135 200 def write(self, text, refresh=True):
136 201 """ Write given text to buffer, while translating the ansi escape
137 202 sequences.
138 203 """
139 204 # XXX: do not put print statements to sys.stdout/sys.stderr in
140 205 # this method, the print statements will call this method, as
141 206 # you will end up with an infinit loop
142 207 title = self.title_pat.split(text)
143 208 if len(title)>1:
144 209 self.title = title[-2]
145 210
146 211 text = self.title_pat.sub('', text)
147 212 segments = self.color_pat.split(text)
148 213 segment = segments.pop(0)
149 214 self.GotoPos(self.GetLength())
150 215 self.StartStyling(self.GetLength(), 0xFF)
151 216 try:
152 217 self.AppendText(segment)
153 218 except UnicodeDecodeError:
154 219 # XXX: Do I really want to skip the exception?
155 220 pass
156 221
157 222 if segments:
158 223 for ansi_tag, text in zip(segments[::2], segments[1::2]):
159 224 self.StartStyling(self.GetLength(), 0xFF)
160 225 try:
161 226 self.AppendText(text)
162 227 except UnicodeDecodeError:
163 228 # XXX: Do I really want to skip the exception?
164 229 pass
165 230
166 231 if ansi_tag not in self.ANSI_STYLES:
167 232 style = 0
168 233 else:
169 234 style = self.ANSI_STYLES[ansi_tag][0]
170 235
171 236 self.SetStyling(len(text), style)
172 237
173 238 self.GotoPos(self.GetLength())
174 239 if refresh:
175 240 current_time = time.time()
176 241 if current_time - self._last_refresh_time > 0.03:
177 242 if sys.platform == 'win32':
178 243 wx.SafeYield()
179 244 else:
180 245 wx.Yield()
181 246 # self.ProcessEvent(wx.PaintEvent())
182 247 self._last_refresh_time = current_time
183 248
184 249
185 250 def new_prompt(self, prompt):
186 251 """ Prints a prompt at start of line, and move the start of the
187 252 current block there.
188 253
189 254 The prompt can be given with ascii escape sequences.
190 255 """
191 256 self.write(prompt, refresh=False)
192 257 # now we update our cursor giving end of prompt
193 258 self.current_prompt_pos = self.GetLength()
194 259 self.current_prompt_line = self.GetCurrentLine()
195 260 self.EnsureCaretVisible()
261 self.last_prompt = prompt
196 262
197 263
264 def continuation_prompt(self):
265 """ Returns the current continuation prompt.
266 We need to implement this method here to deal with the
267 ascii escape sequences cleaning up.
268 """
269 # ASCII-less prompt
270 ascii_less = ''.join(self.color_pat.split(self.last_prompt)[2::2])
271 return "."*(len(ascii_less)-2) + ': '
272
273
198 274 def scroll_to_bottom(self):
199 275 maxrange = self.GetScrollRange(wx.VERTICAL)
200 276 self.ScrollLines(maxrange)
201 277
202 278
203 279 def pop_completion(self, possibilities, offset=0):
204 280 """ Pops up an autocompletion menu. Offset is the offset
205 281 in characters of the position at which the menu should
206 282 appear, relativ to the cursor.
207 283 """
208 284 self.AutoCompSetIgnoreCase(False)
209 285 self.AutoCompSetAutoHide(False)
210 286 self.AutoCompSetMaxHeight(len(possibilities))
211 287 self.AutoCompShow(offset, " ".join(possibilities))
212 288
213 289
214 290 def get_line_width(self):
215 291 """ Return the width of the line in characters.
216 292 """
217 293 return self.GetSize()[0]/self.GetCharWidth()
218 294
219 #--------------------------------------------------------------------------
220 # EditWindow API
221 #--------------------------------------------------------------------------
222 295
223 def OnUpdateUI(self, event):
224 """ Override the OnUpdateUI of the EditWindow class, to prevent
225 syntax highlighting both for faster redraw, and for more
226 consistent look and feel.
296 def configure_scintilla(self):
297 """ Set up all the styling option of the embedded scintilla
298 widget.
227 299 """
300 p = self.style.copy()
301
302 # Marker for complete buffer.
303 self.MarkerDefine(_COMPLETE_BUFFER_MARKER, stc.STC_MARK_BACKGROUND,
304 background=p['trace'])
228 305
229 #--------------------------------------------------------------------------
230 # Private API
231 #--------------------------------------------------------------------------
232
233 def _apply_style(self):
234 """ Applies the colors for the different text elements and the
235 carret.
236 """
237 self.SetCaretForeground(self.carret_color)
238
239 #self.StyleClearAll()
240 self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT,
241 "fore:#FF0000,back:#0000FF,bold")
242 self.StyleSetSpec(stc.STC_STYLE_BRACEBAD,
243 "fore:#000000,back:#FF0000,bold")
244
245 for style in self.ANSI_STYLES.values():
246 self.StyleSetSpec(style[0], "bold,fore:%s" % style[1])
306 # Marker for current input buffer.
307 self.MarkerDefine(_INPUT_MARKER, stc.STC_MARK_BACKGROUND,
308 background=p['stdout'])
309 # Marker for tracebacks.
310 self.MarkerDefine(_ERROR_MARKER, stc.STC_MARK_BACKGROUND,
311 background=p['stderr'])
247 312
248
249 def _configure_scintilla(self):
250 313 self.SetEOLMode(stc.STC_EOL_LF)
251 314
252 315 # Ctrl"+" or Ctrl "-" can be used to zoomin/zoomout the text inside
253 316 # the widget
254 317 self.CmdKeyAssign(ord('+'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN)
255 318 self.CmdKeyAssign(ord('-'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT)
256 319 # Also allow Ctrl Shift "=" for poor non US keyboard users.
257 320 self.CmdKeyAssign(ord('='), stc.STC_SCMOD_CTRL|stc.STC_SCMOD_SHIFT,
258 321 stc.STC_CMD_ZOOMIN)
259 322
260 323 # Keys: we need to clear some of the keys the that don't play
261 324 # well with a console.
262 325 self.CmdKeyClear(ord('D'), stc.STC_SCMOD_CTRL)
263 326 self.CmdKeyClear(ord('L'), stc.STC_SCMOD_CTRL)
264 327 self.CmdKeyClear(ord('T'), stc.STC_SCMOD_CTRL)
265 328 self.CmdKeyClear(ord('A'), stc.STC_SCMOD_CTRL)
266 329
267 330 self.SetEOLMode(stc.STC_EOL_CRLF)
268 331 self.SetWrapMode(stc.STC_WRAP_CHAR)
269 332 self.SetWrapMode(stc.STC_WRAP_WORD)
270 333 self.SetBufferedDraw(True)
271 self.SetUseAntiAliasing(True)
334
335 self.SetUseAntiAliasing(p['antialiasing'])
336
272 337 self.SetLayoutCache(stc.STC_CACHE_PAGE)
273 338 self.SetUndoCollection(False)
274 339 self.SetUseTabs(True)
275 340 self.SetIndent(4)
276 341 self.SetTabWidth(4)
277 342
278 343 # we don't want scintilla's autocompletion to choose
279 344 # automaticaly out of a single choice list, as we pop it up
280 345 # automaticaly
281 346 self.AutoCompSetChooseSingle(False)
282 347 self.AutoCompSetMaxHeight(10)
283 348 # XXX: this doesn't seem to have an effect.
284 349 self.AutoCompSetFillUps('\n')
285 350
286 351 self.SetMargins(3, 3) #text is moved away from border with 3px
287 352 # Suppressing Scintilla margins
288 353 self.SetMarginWidth(0, 0)
289 354 self.SetMarginWidth(1, 0)
290 355 self.SetMarginWidth(2, 0)
291 356
292 self._apply_style()
293
294 357 # Xterm escape sequences
295 358 self.color_pat = re.compile('\x01?\x1b\[(.*?)m\x02?')
296 359 self.title_pat = re.compile('\x1b]0;(.*?)\x07')
297 360
298 #self.SetEdgeMode(stc.STC_EDGE_LINE)
299 #self.SetEdgeColumn(80)
300
301 361 # styles
302 p = self.style
303 self.StyleSetSpec(stc.STC_STYLE_DEFAULT, p['default'])
362
363 self.SetCaretForeground(p['carret_color'])
364
365 background_color = p['background_color']
366
367 if 'default' in p:
368 if 'back' not in p['default']:
369 p['default'] += ',back:%s' % background_color
370 if 'size' not in p['default']:
371 p['default'] += ',size:%s' % self.faces['size']
372 if 'face' not in p['default']:
373 p['default'] += ',face:%s' % self.faces['mono']
374
375 self.StyleSetSpec(stc.STC_STYLE_DEFAULT, p['default'])
376 else:
377 self.StyleSetSpec(stc.STC_STYLE_DEFAULT,
378 "fore:%s,back:%s,size:%d,face:%s"
379 % (self.ANSI_STYLES['0;30'][1],
380 background_color,
381 self.faces['size'], self.faces['mono']))
382
304 383 self.StyleClearAll()
384
385 # XXX: two lines below are usefull if not using the lexer
386 #for style in self.ANSI_STYLES.values():
387 # self.StyleSetSpec(style[0], "bold,fore:%s" % style[1])
388
389 # prompt definition
390 self.prompt_in1 = p['prompt_in1']
391 self.prompt_out = p['prompt_out']
392
393 self.output_prompt_template = string.Template(self.prompt_out)
394 self.input_prompt_template = string.Template(self.prompt_in1)
395
305 396 self.StyleSetSpec(_STDOUT_STYLE, p['stdout'])
306 397 self.StyleSetSpec(_STDERR_STYLE, p['stderr'])
307 398 self.StyleSetSpec(_TRACE_STYLE, p['trace'])
308
309 399 self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT, p['bracegood'])
310 400 self.StyleSetSpec(stc.STC_STYLE_BRACEBAD, p['bracebad'])
311 401 self.StyleSetSpec(stc.STC_P_COMMENTLINE, p['comment'])
312 402 self.StyleSetSpec(stc.STC_P_NUMBER, p['number'])
313 403 self.StyleSetSpec(stc.STC_P_STRING, p['string'])
314 404 self.StyleSetSpec(stc.STC_P_CHARACTER, p['char'])
315 405 self.StyleSetSpec(stc.STC_P_WORD, p['keyword'])
316 406 self.StyleSetSpec(stc.STC_P_WORD2, p['keyword'])
317 407 self.StyleSetSpec(stc.STC_P_TRIPLE, p['triple'])
318 408 self.StyleSetSpec(stc.STC_P_TRIPLEDOUBLE, p['tripledouble'])
319 409 self.StyleSetSpec(stc.STC_P_CLASSNAME, p['class'])
320 410 self.StyleSetSpec(stc.STC_P_DEFNAME, p['def'])
321 411 self.StyleSetSpec(stc.STC_P_OPERATOR, p['operator'])
322 412 self.StyleSetSpec(stc.STC_P_COMMENTBLOCK, p['comment'])
323 413
414 edge_column = p['edge_column']
415 if edge_column is not None and edge_column > 0:
416 #we add a vertical line to console widget
417 self.SetEdgeMode(stc.STC_EDGE_LINE)
418 self.SetEdgeColumn(edge_column)
419
420
421 #--------------------------------------------------------------------------
422 # EditWindow API
423 #--------------------------------------------------------------------------
424
425 def OnUpdateUI(self, event):
426 """ Override the OnUpdateUI of the EditWindow class, to prevent
427 syntax highlighting both for faster redraw, and for more
428 consistent look and feel.
429 """
430
431
432 #--------------------------------------------------------------------------
433 # Private API
434 #--------------------------------------------------------------------------
435
324 436 def _on_key_down(self, event, skip=True):
325 437 """ Key press callback used for correcting behavior for
326 438 console-like interfaces: the cursor is constraint to be after
327 439 the last prompt.
328 440
329 441 Return True if event as been catched.
330 442 """
331 443 catched = True
444 # XXX: Would the right way to do this be to have a
445 # dictionary at the instance level associating keys with
446 # callbacks? How would we deal with inheritance? And Do the
447 # different callbacks share local variables?
448
332 449 # Intercept some specific keys.
333 450 if event.KeyCode == ord('L') and event.ControlDown() :
334 451 self.scroll_to_bottom()
335 452 elif event.KeyCode == ord('K') and event.ControlDown() :
336 453 self.input_buffer = ''
337 454 elif event.KeyCode == ord('A') and event.ControlDown() :
338 455 self.GotoPos(self.GetLength())
339 456 self.SetSelectionStart(self.current_prompt_pos)
340 457 self.SetSelectionEnd(self.GetCurrentPos())
341 458 catched = True
342 459 elif event.KeyCode == ord('E') and event.ControlDown() :
343 460 self.GotoPos(self.GetLength())
344 461 catched = True
345 462 elif event.KeyCode == wx.WXK_PAGEUP:
346 463 self.ScrollPages(-1)
347 464 elif event.KeyCode == wx.WXK_PAGEDOWN:
348 465 self.ScrollPages(1)
466 elif event.KeyCode == wx.WXK_HOME:
467 self.GotoPos(self.GetLength())
468 elif event.KeyCode == wx.WXK_END:
469 self.GotoPos(self.GetLength())
349 470 elif event.KeyCode == wx.WXK_UP and event.ShiftDown():
350 471 self.ScrollLines(-1)
351 472 elif event.KeyCode == wx.WXK_DOWN and event.ShiftDown():
352 473 self.ScrollLines(1)
353 474 else:
354 475 catched = False
355 476
356 477 if self.AutoCompActive():
357 478 event.Skip()
358 479 else:
359 480 if event.KeyCode in (13, wx.WXK_NUMPAD_ENTER) and \
360 event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN):
481 event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN,
482 wx.MOD_SHIFT):
361 483 catched = True
362 self.CallTipCancel()
363 self.write('\n', refresh=False)
364 # Under windows scintilla seems to be doing funny stuff to the
365 # line returns here, but the getter for input_buffer filters
366 # this out.
367 if sys.platform == 'win32':
368 self.input_buffer = self.input_buffer
369 self._on_enter()
484 if not self.enter_catched:
485 self.CallTipCancel()
486 if event.Modifiers == wx.MOD_SHIFT:
487 # Try to force execution
488 self.GotoPos(self.GetLength())
489 self.write('\n' + self.continuation_prompt(),
490 refresh=False)
491 self._on_enter()
492 else:
493 self._on_enter()
494 self.enter_catched = True
370 495
371 496 elif event.KeyCode == wx.WXK_HOME:
372 497 if event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN):
373 498 self.GotoPos(self.current_prompt_pos)
374 499 catched = True
375 500
376 501 elif event.Modifiers == wx.MOD_SHIFT:
377 502 # FIXME: This behavior is not ideal: if the selection
378 503 # is already started, it will jump.
379 504 self.SetSelectionStart(self.current_prompt_pos)
380 505 self.SetSelectionEnd(self.GetCurrentPos())
381 506 catched = True
382 507
383 508 elif event.KeyCode == wx.WXK_UP:
384 509 if self.GetCurrentLine() > self.current_prompt_line:
385 510 if self.GetCurrentLine() == self.current_prompt_line + 1 \
386 511 and self.GetColumn(self.GetCurrentPos()) < \
387 512 self.GetColumn(self.current_prompt_pos):
388 513 self.GotoPos(self.current_prompt_pos)
389 514 else:
390 515 event.Skip()
391 516 catched = True
392 517
393 518 elif event.KeyCode in (wx.WXK_LEFT, wx.WXK_BACK):
394 if self.GetCurrentPos() > self.current_prompt_pos:
519 if not self._keep_cursor_in_buffer(self.GetCurrentPos() - 1):
520 event.Skip()
521 catched = True
522
523 elif event.KeyCode == wx.WXK_RIGHT:
524 if not self._keep_cursor_in_buffer(self.GetCurrentPos() + 1):
525 event.Skip()
526 catched = True
527
528
529 elif event.KeyCode == wx.WXK_DELETE:
530 if not self._keep_cursor_in_buffer(self.GetCurrentPos() - 1):
395 531 event.Skip()
396 532 catched = True
397 533
398 534 if skip and not catched:
399 535 # Put the cursor back in the edit region
400 if self.GetCurrentPos() < self.current_prompt_pos:
401 self.GotoPos(self.current_prompt_pos)
402 else:
403 event.Skip()
536 if not self._keep_cursor_in_buffer():
537 if not (self.GetCurrentPos() == self.GetLength()
538 and event.KeyCode == wx.WXK_DELETE):
539 event.Skip()
540 catched = True
404 541
405 542 return catched
406 543
407 544
408 545 def _on_key_up(self, event, skip=True):
409 546 """ If cursor is outside the editing region, put it back.
410 547 """
411 event.Skip()
412 if self.GetCurrentPos() < self.current_prompt_pos:
413 self.GotoPos(self.current_prompt_pos)
548 if skip:
549 event.Skip()
550 self._keep_cursor_in_buffer()
551
552
553 # XXX: I need to avoid the problem of having an empty glass;
554 def _keep_cursor_in_buffer(self, pos=None):
555 """ Checks if the cursor is where it is allowed to be. If not,
556 put it back.
414 557
558 Returns
559 -------
560 cursor_moved: Boolean
561 whether or not the cursor was moved by this routine.
562
563 Notes
564 ------
565 WARNING: This does proper checks only for horizontal
566 movements.
567 """
568 if pos is None:
569 current_pos = self.GetCurrentPos()
570 else:
571 current_pos = pos
572 if current_pos < self.current_prompt_pos:
573 self.GotoPos(self.current_prompt_pos)
574 return True
575 line_num = self.LineFromPosition(current_pos)
576 if not current_pos > self.GetLength():
577 line_pos = self.GetColumn(current_pos)
578 else:
579 line_pos = self.GetColumn(self.GetLength())
580 line = self.GetLine(line_num)
581 # Jump the continuation prompt
582 continuation_prompt = self.continuation_prompt()
583 if ( line.startswith(continuation_prompt)
584 and line_pos < len(continuation_prompt)):
585 if line_pos < 2:
586 # We are at the beginning of the line, trying to move
587 # forward: jump forward.
588 self.GotoPos(current_pos + 1 +
589 len(continuation_prompt) - line_pos)
590 else:
591 # Jump back up
592 self.GotoPos(self.GetLineEndPosition(line_num-1))
593 return True
594 elif ( current_pos > self.GetLineEndPosition(line_num)
595 and not current_pos == self.GetLength()):
596 # Jump to next line
597 self.GotoPos(current_pos + 1 +
598 len(continuation_prompt))
599 return True
600
601 # We re-allow enter event processing
602 self.enter_catched = False
603 return False
415 604
416 605
417 606 if __name__ == '__main__':
418 607 # Some simple code to test the console widget.
419 608 class MainWindow(wx.Frame):
420 609 def __init__(self, parent, id, title):
421 wx.Frame.__init__(self, parent, id, title, size=(300,250))
610 wx.Frame.__init__(self, parent, id, title, size=(300, 250))
422 611 self._sizer = wx.BoxSizer(wx.VERTICAL)
423 612 self.console_widget = ConsoleWidget(self)
424 613 self._sizer.Add(self.console_widget, 1, wx.EXPAND)
425 614 self.SetSizer(self._sizer)
426 615 self.SetAutoLayout(1)
427 616 self.Show(True)
428 617
429 618 app = wx.PySimpleApp()
430 619 w = MainWindow(None, wx.ID_ANY, 'ConsoleWidget')
431 620 w.SetSize((780, 460))
432 621 w.Show()
433 622
434 623 app.MainLoop()
435 624
436 625
@@ -1,110 +1,119 b''
1 1 """
2 2 Entry point for a simple application giving a graphical frontend to
3 3 ipython.
4 4 """
5 5
6 6 try:
7 7 import wx
8 8 except ImportError, e:
9 9 e.message = """%s
10 10 ________________________________________________________________________________
11 11 You need wxPython to run this application.
12 12 """ % e.message
13 13 e.args = (e.message, ) + e.args[1:]
14 14 raise e
15 15
16 16 from wx_frontend import WxController
17 17 import __builtin__
18 18
19 19
20 20 class IPythonXController(WxController):
21 21 """ Sub class of WxController that adds some application-specific
22 22 bindings.
23 23 """
24 24
25 25 debug = False
26 26
27 27 def __init__(self, *args, **kwargs):
28 28 WxController.__init__(self, *args, **kwargs)
29 29 self.ipython0.ask_exit = self.do_exit
30 30 # Scroll to top
31 31 maxrange = self.GetScrollRange(wx.VERTICAL)
32 32 self.ScrollLines(-maxrange)
33 33
34 34
35 35 def _on_key_down(self, event, skip=True):
36 36 # Intercept Ctrl-D to quit
37 37 if event.KeyCode == ord('D') and event.ControlDown() and \
38 38 self.input_buffer == '' and \
39 39 self._input_state == 'readline':
40 40 wx.CallAfter(self.ask_exit)
41 41 else:
42 42 WxController._on_key_down(self, event, skip=skip)
43 43
44 44
45 45 def ask_exit(self):
46 46 """ Ask the user whether to exit.
47 47 """
48 48 self._input_state = 'subprocess'
49 49 self.write('\n', refresh=False)
50 50 self.capture_output()
51 51 self.ipython0.shell.exit()
52 52 self.release_output()
53 53 if not self.ipython0.exit_now:
54 54 wx.CallAfter(self.new_prompt,
55 55 self.input_prompt_template.substitute(
56 56 number=self.last_result['number'] + 1))
57 57 else:
58 58 wx.CallAfter(wx.GetApp().Exit)
59 59 self.write('Exiting ...', refresh=False)
60 60
61 61
62 62 def do_exit(self):
63 63 """ Exits the interpreter, kills the windows.
64 64 """
65 65 WxController.do_exit(self)
66 66 self.release_output()
67 67 wx.CallAfter(wx.Exit)
68 68
69 69
70 70
71 71 class IPythonX(wx.Frame):
72 72 """ Main frame of the IPythonX app.
73 73 """
74 74
75 75 def __init__(self, parent, id, title, debug=False):
76 76 wx.Frame.__init__(self, parent, id, title, size=(300,250))
77 77 self._sizer = wx.BoxSizer(wx.VERTICAL)
78 78 self.shell = IPythonXController(self, debug=debug)
79 79 self._sizer.Add(self.shell, 1, wx.EXPAND)
80 80 self.SetSizer(self._sizer)
81 81 self.SetAutoLayout(1)
82 82 self.Show(True)
83 wx.EVT_CLOSE(self, self.on_close)
84
85
86 def on_close(self, event):
87 """ Called on closing the windows.
88
89 Stops the event loop, to close all the child windows.
90 """
91 wx.CallAfter(wx.Exit)
83 92
84 93
85 94 def main():
86 95 from optparse import OptionParser
87 96 usage = """usage: %prog [options]
88 97
89 98 Simple graphical frontend to IPython, using WxWidgets."""
90 99 parser = OptionParser(usage=usage)
91 100 parser.add_option("-d", "--debug",
92 101 action="store_true", dest="debug", default=False,
93 102 help="Enable debug message for the wx frontend.")
94 103
95 104 options, args = parser.parse_args()
96 105
97 106 # Clear the options, to avoid having the ipython0 instance complain
98 107 import sys
99 108 sys.argv = sys.argv[:1]
100 109
101 110 app = wx.PySimpleApp()
102 111 frame = IPythonX(None, wx.ID_ANY, 'IPythonX', debug=options.debug)
103 112 frame.shell.SetFocus()
104 113 frame.shell.app = app
105 114 frame.SetSize((680, 460))
106 115
107 116 app.MainLoop()
108 117
109 118 if __name__ == '__main__':
110 119 main()
@@ -1,526 +1,601 b''
1 1 # encoding: utf-8 -*- test-case-name:
2 2 # FIXME: Need to add tests.
3 3 # ipython1.frontend.wx.tests.test_wx_frontend -*-
4 4
5 5 """Classes to provide a Wx frontend to the
6 6 IPython.kernel.core.interpreter.
7 7
8 8 This class inherits from ConsoleWidget, that provides a console-like
9 9 widget to provide a text-rendering widget suitable for a terminal.
10 10 """
11 11
12 12 __docformat__ = "restructuredtext en"
13 13
14 14 #-------------------------------------------------------------------------------
15 15 # Copyright (C) 2008 The IPython Development Team
16 16 #
17 17 # Distributed under the terms of the BSD License. The full license is in
18 18 # the file COPYING, distributed as part of this software.
19 19 #-------------------------------------------------------------------------------
20 20
21 21 #-------------------------------------------------------------------------------
22 22 # Imports
23 23 #-------------------------------------------------------------------------------
24 24
25 25 # Major library imports
26 26 import re
27 27 import __builtin__
28 from time import sleep
29 28 import sys
30 29 from threading import Lock
31 import string
32 30
33 31 import wx
34 32 from wx import stc
35 33
36 34 # Ipython-specific imports.
37 from IPython.frontend._process import PipedProcess
38 from console_widget import ConsoleWidget
35 from IPython.frontend.process import PipedProcess
36 from console_widget import ConsoleWidget, _COMPLETE_BUFFER_MARKER, \
37 _ERROR_MARKER, _INPUT_MARKER
39 38 from IPython.frontend.prefilterfrontend import PrefilterFrontEnd
40 39
41 40 #-------------------------------------------------------------------------------
42 # Constants
43 #-------------------------------------------------------------------------------
44
45 _COMPLETE_BUFFER_BG = '#FAFAF1' # Nice green
46 _INPUT_BUFFER_BG = '#FDFFD3' # Nice yellow
47 _ERROR_BG = '#FFF1F1' # Nice red
48
49 _COMPLETE_BUFFER_MARKER = 31
50 _ERROR_MARKER = 30
51 _INPUT_MARKER = 29
52
53 prompt_in1 = \
54 '\n\x01\x1b[0;34m\x02In [\x01\x1b[1;34m\x02$number\x01\x1b[0;34m\x02]: \x01\x1b[0m\x02'
55
56 prompt_out = \
57 '\x01\x1b[0;31m\x02Out[\x01\x1b[1;31m\x02$number\x01\x1b[0;31m\x02]: \x01\x1b[0m\x02'
58
59 #-------------------------------------------------------------------------------
60 41 # Classes to implement the Wx frontend
61 42 #-------------------------------------------------------------------------------
62 43 class WxController(ConsoleWidget, PrefilterFrontEnd):
63 44 """Classes to provide a Wx frontend to the
64 45 IPython.kernel.core.interpreter.
65 46
66 47 This class inherits from ConsoleWidget, that provides a console-like
67 48 widget to provide a text-rendering widget suitable for a terminal.
68 49 """
69
70 output_prompt_template = string.Template(prompt_out)
71
72 input_prompt_template = string.Template(prompt_in1)
73
50
74 51 # Print debug info on what is happening to the console.
75 52 debug = False
76 53
77 54 # The title of the terminal, as captured through the ANSI escape
78 55 # sequences.
79 56 def _set_title(self, title):
80 57 return self.Parent.SetTitle(title)
81 58
82 59 def _get_title(self):
83 60 return self.Parent.GetTitle()
84 61
85 62 title = property(_get_title, _set_title)
86 63
87 64
88 65 # The buffer being edited.
89 66 # We are duplicating the definition here because of multiple
90 67 # inheritence
91 68 def _set_input_buffer(self, string):
92 69 ConsoleWidget._set_input_buffer(self, string)
93 70 self._colorize_input_buffer()
94 71
95 72 def _get_input_buffer(self):
96 73 """ Returns the text in current edit buffer.
97 74 """
98 75 return ConsoleWidget._get_input_buffer(self)
99 76
100 77 input_buffer = property(_get_input_buffer, _set_input_buffer)
101 78
102 79
103 80 #--------------------------------------------------------------------------
104 81 # Private Attributes
105 82 #--------------------------------------------------------------------------
106 83
107 84 # A flag governing the behavior of the input. Can be:
108 85 #
109 86 # 'readline' for readline-like behavior with a prompt
110 87 # and an edit buffer.
111 88 # 'raw_input' similar to readline, but triggered by a raw-input
112 89 # call. Can be used by subclasses to act differently.
113 90 # 'subprocess' for sending the raw input directly to a
114 91 # subprocess.
115 92 # 'buffering' for buffering of the input, that will be used
116 93 # when the input state switches back to another state.
117 94 _input_state = 'readline'
118 95
119 96 # Attribute to store reference to the pipes of a subprocess, if we
120 97 # are running any.
121 98 _running_process = False
122 99
123 100 # A queue for writing fast streams to the screen without flooding the
124 101 # event loop
125 102 _out_buffer = []
126 103
127 104 # A lock to lock the _out_buffer to make sure we don't empty it
128 105 # while it is being swapped
129 106 _out_buffer_lock = Lock()
130 107
131 108 # The different line markers used to higlight the prompts.
132 109 _markers = dict()
133 110
134 111 #--------------------------------------------------------------------------
135 112 # Public API
136 113 #--------------------------------------------------------------------------
137 114
138 115 def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition,
139 116 size=wx.DefaultSize,
140 117 style=wx.CLIP_CHILDREN|wx.WANTS_CHARS,
118 styledef=None,
141 119 *args, **kwds):
142 120 """ Create Shell instance.
121
122 Parameters
123 -----------
124 styledef : dict, optional
125 styledef is the dictionary of options used to define the
126 style.
143 127 """
128 if styledef is not None:
129 self.style = styledef
144 130 ConsoleWidget.__init__(self, parent, id, pos, size, style)
145 131 PrefilterFrontEnd.__init__(self, **kwds)
146 132
147 133 # Stick in our own raw_input:
148 134 self.ipython0.raw_input = self.raw_input
149 135
150 # Marker for complete buffer.
151 self.MarkerDefine(_COMPLETE_BUFFER_MARKER, stc.STC_MARK_BACKGROUND,
152 background=_COMPLETE_BUFFER_BG)
153 # Marker for current input buffer.
154 self.MarkerDefine(_INPUT_MARKER, stc.STC_MARK_BACKGROUND,
155 background=_INPUT_BUFFER_BG)
156 # Marker for tracebacks.
157 self.MarkerDefine(_ERROR_MARKER, stc.STC_MARK_BACKGROUND,
158 background=_ERROR_BG)
159
160 136 # A time for flushing the write buffer
161 137 BUFFER_FLUSH_TIMER_ID = 100
162 138 self._buffer_flush_timer = wx.Timer(self, BUFFER_FLUSH_TIMER_ID)
163 139 wx.EVT_TIMER(self, BUFFER_FLUSH_TIMER_ID, self._buffer_flush)
164 140
165 141 if 'debug' in kwds:
166 142 self.debug = kwds['debug']
167 143 kwds.pop('debug')
168 144
169 145 # Inject self in namespace, for debug
170 146 if self.debug:
171 147 self.shell.user_ns['self'] = self
172 148 # Inject our own raw_input in namespace
173 149 self.shell.user_ns['raw_input'] = self.raw_input
174
175
150
176 151 def raw_input(self, prompt=''):
177 152 """ A replacement from python's raw_input.
178 153 """
179 154 self.new_prompt(prompt)
180 155 self._input_state = 'raw_input'
181 156 if hasattr(self, '_cursor'):
182 157 del self._cursor
183 158 self.SetCursor(wx.StockCursor(wx.CURSOR_CROSS))
184 159 self.__old_on_enter = self._on_enter
185 160 event_loop = wx.EventLoop()
186 161 def my_on_enter():
187 162 event_loop.Exit()
188 163 self._on_enter = my_on_enter
189 164 # XXX: Running a separate event_loop. Ugly.
190 165 event_loop.Run()
191 166 self._on_enter = self.__old_on_enter
192 167 self._input_state = 'buffering'
193 168 self._cursor = wx.BusyCursor()
194 169 return self.input_buffer.rstrip('\n')
195 170
196 171
197 172 def system_call(self, command_string):
198 173 self._input_state = 'subprocess'
199 174 event_loop = wx.EventLoop()
200 175 def _end_system_call():
201 176 self._input_state = 'buffering'
202 177 self._running_process = False
203 178 event_loop.Exit()
204 179
205 180 self._running_process = PipedProcess(command_string,
206 181 out_callback=self.buffered_write,
207 182 end_callback = _end_system_call)
208 183 self._running_process.start()
209 184 # XXX: Running a separate event_loop. Ugly.
210 185 event_loop.Run()
211 186 # Be sure to flush the buffer.
212 187 self._buffer_flush(event=None)
213 188
214 189
215 190 def do_calltip(self):
216 191 """ Analyse current and displays useful calltip for it.
217 192 """
218 193 if self.debug:
219 194 print >>sys.__stdout__, "do_calltip"
220 195 separators = re.compile('[\s\{\}\[\]\(\)\= ,:]')
221 196 symbol = self.input_buffer
222 197 symbol_string = separators.split(symbol)[-1]
223 198 base_symbol_string = symbol_string.split('.')[0]
224 199 if base_symbol_string in self.shell.user_ns:
225 200 symbol = self.shell.user_ns[base_symbol_string]
226 201 elif base_symbol_string in self.shell.user_global_ns:
227 202 symbol = self.shell.user_global_ns[base_symbol_string]
228 203 elif base_symbol_string in __builtin__.__dict__:
229 204 symbol = __builtin__.__dict__[base_symbol_string]
230 205 else:
231 206 return False
232 207 try:
233 208 for name in symbol_string.split('.')[1:] + ['__doc__']:
234 209 symbol = getattr(symbol, name)
235 210 self.AutoCompCancel()
236 211 # Check that the symbol can indeed be converted to a string:
237 212 symbol += ''
238 213 wx.CallAfter(self.CallTipShow, self.GetCurrentPos(), symbol)
239 214 except:
240 215 # The retrieve symbol couldn't be converted to a string
241 216 pass
242 217
243 218
244 219 def _popup_completion(self, create=False):
245 220 """ Updates the popup completion menu if it exists. If create is
246 221 true, open the menu.
247 222 """
248 223 if self.debug:
249 224 print >>sys.__stdout__, "_popup_completion"
250 225 line = self.input_buffer
251 226 if (self.AutoCompActive() and line and not line[-1] == '.') \
252 227 or create==True:
253 228 suggestion, completions = self.complete(line)
254 offset=0
255 229 if completions:
256 complete_sep = re.compile('[\s\{\}\[\]\(\)\= ,:]')
257 residual = complete_sep.split(line)[-1]
258 offset = len(residual)
230 offset = len(self._get_completion_text(line))
259 231 self.pop_completion(completions, offset=offset)
260 232 if self.debug:
261 233 print >>sys.__stdout__, completions
262 234
263 235
264 236 def buffered_write(self, text):
265 237 """ A write method for streams, that caches the stream in order
266 238 to avoid flooding the event loop.
267 239
268 240 This can be called outside of the main loop, in separate
269 241 threads.
270 242 """
271 243 self._out_buffer_lock.acquire()
272 244 self._out_buffer.append(text)
273 245 self._out_buffer_lock.release()
274 246 if not self._buffer_flush_timer.IsRunning():
275 247 wx.CallAfter(self._buffer_flush_timer.Start,
276 248 milliseconds=100, oneShot=True)
277 249
278 250
251 def clear_screen(self):
252 """ Empty completely the widget.
253 """
254 self.ClearAll()
255 self.new_prompt(self.input_prompt_template.substitute(
256 number=(self.last_result['number'] + 1)))
257
258
279 259 #--------------------------------------------------------------------------
280 260 # LineFrontEnd interface
281 261 #--------------------------------------------------------------------------
282 262
283 263 def execute(self, python_string, raw_string=None):
284 264 self._input_state = 'buffering'
285 265 self.CallTipCancel()
286 266 self._cursor = wx.BusyCursor()
287 267 if raw_string is None:
288 268 raw_string = python_string
289 269 end_line = self.current_prompt_line \
290 270 + max(1, len(raw_string.split('\n'))-1)
291 271 for i in range(self.current_prompt_line, end_line):
292 272 if i in self._markers:
293 273 self.MarkerDeleteHandle(self._markers[i])
294 274 self._markers[i] = self.MarkerAdd(i, _COMPLETE_BUFFER_MARKER)
295 275 # Use a callafter to update the display robustly under windows
296 276 def callback():
297 277 self.GotoPos(self.GetLength())
298 278 PrefilterFrontEnd.execute(self, python_string,
299 279 raw_string=raw_string)
300 280 wx.CallAfter(callback)
301 281
282
283 def execute_command(self, command, hidden=False):
284 """ Execute a command, not only in the model, but also in the
285 view.
286 """
287 # XXX: This method needs to be integrated in the base fronted
288 # interface
289 if hidden:
290 return self.shell.execute(command)
291 else:
292 # XXX: we are not storing the input buffer previous to the
293 # execution, as this forces us to run the execution
294 # input_buffer a yield, which is not good.
295 ##current_buffer = self.shell.control.input_buffer
296 command = command.rstrip()
297 if len(command.split('\n')) > 1:
298 # The input command is several lines long, we need to
299 # force the execution to happen
300 command += '\n'
301 cleaned_command = self.prefilter_input(command)
302 self.input_buffer = command
303 # Do not use wx.Yield() (aka GUI.process_events()) to avoid
304 # recursive yields.
305 self.ProcessEvent(wx.PaintEvent())
306 self.write('\n')
307 if not self.is_complete(cleaned_command + '\n'):
308 self._colorize_input_buffer()
309 self.render_error('Incomplete or invalid input')
310 self.new_prompt(self.input_prompt_template.substitute(
311 number=(self.last_result['number'] + 1)))
312 return False
313 self._on_enter()
314 return True
315
316
302 317 def save_output_hooks(self):
303 318 self.__old_raw_input = __builtin__.raw_input
304 319 PrefilterFrontEnd.save_output_hooks(self)
305 320
306 321 def capture_output(self):
307 322 self.SetLexer(stc.STC_LEX_NULL)
308 323 PrefilterFrontEnd.capture_output(self)
309 324 __builtin__.raw_input = self.raw_input
310 325
311 326
312 327 def release_output(self):
313 328 __builtin__.raw_input = self.__old_raw_input
314 329 PrefilterFrontEnd.release_output(self)
315 330 self.SetLexer(stc.STC_LEX_PYTHON)
316 331
317 332
318 333 def after_execute(self):
319 334 PrefilterFrontEnd.after_execute(self)
320 335 # Clear the wait cursor
321 336 if hasattr(self, '_cursor'):
322 337 del self._cursor
323 338 self.SetCursor(wx.StockCursor(wx.CURSOR_CHAR))
324 339
325 340
326 341 def show_traceback(self):
327 342 start_line = self.GetCurrentLine()
328 343 PrefilterFrontEnd.show_traceback(self)
329 344 self.ProcessEvent(wx.PaintEvent())
330 345 #wx.Yield()
331 346 for i in range(start_line, self.GetCurrentLine()):
332 347 self._markers[i] = self.MarkerAdd(i, _ERROR_MARKER)
333 348
334 349
335 350 #--------------------------------------------------------------------------
336 351 # FrontEndBase interface
337 352 #--------------------------------------------------------------------------
338 353
339 354 def render_error(self, e):
340 355 start_line = self.GetCurrentLine()
341 356 self.write('\n' + e + '\n')
342 357 for i in range(start_line, self.GetCurrentLine()):
343 358 self._markers[i] = self.MarkerAdd(i, _ERROR_MARKER)
344 359
345 360
346 361 #--------------------------------------------------------------------------
347 362 # ConsoleWidget interface
348 363 #--------------------------------------------------------------------------
349 364
350 365 def new_prompt(self, prompt):
351 366 """ Display a new prompt, and start a new input buffer.
352 367 """
353 368 self._input_state = 'readline'
354 369 ConsoleWidget.new_prompt(self, prompt)
355 370 i = self.current_prompt_line
356 371 self._markers[i] = self.MarkerAdd(i, _INPUT_MARKER)
357 372
358 373
374 def continuation_prompt(self, *args, **kwargs):
375 # Avoid multiple inheritence, be explicit about which
376 # parent method class gets called
377 return ConsoleWidget.continuation_prompt(self, *args, **kwargs)
378
379
359 380 def write(self, *args, **kwargs):
360 381 # Avoid multiple inheritence, be explicit about which
361 382 # parent method class gets called
362 ConsoleWidget.write(self, *args, **kwargs)
383 return ConsoleWidget.write(self, *args, **kwargs)
363 384
364 385
365 386 def _on_key_down(self, event, skip=True):
366 387 """ Capture the character events, let the parent
367 388 widget handle them, and put our logic afterward.
368 389 """
369 390 # FIXME: This method needs to be broken down in smaller ones.
370 current_line_number = self.GetCurrentLine()
391 current_line_num = self.GetCurrentLine()
371 392 if event.KeyCode in (ord('c'), ord('C')) and event.ControlDown():
372 393 # Capture Control-C
373 394 if self._input_state == 'subprocess':
374 395 if self.debug:
375 396 print >>sys.__stderr__, 'Killing running process'
376 397 if hasattr(self._running_process, 'process'):
377 398 self._running_process.process.kill()
378 399 elif self._input_state == 'buffering':
379 400 if self.debug:
380 401 print >>sys.__stderr__, 'Raising KeyboardInterrupt'
381 402 raise KeyboardInterrupt
382 403 # XXX: We need to make really sure we
383 404 # get back to a prompt.
384 405 elif self._input_state == 'subprocess' and (
385 406 ( event.KeyCode<256 and
386 407 not event.ControlDown() )
387 408 or
388 409 ( event.KeyCode in (ord('d'), ord('D')) and
389 410 event.ControlDown())):
390 411 # We are running a process, we redirect keys.
391 412 ConsoleWidget._on_key_down(self, event, skip=skip)
392 413 char = chr(event.KeyCode)
393 414 # Deal with some inconsistency in wx keycodes:
394 415 if char == '\r':
395 416 char = '\n'
396 417 elif not event.ShiftDown():
397 418 char = char.lower()
398 419 if event.ControlDown() and event.KeyCode in (ord('d'), ord('D')):
399 420 char = '\04'
400 421 self._running_process.process.stdin.write(char)
401 422 self._running_process.process.stdin.flush()
402 423 elif event.KeyCode in (ord('('), 57, 53):
403 424 # Calltips
404 425 event.Skip()
405 426 self.do_calltip()
406 427 elif self.AutoCompActive() and not event.KeyCode == ord('\t'):
407 428 event.Skip()
408 429 if event.KeyCode in (wx.WXK_BACK, wx.WXK_DELETE):
409 430 wx.CallAfter(self._popup_completion, create=True)
410 431 elif not event.KeyCode in (wx.WXK_UP, wx.WXK_DOWN, wx.WXK_LEFT,
411 432 wx.WXK_RIGHT, wx.WXK_ESCAPE):
412 433 wx.CallAfter(self._popup_completion)
413 434 else:
414 435 # Up history
415 436 if event.KeyCode == wx.WXK_UP and (
416 ( current_line_number == self.current_prompt_line and
437 ( current_line_num == self.current_prompt_line and
417 438 event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN) )
418 439 or event.ControlDown() ):
419 440 new_buffer = self.get_history_previous(
420 441 self.input_buffer)
421 442 if new_buffer is not None:
422 443 self.input_buffer = new_buffer
423 444 if self.GetCurrentLine() > self.current_prompt_line:
424 445 # Go to first line, for seemless history up.
425 446 self.GotoPos(self.current_prompt_pos)
426 447 # Down history
427 448 elif event.KeyCode == wx.WXK_DOWN and (
428 ( current_line_number == self.LineCount -1 and
449 ( current_line_num == self.LineCount -1 and
429 450 event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN) )
430 451 or event.ControlDown() ):
431 452 new_buffer = self.get_history_next()
432 453 if new_buffer is not None:
433 454 self.input_buffer = new_buffer
434 455 # Tab-completion
435 456 elif event.KeyCode == ord('\t'):
436 current_line, current_line_number = self.CurLine
457 current_line, current_line_num = self.CurLine
437 458 if not re.match(r'^\s*$', current_line):
438 459 self.complete_current_input()
439 460 if self.AutoCompActive():
440 461 wx.CallAfter(self._popup_completion, create=True)
441 462 else:
442 463 event.Skip()
464 elif event.KeyCode == wx.WXK_BACK:
465 # If characters where erased, check if we have to
466 # remove a line.
467 # XXX: What about DEL?
468 # FIXME: This logics should be in ConsoleWidget, as it is
469 # independant of IPython
470 current_line, _ = self.CurLine
471 current_pos = self.GetCurrentPos()
472 current_line_num = self.LineFromPosition(current_pos)
473 current_col = self.GetColumn(current_pos)
474 len_prompt = len(self.continuation_prompt())
475 if ( current_line.startswith(self.continuation_prompt())
476 and current_col == len_prompt):
477 new_lines = []
478 for line_num, line in enumerate(
479 self.input_buffer.split('\n')):
480 if (line_num + self.current_prompt_line ==
481 current_line_num):
482 new_lines.append(line[len_prompt:])
483 else:
484 new_lines.append('\n'+line)
485 # The first character is '\n', due to the above
486 # code:
487 self.input_buffer = ''.join(new_lines)[1:]
488 self.GotoPos(current_pos - 1 - len_prompt)
489 else:
490 ConsoleWidget._on_key_down(self, event, skip=skip)
443 491 else:
444 492 ConsoleWidget._on_key_down(self, event, skip=skip)
493
445 494
446 495
447 496 def _on_key_up(self, event, skip=True):
448 497 """ Called when any key is released.
449 498 """
450 499 if event.KeyCode in (59, ord('.')):
451 500 # Intercepting '.'
452 501 event.Skip()
453 502 wx.CallAfter(self._popup_completion, create=True)
454 503 else:
455 504 ConsoleWidget._on_key_up(self, event, skip=skip)
505 # Make sure the continuation_prompts are always followed by a
506 # whitespace
507 new_lines = []
508 if self._input_state == 'readline':
509 position = self.GetCurrentPos()
510 continuation_prompt = self.continuation_prompt()[:-1]
511 for line in self.input_buffer.split('\n'):
512 if not line == continuation_prompt:
513 new_lines.append(line)
514 self.input_buffer = '\n'.join(new_lines)
515 self.GotoPos(position)
456 516
457 517
458 518 def _on_enter(self):
459 519 """ Called on return key down, in readline input_state.
460 520 """
521 last_line_num = self.LineFromPosition(self.GetLength())
522 current_line_num = self.LineFromPosition(self.GetCurrentPos())
523 new_line_pos = (last_line_num - current_line_num)
461 524 if self.debug:
462 525 print >>sys.__stdout__, repr(self.input_buffer)
463 PrefilterFrontEnd._on_enter(self)
526 self.write('\n', refresh=False)
527 # Under windows scintilla seems to be doing funny
528 # stuff to the line returns here, but the getter for
529 # input_buffer filters this out.
530 if sys.platform == 'win32':
531 self.input_buffer = self.input_buffer
532 old_prompt_num = self.current_prompt_pos
533 has_executed = PrefilterFrontEnd._on_enter(self,
534 new_line_pos=new_line_pos)
535 if old_prompt_num == self.current_prompt_pos:
536 # No execution has happened
537 self.GotoPos(self.GetLineEndPosition(current_line_num + 1))
538 return has_executed
464 539
465 540
466 541 #--------------------------------------------------------------------------
467 542 # EditWindow API
468 543 #--------------------------------------------------------------------------
469 544
470 545 def OnUpdateUI(self, event):
471 546 """ Override the OnUpdateUI of the EditWindow class, to prevent
472 547 syntax highlighting both for faster redraw, and for more
473 548 consistent look and feel.
474 549 """
475 550 if not self._input_state == 'readline':
476 551 ConsoleWidget.OnUpdateUI(self, event)
477 552
478 553 #--------------------------------------------------------------------------
479 554 # Private API
480 555 #--------------------------------------------------------------------------
481 556
482 557 def _buffer_flush(self, event):
483 558 """ Called by the timer to flush the write buffer.
484 559
485 560 This is always called in the mainloop, by the wx timer.
486 561 """
487 562 self._out_buffer_lock.acquire()
488 563 _out_buffer = self._out_buffer
489 564 self._out_buffer = []
490 565 self._out_buffer_lock.release()
491 566 self.write(''.join(_out_buffer), refresh=False)
492 567
493 568
494 569 def _colorize_input_buffer(self):
495 570 """ Keep the input buffer lines at a bright color.
496 571 """
497 572 if not self._input_state in ('readline', 'raw_input'):
498 573 return
499 574 end_line = self.GetCurrentLine()
500 575 if not sys.platform == 'win32':
501 576 end_line += 1
502 577 for i in range(self.current_prompt_line, end_line):
503 578 if i in self._markers:
504 579 self.MarkerDeleteHandle(self._markers[i])
505 580 self._markers[i] = self.MarkerAdd(i, _INPUT_MARKER)
506 581
507 582
508 583 if __name__ == '__main__':
509 584 class MainWindow(wx.Frame):
510 585 def __init__(self, parent, id, title):
511 586 wx.Frame.__init__(self, parent, id, title, size=(300,250))
512 587 self._sizer = wx.BoxSizer(wx.VERTICAL)
513 588 self.shell = WxController(self)
514 589 self._sizer.Add(self.shell, 1, wx.EXPAND)
515 590 self.SetSizer(self._sizer)
516 591 self.SetAutoLayout(1)
517 592 self.Show(True)
518 593
519 594 app = wx.PySimpleApp()
520 595 frame = MainWindow(None, wx.ID_ANY, 'Ipython')
521 596 frame.shell.SetFocus()
522 597 frame.SetSize((680, 460))
523 598 self = frame.shell
524 599
525 600 app.MainLoop()
526 601
@@ -1,2161 +1,2171 b''
1 1 # -*- coding: utf-8 -*-
2 2 """General purpose utilities.
3 3
4 4 This is a grab-bag of stuff I find useful in most programs I write. Some of
5 5 these things are also convenient when working at the command line.
6 6 """
7 7
8 8 #*****************************************************************************
9 9 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
10 10 #
11 11 # Distributed under the terms of the BSD License. The full license is in
12 12 # the file COPYING, distributed as part of this software.
13 13 #*****************************************************************************
14 14
15 15 #****************************************************************************
16 16 # required modules from the Python standard library
17 17 import __main__
18 18 import commands
19 19 try:
20 20 import doctest
21 21 except ImportError:
22 22 pass
23 23 import os
24 24 import platform
25 25 import re
26 26 import shlex
27 27 import shutil
28 28 import subprocess
29 29 import sys
30 30 import tempfile
31 31 import time
32 32 import types
33 33 import warnings
34 34
35 35 # Curses and termios are Unix-only modules
36 36 try:
37 37 import curses
38 38 # We need termios as well, so if its import happens to raise, we bail on
39 39 # using curses altogether.
40 40 import termios
41 41 except ImportError:
42 42 USE_CURSES = False
43 43 else:
44 44 # Curses on Solaris may not be complete, so we can't use it there
45 45 USE_CURSES = hasattr(curses,'initscr')
46 46
47 47 # Other IPython utilities
48 48 import IPython
49 49 from IPython.Itpl import Itpl,itpl,printpl
50 50 from IPython import DPyGetOpt, platutils
51 51 from IPython.generics import result_display
52 52 import IPython.ipapi
53 53 from IPython.external.path import path
54 54 if os.name == "nt":
55 55 from IPython.winconsole import get_console_size
56 56
57 57 try:
58 58 set
59 59 except:
60 60 from sets import Set as set
61 61
62 62
63 63 #****************************************************************************
64 64 # Exceptions
65 65 class Error(Exception):
66 66 """Base class for exceptions in this module."""
67 67 pass
68 68
69 69 #----------------------------------------------------------------------------
70 70 class IOStream:
71 71 def __init__(self,stream,fallback):
72 72 if not hasattr(stream,'write') or not hasattr(stream,'flush'):
73 73 stream = fallback
74 74 self.stream = stream
75 75 self._swrite = stream.write
76 76 self.flush = stream.flush
77 77
78 78 def write(self,data):
79 79 try:
80 80 self._swrite(data)
81 81 except:
82 82 try:
83 83 # print handles some unicode issues which may trip a plain
84 84 # write() call. Attempt to emulate write() by using a
85 85 # trailing comma
86 86 print >> self.stream, data,
87 87 except:
88 88 # if we get here, something is seriously broken.
89 89 print >> sys.stderr, \
90 90 'ERROR - failed to write data to stream:', self.stream
91 91
92 92 def close(self):
93 93 pass
94 94
95 95
96 96 class IOTerm:
97 97 """ Term holds the file or file-like objects for handling I/O operations.
98 98
99 99 These are normally just sys.stdin, sys.stdout and sys.stderr but for
100 100 Windows they can can replaced to allow editing the strings before they are
101 101 displayed."""
102 102
103 103 # In the future, having IPython channel all its I/O operations through
104 104 # this class will make it easier to embed it into other environments which
105 105 # are not a normal terminal (such as a GUI-based shell)
106 106 def __init__(self,cin=None,cout=None,cerr=None):
107 107 self.cin = IOStream(cin,sys.stdin)
108 108 self.cout = IOStream(cout,sys.stdout)
109 109 self.cerr = IOStream(cerr,sys.stderr)
110 110
111 111 # Global variable to be used for all I/O
112 112 Term = IOTerm()
113 113
114 114 import IPython.rlineimpl as readline
115 115 # Remake Term to use the readline i/o facilities
116 116 if sys.platform == 'win32' and readline.have_readline:
117 117
118 118 Term = IOTerm(cout=readline._outputfile,cerr=readline._outputfile)
119 119
120 120
121 121 #****************************************************************************
122 122 # Generic warning/error printer, used by everything else
123 123 def warn(msg,level=2,exit_val=1):
124 124 """Standard warning printer. Gives formatting consistency.
125 125
126 126 Output is sent to Term.cerr (sys.stderr by default).
127 127
128 128 Options:
129 129
130 130 -level(2): allows finer control:
131 131 0 -> Do nothing, dummy function.
132 132 1 -> Print message.
133 133 2 -> Print 'WARNING:' + message. (Default level).
134 134 3 -> Print 'ERROR:' + message.
135 135 4 -> Print 'FATAL ERROR:' + message and trigger a sys.exit(exit_val).
136 136
137 137 -exit_val (1): exit value returned by sys.exit() for a level 4
138 138 warning. Ignored for all other levels."""
139 139
140 140 if level>0:
141 141 header = ['','','WARNING: ','ERROR: ','FATAL ERROR: ']
142 142 print >> Term.cerr, '%s%s' % (header[level],msg)
143 143 if level == 4:
144 144 print >> Term.cerr,'Exiting.\n'
145 145 sys.exit(exit_val)
146 146
147 147 def info(msg):
148 148 """Equivalent to warn(msg,level=1)."""
149 149
150 150 warn(msg,level=1)
151 151
152 152 def error(msg):
153 153 """Equivalent to warn(msg,level=3)."""
154 154
155 155 warn(msg,level=3)
156 156
157 157 def fatal(msg,exit_val=1):
158 158 """Equivalent to warn(msg,exit_val=exit_val,level=4)."""
159 159
160 160 warn(msg,exit_val=exit_val,level=4)
161 161
162 162 #---------------------------------------------------------------------------
163 163 # Debugging routines
164 164 #
165 165 def debugx(expr,pre_msg=''):
166 166 """Print the value of an expression from the caller's frame.
167 167
168 168 Takes an expression, evaluates it in the caller's frame and prints both
169 169 the given expression and the resulting value (as well as a debug mark
170 170 indicating the name of the calling function. The input must be of a form
171 171 suitable for eval().
172 172
173 173 An optional message can be passed, which will be prepended to the printed
174 174 expr->value pair."""
175 175
176 176 cf = sys._getframe(1)
177 177 print '[DBG:%s] %s%s -> %r' % (cf.f_code.co_name,pre_msg,expr,
178 178 eval(expr,cf.f_globals,cf.f_locals))
179 179
180 180 # deactivate it by uncommenting the following line, which makes it a no-op
181 181 #def debugx(expr,pre_msg=''): pass
182 182
183 183 #----------------------------------------------------------------------------
184 184 StringTypes = types.StringTypes
185 185
186 186 # Basic timing functionality
187 187
188 188 # If possible (Unix), use the resource module instead of time.clock()
189 189 try:
190 190 import resource
191 191 def clocku():
192 192 """clocku() -> floating point number
193 193
194 194 Return the *USER* CPU time in seconds since the start of the process.
195 195 This is done via a call to resource.getrusage, so it avoids the
196 196 wraparound problems in time.clock()."""
197 197
198 198 return resource.getrusage(resource.RUSAGE_SELF)[0]
199 199
200 200 def clocks():
201 201 """clocks() -> floating point number
202 202
203 203 Return the *SYSTEM* CPU time in seconds since the start of the process.
204 204 This is done via a call to resource.getrusage, so it avoids the
205 205 wraparound problems in time.clock()."""
206 206
207 207 return resource.getrusage(resource.RUSAGE_SELF)[1]
208 208
209 209 def clock():
210 210 """clock() -> floating point number
211 211
212 212 Return the *TOTAL USER+SYSTEM* CPU time in seconds since the start of
213 213 the process. This is done via a call to resource.getrusage, so it
214 214 avoids the wraparound problems in time.clock()."""
215 215
216 216 u,s = resource.getrusage(resource.RUSAGE_SELF)[:2]
217 217 return u+s
218 218
219 219 def clock2():
220 220 """clock2() -> (t_user,t_system)
221 221
222 222 Similar to clock(), but return a tuple of user/system times."""
223 223 return resource.getrusage(resource.RUSAGE_SELF)[:2]
224 224
225 225 except ImportError:
226 226 # There is no distinction of user/system time under windows, so we just use
227 227 # time.clock() for everything...
228 228 clocku = clocks = clock = time.clock
229 229 def clock2():
230 230 """Under windows, system CPU time can't be measured.
231 231
232 232 This just returns clock() and zero."""
233 233 return time.clock(),0.0
234 234
235 235 def timings_out(reps,func,*args,**kw):
236 236 """timings_out(reps,func,*args,**kw) -> (t_total,t_per_call,output)
237 237
238 238 Execute a function reps times, return a tuple with the elapsed total
239 239 CPU time in seconds, the time per call and the function's output.
240 240
241 241 Under Unix, the return value is the sum of user+system time consumed by
242 242 the process, computed via the resource module. This prevents problems
243 243 related to the wraparound effect which the time.clock() function has.
244 244
245 245 Under Windows the return value is in wall clock seconds. See the
246 246 documentation for the time module for more details."""
247 247
248 248 reps = int(reps)
249 249 assert reps >=1, 'reps must be >= 1'
250 250 if reps==1:
251 251 start = clock()
252 252 out = func(*args,**kw)
253 253 tot_time = clock()-start
254 254 else:
255 255 rng = xrange(reps-1) # the last time is executed separately to store output
256 256 start = clock()
257 257 for dummy in rng: func(*args,**kw)
258 258 out = func(*args,**kw) # one last time
259 259 tot_time = clock()-start
260 260 av_time = tot_time / reps
261 261 return tot_time,av_time,out
262 262
263 263 def timings(reps,func,*args,**kw):
264 264 """timings(reps,func,*args,**kw) -> (t_total,t_per_call)
265 265
266 266 Execute a function reps times, return a tuple with the elapsed total CPU
267 267 time in seconds and the time per call. These are just the first two values
268 268 in timings_out()."""
269 269
270 270 return timings_out(reps,func,*args,**kw)[0:2]
271 271
272 272 def timing(func,*args,**kw):
273 273 """timing(func,*args,**kw) -> t_total
274 274
275 275 Execute a function once, return the elapsed total CPU time in
276 276 seconds. This is just the first value in timings_out()."""
277 277
278 278 return timings_out(1,func,*args,**kw)[0]
279 279
280 280 #****************************************************************************
281 281 # file and system
282 282
283 283 def arg_split(s,posix=False):
284 284 """Split a command line's arguments in a shell-like manner.
285 285
286 286 This is a modified version of the standard library's shlex.split()
287 287 function, but with a default of posix=False for splitting, so that quotes
288 288 in inputs are respected."""
289 289
290 290 # XXX - there may be unicode-related problems here!!! I'm not sure that
291 291 # shlex is truly unicode-safe, so it might be necessary to do
292 292 #
293 293 # s = s.encode(sys.stdin.encoding)
294 294 #
295 295 # first, to ensure that shlex gets a normal string. Input from anyone who
296 296 # knows more about unicode and shlex than I would be good to have here...
297 297 lex = shlex.shlex(s, posix=posix)
298 298 lex.whitespace_split = True
299 299 return list(lex)
300 300
301 301 def system(cmd,verbose=0,debug=0,header=''):
302 302 """Execute a system command, return its exit status.
303 303
304 304 Options:
305 305
306 306 - verbose (0): print the command to be executed.
307 307
308 308 - debug (0): only print, do not actually execute.
309 309
310 310 - header (''): Header to print on screen prior to the executed command (it
311 311 is only prepended to the command, no newlines are added).
312 312
313 313 Note: a stateful version of this function is available through the
314 314 SystemExec class."""
315 315
316 316 stat = 0
317 317 if verbose or debug: print header+cmd
318 318 sys.stdout.flush()
319 319 if not debug: stat = os.system(cmd)
320 320 return stat
321 321
322 322 def abbrev_cwd():
323 323 """ Return abbreviated version of cwd, e.g. d:mydir """
324 324 cwd = os.getcwd().replace('\\','/')
325 325 drivepart = ''
326 326 tail = cwd
327 327 if sys.platform == 'win32':
328 328 if len(cwd) < 4:
329 329 return cwd
330 330 drivepart,tail = os.path.splitdrive(cwd)
331 331
332 332
333 333 parts = tail.split('/')
334 334 if len(parts) > 2:
335 335 tail = '/'.join(parts[-2:])
336 336
337 337 return (drivepart + (
338 338 cwd == '/' and '/' or tail))
339 339
340 340
341 341 # This function is used by ipython in a lot of places to make system calls.
342 342 # We need it to be slightly different under win32, due to the vagaries of
343 343 # 'network shares'. A win32 override is below.
344 344
345 345 def shell(cmd,verbose=0,debug=0,header=''):
346 346 """Execute a command in the system shell, always return None.
347 347
348 348 Options:
349 349
350 350 - verbose (0): print the command to be executed.
351 351
352 352 - debug (0): only print, do not actually execute.
353 353
354 354 - header (''): Header to print on screen prior to the executed command (it
355 355 is only prepended to the command, no newlines are added).
356 356
357 357 Note: this is similar to genutils.system(), but it returns None so it can
358 358 be conveniently used in interactive loops without getting the return value
359 359 (typically 0) printed many times."""
360 360
361 361 stat = 0
362 362 if verbose or debug: print header+cmd
363 363 # flush stdout so we don't mangle python's buffering
364 364 sys.stdout.flush()
365 365
366 366 if not debug:
367 367 platutils.set_term_title("IPy " + cmd)
368 368 os.system(cmd)
369 369 platutils.set_term_title("IPy " + abbrev_cwd())
370 370
371 371 # override shell() for win32 to deal with network shares
372 372 if os.name in ('nt','dos'):
373 373
374 374 shell_ori = shell
375 375
376 376 def shell(cmd,verbose=0,debug=0,header=''):
377 377 if os.getcwd().startswith(r"\\"):
378 378 path = os.getcwd()
379 379 # change to c drive (cannot be on UNC-share when issuing os.system,
380 380 # as cmd.exe cannot handle UNC addresses)
381 381 os.chdir("c:")
382 382 # issue pushd to the UNC-share and then run the command
383 383 try:
384 384 shell_ori('"pushd %s&&"'%path+cmd,verbose,debug,header)
385 385 finally:
386 386 os.chdir(path)
387 387 else:
388 388 shell_ori(cmd,verbose,debug,header)
389 389
390 390 shell.__doc__ = shell_ori.__doc__
391 391
392 392 def getoutput(cmd,verbose=0,debug=0,header='',split=0):
393 393 """Dummy substitute for perl's backquotes.
394 394
395 395 Executes a command and returns the output.
396 396
397 397 Accepts the same arguments as system(), plus:
398 398
399 399 - split(0): if true, the output is returned as a list split on newlines.
400 400
401 401 Note: a stateful version of this function is available through the
402 402 SystemExec class.
403 403
404 404 This is pretty much deprecated and rarely used,
405 405 genutils.getoutputerror may be what you need.
406 406
407 407 """
408 408
409 409 if verbose or debug: print header+cmd
410 410 if not debug:
411 411 output = os.popen(cmd).read()
412 412 # stipping last \n is here for backwards compat.
413 413 if output.endswith('\n'):
414 414 output = output[:-1]
415 415 if split:
416 416 return output.split('\n')
417 417 else:
418 418 return output
419 419
420 420 def getoutputerror(cmd,verbose=0,debug=0,header='',split=0):
421 421 """Return (standard output,standard error) of executing cmd in a shell.
422 422
423 423 Accepts the same arguments as system(), plus:
424 424
425 425 - split(0): if true, each of stdout/err is returned as a list split on
426 426 newlines.
427 427
428 428 Note: a stateful version of this function is available through the
429 429 SystemExec class."""
430 430
431 431 if verbose or debug: print header+cmd
432 432 if not cmd:
433 433 if split:
434 434 return [],[]
435 435 else:
436 436 return '',''
437 437 if not debug:
438 438 pin,pout,perr = os.popen3(cmd)
439 439 tout = pout.read().rstrip()
440 440 terr = perr.read().rstrip()
441 441 pin.close()
442 442 pout.close()
443 443 perr.close()
444 444 if split:
445 445 return tout.split('\n'),terr.split('\n')
446 446 else:
447 447 return tout,terr
448 448
449 449 # for compatibility with older naming conventions
450 450 xsys = system
451 451 bq = getoutput
452 452
453 453 class SystemExec:
454 454 """Access the system and getoutput functions through a stateful interface.
455 455
456 456 Note: here we refer to the system and getoutput functions from this
457 457 library, not the ones from the standard python library.
458 458
459 459 This class offers the system and getoutput functions as methods, but the
460 460 verbose, debug and header parameters can be set for the instance (at
461 461 creation time or later) so that they don't need to be specified on each
462 462 call.
463 463
464 464 For efficiency reasons, there's no way to override the parameters on a
465 465 per-call basis other than by setting instance attributes. If you need
466 466 local overrides, it's best to directly call system() or getoutput().
467 467
468 468 The following names are provided as alternate options:
469 469 - xsys: alias to system
470 470 - bq: alias to getoutput
471 471
472 472 An instance can then be created as:
473 473 >>> sysexec = SystemExec(verbose=1,debug=0,header='Calling: ')
474 474 """
475 475
476 476 def __init__(self,verbose=0,debug=0,header='',split=0):
477 477 """Specify the instance's values for verbose, debug and header."""
478 478 setattr_list(self,'verbose debug header split')
479 479
480 480 def system(self,cmd):
481 481 """Stateful interface to system(), with the same keyword parameters."""
482 482
483 483 system(cmd,self.verbose,self.debug,self.header)
484 484
485 485 def shell(self,cmd):
486 486 """Stateful interface to shell(), with the same keyword parameters."""
487 487
488 488 shell(cmd,self.verbose,self.debug,self.header)
489 489
490 490 xsys = system # alias
491 491
492 492 def getoutput(self,cmd):
493 493 """Stateful interface to getoutput()."""
494 494
495 495 return getoutput(cmd,self.verbose,self.debug,self.header,self.split)
496 496
497 497 def getoutputerror(self,cmd):
498 498 """Stateful interface to getoutputerror()."""
499 499
500 500 return getoutputerror(cmd,self.verbose,self.debug,self.header,self.split)
501 501
502 502 bq = getoutput # alias
503 503
504 504 #-----------------------------------------------------------------------------
505 505 def mutex_opts(dict,ex_op):
506 506 """Check for presence of mutually exclusive keys in a dict.
507 507
508 508 Call: mutex_opts(dict,[[op1a,op1b],[op2a,op2b]...]"""
509 509 for op1,op2 in ex_op:
510 510 if op1 in dict and op2 in dict:
511 511 raise ValueError,'\n*** ERROR in Arguments *** '\
512 512 'Options '+op1+' and '+op2+' are mutually exclusive.'
513 513
514 514 #-----------------------------------------------------------------------------
515 515 def get_py_filename(name):
516 516 """Return a valid python filename in the current directory.
517 517
518 518 If the given name is not a file, it adds '.py' and searches again.
519 519 Raises IOError with an informative message if the file isn't found."""
520 520
521 521 name = os.path.expanduser(name)
522 522 if not os.path.isfile(name) and not name.endswith('.py'):
523 523 name += '.py'
524 524 if os.path.isfile(name):
525 525 return name
526 526 else:
527 527 raise IOError,'File `%s` not found.' % name
528 528
529 529 #-----------------------------------------------------------------------------
530 530 def filefind(fname,alt_dirs = None):
531 531 """Return the given filename either in the current directory, if it
532 532 exists, or in a specified list of directories.
533 533
534 534 ~ expansion is done on all file and directory names.
535 535
536 536 Upon an unsuccessful search, raise an IOError exception."""
537 537
538 538 if alt_dirs is None:
539 539 try:
540 540 alt_dirs = get_home_dir()
541 541 except HomeDirError:
542 542 alt_dirs = os.getcwd()
543 543 search = [fname] + list_strings(alt_dirs)
544 544 search = map(os.path.expanduser,search)
545 545 #print 'search list for',fname,'list:',search # dbg
546 546 fname = search[0]
547 547 if os.path.isfile(fname):
548 548 return fname
549 549 for direc in search[1:]:
550 550 testname = os.path.join(direc,fname)
551 551 #print 'testname',testname # dbg
552 552 if os.path.isfile(testname):
553 553 return testname
554 554 raise IOError,'File' + `fname` + \
555 555 ' not found in current or supplied directories:' + `alt_dirs`
556 556
557 557 #----------------------------------------------------------------------------
558 558 def file_read(filename):
559 559 """Read a file and close it. Returns the file source."""
560 560 fobj = open(filename,'r');
561 561 source = fobj.read();
562 562 fobj.close()
563 563 return source
564 564
565 565 def file_readlines(filename):
566 566 """Read a file and close it. Returns the file source using readlines()."""
567 567 fobj = open(filename,'r');
568 568 lines = fobj.readlines();
569 569 fobj.close()
570 570 return lines
571 571
572 572 #----------------------------------------------------------------------------
573 573 def target_outdated(target,deps):
574 574 """Determine whether a target is out of date.
575 575
576 576 target_outdated(target,deps) -> 1/0
577 577
578 578 deps: list of filenames which MUST exist.
579 579 target: single filename which may or may not exist.
580 580
581 581 If target doesn't exist or is older than any file listed in deps, return
582 582 true, otherwise return false.
583 583 """
584 584 try:
585 585 target_time = os.path.getmtime(target)
586 586 except os.error:
587 587 return 1
588 588 for dep in deps:
589 589 dep_time = os.path.getmtime(dep)
590 590 if dep_time > target_time:
591 591 #print "For target",target,"Dep failed:",dep # dbg
592 592 #print "times (dep,tar):",dep_time,target_time # dbg
593 593 return 1
594 594 return 0
595 595
596 596 #-----------------------------------------------------------------------------
597 597 def target_update(target,deps,cmd):
598 598 """Update a target with a given command given a list of dependencies.
599 599
600 600 target_update(target,deps,cmd) -> runs cmd if target is outdated.
601 601
602 602 This is just a wrapper around target_outdated() which calls the given
603 603 command if target is outdated."""
604 604
605 605 if target_outdated(target,deps):
606 606 xsys(cmd)
607 607
608 608 #----------------------------------------------------------------------------
609 609 def unquote_ends(istr):
610 610 """Remove a single pair of quotes from the endpoints of a string."""
611 611
612 612 if not istr:
613 613 return istr
614 614 if (istr[0]=="'" and istr[-1]=="'") or \
615 615 (istr[0]=='"' and istr[-1]=='"'):
616 616 return istr[1:-1]
617 617 else:
618 618 return istr
619 619
620 620 #----------------------------------------------------------------------------
621 621 def process_cmdline(argv,names=[],defaults={},usage=''):
622 622 """ Process command-line options and arguments.
623 623
624 624 Arguments:
625 625
626 626 - argv: list of arguments, typically sys.argv.
627 627
628 628 - names: list of option names. See DPyGetOpt docs for details on options
629 629 syntax.
630 630
631 631 - defaults: dict of default values.
632 632
633 633 - usage: optional usage notice to print if a wrong argument is passed.
634 634
635 635 Return a dict of options and a list of free arguments."""
636 636
637 637 getopt = DPyGetOpt.DPyGetOpt()
638 638 getopt.setIgnoreCase(0)
639 639 getopt.parseConfiguration(names)
640 640
641 641 try:
642 642 getopt.processArguments(argv)
643 643 except DPyGetOpt.ArgumentError, exc:
644 644 print usage
645 645 warn('"%s"' % exc,level=4)
646 646
647 647 defaults.update(getopt.optionValues)
648 648 args = getopt.freeValues
649 649
650 650 return defaults,args
651 651
652 652 #----------------------------------------------------------------------------
653 653 def optstr2types(ostr):
654 654 """Convert a string of option names to a dict of type mappings.
655 655
656 656 optstr2types(str) -> {None:'string_opts',int:'int_opts',float:'float_opts'}
657 657
658 658 This is used to get the types of all the options in a string formatted
659 659 with the conventions of DPyGetOpt. The 'type' None is used for options
660 660 which are strings (they need no further conversion). This function's main
661 661 use is to get a typemap for use with read_dict().
662 662 """
663 663
664 664 typeconv = {None:'',int:'',float:''}
665 665 typemap = {'s':None,'i':int,'f':float}
666 666 opt_re = re.compile(r'([\w]*)([^:=]*:?=?)([sif]?)')
667 667
668 668 for w in ostr.split():
669 669 oname,alias,otype = opt_re.match(w).groups()
670 670 if otype == '' or alias == '!': # simple switches are integers too
671 671 otype = 'i'
672 672 typeconv[typemap[otype]] += oname + ' '
673 673 return typeconv
674 674
675 675 #----------------------------------------------------------------------------
676 676 def read_dict(filename,type_conv=None,**opt):
677 677 r"""Read a dictionary of key=value pairs from an input file, optionally
678 678 performing conversions on the resulting values.
679 679
680 680 read_dict(filename,type_conv,**opt) -> dict
681 681
682 682 Only one value per line is accepted, the format should be
683 683 # optional comments are ignored
684 684 key value\n
685 685
686 686 Args:
687 687
688 688 - type_conv: A dictionary specifying which keys need to be converted to
689 689 which types. By default all keys are read as strings. This dictionary
690 690 should have as its keys valid conversion functions for strings
691 691 (int,long,float,complex, or your own). The value for each key
692 692 (converter) should be a whitespace separated string containing the names
693 693 of all the entries in the file to be converted using that function. For
694 694 keys to be left alone, use None as the conversion function (only needed
695 695 with purge=1, see below).
696 696
697 697 - opt: dictionary with extra options as below (default in parens)
698 698
699 699 purge(0): if set to 1, all keys *not* listed in type_conv are purged out
700 700 of the dictionary to be returned. If purge is going to be used, the
701 701 set of keys to be left as strings also has to be explicitly specified
702 702 using the (non-existent) conversion function None.
703 703
704 704 fs(None): field separator. This is the key/value separator to be used
705 705 when parsing the file. The None default means any whitespace [behavior
706 706 of string.split()].
707 707
708 708 strip(0): if 1, strip string values of leading/trailinig whitespace.
709 709
710 710 warn(1): warning level if requested keys are not found in file.
711 711 - 0: silently ignore.
712 712 - 1: inform but proceed.
713 713 - 2: raise KeyError exception.
714 714
715 715 no_empty(0): if 1, remove keys with whitespace strings as a value.
716 716
717 717 unique([]): list of keys (or space separated string) which can't be
718 718 repeated. If one such key is found in the file, each new instance
719 719 overwrites the previous one. For keys not listed here, the behavior is
720 720 to make a list of all appearances.
721 721
722 722 Example:
723 723
724 724 If the input file test.ini contains (we put it in a string to keep the test
725 725 self-contained):
726 726
727 727 >>> test_ini = '''\
728 728 ... i 3
729 729 ... x 4.5
730 730 ... y 5.5
731 731 ... s hi ho'''
732 732
733 733 Then we can use it as follows:
734 734 >>> type_conv={int:'i',float:'x',None:'s'}
735 735
736 736 >>> d = read_dict(test_ini)
737 737
738 738 >>> sorted(d.items())
739 739 [('i', '3'), ('s', 'hi ho'), ('x', '4.5'), ('y', '5.5')]
740 740
741 741 >>> d = read_dict(test_ini,type_conv)
742 742
743 743 >>> sorted(d.items())
744 744 [('i', 3), ('s', 'hi ho'), ('x', 4.5), ('y', '5.5')]
745 745
746 746 >>> d = read_dict(test_ini,type_conv,purge=True)
747 747
748 748 >>> sorted(d.items())
749 749 [('i', 3), ('s', 'hi ho'), ('x', 4.5)]
750 750 """
751 751
752 752 # starting config
753 753 opt.setdefault('purge',0)
754 754 opt.setdefault('fs',None) # field sep defaults to any whitespace
755 755 opt.setdefault('strip',0)
756 756 opt.setdefault('warn',1)
757 757 opt.setdefault('no_empty',0)
758 758 opt.setdefault('unique','')
759 759 if type(opt['unique']) in StringTypes:
760 760 unique_keys = qw(opt['unique'])
761 761 elif type(opt['unique']) in (types.TupleType,types.ListType):
762 762 unique_keys = opt['unique']
763 763 else:
764 764 raise ValueError, 'Unique keys must be given as a string, List or Tuple'
765 765
766 766 dict = {}
767 767
768 768 # first read in table of values as strings
769 769 if '\n' in filename:
770 770 lines = filename.splitlines()
771 771 file = None
772 772 else:
773 773 file = open(filename,'r')
774 774 lines = file.readlines()
775 775 for line in lines:
776 776 line = line.strip()
777 777 if len(line) and line[0]=='#': continue
778 778 if len(line)>0:
779 779 lsplit = line.split(opt['fs'],1)
780 780 try:
781 781 key,val = lsplit
782 782 except ValueError:
783 783 key,val = lsplit[0],''
784 784 key = key.strip()
785 785 if opt['strip']: val = val.strip()
786 786 if val == "''" or val == '""': val = ''
787 787 if opt['no_empty'] and (val=='' or val.isspace()):
788 788 continue
789 789 # if a key is found more than once in the file, build a list
790 790 # unless it's in the 'unique' list. In that case, last found in file
791 791 # takes precedence. User beware.
792 792 try:
793 793 if dict[key] and key in unique_keys:
794 794 dict[key] = val
795 795 elif type(dict[key]) is types.ListType:
796 796 dict[key].append(val)
797 797 else:
798 798 dict[key] = [dict[key],val]
799 799 except KeyError:
800 800 dict[key] = val
801 801 # purge if requested
802 802 if opt['purge']:
803 803 accepted_keys = qwflat(type_conv.values())
804 804 for key in dict.keys():
805 805 if key in accepted_keys: continue
806 806 del(dict[key])
807 807 # now convert if requested
808 808 if type_conv==None: return dict
809 809 conversions = type_conv.keys()
810 810 try: conversions.remove(None)
811 811 except: pass
812 812 for convert in conversions:
813 813 for val in qw(type_conv[convert]):
814 814 try:
815 815 dict[val] = convert(dict[val])
816 816 except KeyError,e:
817 817 if opt['warn'] == 0:
818 818 pass
819 819 elif opt['warn'] == 1:
820 820 print >>sys.stderr, 'Warning: key',val,\
821 821 'not found in file',filename
822 822 elif opt['warn'] == 2:
823 823 raise KeyError,e
824 824 else:
825 825 raise ValueError,'Warning level must be 0,1 or 2'
826 826
827 827 return dict
828 828
829 829 #----------------------------------------------------------------------------
830 830 def flag_calls(func):
831 831 """Wrap a function to detect and flag when it gets called.
832 832
833 833 This is a decorator which takes a function and wraps it in a function with
834 834 a 'called' attribute. wrapper.called is initialized to False.
835 835
836 836 The wrapper.called attribute is set to False right before each call to the
837 837 wrapped function, so if the call fails it remains False. After the call
838 838 completes, wrapper.called is set to True and the output is returned.
839 839
840 840 Testing for truth in wrapper.called allows you to determine if a call to
841 841 func() was attempted and succeeded."""
842 842
843 843 def wrapper(*args,**kw):
844 844 wrapper.called = False
845 845 out = func(*args,**kw)
846 846 wrapper.called = True
847 847 return out
848 848
849 849 wrapper.called = False
850 850 wrapper.__doc__ = func.__doc__
851 851 return wrapper
852 852
853 853 #----------------------------------------------------------------------------
854 854 def dhook_wrap(func,*a,**k):
855 855 """Wrap a function call in a sys.displayhook controller.
856 856
857 857 Returns a wrapper around func which calls func, with all its arguments and
858 858 keywords unmodified, using the default sys.displayhook. Since IPython
859 859 modifies sys.displayhook, it breaks the behavior of certain systems that
860 860 rely on the default behavior, notably doctest.
861 861 """
862 862
863 863 def f(*a,**k):
864 864
865 865 dhook_s = sys.displayhook
866 866 sys.displayhook = sys.__displayhook__
867 867 try:
868 868 out = func(*a,**k)
869 869 finally:
870 870 sys.displayhook = dhook_s
871 871
872 872 return out
873 873
874 874 f.__doc__ = func.__doc__
875 875 return f
876 876
877 877 #----------------------------------------------------------------------------
878 878 def doctest_reload():
879 879 """Properly reload doctest to reuse it interactively.
880 880
881 881 This routine:
882 882
883 883 - reloads doctest
884 884
885 885 - resets its global 'master' attribute to None, so that multiple uses of
886 886 the module interactively don't produce cumulative reports.
887 887
888 888 - Monkeypatches its core test runner method to protect it from IPython's
889 889 modified displayhook. Doctest expects the default displayhook behavior
890 890 deep down, so our modification breaks it completely. For this reason, a
891 891 hard monkeypatch seems like a reasonable solution rather than asking
892 892 users to manually use a different doctest runner when under IPython."""
893 893
894 894 import doctest
895 895 reload(doctest)
896 896 doctest.master=None
897 897
898 898 try:
899 899 doctest.DocTestRunner
900 900 except AttributeError:
901 901 # This is only for python 2.3 compatibility, remove once we move to
902 902 # 2.4 only.
903 903 pass
904 904 else:
905 905 doctest.DocTestRunner.run = dhook_wrap(doctest.DocTestRunner.run)
906 906
907 907 #----------------------------------------------------------------------------
908 908 class HomeDirError(Error):
909 909 pass
910 910
911 911 def get_home_dir():
912 912 """Return the closest possible equivalent to a 'home' directory.
913 913
914 914 We first try $HOME. Absent that, on NT it's $HOMEDRIVE\$HOMEPATH.
915 915
916 916 Currently only Posix and NT are implemented, a HomeDirError exception is
917 917 raised for all other OSes. """
918 918
919 919 isdir = os.path.isdir
920 920 env = os.environ
921 921
922 922 # first, check py2exe distribution root directory for _ipython.
923 923 # This overrides all. Normally does not exist.
924 924
925 925 if hasattr(sys, "frozen"): #Is frozen by py2exe
926 926 if '\\library.zip\\' in IPython.__file__.lower():#libraries compressed to zip-file
927 927 root, rest = IPython.__file__.lower().split('library.zip')
928 928 else:
929 929 root=os.path.join(os.path.split(IPython.__file__)[0],"../../")
930 930 root=os.path.abspath(root).rstrip('\\')
931 931 if isdir(os.path.join(root, '_ipython')):
932 932 os.environ["IPYKITROOT"] = root
933 933 return root
934 934 try:
935 935 homedir = env['HOME']
936 936 if not isdir(homedir):
937 937 # in case a user stuck some string which does NOT resolve to a
938 938 # valid path, it's as good as if we hadn't foud it
939 939 raise KeyError
940 940 return homedir
941 941 except KeyError:
942 942 if os.name == 'posix':
943 943 raise HomeDirError,'undefined $HOME, IPython can not proceed.'
944 944 elif os.name == 'nt':
945 945 # For some strange reason, win9x returns 'nt' for os.name.
946 946 try:
947 947 homedir = os.path.join(env['HOMEDRIVE'],env['HOMEPATH'])
948 948 if not isdir(homedir):
949 949 homedir = os.path.join(env['USERPROFILE'])
950 950 if not isdir(homedir):
951 951 raise HomeDirError
952 952 return homedir
953 953 except KeyError:
954 954 try:
955 955 # Use the registry to get the 'My Documents' folder.
956 956 import _winreg as wreg
957 957 key = wreg.OpenKey(wreg.HKEY_CURRENT_USER,
958 958 "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders")
959 959 homedir = wreg.QueryValueEx(key,'Personal')[0]
960 960 key.Close()
961 961 if not isdir(homedir):
962 962 e = ('Invalid "Personal" folder registry key '
963 963 'typically "My Documents".\n'
964 964 'Value: %s\n'
965 965 'This is not a valid directory on your system.' %
966 966 homedir)
967 967 raise HomeDirError(e)
968 968 return homedir
969 969 except HomeDirError:
970 970 raise
971 971 except:
972 972 return 'C:\\'
973 973 elif os.name == 'dos':
974 974 # Desperate, may do absurd things in classic MacOS. May work under DOS.
975 975 return 'C:\\'
976 976 else:
977 977 raise HomeDirError,'support for your operating system not implemented.'
978 978
979 979
980 980 def get_ipython_dir():
981 981 """Get the IPython directory for this platform and user.
982 982
983 983 This uses the logic in `get_home_dir` to find the home directory
984 984 and the adds either .ipython or _ipython to the end of the path.
985 985 """
986 986 if os.name == 'posix':
987 987 ipdir_def = '.ipython'
988 988 else:
989 989 ipdir_def = '_ipython'
990 990 home_dir = get_home_dir()
991 991 ipdir = os.path.abspath(os.environ.get('IPYTHONDIR',
992 992 os.path.join(home_dir, ipdir_def)))
993 993 return ipdir.decode(sys.getfilesystemencoding())
994 994
995 995 def get_security_dir():
996 996 """Get the IPython security directory.
997 997
998 998 This directory is the default location for all security related files,
999 999 including SSL/TLS certificates and FURL files.
1000 1000
1001 1001 If the directory does not exist, it is created with 0700 permissions.
1002 1002 If it exists, permissions are set to 0700.
1003 1003 """
1004 1004 security_dir = os.path.join(get_ipython_dir(), 'security')
1005 1005 if not os.path.isdir(security_dir):
1006 1006 os.mkdir(security_dir, 0700)
1007 1007 else:
1008 1008 os.chmod(security_dir, 0700)
1009 1009 return security_dir
1010
1010
1011 def get_log_dir():
1012 """Get the IPython log directory.
1013
1014 If the log directory does not exist, it is created.
1015 """
1016 log_dir = os.path.join(get_ipython_dir(), 'log')
1017 if not os.path.isdir(log_dir):
1018 os.mkdir(log_dir, 0777)
1019 return log_dir
1020
1011 1021 #****************************************************************************
1012 1022 # strings and text
1013 1023
1014 1024 class LSString(str):
1015 1025 """String derivative with a special access attributes.
1016 1026
1017 1027 These are normal strings, but with the special attributes:
1018 1028
1019 1029 .l (or .list) : value as list (split on newlines).
1020 1030 .n (or .nlstr): original value (the string itself).
1021 1031 .s (or .spstr): value as whitespace-separated string.
1022 1032 .p (or .paths): list of path objects
1023 1033
1024 1034 Any values which require transformations are computed only once and
1025 1035 cached.
1026 1036
1027 1037 Such strings are very useful to efficiently interact with the shell, which
1028 1038 typically only understands whitespace-separated options for commands."""
1029 1039
1030 1040 def get_list(self):
1031 1041 try:
1032 1042 return self.__list
1033 1043 except AttributeError:
1034 1044 self.__list = self.split('\n')
1035 1045 return self.__list
1036 1046
1037 1047 l = list = property(get_list)
1038 1048
1039 1049 def get_spstr(self):
1040 1050 try:
1041 1051 return self.__spstr
1042 1052 except AttributeError:
1043 1053 self.__spstr = self.replace('\n',' ')
1044 1054 return self.__spstr
1045 1055
1046 1056 s = spstr = property(get_spstr)
1047 1057
1048 1058 def get_nlstr(self):
1049 1059 return self
1050 1060
1051 1061 n = nlstr = property(get_nlstr)
1052 1062
1053 1063 def get_paths(self):
1054 1064 try:
1055 1065 return self.__paths
1056 1066 except AttributeError:
1057 1067 self.__paths = [path(p) for p in self.split('\n') if os.path.exists(p)]
1058 1068 return self.__paths
1059 1069
1060 1070 p = paths = property(get_paths)
1061 1071
1062 1072 def print_lsstring(arg):
1063 1073 """ Prettier (non-repr-like) and more informative printer for LSString """
1064 1074 print "LSString (.p, .n, .l, .s available). Value:"
1065 1075 print arg
1066 1076
1067 1077 print_lsstring = result_display.when_type(LSString)(print_lsstring)
1068 1078
1069 1079 #----------------------------------------------------------------------------
1070 1080 class SList(list):
1071 1081 """List derivative with a special access attributes.
1072 1082
1073 1083 These are normal lists, but with the special attributes:
1074 1084
1075 1085 .l (or .list) : value as list (the list itself).
1076 1086 .n (or .nlstr): value as a string, joined on newlines.
1077 1087 .s (or .spstr): value as a string, joined on spaces.
1078 1088 .p (or .paths): list of path objects
1079 1089
1080 1090 Any values which require transformations are computed only once and
1081 1091 cached."""
1082 1092
1083 1093 def get_list(self):
1084 1094 return self
1085 1095
1086 1096 l = list = property(get_list)
1087 1097
1088 1098 def get_spstr(self):
1089 1099 try:
1090 1100 return self.__spstr
1091 1101 except AttributeError:
1092 1102 self.__spstr = ' '.join(self)
1093 1103 return self.__spstr
1094 1104
1095 1105 s = spstr = property(get_spstr)
1096 1106
1097 1107 def get_nlstr(self):
1098 1108 try:
1099 1109 return self.__nlstr
1100 1110 except AttributeError:
1101 1111 self.__nlstr = '\n'.join(self)
1102 1112 return self.__nlstr
1103 1113
1104 1114 n = nlstr = property(get_nlstr)
1105 1115
1106 1116 def get_paths(self):
1107 1117 try:
1108 1118 return self.__paths
1109 1119 except AttributeError:
1110 1120 self.__paths = [path(p) for p in self if os.path.exists(p)]
1111 1121 return self.__paths
1112 1122
1113 1123 p = paths = property(get_paths)
1114 1124
1115 1125 def grep(self, pattern, prune = False, field = None):
1116 1126 """ Return all strings matching 'pattern' (a regex or callable)
1117 1127
1118 1128 This is case-insensitive. If prune is true, return all items
1119 1129 NOT matching the pattern.
1120 1130
1121 1131 If field is specified, the match must occur in the specified
1122 1132 whitespace-separated field.
1123 1133
1124 1134 Examples::
1125 1135
1126 1136 a.grep( lambda x: x.startswith('C') )
1127 1137 a.grep('Cha.*log', prune=1)
1128 1138 a.grep('chm', field=-1)
1129 1139 """
1130 1140
1131 1141 def match_target(s):
1132 1142 if field is None:
1133 1143 return s
1134 1144 parts = s.split()
1135 1145 try:
1136 1146 tgt = parts[field]
1137 1147 return tgt
1138 1148 except IndexError:
1139 1149 return ""
1140 1150
1141 1151 if isinstance(pattern, basestring):
1142 1152 pred = lambda x : re.search(pattern, x, re.IGNORECASE)
1143 1153 else:
1144 1154 pred = pattern
1145 1155 if not prune:
1146 1156 return SList([el for el in self if pred(match_target(el))])
1147 1157 else:
1148 1158 return SList([el for el in self if not pred(match_target(el))])
1149 1159 def fields(self, *fields):
1150 1160 """ Collect whitespace-separated fields from string list
1151 1161
1152 1162 Allows quick awk-like usage of string lists.
1153 1163
1154 1164 Example data (in var a, created by 'a = !ls -l')::
1155 1165 -rwxrwxrwx 1 ville None 18 Dec 14 2006 ChangeLog
1156 1166 drwxrwxrwx+ 6 ville None 0 Oct 24 18:05 IPython
1157 1167
1158 1168 a.fields(0) is ['-rwxrwxrwx', 'drwxrwxrwx+']
1159 1169 a.fields(1,0) is ['1 -rwxrwxrwx', '6 drwxrwxrwx+']
1160 1170 (note the joining by space).
1161 1171 a.fields(-1) is ['ChangeLog', 'IPython']
1162 1172
1163 1173 IndexErrors are ignored.
1164 1174
1165 1175 Without args, fields() just split()'s the strings.
1166 1176 """
1167 1177 if len(fields) == 0:
1168 1178 return [el.split() for el in self]
1169 1179
1170 1180 res = SList()
1171 1181 for el in [f.split() for f in self]:
1172 1182 lineparts = []
1173 1183
1174 1184 for fd in fields:
1175 1185 try:
1176 1186 lineparts.append(el[fd])
1177 1187 except IndexError:
1178 1188 pass
1179 1189 if lineparts:
1180 1190 res.append(" ".join(lineparts))
1181 1191
1182 1192 return res
1183 1193 def sort(self,field= None, nums = False):
1184 1194 """ sort by specified fields (see fields())
1185 1195
1186 1196 Example::
1187 1197 a.sort(1, nums = True)
1188 1198
1189 1199 Sorts a by second field, in numerical order (so that 21 > 3)
1190 1200
1191 1201 """
1192 1202
1193 1203 #decorate, sort, undecorate
1194 1204 if field is not None:
1195 1205 dsu = [[SList([line]).fields(field), line] for line in self]
1196 1206 else:
1197 1207 dsu = [[line, line] for line in self]
1198 1208 if nums:
1199 1209 for i in range(len(dsu)):
1200 1210 numstr = "".join([ch for ch in dsu[i][0] if ch.isdigit()])
1201 1211 try:
1202 1212 n = int(numstr)
1203 1213 except ValueError:
1204 1214 n = 0;
1205 1215 dsu[i][0] = n
1206 1216
1207 1217
1208 1218 dsu.sort()
1209 1219 return SList([t[1] for t in dsu])
1210 1220
1211 1221 def print_slist(arg):
1212 1222 """ Prettier (non-repr-like) and more informative printer for SList """
1213 1223 print "SList (.p, .n, .l, .s, .grep(), .fields(), sort() available):"
1214 1224 if hasattr(arg, 'hideonce') and arg.hideonce:
1215 1225 arg.hideonce = False
1216 1226 return
1217 1227
1218 1228 nlprint(arg)
1219 1229
1220 1230 print_slist = result_display.when_type(SList)(print_slist)
1221 1231
1222 1232
1223 1233
1224 1234 #----------------------------------------------------------------------------
1225 1235 def esc_quotes(strng):
1226 1236 """Return the input string with single and double quotes escaped out"""
1227 1237
1228 1238 return strng.replace('"','\\"').replace("'","\\'")
1229 1239
1230 1240 #----------------------------------------------------------------------------
1231 1241 def make_quoted_expr(s):
1232 1242 """Return string s in appropriate quotes, using raw string if possible.
1233 1243
1234 1244 XXX - example removed because it caused encoding errors in documentation
1235 1245 generation. We need a new example that doesn't contain invalid chars.
1236 1246
1237 1247 Note the use of raw string and padding at the end to allow trailing
1238 1248 backslash.
1239 1249 """
1240 1250
1241 1251 tail = ''
1242 1252 tailpadding = ''
1243 1253 raw = ''
1244 1254 if "\\" in s:
1245 1255 raw = 'r'
1246 1256 if s.endswith('\\'):
1247 1257 tail = '[:-1]'
1248 1258 tailpadding = '_'
1249 1259 if '"' not in s:
1250 1260 quote = '"'
1251 1261 elif "'" not in s:
1252 1262 quote = "'"
1253 1263 elif '"""' not in s and not s.endswith('"'):
1254 1264 quote = '"""'
1255 1265 elif "'''" not in s and not s.endswith("'"):
1256 1266 quote = "'''"
1257 1267 else:
1258 1268 # give up, backslash-escaped string will do
1259 1269 return '"%s"' % esc_quotes(s)
1260 1270 res = raw + quote + s + tailpadding + quote + tail
1261 1271 return res
1262 1272
1263 1273
1264 1274 #----------------------------------------------------------------------------
1265 1275 def raw_input_multi(header='', ps1='==> ', ps2='..> ',terminate_str = '.'):
1266 1276 """Take multiple lines of input.
1267 1277
1268 1278 A list with each line of input as a separate element is returned when a
1269 1279 termination string is entered (defaults to a single '.'). Input can also
1270 1280 terminate via EOF (^D in Unix, ^Z-RET in Windows).
1271 1281
1272 1282 Lines of input which end in \\ are joined into single entries (and a
1273 1283 secondary continuation prompt is issued as long as the user terminates
1274 1284 lines with \\). This allows entering very long strings which are still
1275 1285 meant to be treated as single entities.
1276 1286 """
1277 1287
1278 1288 try:
1279 1289 if header:
1280 1290 header += '\n'
1281 1291 lines = [raw_input(header + ps1)]
1282 1292 except EOFError:
1283 1293 return []
1284 1294 terminate = [terminate_str]
1285 1295 try:
1286 1296 while lines[-1:] != terminate:
1287 1297 new_line = raw_input(ps1)
1288 1298 while new_line.endswith('\\'):
1289 1299 new_line = new_line[:-1] + raw_input(ps2)
1290 1300 lines.append(new_line)
1291 1301
1292 1302 return lines[:-1] # don't return the termination command
1293 1303 except EOFError:
1294 1304 print
1295 1305 return lines
1296 1306
1297 1307 #----------------------------------------------------------------------------
1298 1308 def raw_input_ext(prompt='', ps2='... '):
1299 1309 """Similar to raw_input(), but accepts extended lines if input ends with \\."""
1300 1310
1301 1311 line = raw_input(prompt)
1302 1312 while line.endswith('\\'):
1303 1313 line = line[:-1] + raw_input(ps2)
1304 1314 return line
1305 1315
1306 1316 #----------------------------------------------------------------------------
1307 1317 def ask_yes_no(prompt,default=None):
1308 1318 """Asks a question and returns a boolean (y/n) answer.
1309 1319
1310 1320 If default is given (one of 'y','n'), it is used if the user input is
1311 1321 empty. Otherwise the question is repeated until an answer is given.
1312 1322
1313 1323 An EOF is treated as the default answer. If there is no default, an
1314 1324 exception is raised to prevent infinite loops.
1315 1325
1316 1326 Valid answers are: y/yes/n/no (match is not case sensitive)."""
1317 1327
1318 1328 answers = {'y':True,'n':False,'yes':True,'no':False}
1319 1329 ans = None
1320 1330 while ans not in answers.keys():
1321 1331 try:
1322 1332 ans = raw_input(prompt+' ').lower()
1323 1333 if not ans: # response was an empty string
1324 1334 ans = default
1325 1335 except KeyboardInterrupt:
1326 1336 pass
1327 1337 except EOFError:
1328 1338 if default in answers.keys():
1329 1339 ans = default
1330 1340 print
1331 1341 else:
1332 1342 raise
1333 1343
1334 1344 return answers[ans]
1335 1345
1336 1346 #----------------------------------------------------------------------------
1337 1347 def marquee(txt='',width=78,mark='*'):
1338 1348 """Return the input string centered in a 'marquee'."""
1339 1349 if not txt:
1340 1350 return (mark*width)[:width]
1341 1351 nmark = (width-len(txt)-2)/len(mark)/2
1342 1352 if nmark < 0: nmark =0
1343 1353 marks = mark*nmark
1344 1354 return '%s %s %s' % (marks,txt,marks)
1345 1355
1346 1356 #----------------------------------------------------------------------------
1347 1357 class EvalDict:
1348 1358 """
1349 1359 Emulate a dict which evaluates its contents in the caller's frame.
1350 1360
1351 1361 Usage:
1352 1362 >>> number = 19
1353 1363
1354 1364 >>> text = "python"
1355 1365
1356 1366 >>> print "%(text.capitalize())s %(number/9.0).1f rules!" % EvalDict()
1357 1367 Python 2.1 rules!
1358 1368 """
1359 1369
1360 1370 # This version is due to sismex01@hebmex.com on c.l.py, and is basically a
1361 1371 # modified (shorter) version of:
1362 1372 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66018 by
1363 1373 # Skip Montanaro (skip@pobox.com).
1364 1374
1365 1375 def __getitem__(self, name):
1366 1376 frame = sys._getframe(1)
1367 1377 return eval(name, frame.f_globals, frame.f_locals)
1368 1378
1369 1379 EvalString = EvalDict # for backwards compatibility
1370 1380 #----------------------------------------------------------------------------
1371 1381 def qw(words,flat=0,sep=None,maxsplit=-1):
1372 1382 """Similar to Perl's qw() operator, but with some more options.
1373 1383
1374 1384 qw(words,flat=0,sep=' ',maxsplit=-1) -> words.split(sep,maxsplit)
1375 1385
1376 1386 words can also be a list itself, and with flat=1, the output will be
1377 1387 recursively flattened.
1378 1388
1379 1389 Examples:
1380 1390
1381 1391 >>> qw('1 2')
1382 1392 ['1', '2']
1383 1393
1384 1394 >>> qw(['a b','1 2',['m n','p q']])
1385 1395 [['a', 'b'], ['1', '2'], [['m', 'n'], ['p', 'q']]]
1386 1396
1387 1397 >>> qw(['a b','1 2',['m n','p q']],flat=1)
1388 1398 ['a', 'b', '1', '2', 'm', 'n', 'p', 'q']
1389 1399 """
1390 1400
1391 1401 if type(words) in StringTypes:
1392 1402 return [word.strip() for word in words.split(sep,maxsplit)
1393 1403 if word and not word.isspace() ]
1394 1404 if flat:
1395 1405 return flatten(map(qw,words,[1]*len(words)))
1396 1406 return map(qw,words)
1397 1407
1398 1408 #----------------------------------------------------------------------------
1399 1409 def qwflat(words,sep=None,maxsplit=-1):
1400 1410 """Calls qw(words) in flat mode. It's just a convenient shorthand."""
1401 1411 return qw(words,1,sep,maxsplit)
1402 1412
1403 1413 #----------------------------------------------------------------------------
1404 1414 def qw_lol(indata):
1405 1415 """qw_lol('a b') -> [['a','b']],
1406 1416 otherwise it's just a call to qw().
1407 1417
1408 1418 We need this to make sure the modules_some keys *always* end up as a
1409 1419 list of lists."""
1410 1420
1411 1421 if type(indata) in StringTypes:
1412 1422 return [qw(indata)]
1413 1423 else:
1414 1424 return qw(indata)
1415 1425
1416 1426 #-----------------------------------------------------------------------------
1417 1427 def list_strings(arg):
1418 1428 """Always return a list of strings, given a string or list of strings
1419 1429 as input."""
1420 1430
1421 1431 if type(arg) in StringTypes: return [arg]
1422 1432 else: return arg
1423 1433
1424 1434 #----------------------------------------------------------------------------
1425 1435 def grep(pat,list,case=1):
1426 1436 """Simple minded grep-like function.
1427 1437 grep(pat,list) returns occurrences of pat in list, None on failure.
1428 1438
1429 1439 It only does simple string matching, with no support for regexps. Use the
1430 1440 option case=0 for case-insensitive matching."""
1431 1441
1432 1442 # This is pretty crude. At least it should implement copying only references
1433 1443 # to the original data in case it's big. Now it copies the data for output.
1434 1444 out=[]
1435 1445 if case:
1436 1446 for term in list:
1437 1447 if term.find(pat)>-1: out.append(term)
1438 1448 else:
1439 1449 lpat=pat.lower()
1440 1450 for term in list:
1441 1451 if term.lower().find(lpat)>-1: out.append(term)
1442 1452
1443 1453 if len(out): return out
1444 1454 else: return None
1445 1455
1446 1456 #----------------------------------------------------------------------------
1447 1457 def dgrep(pat,*opts):
1448 1458 """Return grep() on dir()+dir(__builtins__).
1449 1459
1450 1460 A very common use of grep() when working interactively."""
1451 1461
1452 1462 return grep(pat,dir(__main__)+dir(__main__.__builtins__),*opts)
1453 1463
1454 1464 #----------------------------------------------------------------------------
1455 1465 def idgrep(pat):
1456 1466 """Case-insensitive dgrep()"""
1457 1467
1458 1468 return dgrep(pat,0)
1459 1469
1460 1470 #----------------------------------------------------------------------------
1461 1471 def igrep(pat,list):
1462 1472 """Synonym for case-insensitive grep."""
1463 1473
1464 1474 return grep(pat,list,case=0)
1465 1475
1466 1476 #----------------------------------------------------------------------------
1467 1477 def indent(str,nspaces=4,ntabs=0):
1468 1478 """Indent a string a given number of spaces or tabstops.
1469 1479
1470 1480 indent(str,nspaces=4,ntabs=0) -> indent str by ntabs+nspaces.
1471 1481 """
1472 1482 if str is None:
1473 1483 return
1474 1484 ind = '\t'*ntabs+' '*nspaces
1475 1485 outstr = '%s%s' % (ind,str.replace(os.linesep,os.linesep+ind))
1476 1486 if outstr.endswith(os.linesep+ind):
1477 1487 return outstr[:-len(ind)]
1478 1488 else:
1479 1489 return outstr
1480 1490
1481 1491 #-----------------------------------------------------------------------------
1482 1492 def native_line_ends(filename,backup=1):
1483 1493 """Convert (in-place) a file to line-ends native to the current OS.
1484 1494
1485 1495 If the optional backup argument is given as false, no backup of the
1486 1496 original file is left. """
1487 1497
1488 1498 backup_suffixes = {'posix':'~','dos':'.bak','nt':'.bak','mac':'.bak'}
1489 1499
1490 1500 bak_filename = filename + backup_suffixes[os.name]
1491 1501
1492 1502 original = open(filename).read()
1493 1503 shutil.copy2(filename,bak_filename)
1494 1504 try:
1495 1505 new = open(filename,'wb')
1496 1506 new.write(os.linesep.join(original.splitlines()))
1497 1507 new.write(os.linesep) # ALWAYS put an eol at the end of the file
1498 1508 new.close()
1499 1509 except:
1500 1510 os.rename(bak_filename,filename)
1501 1511 if not backup:
1502 1512 try:
1503 1513 os.remove(bak_filename)
1504 1514 except:
1505 1515 pass
1506 1516
1507 1517 #----------------------------------------------------------------------------
1508 1518 def get_pager_cmd(pager_cmd = None):
1509 1519 """Return a pager command.
1510 1520
1511 1521 Makes some attempts at finding an OS-correct one."""
1512 1522
1513 1523 if os.name == 'posix':
1514 1524 default_pager_cmd = 'less -r' # -r for color control sequences
1515 1525 elif os.name in ['nt','dos']:
1516 1526 default_pager_cmd = 'type'
1517 1527
1518 1528 if pager_cmd is None:
1519 1529 try:
1520 1530 pager_cmd = os.environ['PAGER']
1521 1531 except:
1522 1532 pager_cmd = default_pager_cmd
1523 1533 return pager_cmd
1524 1534
1525 1535 #-----------------------------------------------------------------------------
1526 1536 def get_pager_start(pager,start):
1527 1537 """Return the string for paging files with an offset.
1528 1538
1529 1539 This is the '+N' argument which less and more (under Unix) accept.
1530 1540 """
1531 1541
1532 1542 if pager in ['less','more']:
1533 1543 if start:
1534 1544 start_string = '+' + str(start)
1535 1545 else:
1536 1546 start_string = ''
1537 1547 else:
1538 1548 start_string = ''
1539 1549 return start_string
1540 1550
1541 1551 #----------------------------------------------------------------------------
1542 1552 # (X)emacs on W32 doesn't like to be bypassed with msvcrt.getch()
1543 1553 if os.name == 'nt' and os.environ.get('TERM','dumb') != 'emacs':
1544 1554 import msvcrt
1545 1555 def page_more():
1546 1556 """ Smart pausing between pages
1547 1557
1548 1558 @return: True if need print more lines, False if quit
1549 1559 """
1550 1560 Term.cout.write('---Return to continue, q to quit--- ')
1551 1561 ans = msvcrt.getch()
1552 1562 if ans in ("q", "Q"):
1553 1563 result = False
1554 1564 else:
1555 1565 result = True
1556 1566 Term.cout.write("\b"*37 + " "*37 + "\b"*37)
1557 1567 return result
1558 1568 else:
1559 1569 def page_more():
1560 1570 ans = raw_input('---Return to continue, q to quit--- ')
1561 1571 if ans.lower().startswith('q'):
1562 1572 return False
1563 1573 else:
1564 1574 return True
1565 1575
1566 1576 esc_re = re.compile(r"(\x1b[^m]+m)")
1567 1577
1568 1578 def page_dumb(strng,start=0,screen_lines=25):
1569 1579 """Very dumb 'pager' in Python, for when nothing else works.
1570 1580
1571 1581 Only moves forward, same interface as page(), except for pager_cmd and
1572 1582 mode."""
1573 1583
1574 1584 out_ln = strng.splitlines()[start:]
1575 1585 screens = chop(out_ln,screen_lines-1)
1576 1586 if len(screens) == 1:
1577 1587 print >>Term.cout, os.linesep.join(screens[0])
1578 1588 else:
1579 1589 last_escape = ""
1580 1590 for scr in screens[0:-1]:
1581 1591 hunk = os.linesep.join(scr)
1582 1592 print >>Term.cout, last_escape + hunk
1583 1593 if not page_more():
1584 1594 return
1585 1595 esc_list = esc_re.findall(hunk)
1586 1596 if len(esc_list) > 0:
1587 1597 last_escape = esc_list[-1]
1588 1598 print >>Term.cout, last_escape + os.linesep.join(screens[-1])
1589 1599
1590 1600 #----------------------------------------------------------------------------
1591 1601 def page(strng,start=0,screen_lines=0,pager_cmd = None):
1592 1602 """Print a string, piping through a pager after a certain length.
1593 1603
1594 1604 The screen_lines parameter specifies the number of *usable* lines of your
1595 1605 terminal screen (total lines minus lines you need to reserve to show other
1596 1606 information).
1597 1607
1598 1608 If you set screen_lines to a number <=0, page() will try to auto-determine
1599 1609 your screen size and will only use up to (screen_size+screen_lines) for
1600 1610 printing, paging after that. That is, if you want auto-detection but need
1601 1611 to reserve the bottom 3 lines of the screen, use screen_lines = -3, and for
1602 1612 auto-detection without any lines reserved simply use screen_lines = 0.
1603 1613
1604 1614 If a string won't fit in the allowed lines, it is sent through the
1605 1615 specified pager command. If none given, look for PAGER in the environment,
1606 1616 and ultimately default to less.
1607 1617
1608 1618 If no system pager works, the string is sent through a 'dumb pager'
1609 1619 written in python, very simplistic.
1610 1620 """
1611 1621
1612 1622 # Some routines may auto-compute start offsets incorrectly and pass a
1613 1623 # negative value. Offset to 0 for robustness.
1614 1624 start = max(0,start)
1615 1625
1616 1626 # first, try the hook
1617 1627 ip = IPython.ipapi.get()
1618 1628 if ip:
1619 1629 try:
1620 1630 ip.IP.hooks.show_in_pager(strng)
1621 1631 return
1622 1632 except IPython.ipapi.TryNext:
1623 1633 pass
1624 1634
1625 1635 # Ugly kludge, but calling curses.initscr() flat out crashes in emacs
1626 1636 TERM = os.environ.get('TERM','dumb')
1627 1637 if TERM in ['dumb','emacs'] and os.name != 'nt':
1628 1638 print strng
1629 1639 return
1630 1640 # chop off the topmost part of the string we don't want to see
1631 1641 str_lines = strng.split(os.linesep)[start:]
1632 1642 str_toprint = os.linesep.join(str_lines)
1633 1643 num_newlines = len(str_lines)
1634 1644 len_str = len(str_toprint)
1635 1645
1636 1646 # Dumb heuristics to guesstimate number of on-screen lines the string
1637 1647 # takes. Very basic, but good enough for docstrings in reasonable
1638 1648 # terminals. If someone later feels like refining it, it's not hard.
1639 1649 numlines = max(num_newlines,int(len_str/80)+1)
1640 1650
1641 1651 if os.name == "nt":
1642 1652 screen_lines_def = get_console_size(defaulty=25)[1]
1643 1653 else:
1644 1654 screen_lines_def = 25 # default value if we can't auto-determine
1645 1655
1646 1656 # auto-determine screen size
1647 1657 if screen_lines <= 0:
1648 1658 if TERM=='xterm':
1649 1659 use_curses = USE_CURSES
1650 1660 else:
1651 1661 # curses causes problems on many terminals other than xterm.
1652 1662 use_curses = False
1653 1663 if use_curses:
1654 1664 # There is a bug in curses, where *sometimes* it fails to properly
1655 1665 # initialize, and then after the endwin() call is made, the
1656 1666 # terminal is left in an unusable state. Rather than trying to
1657 1667 # check everytime for this (by requesting and comparing termios
1658 1668 # flags each time), we just save the initial terminal state and
1659 1669 # unconditionally reset it every time. It's cheaper than making
1660 1670 # the checks.
1661 1671 term_flags = termios.tcgetattr(sys.stdout)
1662 1672 scr = curses.initscr()
1663 1673 screen_lines_real,screen_cols = scr.getmaxyx()
1664 1674 curses.endwin()
1665 1675 # Restore terminal state in case endwin() didn't.
1666 1676 termios.tcsetattr(sys.stdout,termios.TCSANOW,term_flags)
1667 1677 # Now we have what we needed: the screen size in rows/columns
1668 1678 screen_lines += screen_lines_real
1669 1679 #print '***Screen size:',screen_lines_real,'lines x',\
1670 1680 #screen_cols,'columns.' # dbg
1671 1681 else:
1672 1682 screen_lines += screen_lines_def
1673 1683
1674 1684 #print 'numlines',numlines,'screenlines',screen_lines # dbg
1675 1685 if numlines <= screen_lines :
1676 1686 #print '*** normal print' # dbg
1677 1687 print >>Term.cout, str_toprint
1678 1688 else:
1679 1689 # Try to open pager and default to internal one if that fails.
1680 1690 # All failure modes are tagged as 'retval=1', to match the return
1681 1691 # value of a failed system command. If any intermediate attempt
1682 1692 # sets retval to 1, at the end we resort to our own page_dumb() pager.
1683 1693 pager_cmd = get_pager_cmd(pager_cmd)
1684 1694 pager_cmd += ' ' + get_pager_start(pager_cmd,start)
1685 1695 if os.name == 'nt':
1686 1696 if pager_cmd.startswith('type'):
1687 1697 # The default WinXP 'type' command is failing on complex strings.
1688 1698 retval = 1
1689 1699 else:
1690 1700 tmpname = tempfile.mktemp('.txt')
1691 1701 tmpfile = file(tmpname,'wt')
1692 1702 tmpfile.write(strng)
1693 1703 tmpfile.close()
1694 1704 cmd = "%s < %s" % (pager_cmd,tmpname)
1695 1705 if os.system(cmd):
1696 1706 retval = 1
1697 1707 else:
1698 1708 retval = None
1699 1709 os.remove(tmpname)
1700 1710 else:
1701 1711 try:
1702 1712 retval = None
1703 1713 # if I use popen4, things hang. No idea why.
1704 1714 #pager,shell_out = os.popen4(pager_cmd)
1705 1715 pager = os.popen(pager_cmd,'w')
1706 1716 pager.write(strng)
1707 1717 pager.close()
1708 1718 retval = pager.close() # success returns None
1709 1719 except IOError,msg: # broken pipe when user quits
1710 1720 if msg.args == (32,'Broken pipe'):
1711 1721 retval = None
1712 1722 else:
1713 1723 retval = 1
1714 1724 except OSError:
1715 1725 # Other strange problems, sometimes seen in Win2k/cygwin
1716 1726 retval = 1
1717 1727 if retval is not None:
1718 1728 page_dumb(strng,screen_lines=screen_lines)
1719 1729
1720 1730 #----------------------------------------------------------------------------
1721 1731 def page_file(fname,start = 0, pager_cmd = None):
1722 1732 """Page a file, using an optional pager command and starting line.
1723 1733 """
1724 1734
1725 1735 pager_cmd = get_pager_cmd(pager_cmd)
1726 1736 pager_cmd += ' ' + get_pager_start(pager_cmd,start)
1727 1737
1728 1738 try:
1729 1739 if os.environ['TERM'] in ['emacs','dumb']:
1730 1740 raise EnvironmentError
1731 1741 xsys(pager_cmd + ' ' + fname)
1732 1742 except:
1733 1743 try:
1734 1744 if start > 0:
1735 1745 start -= 1
1736 1746 page(open(fname).read(),start)
1737 1747 except:
1738 1748 print 'Unable to show file',`fname`
1739 1749
1740 1750
1741 1751 #----------------------------------------------------------------------------
1742 1752 def snip_print(str,width = 75,print_full = 0,header = ''):
1743 1753 """Print a string snipping the midsection to fit in width.
1744 1754
1745 1755 print_full: mode control:
1746 1756 - 0: only snip long strings
1747 1757 - 1: send to page() directly.
1748 1758 - 2: snip long strings and ask for full length viewing with page()
1749 1759 Return 1 if snipping was necessary, 0 otherwise."""
1750 1760
1751 1761 if print_full == 1:
1752 1762 page(header+str)
1753 1763 return 0
1754 1764
1755 1765 print header,
1756 1766 if len(str) < width:
1757 1767 print str
1758 1768 snip = 0
1759 1769 else:
1760 1770 whalf = int((width -5)/2)
1761 1771 print str[:whalf] + ' <...> ' + str[-whalf:]
1762 1772 snip = 1
1763 1773 if snip and print_full == 2:
1764 1774 if raw_input(header+' Snipped. View (y/n)? [N]').lower() == 'y':
1765 1775 page(str)
1766 1776 return snip
1767 1777
1768 1778 #****************************************************************************
1769 1779 # lists, dicts and structures
1770 1780
1771 1781 def belong(candidates,checklist):
1772 1782 """Check whether a list of items appear in a given list of options.
1773 1783
1774 1784 Returns a list of 1 and 0, one for each candidate given."""
1775 1785
1776 1786 return [x in checklist for x in candidates]
1777 1787
1778 1788 #----------------------------------------------------------------------------
1779 1789 def uniq_stable(elems):
1780 1790 """uniq_stable(elems) -> list
1781 1791
1782 1792 Return from an iterable, a list of all the unique elements in the input,
1783 1793 but maintaining the order in which they first appear.
1784 1794
1785 1795 A naive solution to this problem which just makes a dictionary with the
1786 1796 elements as keys fails to respect the stability condition, since
1787 1797 dictionaries are unsorted by nature.
1788 1798
1789 1799 Note: All elements in the input must be valid dictionary keys for this
1790 1800 routine to work, as it internally uses a dictionary for efficiency
1791 1801 reasons."""
1792 1802
1793 1803 unique = []
1794 1804 unique_dict = {}
1795 1805 for nn in elems:
1796 1806 if nn not in unique_dict:
1797 1807 unique.append(nn)
1798 1808 unique_dict[nn] = None
1799 1809 return unique
1800 1810
1801 1811 #----------------------------------------------------------------------------
1802 1812 class NLprinter:
1803 1813 """Print an arbitrarily nested list, indicating index numbers.
1804 1814
1805 1815 An instance of this class called nlprint is available and callable as a
1806 1816 function.
1807 1817
1808 1818 nlprint(list,indent=' ',sep=': ') -> prints indenting each level by 'indent'
1809 1819 and using 'sep' to separate the index from the value. """
1810 1820
1811 1821 def __init__(self):
1812 1822 self.depth = 0
1813 1823
1814 1824 def __call__(self,lst,pos='',**kw):
1815 1825 """Prints the nested list numbering levels."""
1816 1826 kw.setdefault('indent',' ')
1817 1827 kw.setdefault('sep',': ')
1818 1828 kw.setdefault('start',0)
1819 1829 kw.setdefault('stop',len(lst))
1820 1830 # we need to remove start and stop from kw so they don't propagate
1821 1831 # into a recursive call for a nested list.
1822 1832 start = kw['start']; del kw['start']
1823 1833 stop = kw['stop']; del kw['stop']
1824 1834 if self.depth == 0 and 'header' in kw.keys():
1825 1835 print kw['header']
1826 1836
1827 1837 for idx in range(start,stop):
1828 1838 elem = lst[idx]
1829 1839 if type(elem)==type([]):
1830 1840 self.depth += 1
1831 1841 self.__call__(elem,itpl('$pos$idx,'),**kw)
1832 1842 self.depth -= 1
1833 1843 else:
1834 1844 printpl(kw['indent']*self.depth+'$pos$idx$kw["sep"]$elem')
1835 1845
1836 1846 nlprint = NLprinter()
1837 1847 #----------------------------------------------------------------------------
1838 1848 def all_belong(candidates,checklist):
1839 1849 """Check whether a list of items ALL appear in a given list of options.
1840 1850
1841 1851 Returns a single 1 or 0 value."""
1842 1852
1843 1853 return 1-(0 in [x in checklist for x in candidates])
1844 1854
1845 1855 #----------------------------------------------------------------------------
1846 1856 def sort_compare(lst1,lst2,inplace = 1):
1847 1857 """Sort and compare two lists.
1848 1858
1849 1859 By default it does it in place, thus modifying the lists. Use inplace = 0
1850 1860 to avoid that (at the cost of temporary copy creation)."""
1851 1861 if not inplace:
1852 1862 lst1 = lst1[:]
1853 1863 lst2 = lst2[:]
1854 1864 lst1.sort(); lst2.sort()
1855 1865 return lst1 == lst2
1856 1866
1857 1867 #----------------------------------------------------------------------------
1858 1868 def list2dict(lst):
1859 1869 """Takes a list of (key,value) pairs and turns it into a dict."""
1860 1870
1861 1871 dic = {}
1862 1872 for k,v in lst: dic[k] = v
1863 1873 return dic
1864 1874
1865 1875 #----------------------------------------------------------------------------
1866 1876 def list2dict2(lst,default=''):
1867 1877 """Takes a list and turns it into a dict.
1868 1878 Much slower than list2dict, but more versatile. This version can take
1869 1879 lists with sublists of arbitrary length (including sclars)."""
1870 1880
1871 1881 dic = {}
1872 1882 for elem in lst:
1873 1883 if type(elem) in (types.ListType,types.TupleType):
1874 1884 size = len(elem)
1875 1885 if size == 0:
1876 1886 pass
1877 1887 elif size == 1:
1878 1888 dic[elem] = default
1879 1889 else:
1880 1890 k,v = elem[0], elem[1:]
1881 1891 if len(v) == 1: v = v[0]
1882 1892 dic[k] = v
1883 1893 else:
1884 1894 dic[elem] = default
1885 1895 return dic
1886 1896
1887 1897 #----------------------------------------------------------------------------
1888 1898 def flatten(seq):
1889 1899 """Flatten a list of lists (NOT recursive, only works for 2d lists)."""
1890 1900
1891 1901 return [x for subseq in seq for x in subseq]
1892 1902
1893 1903 #----------------------------------------------------------------------------
1894 1904 def get_slice(seq,start=0,stop=None,step=1):
1895 1905 """Get a slice of a sequence with variable step. Specify start,stop,step."""
1896 1906 if stop == None:
1897 1907 stop = len(seq)
1898 1908 item = lambda i: seq[i]
1899 1909 return map(item,xrange(start,stop,step))
1900 1910
1901 1911 #----------------------------------------------------------------------------
1902 1912 def chop(seq,size):
1903 1913 """Chop a sequence into chunks of the given size."""
1904 1914 chunk = lambda i: seq[i:i+size]
1905 1915 return map(chunk,xrange(0,len(seq),size))
1906 1916
1907 1917 #----------------------------------------------------------------------------
1908 1918 # with is a keyword as of python 2.5, so this function is renamed to withobj
1909 1919 # from its old 'with' name.
1910 1920 def with_obj(object, **args):
1911 1921 """Set multiple attributes for an object, similar to Pascal's with.
1912 1922
1913 1923 Example:
1914 1924 with_obj(jim,
1915 1925 born = 1960,
1916 1926 haircolour = 'Brown',
1917 1927 eyecolour = 'Green')
1918 1928
1919 1929 Credit: Greg Ewing, in
1920 1930 http://mail.python.org/pipermail/python-list/2001-May/040703.html.
1921 1931
1922 1932 NOTE: up until IPython 0.7.2, this was called simply 'with', but 'with'
1923 1933 has become a keyword for Python 2.5, so we had to rename it."""
1924 1934
1925 1935 object.__dict__.update(args)
1926 1936
1927 1937 #----------------------------------------------------------------------------
1928 1938 def setattr_list(obj,alist,nspace = None):
1929 1939 """Set a list of attributes for an object taken from a namespace.
1930 1940
1931 1941 setattr_list(obj,alist,nspace) -> sets in obj all the attributes listed in
1932 1942 alist with their values taken from nspace, which must be a dict (something
1933 1943 like locals() will often do) If nspace isn't given, locals() of the
1934 1944 *caller* is used, so in most cases you can omit it.
1935 1945
1936 1946 Note that alist can be given as a string, which will be automatically
1937 1947 split into a list on whitespace. If given as a list, it must be a list of
1938 1948 *strings* (the variable names themselves), not of variables."""
1939 1949
1940 1950 # this grabs the local variables from the *previous* call frame -- that is
1941 1951 # the locals from the function that called setattr_list().
1942 1952 # - snipped from weave.inline()
1943 1953 if nspace is None:
1944 1954 call_frame = sys._getframe().f_back
1945 1955 nspace = call_frame.f_locals
1946 1956
1947 1957 if type(alist) in StringTypes:
1948 1958 alist = alist.split()
1949 1959 for attr in alist:
1950 1960 val = eval(attr,nspace)
1951 1961 setattr(obj,attr,val)
1952 1962
1953 1963 #----------------------------------------------------------------------------
1954 1964 def getattr_list(obj,alist,*args):
1955 1965 """getattr_list(obj,alist[, default]) -> attribute list.
1956 1966
1957 1967 Get a list of named attributes for an object. When a default argument is
1958 1968 given, it is returned when the attribute doesn't exist; without it, an
1959 1969 exception is raised in that case.
1960 1970
1961 1971 Note that alist can be given as a string, which will be automatically
1962 1972 split into a list on whitespace. If given as a list, it must be a list of
1963 1973 *strings* (the variable names themselves), not of variables."""
1964 1974
1965 1975 if type(alist) in StringTypes:
1966 1976 alist = alist.split()
1967 1977 if args:
1968 1978 if len(args)==1:
1969 1979 default = args[0]
1970 1980 return map(lambda attr: getattr(obj,attr,default),alist)
1971 1981 else:
1972 1982 raise ValueError,'getattr_list() takes only one optional argument'
1973 1983 else:
1974 1984 return map(lambda attr: getattr(obj,attr),alist)
1975 1985
1976 1986 #----------------------------------------------------------------------------
1977 1987 def map_method(method,object_list,*argseq,**kw):
1978 1988 """map_method(method,object_list,*args,**kw) -> list
1979 1989
1980 1990 Return a list of the results of applying the methods to the items of the
1981 1991 argument sequence(s). If more than one sequence is given, the method is
1982 1992 called with an argument list consisting of the corresponding item of each
1983 1993 sequence. All sequences must be of the same length.
1984 1994
1985 1995 Keyword arguments are passed verbatim to all objects called.
1986 1996
1987 1997 This is Python code, so it's not nearly as fast as the builtin map()."""
1988 1998
1989 1999 out_list = []
1990 2000 idx = 0
1991 2001 for object in object_list:
1992 2002 try:
1993 2003 handler = getattr(object, method)
1994 2004 except AttributeError:
1995 2005 out_list.append(None)
1996 2006 else:
1997 2007 if argseq:
1998 2008 args = map(lambda lst:lst[idx],argseq)
1999 2009 #print 'ob',object,'hand',handler,'ar',args # dbg
2000 2010 out_list.append(handler(args,**kw))
2001 2011 else:
2002 2012 out_list.append(handler(**kw))
2003 2013 idx += 1
2004 2014 return out_list
2005 2015
2006 2016 #----------------------------------------------------------------------------
2007 2017 def get_class_members(cls):
2008 2018 ret = dir(cls)
2009 2019 if hasattr(cls,'__bases__'):
2010 2020 for base in cls.__bases__:
2011 2021 ret.extend(get_class_members(base))
2012 2022 return ret
2013 2023
2014 2024 #----------------------------------------------------------------------------
2015 2025 def dir2(obj):
2016 2026 """dir2(obj) -> list of strings
2017 2027
2018 2028 Extended version of the Python builtin dir(), which does a few extra
2019 2029 checks, and supports common objects with unusual internals that confuse
2020 2030 dir(), such as Traits and PyCrust.
2021 2031
2022 2032 This version is guaranteed to return only a list of true strings, whereas
2023 2033 dir() returns anything that objects inject into themselves, even if they
2024 2034 are later not really valid for attribute access (many extension libraries
2025 2035 have such bugs).
2026 2036 """
2027 2037
2028 2038 # Start building the attribute list via dir(), and then complete it
2029 2039 # with a few extra special-purpose calls.
2030 2040 words = dir(obj)
2031 2041
2032 2042 if hasattr(obj,'__class__'):
2033 2043 words.append('__class__')
2034 2044 words.extend(get_class_members(obj.__class__))
2035 2045 #if '__base__' in words: 1/0
2036 2046
2037 2047 # Some libraries (such as traits) may introduce duplicates, we want to
2038 2048 # track and clean this up if it happens
2039 2049 may_have_dupes = False
2040 2050
2041 2051 # this is the 'dir' function for objects with Enthought's traits
2042 2052 if hasattr(obj, 'trait_names'):
2043 2053 try:
2044 2054 words.extend(obj.trait_names())
2045 2055 may_have_dupes = True
2046 2056 except TypeError:
2047 2057 # This will happen if `obj` is a class and not an instance.
2048 2058 pass
2049 2059
2050 2060 # Support for PyCrust-style _getAttributeNames magic method.
2051 2061 if hasattr(obj, '_getAttributeNames'):
2052 2062 try:
2053 2063 words.extend(obj._getAttributeNames())
2054 2064 may_have_dupes = True
2055 2065 except TypeError:
2056 2066 # `obj` is a class and not an instance. Ignore
2057 2067 # this error.
2058 2068 pass
2059 2069
2060 2070 if may_have_dupes:
2061 2071 # eliminate possible duplicates, as some traits may also
2062 2072 # appear as normal attributes in the dir() call.
2063 2073 words = list(set(words))
2064 2074 words.sort()
2065 2075
2066 2076 # filter out non-string attributes which may be stuffed by dir() calls
2067 2077 # and poor coding in third-party modules
2068 2078 return [w for w in words if isinstance(w, basestring)]
2069 2079
2070 2080 #----------------------------------------------------------------------------
2071 2081 def import_fail_info(mod_name,fns=None):
2072 2082 """Inform load failure for a module."""
2073 2083
2074 2084 if fns == None:
2075 2085 warn("Loading of %s failed.\n" % (mod_name,))
2076 2086 else:
2077 2087 warn("Loading of %s from %s failed.\n" % (fns,mod_name))
2078 2088
2079 2089 #----------------------------------------------------------------------------
2080 2090 # Proposed popitem() extension, written as a method
2081 2091
2082 2092
2083 2093 class NotGiven: pass
2084 2094
2085 2095 def popkey(dct,key,default=NotGiven):
2086 2096 """Return dct[key] and delete dct[key].
2087 2097
2088 2098 If default is given, return it if dct[key] doesn't exist, otherwise raise
2089 2099 KeyError. """
2090 2100
2091 2101 try:
2092 2102 val = dct[key]
2093 2103 except KeyError:
2094 2104 if default is NotGiven:
2095 2105 raise
2096 2106 else:
2097 2107 return default
2098 2108 else:
2099 2109 del dct[key]
2100 2110 return val
2101 2111
2102 2112 def wrap_deprecated(func, suggest = '<nothing>'):
2103 2113 def newFunc(*args, **kwargs):
2104 2114 warnings.warn("Call to deprecated function %s, use %s instead" %
2105 2115 ( func.__name__, suggest),
2106 2116 category=DeprecationWarning,
2107 2117 stacklevel = 2)
2108 2118 return func(*args, **kwargs)
2109 2119 return newFunc
2110 2120
2111 2121
2112 2122 def _num_cpus_unix():
2113 2123 """Return the number of active CPUs on a Unix system."""
2114 2124 return os.sysconf("SC_NPROCESSORS_ONLN")
2115 2125
2116 2126
2117 2127 def _num_cpus_darwin():
2118 2128 """Return the number of active CPUs on a Darwin system."""
2119 2129 p = subprocess.Popen(['sysctl','-n','hw.ncpu'],stdout=subprocess.PIPE)
2120 2130 return p.stdout.read()
2121 2131
2122 2132
2123 2133 def _num_cpus_windows():
2124 2134 """Return the number of active CPUs on a Windows system."""
2125 2135 return os.environ.get("NUMBER_OF_PROCESSORS")
2126 2136
2127 2137
2128 2138 def num_cpus():
2129 2139 """Return the effective number of CPUs in the system as an integer.
2130 2140
2131 2141 This cross-platform function makes an attempt at finding the total number of
2132 2142 available CPUs in the system, as returned by various underlying system and
2133 2143 python calls.
2134 2144
2135 2145 If it can't find a sensible answer, it returns 1 (though an error *may* make
2136 2146 it return a large positive number that's actually incorrect).
2137 2147 """
2138 2148
2139 2149 # Many thanks to the Parallel Python project (http://www.parallelpython.com)
2140 2150 # for the names of the keys we needed to look up for this function. This
2141 2151 # code was inspired by their equivalent function.
2142 2152
2143 2153 ncpufuncs = {'Linux':_num_cpus_unix,
2144 2154 'Darwin':_num_cpus_darwin,
2145 2155 'Windows':_num_cpus_windows,
2146 2156 # On Vista, python < 2.5.2 has a bug and returns 'Microsoft'
2147 2157 # See http://bugs.python.org/issue1082 for details.
2148 2158 'Microsoft':_num_cpus_windows,
2149 2159 }
2150 2160
2151 2161 ncpufunc = ncpufuncs.get(platform.system(),
2152 2162 # default to unix version (Solaris, AIX, etc)
2153 2163 _num_cpus_unix)
2154 2164
2155 2165 try:
2156 2166 ncpus = max(1,int(ncpufunc()))
2157 2167 except:
2158 2168 ncpus = 1
2159 2169 return ncpus
2160 2170
2161 2171 #*************************** end of file <genutils.py> **********************
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now