##// END OF EJS Templates
Merge pull request #1245 from gbrandonp/pythonw-py3k...
Thomas Kluyver -
r6719:4cf98b43 merge
parent child Browse files
Show More
@@ -0,0 +1,56 b''
1 # coding: utf-8
2 """
3 Utilities for dealing with text encodings
4 """
5
6 #-----------------------------------------------------------------------------
7 # Copyright (C) 2008-2012 The IPython Development Team
8 #
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16 import sys
17 import locale
18
19 # to deal with the possibility of sys.std* not being a stream at all
20 def get_stream_enc(stream, default=None):
21 """Return the given stream's encoding or a default.
22
23 There are cases where sys.std* might not actually be a stream, so
24 check for the encoding attribute prior to returning it, and return
25 a default if it doesn't exist or evaluates as False. `default'
26 is None if not provided.
27 """
28 if not hasattr(stream, 'encoding') or not stream.encoding:
29 return default
30 else:
31 return stream.encoding
32
33 # Less conservative replacement for sys.getdefaultencoding, that will try
34 # to match the environment.
35 # Defined here as central function, so if we find better choices, we
36 # won't need to make changes all over IPython.
37 def getdefaultencoding():
38 """Return IPython's guess for the default encoding for bytes as text.
39
40 Asks for stdin.encoding first, to match the calling Terminal, but that
41 is often None for subprocesses. Fall back on locale.getpreferredencoding()
42 which should be a sensible platform default (that respects LANG environment),
43 and finally to sys.getdefaultencoding() which is the most conservative option,
44 and usually ASCII.
45 """
46 enc = get_stream_enc(sys.stdin)
47 if not enc or enc=='ascii':
48 try:
49 # There are reports of getpreferredencoding raising errors
50 # in some cases, which may well be fixed, but let's be conservative here.
51 enc = locale.getpreferredencoding()
52 except Exception:
53 pass
54 return enc or sys.getdefaultencoding()
55
56 DEFAULT_ENCODING = getdefaultencoding()
@@ -26,6 +26,7 b' import sys'
26 from IPython.external import argparse
26 from IPython.external import argparse
27 from IPython.utils.path import filefind, get_ipython_dir
27 from IPython.utils.path import filefind, get_ipython_dir
28 from IPython.utils import py3compat, text, warn
28 from IPython.utils import py3compat, text, warn
29 from IPython.utils.encoding import DEFAULT_ENCODING
29
30
30 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
31 # Exceptions
32 # Exceptions
@@ -439,7 +440,7 b' class KeyValueConfigLoader(CommandLineConfigLoader):'
439 """decode argv if bytes, using stin.encoding, falling back on default enc"""
440 """decode argv if bytes, using stin.encoding, falling back on default enc"""
440 uargv = []
441 uargv = []
441 if enc is None:
442 if enc is None:
442 enc = text.getdefaultencoding()
443 enc = DEFAULT_ENCODING
443 for arg in argv:
444 for arg in argv:
444 if not isinstance(arg, unicode):
445 if not isinstance(arg, unicode):
445 # only decode if not already decoded
446 # only decode if not already decoded
@@ -603,7 +604,7 b' class ArgParseConfigLoader(CommandLineConfigLoader):'
603 def _parse_args(self, args):
604 def _parse_args(self, args):
604 """self.parser->self.parsed_data"""
605 """self.parser->self.parsed_data"""
605 # decode sys.argv to support unicode command-line options
606 # decode sys.argv to support unicode command-line options
606 enc = text.getdefaultencoding()
607 enc = DEFAULT_ENCODING
607 uargs = [py3compat.cast_unicode(a, enc) for a in args]
608 uargs = [py3compat.cast_unicode(a, enc) for a in args]
608 self.parsed_data, self.extra_args = self.parser.parse_known_args(uargs)
609 self.parsed_data, self.extra_args = self.parser.parse_known_args(uargs)
609
610
@@ -11,6 +11,7 b' import re'
11 import sys
11 import sys
12
12
13 from IPython.utils import py3compat
13 from IPython.utils import py3compat
14 from IPython.utils.encoding import DEFAULT_ENCODING
14
15
15 coding_declaration = re.compile(r"#\s*coding[:=]\s*([-\w.]+)")
16 coding_declaration = re.compile(r"#\s*coding[:=]\s*([-\w.]+)")
16
17
@@ -35,7 +36,7 b' class Macro(object):'
35 lines.append(line)
36 lines.append(line)
36 code = "\n".join(lines)
37 code = "\n".join(lines)
37 if isinstance(code, bytes):
38 if isinstance(code, bytes):
38 code = code.decode(enc or sys.getdefaultencoding())
39 code = code.decode(enc or DEFAULT_ENCODING)
39 self.value = code + '\n'
40 self.value = code + '\n'
40
41
41 def __str__(self):
42 def __str__(self):
@@ -58,6 +58,7 b' from IPython.core.pylabtools import mpl_runner'
58 from IPython.testing.skipdoctest import skip_doctest
58 from IPython.testing.skipdoctest import skip_doctest
59 from IPython.utils import py3compat
59 from IPython.utils import py3compat
60 from IPython.utils import openpy
60 from IPython.utils import openpy
61 from IPython.utils.encoding import DEFAULT_ENCODING
61 from IPython.utils.io import file_read, nlprint
62 from IPython.utils.io import file_read, nlprint
62 from IPython.utils.module_paths import find_mod
63 from IPython.utils.module_paths import find_mod
63 from IPython.utils.path import get_py_filename, unquote_filename
64 from IPython.utils.path import get_py_filename, unquote_filename
@@ -614,7 +615,7 b' Currently the magic system has the following functions:\\n"""'
614 except IOError,msg:
615 except IOError,msg:
615 print msg
616 print msg
616 return
617 return
617 page.page(self.shell.inspector.format(file(filename).read()))
618 page.page(self.shell.inspector.format(open(filename).read()))
618
619
619 def magic_psearch(self, parameter_s=''):
620 def magic_psearch(self, parameter_s=''):
620 """Search for object in namespaces by wildcard.
621 """Search for object in namespaces by wildcard.
@@ -950,7 +951,7 b' Currently the magic system has the following functions:\\n"""'
950 try:
951 try:
951 vstr = str(var)
952 vstr = str(var)
952 except UnicodeEncodeError:
953 except UnicodeEncodeError:
953 vstr = unicode(var).encode(sys.getdefaultencoding(),
954 vstr = unicode(var).encode(DEFAULT_ENCODING,
954 'backslashreplace')
955 'backslashreplace')
955 vstr = vstr.replace('\n','\\n')
956 vstr = vstr.replace('\n','\\n')
956 if len(vstr) < 50:
957 if len(vstr) < 50:
@@ -1542,7 +1543,7 b' Currently the magic system has the following functions:\\n"""'
1542 `dump_file`+'.',sys_exit
1543 `dump_file`+'.',sys_exit
1543 if text_file:
1544 if text_file:
1544 text_file = unquote_filename(text_file)
1545 text_file = unquote_filename(text_file)
1545 pfile = file(text_file,'w')
1546 pfile = open(text_file,'w')
1546 pfile.write(output)
1547 pfile.write(output)
1547 pfile.close()
1548 pfile.close()
1548 print '\n*** Profile printout saved to text file',\
1549 print '\n*** Profile printout saved to text file',\
@@ -203,7 +203,7 b' def page(strng, start=0, screen_lines=0, pager_cmd=None):'
203 retval = 1
203 retval = 1
204 else:
204 else:
205 tmpname = tempfile.mktemp('.txt')
205 tmpname = tempfile.mktemp('.txt')
206 tmpfile = file(tmpname,'wt')
206 tmpfile = open(tmpname,'wt')
207 tmpfile.write(strng)
207 tmpfile.write(strng)
208 tmpfile.close()
208 tmpfile.close()
209 cmd = "%s < %s" % (pager_cmd,tmpname)
209 cmd = "%s < %s" % (pager_cmd,tmpname)
@@ -24,6 +24,7 b' import re'
24 import sys
24 import sys
25
25
26 from IPython.utils import py3compat
26 from IPython.utils import py3compat
27 from IPython.utils.encoding import get_stream_enc
27
28
28 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
29 # Main function
30 # Main function
@@ -53,7 +54,8 b' def split_user_input(line, pattern=None):'
53 and the rest.
54 and the rest.
54 """
55 """
55 # We need to ensure that the rest of this routine deals only with unicode
56 # We need to ensure that the rest of this routine deals only with unicode
56 line = py3compat.cast_unicode(line, sys.stdin.encoding or 'utf-8')
57 encoding = get_stream_enc(sys.stdin, 'utf-8')
58 line = py3compat.cast_unicode(line, encoding)
57
59
58 if pattern is None:
60 if pattern is None:
59 pattern = line_split
61 pattern = line_split
@@ -602,7 +602,7 b' class path(unicode):'
602 u'\x85', u'\r\x85', and u'\u2028'.
602 u'\x85', u'\r\x85', and u'\u2028'.
603
603
604 (This is slightly different from when you open a file for
604 (This is slightly different from when you open a file for
605 writing with fopen(filename, "w") in C or file(filename, 'w')
605 writing with fopen(filename, "w") in C or open(filename, 'w')
606 in Python.)
606 in Python.)
607
607
608
608
@@ -352,7 +352,7 b' class spawnb(object):'
352 Example log input and output to a file::
352 Example log input and output to a file::
353
353
354 child = pexpect.spawn('some_command')
354 child = pexpect.spawn('some_command')
355 fout = file('mylog.txt','w')
355 fout = open('mylog.txt','w')
356 child.logfile = fout
356 child.logfile = fout
357
357
358 Example log to stdout::
358 Example log to stdout::
@@ -31,6 +31,7 b' from IPython.core.usage import interactive_usage, default_banner'
31 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
31 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
32 from IPython.core.pylabtools import pylab_activate
32 from IPython.core.pylabtools import pylab_activate
33 from IPython.testing.skipdoctest import skip_doctest
33 from IPython.testing.skipdoctest import skip_doctest
34 from IPython.utils.encoding import get_stream_enc
34 from IPython.utils import py3compat
35 from IPython.utils import py3compat
35 from IPython.utils.terminal import toggle_set_term_title, set_term_title
36 from IPython.utils.terminal import toggle_set_term_title, set_term_title
36 from IPython.utils.process import abbrev_cwd
37 from IPython.utils.process import abbrev_cwd
@@ -319,7 +320,7 b' class TerminalInteractiveShell(InteractiveShell):'
319
320
320 for i in range(hlen - hlen_before_cell):
321 for i in range(hlen - hlen_before_cell):
321 self.readline.remove_history_item(hlen - i - 1)
322 self.readline.remove_history_item(hlen - i - 1)
322 stdin_encoding = sys.stdin.encoding or "utf-8"
323 stdin_encoding = get_stream_enc(sys.stdin, 'utf-8')
323 self.readline.add_history(py3compat.unicode_to_str(source_raw.rstrip(),
324 self.readline.add_history(py3compat.unicode_to_str(source_raw.rstrip(),
324 stdin_encoding))
325 stdin_encoding))
325 return self.readline.get_current_history_length()
326 return self.readline.get_current_history_length()
@@ -472,7 +473,7 b' class TerminalInteractiveShell(InteractiveShell):'
472 self.showtraceback()
473 self.showtraceback()
473 else:
474 else:
474 try:
475 try:
475 f = file(err.filename)
476 f = open(err.filename)
476 try:
477 try:
477 # This should be inside a display_trap block and I
478 # This should be inside a display_trap block and I
478 # think it is.
479 # think it is.
@@ -42,9 +42,10 b' except ImportError:'
42
42
43 from IPython.config.loader import Config
43 from IPython.config.loader import Config
44 from IPython.utils.process import find_cmd, getoutputerror
44 from IPython.utils.process import find_cmd, getoutputerror
45 from IPython.utils.text import list_strings, getdefaultencoding
45 from IPython.utils.text import list_strings
46 from IPython.utils.io import temp_pyfile, Tee
46 from IPython.utils.io import temp_pyfile, Tee
47 from IPython.utils import py3compat
47 from IPython.utils import py3compat
48 from IPython.utils.encoding import DEFAULT_ENCODING
48
49
49 from . import decorators as dec
50 from . import decorators as dec
50 from . import skipdoctest
51 from . import skipdoctest
@@ -322,7 +323,7 b' else:'
322 # so we need a class that can handle both.
323 # so we need a class that can handle both.
323 class MyStringIO(StringIO):
324 class MyStringIO(StringIO):
324 def write(self, s):
325 def write(self, s):
325 s = py3compat.cast_unicode(s, encoding=getdefaultencoding())
326 s = py3compat.cast_unicode(s, encoding=DEFAULT_ENCODING)
326 super(MyStringIO, self).write(s)
327 super(MyStringIO, self).write(s)
327
328
328 notprinted_msg = """Did not find {0!r} in printed output (on {1}):
329 notprinted_msg = """Did not find {0!r} in printed output (on {1}):
@@ -281,7 +281,7 b' If no filename is given, or if filename is -, read standard input."""'
281 stream = sys.stdin
281 stream = sys.stdin
282 else:
282 else:
283 try:
283 try:
284 stream = file(fname)
284 stream = open(fname)
285 except IOError,msg:
285 except IOError,msg:
286 print >> sys.stderr, msg
286 print >> sys.stderr, msg
287 sys.exit(1)
287 sys.exit(1)
@@ -26,6 +26,7 b' from .autoattr import auto_attr'
26 from ._process_common import getoutput, arg_split
26 from ._process_common import getoutput, arg_split
27 from IPython.utils import text
27 from IPython.utils import text
28 from IPython.utils import py3compat
28 from IPython.utils import py3compat
29 from IPython.utils.encoding import DEFAULT_ENCODING
29
30
30 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
31 # Function definitions
32 # Function definitions
@@ -128,7 +129,7 b' class ProcessHandler(object):'
128 int : child's exitstatus
129 int : child's exitstatus
129 """
130 """
130 # Get likely encoding for the output.
131 # Get likely encoding for the output.
131 enc = text.getdefaultencoding()
132 enc = DEFAULT_ENCODING
132
133
133 # Patterns to match on the output, for pexpect. We read input and
134 # Patterns to match on the output, for pexpect. We read input and
134 # allow either a short timeout or EOF
135 # allow either a short timeout or EOF
@@ -29,6 +29,7 b' from subprocess import STDOUT'
29 from ._process_common import read_no_interrupt, process_handler, arg_split as py_arg_split
29 from ._process_common import read_no_interrupt, process_handler, arg_split as py_arg_split
30 from . import py3compat
30 from . import py3compat
31 from . import text
31 from . import text
32 from .encoding import DEFAULT_ENCODING
32
33
33 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
34 # Function definitions
35 # Function definitions
@@ -94,7 +95,7 b' def _find_cmd(cmd):'
94
95
95 def _system_body(p):
96 def _system_body(p):
96 """Callback for _system."""
97 """Callback for _system."""
97 enc = text.getdefaultencoding()
98 enc = DEFAULT_ENCODING
98 for line in read_no_interrupt(p.stdout).splitlines():
99 for line in read_no_interrupt(p.stdout).splitlines():
99 line = line.decode(enc, 'replace')
100 line = line.decode(enc, 'replace')
100 print(line, file=sys.stdout)
101 print(line, file=sys.stdout)
@@ -14,6 +14,7 b' from __future__ import print_function'
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 # Imports
15 # Imports
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17 import os
17 import sys
18 import sys
18 import tempfile
19 import tempfile
19
20
@@ -70,6 +71,11 b' class IOStream:'
70 def close(self):
71 def close(self):
71 pass
72 pass
72
73
74 # setup stdin/stdout/stderr to sys.stdin/sys.stdout/sys.stderr
75 devnull = open(os.devnull, 'a')
76 stdin = IOStream(sys.stdin, fallback=devnull)
77 stdout = IOStream(sys.stdout, fallback=devnull)
78 stderr = IOStream(sys.stderr, fallback=devnull)
73
79
74 class IOTerm:
80 class IOTerm:
75 """ Term holds the file or file-like objects for handling I/O operations.
81 """ Term holds the file or file-like objects for handling I/O operations.
@@ -82,14 +88,10 b' class IOTerm:'
82 # this class will make it easier to embed it into other environments which
88 # this class will make it easier to embed it into other environments which
83 # are not a normal terminal (such as a GUI-based shell)
89 # are not a normal terminal (such as a GUI-based shell)
84 def __init__(self, stdin=None, stdout=None, stderr=None):
90 def __init__(self, stdin=None, stdout=None, stderr=None):
85 self.stdin = IOStream(stdin, sys.stdin)
91 mymodule = sys.modules[__name__]
86 self.stdout = IOStream(stdout, sys.stdout)
92 self.stdin = IOStream(stdin, mymodule.stdin)
87 self.stderr = IOStream(stderr, sys.stderr)
93 self.stdout = IOStream(stdout, mymodule.stdout)
88
94 self.stderr = IOStream(stderr, mymodule.stderr)
89 # setup stdin/stdout/stderr to sys.stdin/sys.stdout/sys.stderr
90 stdin = IOStream(sys.stdin)
91 stdout = IOStream(sys.stdout)
92 stderr = IOStream(sys.stderr)
93
95
94
96
95 class Tee(object):
97 class Tee(object):
@@ -17,6 +17,7 b' import types'
17 from datetime import datetime
17 from datetime import datetime
18
18
19 from IPython.utils import py3compat
19 from IPython.utils import py3compat
20 from IPython.utils.encoding import DEFAULT_ENCODING
20 from IPython.utils import text
21 from IPython.utils import text
21 next_attr_name = '__next__' if py3compat.PY3 else 'next'
22 next_attr_name = '__next__' if py3compat.PY3 else 'next'
22
23
@@ -135,7 +136,7 b' def json_clean(obj):'
135 return obj
136 return obj
136
137
137 if isinstance(obj, bytes):
138 if isinstance(obj, bytes):
138 return obj.decode(text.getdefaultencoding(), 'replace')
139 return obj.decode(DEFAULT_ENCODING, 'replace')
139
140
140 if isinstance(obj, container_to_list) or (
141 if isinstance(obj, container_to_list) or (
141 hasattr(obj, '__iter__') and hasattr(obj, next_attr_name)):
142 hasattr(obj, '__iter__') and hasattr(obj, next_attr_name)):
@@ -6,19 +6,22 b' import sys'
6 import re
6 import re
7 import types
7 import types
8
8
9 from .encoding import DEFAULT_ENCODING
10
9 orig_open = open
11 orig_open = open
10
12
11 def no_code(x, encoding=None):
13 def no_code(x, encoding=None):
12 return x
14 return x
13
15
14 def decode(s, encoding=None):
16 def decode(s, encoding=None):
15 encoding = encoding or sys.stdin.encoding or sys.getdefaultencoding()
17 encoding = encoding or DEFAULT_ENCODING
16 return s.decode(encoding, "replace")
18 return s.decode(encoding, "replace")
17
19
18 def encode(u, encoding=None):
20 def encode(u, encoding=None):
19 encoding = encoding or sys.stdin.encoding or sys.getdefaultencoding()
21 encoding = encoding or DEFAULT_ENCODING
20 return u.encode(encoding, "replace")
22 return u.encode(encoding, "replace")
21
23
24
22 def cast_unicode(s, encoding=None):
25 def cast_unicode(s, encoding=None):
23 if isinstance(s, bytes):
26 if isinstance(s, bytes):
24 return decode(s, encoding)
27 return decode(s, encoding)
@@ -16,7 +16,6 b' Utilities for working with strings and text.'
16
16
17 import __main__
17 import __main__
18
18
19 import locale
20 import os
19 import os
21 import re
20 import re
22 import shutil
21 import shutil
@@ -34,29 +33,6 b' from IPython.utils.data import flatten'
34 # Code
33 # Code
35 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
36
35
37 # Less conservative replacement for sys.getdefaultencoding, that will try
38 # to match the environment.
39 # Defined here as central function, so if we find better choices, we
40 # won't need to make changes all over IPython.
41 def getdefaultencoding():
42 """Return IPython's guess for the default encoding for bytes as text.
43
44 Asks for stdin.encoding first, to match the calling Terminal, but that
45 is often None for subprocesses. Fall back on locale.getpreferredencoding()
46 which should be a sensible platform default (that respects LANG environment),
47 and finally to sys.getdefaultencoding() which is the most conservative option,
48 and usually ASCII.
49 """
50 enc = sys.stdin.encoding
51 if not enc or enc=='ascii':
52 try:
53 # There are reports of getpreferredencoding raising errors
54 # in some cases, which may well be fixed, but let's be conservative here.
55 enc = locale.getpreferredencoding()
56 except Exception:
57 pass
58 return enc or sys.getdefaultencoding()
59
60 def unquote_ends(istr):
36 def unquote_ends(istr):
61 """Remove a single pair of quotes from the endpoints of a string."""
37 """Remove a single pair of quotes from the endpoints of a string."""
62
38
@@ -4,7 +4,7 b' from io import StringIO'
4
4
5 from session import extract_header, Message
5 from session import extract_header, Message
6
6
7 from IPython.utils import io, text
7 from IPython.utils import io, text, encoding
8
8
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10 # Globals
10 # Globals
@@ -69,7 +69,7 b' class OutStream(object):'
69 else:
69 else:
70 # Make sure that we're handling unicode
70 # Make sure that we're handling unicode
71 if not isinstance(string, unicode):
71 if not isinstance(string, unicode):
72 enc = text.getdefaultencoding()
72 enc = encoding.DEFAULT_ENCODING
73 string = string.decode(enc, 'replace')
73 string = string.decode(enc, 'replace')
74
74
75 self._buffer.write(string)
75 self._buffer.write(string)
@@ -251,7 +251,7 b' class KernelApp(BaseIPythonApplication):'
251 def init_blackhole(self):
251 def init_blackhole(self):
252 """redirects stdout/stderr to devnull if necessary"""
252 """redirects stdout/stderr to devnull if necessary"""
253 if self.no_stdout or self.no_stderr:
253 if self.no_stdout or self.no_stderr:
254 blackhole = file(os.devnull, 'w')
254 blackhole = open(os.devnull, 'w')
255 if self.no_stdout:
255 if self.no_stdout:
256 sys.stdout = sys.__stdout__ = blackhole
256 sys.stdout = sys.__stdout__ = blackhole
257 if self.no_stderr:
257 if self.no_stderr:
General Comments 0
You need to be logged in to leave comments. Login now