[Python-checkins] python/dist/src/Tools/idle IOBinding.py,1.7,1.8 PyShell.py,1.37,1.38
loewis@users.sourceforge.net
loewis@users.sourceforge.net
Mon, 05 Aug 2002 07:55:23 -0700
Update of /cvsroot/python/python/dist/src/Tools/idle
In directory usw-pr-cvs1:/tmp/cvs-serv18841
Modified Files:
IOBinding.py PyShell.py
Log Message:
Patch #590913: PEP 263 support.
Index: IOBinding.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Tools/idle/IOBinding.py,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** IOBinding.py 10 Jun 2002 18:52:02 -0000 1.7
--- IOBinding.py 5 Aug 2002 14:55:20 -0000 1.8
***************
*** 1,3 ****
--- 1,7 ----
import os
+ import types
+ import sys
+ import codecs
+ import re
import tempfile
import tkFileDialog
***************
*** 25,28 ****
--- 29,97 ----
#$ unix <Control-x><Control-p>
+ try:
+ from codecs import BOM_UTF8
+ except ImportError:
+ # only available since Python 2.3
+ BOM_UTF8 = '\xef\xbb\xbf'
+
+ # Try setting the locale, so that we can find out
+ # what encoding to use
+ try:
+ import locale
+ locale.setlocale(locale.LC_CTYPE, "")
+ except ImportError:
+ pass
+
+ encoding = "ascii"
+ if sys.platform == 'win32':
+ # On Windows, we could use "mbcs". However, to give the user
+ # a portable encoding name, we need to find the code page
+ try:
+ encoding = locale.getdefaultlocale()[1]
+ codecs.lookup(encoding)
+ except LookupError:
+ pass
+ else:
+ try:
+ # Different things can fail here: the locale module may not be
+ # loaded, it may not offer nl_langinfo, or CODESET, or the
+ # resulting codeset may be unknown to Python. We ignore all
+ # these problems, falling back to ASCII
+ encoding = locale.nl_langinfo(locale.CODESET)
+ codecs.lookup(encoding)
+ except (NameError, AttributeError, LookupError):
+ # Try getdefaultlocale well: it parses environment variables,
+ # which may give a clue. Unfortunately, getdefaultlocale has
+ # bugs that can cause ValueError.
+ try:
+ encoding = locale.getdefaultlocale()[1]
+ codecs.lookup(encoding)
+ except (ValueError, LookupError):
+ pass
+
+ encoding = encoding.lower()
+
+ coding_re = re.compile("coding[:=]\s*([-\w_.]+)")
+ def coding_spec(str):
+
+ """Return the encoding declaration according to PEP 263.
+ Raise LookupError if the encoding is declared but unknown."""
+
+ # Only consider the first two lines
+ str = str.split("\n")[:2]
+ str = "\n".join(str)
+
+ match = coding_re.search(str)
+ if not match:
+ return None
+ name = match.group(1)
+ # Check whether the encoding is known
+ import codecs
+ try:
+ codecs.lookup(name)
+ except LookupError:
+ # The standard encoding error does not indicate the encoding
+ raise LookupError, "Unknown encoding "+name
+ return name
class IOBinding:
***************
*** 38,41 ****
--- 107,111 ----
self.save_a_copy)
self.__id_print = self.text.bind("<<print-window>>", self.print_window)
+ self.fileencoding = None
def close(self):
***************
*** 102,105 ****
--- 172,178 ----
tkMessageBox.showerror("I/O Error", str(msg), master=self.text)
return False
+
+ chars = self.decode(chars)
+
self.text.delete("1.0", "end")
self.set_filename(None)
***************
*** 111,114 ****
--- 184,235 ----
return True
+ def decode(self, chars):
+ # Try to create a Unicode string. If that fails, let Tcl try
+ # its best
+
+ # Check presence of a UTF-8 signature first
+ if chars.startswith(BOM_UTF8):
+ try:
+ chars = chars[3:].decode("utf-8")
+ except UnicodeError:
+ # has UTF-8 signature, but fails to decode...
+ return chars
+ else:
+ # Indicates that this file originally had a BOM
+ self.fileencoding = BOM_UTF8
+ return chars
+
+ # Next look for coding specification
+ try:
+ enc = coding_spec(chars)
+ except LookupError, name:
+ tkMessageBox.showerror(
+ title="Error loading the file",
+ message="The encoding '%s' is not known to this Python "\
+ "installation. The file may not display correctly" % name,
+ master = self.text)
+ enc = None
+
+ if enc:
+ try:
+ return unicode(chars, enc)
+ except UnicodeError:
+ pass
+
+ # If it is ASCII, we need not to record anything
+ try:
+ return unicode(chars, 'ascii')
+ except UnicodeError:
+ pass
+
+ # Finally, try the locale's encoding. This is deprecated;
+ # the user should declare a non-ASCII encoding
+ try:
+ chars = unicode(chars, encoding)
+ self.fileencoding = encoding
+ except UnicodeError:
+ pass
+ return chars
+
def maybesave(self):
if self.get_saved():
***************
*** 181,185 ****
def writefile(self, filename):
self.fixlastline()
! chars = str(self.text.get("1.0", "end-1c"))
try:
f = open(filename, "w")
--- 302,306 ----
def writefile(self, filename):
self.fixlastline()
! chars = self.encode(self.text.get("1.0", "end-1c"))
try:
f = open(filename, "w")
***************
*** 192,195 ****
--- 313,378 ----
master=self.text)
return False
+
+ def encode(self, chars):
+ if isinstance(chars, types.StringType):
+ # This is either plain ASCII, or Tk was returning mixed-encoding
+ # text to us. Don't try to guess further.
+ return chars
+
+ # See whether there is anything non-ASCII in it.
+ # If not, no need to figure out the encoding.
+ try:
+ return chars.encode('ascii')
+ except UnicodeError:
+ pass
+
+ # If there is an encoding declared, try this first.
+ try:
+ enc = coding_spec(chars)
+ failed = None
+ except LookupError, msg:
+ failed = msg
+ enc = None
+ if enc:
+ try:
+ return chars.encode(enc)
+ except UnicodeError:
+ failed = "Invalid encoding '%s'" % enc
+
+ if failed:
+ tkMessageBox.showerror(
+ "I/O Error",
+ "%s. Saving as UTF-8" % failed,
+ master = self.text)
+
+ # If there was a UTF-8 signature, use that. This should not fail
+ if self.fileencoding == BOM_UTF8 or failed:
+ return BOM_UTF8 + chars.encode("utf-8")
+
+ # Try the original file encoding next, if any
+ if self.fileencoding:
+ try:
+ return chars.encode(self.fileencoding)
+ except UnicodeError:
+ tkMessageBox.showerror(
+ "I/O Error",
+ "Cannot save this as '%s' anymore. Saving as UTF-8" % self.fileencoding,
+ master = self.text)
+ return BOM_UTF8 + chars.encode("utf-8")
+
+ # Nothing was declared, and we had not determined an encoding
+ # on loading. Recommend an encoding line.
+ try:
+ chars = chars.encode(encoding)
+ enc = encoding
+ except UnicodeError:
+ chars = BOM_UTF8 + chars.encode("utf-8")
+ enc = "utf-8"
+ tkMessageBox.showerror(
+ "I/O Error",
+ "Non-ASCII found, yet no encoding declared. Add a line like\n"
+ "# -*- coding: %s -*- \nto your file" % enc,
+ master = self.text)
+ return chars
def fixlastline(self):
Index: PyShell.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Tools/idle/PyShell.py,v
retrieving revision 1.37
retrieving revision 1.38
diff -C2 -d -r1.37 -r1.38
*** PyShell.py 21 May 2002 17:00:20 -0000 1.37
--- PyShell.py 5 Aug 2002 14:55:21 -0000 1.38
***************
*** 7,10 ****
--- 7,11 ----
import re
import warnings
+ import types
import linecache
***************
*** 189,192 ****
--- 190,196 ----
self.save_warnings_filters = warnings.filters[:]
warnings.filterwarnings(action="error", category=SyntaxWarning)
+ if isinstance(source, types.UnicodeType):
+ import IOBinding
+ source = source.encode(IOBinding.encoding)
try:
return InteractiveInterpreter.runsource(self, source, filename)