##// END OF EJS Templates
Unicode fixes (utf-8 used by default if ascii is not enough). This should fix some reported crashes....
fperez -
r5:c83aafa3
parent child Browse files
Show More
@@ -5,7 +5,7 b' We define a special input line filter to allow typing lines which begin with'
5 5 '~', '/' or '.'. If one of those strings is encountered, it is automatically
6 6 executed.
7 7
8 $Id: InterpreterExec.py 573 2005-04-08 08:38:09Z fperez $"""
8 $Id: InterpreterExec.py 638 2005-07-18 03:01:41Z fperez $"""
9 9
10 10 #*****************************************************************************
11 11 # Copyright (C) 2004 W.J. van der Laan <gnufnork@hetdigitalegat.nl>
@@ -264,7 +264,9 b" __IPYTHON__.magic_unalias('sx')"
264 264 # 'gnome-terminal' are interpreted as a single alias instead of variable
265 265 # 'gnome' minus variable 'terminal'.
266 266 import re
267 __IPYTHON__.line_split = re.compile(r'^(\s*)([\?\w\.\-\+]+\w*\s*)(\(?.*$)')
267 __IPYTHON__.line_split = re.compile(r'^([\s*,;/])'
268 r'([\?\w\.\-\+]+\w*\s*)'
269 r'(\(?.*$)')
268 270
269 271 # Namespace cleanup
270 272 del re
@@ -84,13 +84,6 b' import __main__'
84 84
85 85 __all__ = ["Completer"]
86 86
87 # declares Python 2.2 compatibility symbols:
88 try:
89 basestring
90 except NameError:
91 import types
92 basestring = (types.StringType, types.UnicodeType)
93
94 87 class Completer:
95 88 def __init__(self, namespace = None):
96 89 """Create a new completer for the command line.
@@ -44,7 +44,7 b' each time the instance is evaluated with str(instance). For example:'
44 44 foo = "bar"
45 45 print str(s)
46 46
47 $Id: Itpl.py 542 2005-03-18 09:16:04Z fperez $
47 $Id: Itpl.py 638 2005-07-18 03:01:41Z fperez $
48 48 """ # ' -> close an open quote for stupid emacs
49 49
50 50 #*****************************************************************************
@@ -103,8 +103,9 b' class Itpl:'
103 103 evaluation and substitution happens in the namespace of the
104 104 caller when str(instance) is called."""
105 105
106 def __init__(self, format):
107 """The single argument to this constructor is a format string.
106 def __init__(self, format,codec='utf_8',encoding_errors='backslashreplace'):
107 """The single mandatory argument to this constructor is a format
108 string.
108 109
109 110 The format string is parsed according to the following rules:
110 111
@@ -119,11 +120,24 b' class Itpl:'
119 120 a Python expression.
120 121
121 122 3. Outside of the expressions described in the above two rules,
122 two dollar signs in a row give you one literal dollar sign."""
123 two dollar signs in a row give you one literal dollar sign.
123 124
124 if type(format) != StringType:
125 Optional arguments:
126
127 - codec('utf_8'): a string containing the name of a valid Python
128 codec.
129
130 - encoding_errors('backslashreplace'): a string with a valid error handling
131 policy. See the codecs module documentation for details.
132
133 These are used to encode the format string if a call to str() fails on
134 the expanded result."""
135
136 if not isinstance(format,basestring):
125 137 raise TypeError, "needs string initializer"
126 138 self.format = format
139 self.codec = codec
140 self.encoding_errors = encoding_errors
127 141
128 142 namechars = "abcdefghijklmnopqrstuvwxyz" \
129 143 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
@@ -174,6 +188,23 b' class Itpl:'
174 188 def __repr__(self):
175 189 return "<Itpl %s >" % repr(self.format)
176 190
191 def _str(self,glob,loc):
192 """Evaluate to a string in the given globals/locals.
193
194 The final output is built by calling str(), but if this fails, the
195 result is encoded with the instance's codec and error handling policy,
196 via a call to out.encode(self.codec,self.encoding_errors)"""
197 result = []
198 app = result.append
199 for live, chunk in self.chunks:
200 if live: app(str(eval(chunk,glob,loc)))
201 else: app(chunk)
202 out = ''.join(result)
203 try:
204 return str(out)
205 except UnicodeError:
206 return out.encode(self.codec,self.encoding_errors)
207
177 208 def __str__(self):
178 209 """Evaluate and substitute the appropriate parts of the string."""
179 210
@@ -183,12 +214,7 b' class Itpl:'
183 214 while frame.f_globals["__name__"] == __name__: frame = frame.f_back
184 215 loc, glob = frame.f_locals, frame.f_globals
185 216
186 result = []
187 for live, chunk in self.chunks:
188 if live: result.append(str(eval(chunk,glob,loc)))
189 else: result.append(chunk)
190
191 return ''.join(result)
217 return self._str(glob,loc)
192 218
193 219 class ItplNS(Itpl):
194 220 """Class representing a string with interpolation abilities.
@@ -199,7 +225,8 b' class ItplNS(Itpl):'
199 225 caller to supply a different namespace for the interpolation to occur than
200 226 its own."""
201 227
202 def __init__(self, format,globals,locals=None):
228 def __init__(self, format,globals,locals=None,
229 codec='utf_8',encoding_errors='backslashreplace'):
203 230 """ItplNS(format,globals[,locals]) -> interpolating string instance.
204 231
205 232 This constructor, besides a format string, takes a globals dictionary
@@ -211,17 +238,14 b' class ItplNS(Itpl):'
211 238 locals = globals
212 239 self.globals = globals
213 240 self.locals = locals
214 Itpl.__init__(self,format)
241 Itpl.__init__(self,format,codec,encoding_errors)
215 242
216 243 def __str__(self):
217 244 """Evaluate and substitute the appropriate parts of the string."""
218 glob = self.globals
219 loc = self.locals
220 result = []
221 for live, chunk in self.chunks:
222 if live: result.append(str(eval(chunk,glob,loc)))
223 else: result.append(chunk)
224 return ''.join(result)
245 return self._str(self.globals,self.locals)
246
247 def __repr__(self):
248 return "<ItplNS %s >" % repr(self.format)
225 249
226 250 # utilities for fast printing
227 251 def itpl(text): return str(Itpl(text))
@@ -2,7 +2,7 b''
2 2 """
3 3 Classes for handling input/output prompts.
4 4
5 $Id: Prompts.py 564 2005-03-26 22:43:58Z fperez $"""
5 $Id: Prompts.py 638 2005-07-18 03:01:41Z fperez $"""
6 6
7 7 #*****************************************************************************
8 8 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
@@ -196,9 +196,17 b' def str_safe(arg):'
196 196 error message."""
197 197
198 198 try:
199 return str(arg)
199 out = str(arg)
200 except UnicodeError:
201 try:
202 out = arg.encode('utf_8','replace')
203 except Exception,msg:
204 # let's keep this little duplication here, so that the most common
205 # case doesn't suffer from a double try wrapping.
206 out = '<ERROR: %s>' % msg
200 207 except Exception,msg:
201 return '<ERROR: %s>' % msg
208 out = '<ERROR: %s>' % msg
209 return out
202 210
203 211 class BasePrompt:
204 212 """Interactive prompt similar to Mathematica's."""
@@ -413,12 +421,12 b' class CachedOutput:'
413 421 self.ps2_str = self._set_prompt_str(ps2,' .\\D.: ','... ')
414 422 self.ps_out_str = self._set_prompt_str(ps_out,'Out[\\#]: ','')
415 423
424 self.color_table = PromptColors
416 425 self.prompt1 = Prompt1(self,sep=input_sep,prompt=self.ps1_str,
417 426 pad_left=pad_left)
418 427 self.prompt2 = Prompt2(self,prompt=self.ps2_str,pad_left=pad_left)
419 428 self.prompt_out = PromptOut(self,sep='',prompt=self.ps_out_str,
420 429 pad_left=pad_left)
421 self.color_table = PromptColors
422 430 self.set_colors(colors)
423 431
424 432 # other more normal stuff
@@ -480,15 +488,16 b' class CachedOutput:'
480 488 except KeyError:
481 489 pass
482 490 if arg is not None:
491 cout_write = Term.cout.write # fast lookup
483 492 # first handle the cache and counters
484 493 self.update(arg)
485 494 # do not print output if input ends in ';'
486 495 if self.input_hist[self.prompt_count].endswith(';\n'):
487 496 return
488 497 # don't use print, puts an extra space
489 Term.cout.write(self.output_sep)
498 cout_write(self.output_sep)
490 499 if self.do_full_cache:
491 Term.cout.write(str(self.prompt_out))
500 cout_write(str(self.prompt_out))
492 501
493 502 if isinstance(arg,Macro):
494 503 print 'Executing Macro...'
@@ -499,7 +508,7 b' class CachedOutput:'
499 508
500 509 # and now call a possibly user-defined print mechanism
501 510 self.display(arg)
502 Term.cout.write(self.output_sep2)
511 cout_write(self.output_sep2)
503 512 Term.cout.flush()
504 513
505 514 def _display(self,arg):
@@ -509,17 +518,6 b' class CachedOutput:'
509 518 of certain types of output."""
510 519
511 520 if self.Pprint:
512 # The following is an UGLY kludge, b/c python fails to properly
513 # identify instances of classes imported in the user namespace
514 # (they have different memory locations, I guess). Structs are
515 # essentially dicts but pprint doesn't know what to do with them.
516 try:
517 if arg.__class__.__module__ == 'Struct' and \
518 arg.__class__.__name__ == 'Struct':
519 out = 'Struct:\n%s' % pformat(arg.dict())
520 else:
521 out = pformat(arg)
522 except:
523 521 out = pformat(arg)
524 522 if '\n' in out:
525 523 # So that multi-line strings line up with the left column of
@@ -1,7 +1,7 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Mimic C structs with lots of extra functionality.
3 3
4 $Id: Struct.py 410 2004-11-04 07:58:17Z fperez $"""
4 $Id: Struct.py 638 2005-07-18 03:01:41Z fperez $"""
5 5
6 6 #*****************************************************************************
7 7 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
@@ -315,9 +315,8 b' class Struct:'
315 315 del inv_conflict_solve_user[name]
316 316 conflict_solve.update(Struct.__dict_invert(self,inv_conflict_solve_user))
317 317 #print 'merge. conflict_solve: '; pprint(conflict_solve) # dbg
318 # after Python 2.2, use iterators: for key in data_dict will then work
319 318 #print '*'*50,'in merger. conflict_solver:'; pprint(conflict_solve)
320 for key in data_dict.keys():
319 for key in data_dict:
321 320 if key not in self:
322 321 self[key] = data_dict[key]
323 322 else:
@@ -18,7 +18,7 b' http://folk.uio.no/hpl/scripting'
18 18 (although ultimately no code from this text was used, as IPython's system is a
19 19 separate implementation).
20 20
21 $Id: background_jobs.py 515 2005-02-15 07:41:41Z fperez $
21 $Id: background_jobs.py 638 2005-07-18 03:01:41Z fperez $
22 22 """
23 23
24 24 #*****************************************************************************
@@ -38,15 +38,6 b' import threading,sys'
38 38 from IPython.ultraTB import AutoFormattedTB
39 39 from IPython.genutils import warn,error
40 40
41 # declares Python 2.2 compatibility symbols:
42 try:
43 basestring
44 except NameError:
45 import types
46 basestring = (types.StringType, types.UnicodeType)
47 True = 1==1
48 False = 1==0
49
50 41 class BackgroundJobManager:
51 42 """Class to manage a pool of backgrounded threaded jobs.
52 43
@@ -5,7 +5,7 b' General purpose utilities.'
5 5 This is a grab-bag of stuff I find useful in most programs I write. Some of
6 6 these things are also convenient when working at the command line.
7 7
8 $Id: genutils.py 633 2005-07-17 01:03:15Z tzanko $"""
8 $Id: genutils.py 638 2005-07-18 03:01:41Z fperez $"""
9 9
10 10 #*****************************************************************************
11 11 # Copyright (C) 2001-2004 Fernando Perez. <fperez@colorado.edu>
@@ -23,9 +23,33 b' __license__ = Release.license'
23 23 import __main__
24 24 import types,commands,time,sys,os,re,shutil
25 25 import tempfile
26 import codecs
26 27 from IPython.Itpl import Itpl,itpl,printpl
27 28 from IPython import DPyGetOpt
28 29
30 # Build objects which appeared in Python 2.3 for 2.2, to make ipython
31 # 2.2-friendly
32 try:
33 basestring
34 except NameError:
35 import types
36 basestring = (types.StringType, types.UnicodeType)
37 True = 1==1
38 False = 1==0
39
40 def enumerate(obj):
41 i = -1
42 for item in obj:
43 i += 1
44 yield i, item
45
46 # add these to the builtin namespace, so that all modules find them
47 import __builtin__
48 __builtin__.basestring = basestring
49 __builtin__.True = True
50 __builtin__.False = False
51 __builtin__.enumerate = enumerate
52
29 53 #****************************************************************************
30 54 # Exceptions
31 55 class Error(Exception):
@@ -33,26 +57,29 b' class Error(Exception):'
33 57 pass
34 58
35 59 #----------------------------------------------------------------------------
36 class Stream:
37 """Simple class to hold the various I/O streams in Term"""
38
39 def __init__(self,stream,name):
60 class IOStream:
61 def __init__(self,stream,fallback):
62 if not hasattr(stream,'write') or not hasattr(stream,'flush'):
63 stream = fallback
40 64 self.stream = stream
41 self.name = name
65 self._swrite = stream.write
66 self.flush = stream.flush
67
68 def write(self,data):
42 69 try:
43 self.fileno = stream.fileno()
44 except AttributeError:
45 msg = ("Stream <%s> looks suspicious: it lacks a 'fileno' attribute."
46 % name)
47 print >> sys.stderr, 'WARNING:',msg
70 self._swrite(data)
71 except:
48 72 try:
49 self.mode = stream.mode
50 except AttributeError:
51 msg = ("Stream <%s> looks suspicious: it lacks a 'mode' attribute."
52 % name)
53 print >> sys.stderr, 'WARNING:',msg
73 # print handles some unicode issues which may trip a plain
74 # write() call. Attempt to emulate write() by using a
75 # trailing comma
76 print >> self.stream, data,
77 except:
78 # if we get here, something is seriously broken.
79 print >> sys.stderr, \
80 'ERROR - failed to write data to stream:', stream
54 81
55 class Term:
82 class IOTerm:
56 83 """ Term holds the file or file-like objects for handling I/O operations.
57 84
58 85 These are normally just sys.stdin, sys.stdout and sys.stderr but for
@@ -62,51 +89,13 b' class Term:'
62 89 # In the future, having IPython channel all its I/O operations through
63 90 # this class will make it easier to embed it into other environments which
64 91 # are not a normal terminal (such as a GUI-based shell)
65 in_s = Stream(sys.stdin,'cin')
66 out_s = Stream(sys.stdout,'cout')
67 err_s = Stream(sys.stderr,'cerr')
68
69 # Store the three streams in (err,out,in) order so that if we need to reopen
70 # them, the error channel is reopened first to provide info.
71 streams = [err_s,out_s,in_s]
72
73 # The class globals should be the actual 'bare' streams for normal I/O to work
74 cin = streams[2].stream
75 cout = streams[1].stream
76 cerr = streams[0].stream
77
78 def reopen_all(cls):
79 """Reopen all streams if necessary.
80
81 This should only be called if it is suspected that someting closed
82 accidentally one of the I/O streams."""
83
84 any_closed = 0
85
86 for sn in range(len(cls.streams)):
87 st = cls.streams[sn]
88 if st.stream.closed:
89 any_closed = 1
90 new_stream = os.fdopen(os.dup(st.fileno), st.mode,0)
91 cls.streams[sn] = Stream(new_stream,st.name)
92 print >> cls.streams[0].stream, \
93 '\nWARNING:\nStream Term.%s had to be reopened!' % st.name
94
95 # Rebuild the class globals
96 cls.cin = cls.streams[2].stream
97 cls.cout = cls.streams[1].stream
98 cls.cerr = cls.streams[0].stream
99
100 reopen_all = classmethod(reopen_all)
101
102 def set_stdout(cls,stream):
103 """Set the stream """
104 cls.cout = stream
105 set_stdout = classmethod(set_stdout)
92 def __init__(self,cin=None,cout=None,cerr=None):
93 self.cin = IOStream(cin,sys.stdin)
94 self.cout = IOStream(cout,sys.stdout)
95 self.cerr = IOStream(cerr,sys.stderr)
106 96
107 def set_stderr(cls,stream):
108 cls.cerr = stream
109 set_stderr = classmethod(set_stderr)
97 # Global variable to be used for all I/O
98 Term = IOTerm()
110 99
111 100 # Windows-specific code to load Gary Bishop's readline and configure it
112 101 # automatically for the users
@@ -123,8 +112,8 b" if os.name == 'nt':"
123 112 except AttributeError:
124 113 pass
125 114 else:
126 Term.set_stdout(_out)
127 Term.set_stderr(_out)
115 # Remake Term to use the readline i/o facilities
116 Term = IOTerm(cout=_out,cerr=_out)
128 117 del _out
129 118
130 119 #****************************************************************************
@@ -6,7 +6,7 b' Requires Python 2.1 or newer.'
6 6
7 7 This file contains all the classes and helper functions specific to IPython.
8 8
9 $Id: iplib.py 602 2005-06-09 03:02:30Z fperez $
9 $Id: iplib.py 638 2005-07-18 03:01:41Z fperez $
10 10 """
11 11
12 12 #*****************************************************************************
@@ -69,15 +69,6 b' from IPython.genutils import *'
69 69 # overwrites it (like wx.py.PyShell does)
70 70 raw_input_original = raw_input
71 71
72 # declares Python 2.2 compatibility symbols:
73 try:
74 enumerate
75 except NameError:
76 def enumerate(obj):
77 i = -1
78 for item in obj:
79 i += 1
80 yield i, item
81 72 #****************************************************************************
82 73 # Some utility function definitions
83 74
@@ -1337,7 +1328,7 b' want to merge them back into the new files.""" % locals()'
1337 1328 self.interact(header)
1338 1329
1339 1330 # Remove locals from namespace
1340 for k in local_ns.keys():
1331 for k in local_ns:
1341 1332 del self.user_ns[k]
1342 1333
1343 1334 def interact(self, banner=None):
@@ -1363,10 +1354,9 b' want to merge them back into the new files.""" % locals()'
1363 1354
1364 1355 # Mark activity in the builtins
1365 1356 __builtin__.__dict__['__IPYTHON__active'] += 1
1366 while 1:
1367 # This is set by a call to %Exit or %Quit
1368 if self.exit_now:
1369 break
1357
1358 # exit_now is set by a call to %Exit or %Quit
1359 while not self.exit_now:
1370 1360 try:
1371 1361 if more:
1372 1362 prompt = self.outputcache.prompt2
@@ -1421,81 +1411,6 b' want to merge them back into the new files.""" % locals()'
1421 1411 "Because of how pdb handles the stack, it is impossible\n"
1422 1412 "for IPython to properly format this particular exception.\n"
1423 1413 "IPython will resume normal operation.")
1424 except:
1425 # We should never get here except in fairly bizarre situations
1426 # (or b/c of an IPython bug). One reasonable exception is if
1427 # the user sets stdin/out/err to a broken object (or closes
1428 # any of them!)
1429
1430 fixed_in_out_err = 0
1431
1432 # Call the Term I/O class and have it reopen any stream which
1433 # the user might have closed.
1434 Term.reopen_all()
1435
1436 # Do the same manually for sys.stderr/out/in
1437
1438 # err first, so we can print at least warnings
1439 if sys.__stderr__.closed:
1440 sys.__stderr__ = os.fdopen(os.dup(2),'w',0)
1441 fixed_err_err = 1
1442 print >> sys.__stderr__,"""
1443 WARNING:
1444 sys.__stderr__ was closed!
1445 I've tried to reopen it, but bear in mind that things may not work normally
1446 from now. In particular, readline support may have broken.
1447 """
1448 # Next, check stdin/out
1449 if sys.__stdin__.closed:
1450 sys.__stdin__ = os.fdopen(os.dup(0),'r',0)
1451 fixed_in_out_err = 1
1452 print >> sys.__stderr__,"""
1453 WARNING:
1454 sys.__stdin__ was closed!
1455 I've tried to reopen it, but bear in mind that things may not work normally
1456 from now. In particular, readline support may have broken.
1457 """
1458 if sys.__stdout__.closed:
1459 sys.__stdout__ = os.fdopen(os.dup(1),'w',0)
1460 fixed_in_out_err = 1
1461 print >> sys.__stderr__,"""
1462 WARNING:
1463 sys.__stdout__ was closed!
1464 I've tried to reopen it, but bear in mind that things may not work normally
1465 from now. In particular, readline support may have broken.
1466 """
1467
1468 # Now, check mismatch of objects
1469 if sys.stdin is not sys.__stdin__:
1470 sys.stdin = sys.__stdin__
1471 fixed_in_out_err = 1
1472 print >> sys.__stderr__,"""
1473 WARNING:
1474 sys.stdin has been reset to sys.__stdin__.
1475 There seemed to be a problem with your sys.stdin.
1476 """
1477 if sys.stdout is not sys.__stdout__:
1478 sys.stdout = sys.__stdout__
1479 fixed_in_out_err = 1
1480 print >> sys.__stderr__,"""
1481 WARNING:
1482 sys.stdout has been reset to sys.__stdout__.
1483 There seemed to be a problem with your sys.stdout.
1484 """
1485
1486 if sys.stderr is not sys.__stderr__:
1487 sys.stderr = sys.__stderr__
1488 fixed_in_out_err = 1
1489 print >> sys.__stderr__,"""
1490 WARNING:
1491 sys.stderr has been reset to sys.__stderr__.
1492 There seemed to be a problem with your sys.stderr.
1493 """
1494 # If the problem wasn't a broken out/err, it's an IPython bug
1495 # I wish we could ask the user whether to crash or not, but
1496 # calling any function at this point messes up the stack.
1497 if not fixed_in_out_err:
1498 raise
1499 1414
1500 1415 # We are off again...
1501 1416 __builtin__.__dict__['__IPYTHON__active'] -= 1
@@ -6,7 +6,7 b' Requires Python 2.1 or better.'
6 6
7 7 This file contains the main make_IPython() starter function.
8 8
9 $Id: ipmaker.py 582 2005-05-13 21:20:00Z fperez $"""
9 $Id: ipmaker.py 638 2005-07-18 03:01:41Z fperez $"""
10 10
11 11 #*****************************************************************************
12 12 # Copyright (C) 2001-2004 Fernando Perez. <fperez@colorado.edu>
@@ -85,18 +85,7 b' def make_IPython(argv=None,user_ns=None,debug=1,rc_override=None,'
85 85 IP = shell_class('__IP',user_ns=user_ns,**kw)
86 86
87 87 # Put 'help' in the user namespace
88 try:
89 88 from site import _Helper
90 except ImportError:
91 # Use the _Helper class from Python 2.2 for older Python versions
92 class _Helper:
93 def __repr__(self):
94 return "Type help() for interactive help, " \
95 "or help(object) for help about object."
96 def __call__(self, *args, **kwds):
97 import pydoc
98 return pydoc.help(*args, **kwds)
99 else:
100 89 IP.user_ns['help'] = _Helper()
101 90
102 91 if DEVDEBUG:
@@ -1,3 +1,39 b''
1 2005-07-17 Fernando Perez <fperez@colorado.edu>
2
3 * IPython/Prompts.py (str_safe): Make unicode-safe. Also remove
4 some old hacks and clean up a bit other routines; code should be
5 simpler and a bit faster.
6
7 * IPython/iplib.py (interact): removed some last-resort attempts
8 to survive broken stdout/stderr. That code was only making it
9 harder to abstract out the i/o (necessary for gui integration),
10 and the crashes it could prevent were extremely rare in practice
11 (besides being fully user-induced in a pretty violent manner).
12
13 * IPython/genutils.py (IOStream.__init__): Simplify the i/o stuff.
14 Nothing major yet, but the code is simpler to read; this should
15 make it easier to do more serious modifications in the future.
16
17 * IPython/Extensions/InterpreterExec.py: Fix auto-quoting in pysh,
18 which broke in .15 (thanks to a report by Ville).
19
20 * IPython/Itpl.py (Itpl.__init__): add unicode support (it may not
21 be quite correct, I know next to nothing about unicode). This
22 will allow unicode strings to be used in prompts, amongst other
23 cases. It also will prevent ipython from crashing when unicode
24 shows up unexpectedly in many places. If ascii encoding fails, we
25 assume utf_8. Currently the encoding is not a user-visible
26 setting, though it could be made so if there is demand for it.
27
28 * IPython/ipmaker.py (make_IPython): remove old 2.1-specific hack.
29
30 * IPython/Struct.py (Struct.merge): switch keys() to iterator.
31
32 * IPython/background_jobs.py: moved 2.2 compatibility to genutils.
33
34 * IPython/genutils.py: Add 2.2 compatibility here, so all other
35 code can work transparently for 2.2/2.3.
36
1 37 2005-07-16 Fernando Perez <fperez@colorado.edu>
2 38
3 39 * IPython/ultraTB.py (ExceptionColors): Make a global variable
@@ -11,7 +47,7 b''
11 47 slightly modified version of the patch in
12 48 http://www.scipy.net/roundup/ipython/issue34, which also allows me
13 49 to remove the previous try/except solution (which was costlier).
14 Thanks to glehmann for the fix.
50 Thanks to Gaetan Lehmann <gaetan.lehmann AT jouy.inra.fr> for the fix.
15 51
16 52 2005-06-08 Fernando Perez <fperez@colorado.edu>
17 53
General Comments 0
You need to be logged in to leave comments. Login now