Skip to content

Commit

Permalink
Merge pull request #1245 from gbrandonp/pythonw-py3k
Browse files Browse the repository at this point in the history
pythonw py3k fixes for issue #1226
  • Loading branch information
takluyver committed May 5, 2012
2 parents 7bb7aed + 13bd783 commit 4cf98b4
Show file tree
Hide file tree
Showing 19 changed files with 103 additions and 56 deletions.
5 changes: 3 additions & 2 deletions IPython/config/loader.py
Expand Up @@ -26,6 +26,7 @@
from IPython.external import argparse
from IPython.utils.path import filefind, get_ipython_dir
from IPython.utils import py3compat, text, warn
from IPython.utils.encoding import DEFAULT_ENCODING

#-----------------------------------------------------------------------------
# Exceptions
Expand Down Expand Up @@ -439,7 +440,7 @@ def _decode_argv(self, argv, enc=None):
"""decode argv if bytes, using stin.encoding, falling back on default enc"""
uargv = []
if enc is None:
enc = text.getdefaultencoding()
enc = DEFAULT_ENCODING
for arg in argv:
if not isinstance(arg, unicode):
# only decode if not already decoded
Expand Down Expand Up @@ -603,7 +604,7 @@ def _add_arguments(self, aliases=None, flags=None):
def _parse_args(self, args):
"""self.parser->self.parsed_data"""
# decode sys.argv to support unicode command-line options
enc = text.getdefaultencoding()
enc = DEFAULT_ENCODING
uargs = [py3compat.cast_unicode(a, enc) for a in args]
self.parsed_data, self.extra_args = self.parser.parse_known_args(uargs)

Expand Down
3 changes: 2 additions & 1 deletion IPython/core/macro.py
Expand Up @@ -11,6 +11,7 @@
import sys

from IPython.utils import py3compat
from IPython.utils.encoding import DEFAULT_ENCODING

coding_declaration = re.compile(r"#\s*coding[:=]\s*([-\w.]+)")

Expand All @@ -35,7 +36,7 @@ def __init__(self,code):
lines.append(line)
code = "\n".join(lines)
if isinstance(code, bytes):
code = code.decode(enc or sys.getdefaultencoding())
code = code.decode(enc or DEFAULT_ENCODING)
self.value = code + '\n'

def __str__(self):
Expand Down
7 changes: 4 additions & 3 deletions IPython/core/magic.py
Expand Up @@ -58,6 +58,7 @@
from IPython.testing.skipdoctest import skip_doctest
from IPython.utils import py3compat
from IPython.utils import openpy
from IPython.utils.encoding import DEFAULT_ENCODING
from IPython.utils.io import file_read, nlprint
from IPython.utils.module_paths import find_mod
from IPython.utils.path import get_py_filename, unquote_filename
Expand Down Expand Up @@ -614,7 +615,7 @@ def magic_pfile(self, parameter_s=''):
except IOError,msg:
print msg
return
page.page(self.shell.inspector.format(file(filename).read()))
page.page(self.shell.inspector.format(open(filename).read()))

def magic_psearch(self, parameter_s=''):
"""Search for object in namespaces by wildcard.
Expand Down Expand Up @@ -950,7 +951,7 @@ def type_name(v):
try:
vstr = str(var)
except UnicodeEncodeError:
vstr = unicode(var).encode(sys.getdefaultencoding(),
vstr = unicode(var).encode(DEFAULT_ENCODING,
'backslashreplace')
vstr = vstr.replace('\n','\\n')
if len(vstr) < 50:
Expand Down Expand Up @@ -1542,7 +1543,7 @@ def magic_prun(self, parameter_s ='',user_mode=1,
`dump_file`+'.',sys_exit
if text_file:
text_file = unquote_filename(text_file)
pfile = file(text_file,'w')
pfile = open(text_file,'w')
pfile.write(output)
pfile.close()
print '\n*** Profile printout saved to text file',\
Expand Down
2 changes: 1 addition & 1 deletion IPython/core/page.py
Expand Up @@ -203,7 +203,7 @@ def page(strng, start=0, screen_lines=0, pager_cmd=None):
retval = 1
else:
tmpname = tempfile.mktemp('.txt')
tmpfile = file(tmpname,'wt')
tmpfile = open(tmpname,'wt')
tmpfile.write(strng)
tmpfile.close()
cmd = "%s < %s" % (pager_cmd,tmpname)
Expand Down
4 changes: 3 additions & 1 deletion IPython/core/splitinput.py
Expand Up @@ -24,6 +24,7 @@
import sys

from IPython.utils import py3compat
from IPython.utils.encoding import get_stream_enc

#-----------------------------------------------------------------------------
# Main function
Expand Down Expand Up @@ -53,7 +54,8 @@ def split_user_input(line, pattern=None):
and the rest.
"""
# We need to ensure that the rest of this routine deals only with unicode
line = py3compat.cast_unicode(line, sys.stdin.encoding or 'utf-8')
encoding = get_stream_enc(sys.stdin, 'utf-8')
line = py3compat.cast_unicode(line, encoding)

if pattern is None:
pattern = line_split
Expand Down
2 changes: 1 addition & 1 deletion IPython/external/path/_path.py
Expand Up @@ -602,7 +602,7 @@ def write_text(self, text, encoding=None, errors='strict', linesep=os.linesep, a
u'\x85', u'\r\x85', and u'\u2028'.
(This is slightly different from when you open a file for
writing with fopen(filename, "w") in C or file(filename, 'w')
writing with fopen(filename, "w") in C or open(filename, 'w')
in Python.)
Expand Down
2 changes: 1 addition & 1 deletion IPython/external/pexpect/_pexpect.py
Expand Up @@ -352,7 +352,7 @@ def __init__(self, command, args=[], timeout=30, maxread=2000, searchwindowsize=
Example log input and output to a file::
child = pexpect.spawn('some_command')
fout = file('mylog.txt','w')
fout = open('mylog.txt','w')
child.logfile = fout
Example log to stdout::
Expand Down
5 changes: 3 additions & 2 deletions IPython/frontend/terminal/interactiveshell.py
Expand Up @@ -31,6 +31,7 @@
from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
from IPython.core.pylabtools import pylab_activate
from IPython.testing.skipdoctest import skip_doctest
from IPython.utils.encoding import get_stream_enc
from IPython.utils import py3compat
from IPython.utils.terminal import toggle_set_term_title, set_term_title
from IPython.utils.process import abbrev_cwd
Expand Down Expand Up @@ -319,7 +320,7 @@ def _replace_rlhist_multiline(self, source_raw, hlen_before_cell):

for i in range(hlen - hlen_before_cell):
self.readline.remove_history_item(hlen - i - 1)
stdin_encoding = sys.stdin.encoding or "utf-8"
stdin_encoding = get_stream_enc(sys.stdin, 'utf-8')
self.readline.add_history(py3compat.unicode_to_str(source_raw.rstrip(),
stdin_encoding))
return self.readline.get_current_history_length()
Expand Down Expand Up @@ -472,7 +473,7 @@ def edit_syntax_error(self):
self.showtraceback()
else:
try:
f = file(err.filename)
f = open(err.filename)
try:
# This should be inside a display_trap block and I
# think it is.
Expand Down
5 changes: 3 additions & 2 deletions IPython/testing/tools.py
Expand Up @@ -42,9 +42,10 @@

from IPython.config.loader import Config
from IPython.utils.process import find_cmd, getoutputerror
from IPython.utils.text import list_strings, getdefaultencoding
from IPython.utils.text import list_strings
from IPython.utils.io import temp_pyfile, Tee
from IPython.utils import py3compat
from IPython.utils.encoding import DEFAULT_ENCODING

from . import decorators as dec
from . import skipdoctest
Expand Down Expand Up @@ -322,7 +323,7 @@ def check_pairs(func, pairs):
# so we need a class that can handle both.
class MyStringIO(StringIO):
def write(self, s):
s = py3compat.cast_unicode(s, encoding=getdefaultencoding())
s = py3compat.cast_unicode(s, encoding=DEFAULT_ENCODING)
super(MyStringIO, self).write(s)

notprinted_msg = """Did not find {0!r} in printed output (on {1}):
Expand Down
2 changes: 1 addition & 1 deletion IPython/utils/PyColorize.py
Expand Up @@ -281,7 +281,7 @@ def main(argv=None):
stream = sys.stdin
else:
try:
stream = file(fname)
stream = open(fname)
except IOError,msg:
print >> sys.stderr, msg
sys.exit(1)
Expand Down
3 changes: 2 additions & 1 deletion IPython/utils/_process_posix.py
Expand Up @@ -26,6 +26,7 @@
from ._process_common import getoutput, arg_split
from IPython.utils import text
from IPython.utils import py3compat
from IPython.utils.encoding import DEFAULT_ENCODING

#-----------------------------------------------------------------------------
# Function definitions
Expand Down Expand Up @@ -128,7 +129,7 @@ def system(self, cmd):
int : child's exitstatus
"""
# Get likely encoding for the output.
enc = text.getdefaultencoding()
enc = DEFAULT_ENCODING

# Patterns to match on the output, for pexpect. We read input and
# allow either a short timeout or EOF
Expand Down
3 changes: 2 additions & 1 deletion IPython/utils/_process_win32.py
Expand Up @@ -29,6 +29,7 @@
from ._process_common import read_no_interrupt, process_handler, arg_split as py_arg_split
from . import py3compat
from . import text
from .encoding import DEFAULT_ENCODING

#-----------------------------------------------------------------------------
# Function definitions
Expand Down Expand Up @@ -94,7 +95,7 @@ def _find_cmd(cmd):

def _system_body(p):
"""Callback for _system."""
enc = text.getdefaultencoding()
enc = DEFAULT_ENCODING
for line in read_no_interrupt(p.stdout).splitlines():
line = line.decode(enc, 'replace')
print(line, file=sys.stdout)
Expand Down
56 changes: 56 additions & 0 deletions IPython/utils/encoding.py
@@ -0,0 +1,56 @@
# coding: utf-8
"""
Utilities for dealing with text encodings
"""

#-----------------------------------------------------------------------------
# Copyright (C) 2008-2012 The IPython Development Team
#
# Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software.
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
import sys
import locale

# to deal with the possibility of sys.std* not being a stream at all
def get_stream_enc(stream, default=None):
"""Return the given stream's encoding or a default.
There are cases where sys.std* might not actually be a stream, so
check for the encoding attribute prior to returning it, and return
a default if it doesn't exist or evaluates as False. `default'
is None if not provided.
"""
if not hasattr(stream, 'encoding') or not stream.encoding:
return default
else:
return stream.encoding

# Less conservative replacement for sys.getdefaultencoding, that will try
# to match the environment.
# Defined here as central function, so if we find better choices, we
# won't need to make changes all over IPython.
def getdefaultencoding():
"""Return IPython's guess for the default encoding for bytes as text.
Asks for stdin.encoding first, to match the calling Terminal, but that
is often None for subprocesses. Fall back on locale.getpreferredencoding()
which should be a sensible platform default (that respects LANG environment),
and finally to sys.getdefaultencoding() which is the most conservative option,
and usually ASCII.
"""
enc = get_stream_enc(sys.stdin)
if not enc or enc=='ascii':
try:
# There are reports of getpreferredencoding raising errors
# in some cases, which may well be fixed, but let's be conservative here.
enc = locale.getpreferredencoding()
except Exception:
pass
return enc or sys.getdefaultencoding()

DEFAULT_ENCODING = getdefaultencoding()
18 changes: 10 additions & 8 deletions IPython/utils/io.py
Expand Up @@ -14,6 +14,7 @@
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
import os
import sys
import tempfile

Expand Down Expand Up @@ -70,6 +71,11 @@ def closed(self):
def close(self):
pass

# setup stdin/stdout/stderr to sys.stdin/sys.stdout/sys.stderr
devnull = open(os.devnull, 'a')
stdin = IOStream(sys.stdin, fallback=devnull)
stdout = IOStream(sys.stdout, fallback=devnull)
stderr = IOStream(sys.stderr, fallback=devnull)

class IOTerm:
""" Term holds the file or file-like objects for handling I/O operations.
Expand All @@ -82,14 +88,10 @@ class IOTerm:
# this class will make it easier to embed it into other environments which
# are not a normal terminal (such as a GUI-based shell)
def __init__(self, stdin=None, stdout=None, stderr=None):
self.stdin = IOStream(stdin, sys.stdin)
self.stdout = IOStream(stdout, sys.stdout)
self.stderr = IOStream(stderr, sys.stderr)

# setup stdin/stdout/stderr to sys.stdin/sys.stdout/sys.stderr
stdin = IOStream(sys.stdin)
stdout = IOStream(sys.stdout)
stderr = IOStream(sys.stderr)
mymodule = sys.modules[__name__]
self.stdin = IOStream(stdin, mymodule.stdin)
self.stdout = IOStream(stdout, mymodule.stdout)
self.stderr = IOStream(stderr, mymodule.stderr)


class Tee(object):
Expand Down
3 changes: 2 additions & 1 deletion IPython/utils/jsonutil.py
Expand Up @@ -17,6 +17,7 @@
from datetime import datetime

from IPython.utils import py3compat
from IPython.utils.encoding import DEFAULT_ENCODING
from IPython.utils import text
next_attr_name = '__next__' if py3compat.PY3 else 'next'

Expand Down Expand Up @@ -135,7 +136,7 @@ def json_clean(obj):
return obj

if isinstance(obj, bytes):
return obj.decode(text.getdefaultencoding(), 'replace')
return obj.decode(DEFAULT_ENCODING, 'replace')

if isinstance(obj, container_to_list) or (
hasattr(obj, '__iter__') and hasattr(obj, next_attr_name)):
Expand Down
9 changes: 6 additions & 3 deletions IPython/utils/py3compat.py
Expand Up @@ -6,19 +6,22 @@
import re
import types

from .encoding import DEFAULT_ENCODING

orig_open = open

def no_code(x, encoding=None):
return x

def decode(s, encoding=None):
encoding = encoding or sys.stdin.encoding or sys.getdefaultencoding()
encoding = encoding or DEFAULT_ENCODING
return s.decode(encoding, "replace")

def encode(u, encoding=None):
encoding = encoding or sys.stdin.encoding or sys.getdefaultencoding()
encoding = encoding or DEFAULT_ENCODING
return u.encode(encoding, "replace")



def cast_unicode(s, encoding=None):
if isinstance(s, bytes):
return decode(s, encoding)
Expand Down
24 changes: 0 additions & 24 deletions IPython/utils/text.py
Expand Up @@ -16,7 +16,6 @@

import __main__

import locale
import os
import re
import shutil
Expand All @@ -34,29 +33,6 @@
# Code
#-----------------------------------------------------------------------------

# Less conservative replacement for sys.getdefaultencoding, that will try
# to match the environment.
# Defined here as central function, so if we find better choices, we
# won't need to make changes all over IPython.
def getdefaultencoding():
"""Return IPython's guess for the default encoding for bytes as text.
Asks for stdin.encoding first, to match the calling Terminal, but that
is often None for subprocesses. Fall back on locale.getpreferredencoding()
which should be a sensible platform default (that respects LANG environment),
and finally to sys.getdefaultencoding() which is the most conservative option,
and usually ASCII.
"""
enc = sys.stdin.encoding
if not enc or enc=='ascii':
try:
# There are reports of getpreferredencoding raising errors
# in some cases, which may well be fixed, but let's be conservative here.
enc = locale.getpreferredencoding()
except Exception:
pass
return enc or sys.getdefaultencoding()

def unquote_ends(istr):
"""Remove a single pair of quotes from the endpoints of a string."""

Expand Down

0 comments on commit 4cf98b4

Please sign in to comment.