Sep 25, 2008 - IronPythonのエンコーディング判別処理の修正 Ver.2
「エンコーディングの処理はいろんな要因が関連するため、安直な修正を行うと、他のプログラムの箇所や他のエンコーディング形式でレベルダウン障害を引き起こします」と下の記事に書きましたが。やっぱりレベルダウンが発生していましたorz
EncodingWrapperクラスへのパッチが不十分だったため、↓のコードを実行するとエラーになってしまいます。
import sys sys.setdefaultencoding( 'utf-8') f=open(r'e:\temp\utf8.txt', 'w' ) f.writelines( ['あ'*40+'\n']*40 ) f.close()
↓が修正パッチのバージョン2です。EncodingWrapperに包含されている_encodingのプロパティを呼び出すようにしただけです。
*** ./IronPython/Runtime/Operations/StringOps.cs.orig Fri Aug 22 12:05:38 2008 --- ./IronPython/Runtime/Operations/StringOps.cs Thu Sep 25 10:07:19 2008 *************** *** 1800,1805 **** --- 1800,1860 ---- res._encoding = (Encoding)_encoding.Clone(); return res; } + + // this method is called by StreamReader. + public override Decoder GetDecoder() { + return _encoding.GetDecoder(); + } + + public override Encoder GetEncoder() { + return _encoding.GetEncoder(); + } + + // this method is called by PythonContext.GetSourceReader(). + public override int CodePage { + get { return _encoding.CodePage; } + } + + public override string BodyName { + get { return _encoding.BodyName; } + } + + public override string EncodingName { + get { return _encoding.EncodingName; } + } + + public override string HeaderName { + get { return _encoding.HeaderName; } + } + + public override bool IsBrowserDisplay { + get { return _encoding.IsBrowserDisplay; } + } + + public override bool IsBrowserSave { + get { return _encoding.IsBrowserSave; } + } + + public override bool IsMailNewsDisplay { + get { return _encoding.IsMailNewsDisplay; } + } + + public override bool IsMailNewsSave { + get { return _encoding.IsMailNewsSave; } + } + + public override bool IsSingleByte { + get { return _encoding.IsSingleByte; } + } + + public override string WebName { + get { return _encoding.WebName; } + } + + public override int WindowsCodePage { + get { return _encoding.WindowsCodePage; } + } + } private static List SplitEmptyString(bool separators) {
PythonContext.csへのパッチは変更していませんが、一応、再掲載。
*** ./IronPython/Runtime/PythonContext.cs.orig Tue Sep 09 06:33:00 2008 --- ./IronPython/Runtime/PythonContext.cs Wed Sep 24 01:41:00 2008 *************** namespace IronPython.Runtime { *** 598,620 **** } } ! if (gotEncoding && sr.CurrentEncoding != PythonAsciiEncoding.Instance && encoding != sr.CurrentEncoding) { ! // we have both a BOM & an encoding type, throw an error ! throw new IOException("file has both Unicode marker and PEP-263 file encoding"); } if (encoding == null) { throw new IOException("unknown encoding type"); } ! if (!gotEncoding) { ! // if we didn't get an encoding seek back to the beginning... ! stream.Seek(startPosition, SeekOrigin.Begin); ! } else { ! // if we got an encoding seek to the # of bytes we read (so the StreamReader's ! // buffering doesn't throw us off) ! stream.Seek(bytesRead, SeekOrigin.Begin); ! } // re-read w/ the correct encoding type... return new SourceCodeReader(new StreamReader(stream, encoding), encoding); --- 598,616 ---- } } ! if (gotEncoding && sr.CurrentEncoding != PythonAsciiEncoding.Instance) { ! Encoding enc; ! if (!StringOps.TryGetEncoding(sr.CurrentEncoding.WebName, out enc) || enc.CodePage != encoding.CodePage) { ! // we have both a BOM & an encoding type, throw an error ! throw new IOException("file has both Unicode marker and PEP-263 file encoding"); ! } } if (encoding == null) { throw new IOException("unknown encoding type"); } ! stream.Seek(startPosition, SeekOrigin.Begin); // re-read w/ the correct encoding type... return new SourceCodeReader(new StreamReader(stream, encoding), encoding);