diff -r cf70f030a744 Lib/_pyio.py --- a/Lib/_pyio.py Wed Jun 18 23:07:46 2014 -0400 +++ b/Lib/_pyio.py Mon Jun 23 23:07:05 2014 +0300 @@ -19,6 +19,14 @@ from io import (__all__, SEEK_SET, SEEK_CUR, SEEK_END) from errno import EINTR +try: + _unicode = unicode +except NameError: + # If Python is built without Unicode support, the unicode type + # will not exist. Fake one. + class _unicode(object): + pass + __metaclass__ = type # open() uses st_blksize whenever we can @@ -224,6 +232,10 @@ result = buffer if binary: return result + try: + unicode + except NameError: + return result text = TextIOWrapper(buffer, encoding, errors, newline, line_buffering) result = text text.mode = mode @@ -837,7 +849,7 @@ def write(self, b): if self.closed: raise ValueError("write to closed file") - if isinstance(b, unicode): + if isinstance(b, _unicode): raise TypeError("can't write unicode to binary stream") n = len(b) if n == 0: @@ -1087,7 +1099,7 @@ def write(self, b): if self.closed: raise ValueError("write to closed file") - if isinstance(b, unicode): + if isinstance(b, _unicode): raise TypeError("can't write unicode to binary stream") with self._write_lock: # XXX we can implement some more tricks to try and avoid @@ -1363,7 +1375,8 @@ Subclasses should override.""" return None -io.TextIOBase.register(TextIOBase) +if hasattr(io, 'TextIOBase'): + io.TextIOBase.register(TextIOBase) class IncrementalNewlineDecoder(codecs.IncrementalDecoder): diff -r cf70f030a744 Lib/io.py --- a/Lib/io.py Wed Jun 18 23:07:46 2014 -0400 +++ b/Lib/io.py Mon Jun 23 23:07:05 2014 +0300 @@ -42,9 +42,8 @@ "Benjamin Peterson ") __all__ = ["BlockingIOError", "open", "IOBase", "RawIOBase", "FileIO", - "BytesIO", "StringIO", "BufferedIOBase", - "BufferedReader", "BufferedWriter", "BufferedRWPair", - "BufferedRandom", "TextIOBase", "TextIOWrapper", + "BytesIO", "BufferedIOBase", "BufferedReader", "BufferedWriter", + "BufferedRWPair", "BufferedRandom", "UnsupportedOperation", "SEEK_SET", "SEEK_CUR", "SEEK_END"] @@ -52,9 +51,15 @@ import abc from _io import (DEFAULT_BUFFER_SIZE, BlockingIOError, UnsupportedOperation, - open, FileIO, BytesIO, StringIO, BufferedReader, - BufferedWriter, BufferedRWPair, BufferedRandom, - IncrementalNewlineDecoder, TextIOWrapper) + open, FileIO, BytesIO, BufferedReader, + BufferedWriter, BufferedRWPair, BufferedRandom) + +try: + from _io import StringIO, IncrementalNewlineDecoder, TextIOWrapper +except ImportError: + pass +else: + __all__ += ["StringIO", "TextIOBase", "TextIOWrapper"] OpenWrapper = _io.open # for compatibility with _pyio @@ -76,8 +81,11 @@ class BufferedIOBase(_io._BufferedIOBase, IOBase): __doc__ = _io._BufferedIOBase.__doc__ -class TextIOBase(_io._TextIOBase, IOBase): - __doc__ = _io._TextIOBase.__doc__ +try: + class TextIOBase(_io._TextIOBase, IOBase): + __doc__ = _io._TextIOBase.__doc__ +except AttributeError: + pass RawIOBase.register(FileIO) @@ -85,6 +93,9 @@ BufferedRWPair): BufferedIOBase.register(klass) -for klass in (StringIO, TextIOWrapper): - TextIOBase.register(klass) +try: + for klass in (StringIO, TextIOWrapper): + TextIOBase.register(klass) +except NameError: + pass del klass diff -r cf70f030a744 Lib/test/test_file.py --- a/Lib/test/test_file.py Wed Jun 18 23:07:46 2014 -0400 +++ b/Lib/test/test_file.py Mon Jun 23 23:07:05 2014 +0300 @@ -12,7 +12,7 @@ import io import _pyio as pyio -from test.test_support import TESTFN, run_unittest +from test.test_support import TESTFN, run_unittest, requires_unicode from UserList import UserList class AutoFileTests(unittest.TestCase): @@ -51,6 +51,7 @@ n = self.f.readinto(a) self.assertEqual(b'12', a.tostring()[:n]) + @requires_unicode def testReadinto_text(self): # verify readinto refuses text files a = array('b', b'x'*10) @@ -176,11 +177,11 @@ for s in (-1, 0, 1, 512): try: f = self.open(TESTFN, 'wb', s) - f.write(str(s).encode("ascii")) + f.write(str(s)) f.close() f.close() f = self.open(TESTFN, 'rb', s) - d = int(f.read().decode("ascii")) + d = int(f.read()) f.close() f.close() except IOError as msg: diff -r cf70f030a744 Lib/test/test_file2k.py --- a/Lib/test/test_file2k.py Wed Jun 18 23:07:46 2014 -0400 +++ b/Lib/test/test_file2k.py Mon Jun 23 23:07:05 2014 +0300 @@ -14,8 +14,12 @@ threading = None from test import test_support -from test.test_support import TESTFN, run_unittest +from test.test_support import TESTFN, run_unittest, requires_unicode, u from UserList import UserList +try: + from test.test_support import TESTFN_UNICODE +except ImportError: + TESTFN_UNICODE = None class AutoFileTests(unittest.TestCase): # file tests for which a test file is automatically set up @@ -222,7 +226,10 @@ # Some invalid modes fail on Windows, but pass on Unix # Issue3965: avoid a crash on Windows when filename is unicode - for name in (TESTFN, unicode(TESTFN), unicode(TESTFN + '\t')): + names = [TESTFN] + if TESTFN_UNICODE: + names += [TESTFN_UNICODE, TESTFN_UNICODE + '\t'] + for name in names: try: f = open(name, "rr") except (IOError, ValueError): @@ -240,12 +247,13 @@ ' Test manually.') self.assertRaises(IOError, sys.stdin.truncate) + @requires_unicode def testUnicodeOpen(self): # verify repr works for unicode too - f = open(unicode(TESTFN), "w") - self.assertTrue(repr(f).startswith("" % clsname) - raw.name = "dummy" - self.assertEqual(repr(b), "<%s name=u'dummy'>" % clsname) + if support.have_unicode: + raw.name = "dummy" + self.assertEqual(repr(b), "<%s name=u'dummy'>" % clsname) raw.name = b"dummy" self.assertEqual(repr(b), "<%s name='dummy'>" % clsname) @@ -1836,6 +1840,7 @@ codecs.register(StatefulIncrementalDecoder.lookupTestDecoder) +@support.requires_unicode class StatefulIncrementalDecoderTest(unittest.TestCase): """ Make sure the StatefulIncrementalDecoder actually works. @@ -1879,6 +1884,7 @@ self.assertEqual(d.decode(b'oiabcd'), '') self.assertEqual(d.decode(b'', 1), 'abcd.') +@support.requires_unicode class TextIOWrapperTest(unittest.TestCase): def setUp(self): @@ -1923,9 +1929,10 @@ modname = self.TextIOWrapper.__module__ self.assertEqual(repr(t), "<%s.TextIOWrapper encoding='utf-8'>" % modname) - raw.name = "dummy" - self.assertEqual(repr(t), - "<%s.TextIOWrapper name=u'dummy' encoding='utf-8'>" % modname) + if support.have_unicode: + raw.name = "dummy" + self.assertEqual(repr(t), + "<%s.TextIOWrapper name=u'dummy' encoding='utf-8'>" % modname) raw.name = b"dummy" self.assertEqual(repr(t), "<%s.TextIOWrapper name='dummy' encoding='utf-8'>" % modname) @@ -1966,7 +1973,7 @@ # (4) replace b = self.BytesIO(b"abc\n\xff\n") t = self.TextIOWrapper(b, encoding="ascii", errors="replace") - self.assertEqual(t.read(), "abc\n\ufffd\n") + self.assertEqual(t.read(), support.u(br"abc\n\ufffd\n")) def test_encoding_errors_writing(self): # (1) default @@ -2154,7 +2161,7 @@ def multi_line_test(self, f, enc): f.seek(0) f.truncate() - sample = "s\xff\u0fff\uffff" + sample = support.u(br"s\xff\u0fff\uffff") wlines = [] for size in (0, 1, 2, 3, 4, 5, 30, 31, 32, 33, 62, 63, 64, 65, 1000): chars = [] @@ -2199,7 +2206,7 @@ u_prefix = "a" * prefix_size prefix = bytes(u_prefix.encode("utf-8")) self.assertEqual(len(u_prefix), len(prefix)) - u_suffix = "\u8888\n" + u_suffix = support.u(br"\u8888\n") suffix = bytes(u_suffix.encode("utf-8")) line = prefix + suffix f = self.open(support.TESTFN, "wb") @@ -2570,6 +2577,7 @@ yield +@support.requires_unicode class IncrementalNewlineDecoderTest(unittest.TestCase): def check_newline_decoding_utf8(self, decoder): @@ -2581,15 +2589,15 @@ decoder.setstate(state) self.assertEqual(decoder.decode(b, **kwargs), s) - _check_decode(b'\xe8\xa2\x88', "\u8888") + _check_decode(b'\xe8\xa2\x88', unichr(0x8888)) _check_decode(b'\xe8', "") _check_decode(b'\xa2', "") - _check_decode(b'\x88', "\u8888") + _check_decode(b'\x88', unichr(0x8888)) _check_decode(b'\xe8', "") _check_decode(b'\xa2', "") - _check_decode(b'\x88', "\u8888") + _check_decode(b'\x88', unichr(0x8888)) _check_decode(b'\xe8', "") self.assertRaises(UnicodeDecodeError, decoder.decode, b'', final=True) @@ -2608,10 +2616,10 @@ _check_decode(b'\r', "\n") _check_decode(b'\na', "\na") - _check_decode(b'\xe8\xa2\x88\r\n', "\u8888\n") - _check_decode(b'\xe8\xa2\x88', "\u8888") + _check_decode(b'\xe8\xa2\x88\r\n', support.u(br"\u8888\n")) + _check_decode(b'\xe8\xa2\x88', unichr(0x8888)) _check_decode(b'\n', "\n") - _check_decode(b'\xe8\xa2\x88\r', "\u8888") + _check_decode(b'\xe8\xa2\x88\r', unichr(0x8888)) _check_decode(b'\n', "\n") def check_newline_decoding(self, decoder, encoding): @@ -2667,9 +2675,9 @@ # Issue 5433: Excessive optimization in IncrementalNewlineDecoder def _check(dec): self.assertEqual(dec.newlines, None) - self.assertEqual(dec.decode("\u0D00"), "\u0D00") + self.assertEqual(dec.decode(unichr(0x0D00)), unichr(0x0D00)) self.assertEqual(dec.newlines, None) - self.assertEqual(dec.decode("\u0A00"), "\u0A00") + self.assertEqual(dec.decode(unichr(0x0A00)), unichr(0x0A00)) self.assertEqual(dec.newlines, None) dec = self.IncrementalNewlineDecoder(None, translate=False) _check(dec) @@ -2706,19 +2714,21 @@ self.assertEqual(f.mode, "wb") f.close() - f = self.open(support.TESTFN, "U") - self.assertEqual(f.name, support.TESTFN) - self.assertEqual(f.buffer.name, support.TESTFN) - self.assertEqual(f.buffer.raw.name, support.TESTFN) - self.assertEqual(f.mode, "U") - self.assertEqual(f.buffer.mode, "rb") - self.assertEqual(f.buffer.raw.mode, "rb") - f.close() + if support.have_unicode: + f = self.open(support.TESTFN, "U") + self.assertEqual(f.name, support.TESTFN) + self.assertEqual(f.buffer.name, support.TESTFN) + self.assertEqual(f.buffer.raw.name, support.TESTFN) + self.assertEqual(f.mode, "U") + self.assertEqual(f.buffer.mode, "rb") + self.assertEqual(f.buffer.raw.mode, "rb") + f.close() f = self.open(support.TESTFN, "w+") - self.assertEqual(f.mode, "w+") - self.assertEqual(f.buffer.mode, "rb+") # Does it really matter? - self.assertEqual(f.buffer.raw.mode, "rb+") + if support.have_unicode: + self.assertEqual(f.mode, "w+") + self.assertEqual(f.buffer.mode, "rb+") # Does it really matter? + self.assertEqual(f.buffer.raw.mode, "rb+") g = self.open(f.fileno(), "wb", closefd=False) self.assertEqual(g.mode, "wb") @@ -2779,40 +2789,45 @@ self.assertRaises(TypeError, self.BlockingIOError, 1, "", None) b = self.BlockingIOError(1, "") self.assertEqual(b.characters_written, 0) - class C(unicode): - pass - c = C("") - b = self.BlockingIOError(1, c) - c.b = b - b.c = c - wr = weakref.ref(c) - del c, b - support.gc_collect() - self.assertTrue(wr() is None, wr) + if support.have_unicode: + class C(unicode): + pass + c = C("") + b = self.BlockingIOError(1, c) + c.b = b + b.c = c + wr = weakref.ref(c) + del c, b + support.gc_collect() + self.assertTrue(wr() is None, wr) def test_abcs(self): # Test the visible base classes are ABCs. self.assertIsInstance(self.IOBase, abc.ABCMeta) self.assertIsInstance(self.RawIOBase, abc.ABCMeta) self.assertIsInstance(self.BufferedIOBase, abc.ABCMeta) - self.assertIsInstance(self.TextIOBase, abc.ABCMeta) + if support.have_unicode: + self.assertIsInstance(self.TextIOBase, abc.ABCMeta) def _check_abc_inheritance(self, abcmodule): with self.open(support.TESTFN, "wb", buffering=0) as f: self.assertIsInstance(f, abcmodule.IOBase) self.assertIsInstance(f, abcmodule.RawIOBase) self.assertNotIsInstance(f, abcmodule.BufferedIOBase) - self.assertNotIsInstance(f, abcmodule.TextIOBase) + if support.have_unicode: + self.assertNotIsInstance(f, abcmodule.TextIOBase) with self.open(support.TESTFN, "wb") as f: self.assertIsInstance(f, abcmodule.IOBase) self.assertNotIsInstance(f, abcmodule.RawIOBase) self.assertIsInstance(f, abcmodule.BufferedIOBase) - self.assertNotIsInstance(f, abcmodule.TextIOBase) + if support.have_unicode: + self.assertNotIsInstance(f, abcmodule.TextIOBase) with self.open(support.TESTFN, "w") as f: self.assertIsInstance(f, abcmodule.IOBase) self.assertNotIsInstance(f, abcmodule.RawIOBase) - self.assertNotIsInstance(f, abcmodule.BufferedIOBase) - self.assertIsInstance(f, abcmodule.TextIOBase) + if support.have_unicode: + self.assertNotIsInstance(f, abcmodule.BufferedIOBase) + self.assertIsInstance(f, abcmodule.TextIOBase) def test_abc_inheritance(self): # Test implementations inherit from their respective ABCs @@ -3011,6 +3026,7 @@ os.close(w) os.close(r) + @support.requires_unicode def test_interrupterd_read_retry_buffered(self): self.check_interrupted_read_retry(lambda x: x.decode('latin1'), mode="rb") @@ -3110,7 +3126,9 @@ # classes in the __dict__ of each test. mocks = (MockRawIO, MisbehavedRawIO, MockFileIO, CloseFailureIO, MockNonBlockWriterIO, MockRawIOWithoutRead) - all_members = io.__all__ + ["IncrementalNewlineDecoder"] + all_members = io.__all__ + if support.have_unicode: + all_members = all_members + ["IncrementalNewlineDecoder"] c_io_ns = dict((name, getattr(io, name)) for name in all_members) py_io_ns = dict((name, getattr(pyio, name)) for name in all_members) globs = globals() diff -r cf70f030a744 Lib/test/test_memoryio.py --- a/Lib/test/test_memoryio.py Wed Jun 18 23:07:46 2014 -0400 +++ b/Lib/test/test_memoryio.py Mon Jun 23 23:07:05 2014 +0300 @@ -398,9 +398,14 @@ UnsupportedOperation = pyio.UnsupportedOperation - @staticmethod - def buftype(s): - return s.encode("ascii") + if support.have_unicode: + @staticmethod + def buftype(s): + return s.encode("ascii") + else: + @staticmethod + def buftype(s): + return s ioclass = pyio.BytesIO EOF = b"" @@ -460,6 +465,7 @@ memio.seek(1, 1) self.assertEqual(memio.read(), buf[1:]) + @support.requires_unicode def test_unicode(self): memio = self.ioclass() @@ -625,36 +631,37 @@ self.assertEqual(memio.getvalue(), "a\nb\n") -class PyStringIOTest(MemoryTestMixin, MemorySeekTestMixin, +if support.have_unicode: + class PyStringIOTest(MemoryTestMixin, MemorySeekTestMixin, TextIOTestMixin, unittest.TestCase): - buftype = unicode - ioclass = pyio.StringIO - UnsupportedOperation = pyio.UnsupportedOperation - EOF = "" + buftype = unicode + ioclass = pyio.StringIO + UnsupportedOperation = pyio.UnsupportedOperation + EOF = "" - def test_lone_surrogates(self): - # Issue #20424 - surrogate = unichr(0xd800) - memio = self.ioclass(surrogate) - self.assertEqual(memio.read(), surrogate) + def test_lone_surrogates(self): + # Issue #20424 + surrogate = unichr(0xd800) + memio = self.ioclass(surrogate) + self.assertEqual(memio.read(), surrogate) - memio = self.ioclass() - memio.write(surrogate) - self.assertEqual(memio.getvalue(), surrogate) + memio = self.ioclass() + memio.write(surrogate) + self.assertEqual(memio.getvalue(), surrogate) -class PyStringIOPickleTest(TextIOTestMixin, unittest.TestCase): - """Test if pickle restores properly the internal state of StringIO. - """ - buftype = unicode - UnsupportedOperation = pyio.UnsupportedOperation - EOF = "" + class PyStringIOPickleTest(TextIOTestMixin, unittest.TestCase): + """Test if pickle restores properly the internal state of StringIO. + """ + buftype = unicode + UnsupportedOperation = pyio.UnsupportedOperation + EOF = "" - class ioclass(pyio.StringIO): - def __new__(cls, *args, **kwargs): - return pickle.loads(pickle.dumps(pyio.StringIO(*args, **kwargs))) - def __init__(self, *args, **kwargs): - pass + class ioclass(pyio.StringIO): + def __new__(cls, *args, **kwargs): + return pickle.loads(pickle.dumps(pyio.StringIO(*args, **kwargs))) + def __init__(self, *args, **kwargs): + pass class CBytesIOTest(PyBytesIOTest): @@ -683,7 +690,8 @@ memio.__setstate__((bytearray(b"no error"), 0, None)) memio.__setstate__((b"no error", 0, {'spam': 3})) self.assertRaises(ValueError, memio.__setstate__, (b"", -1, None)) - self.assertRaises(TypeError, memio.__setstate__, ("unicode", 0, None)) + if support.have_unicode: + self.assertRaises(TypeError, memio.__setstate__, ("unicode", 0, None)) self.assertRaises(TypeError, memio.__setstate__, (b"", 0.0, None)) self.assertRaises(TypeError, memio.__setstate__, (b"", 0, 0)) self.assertRaises(TypeError, memio.__setstate__, (b"len-test", 0)) @@ -703,68 +711,71 @@ check(io.BytesIO(b'a'), basesize + 1 + 1 ) check(io.BytesIO(b'a' * 1000), basesize + 1000 + 1 ) -class CStringIOTest(PyStringIOTest): - ioclass = io.StringIO - UnsupportedOperation = io.UnsupportedOperation +if support.have_unicode: + class CStringIOTest(PyStringIOTest): + ioclass = io.StringIO + UnsupportedOperation = io.UnsupportedOperation - # XXX: For the Python version of io.StringIO, this is highly - # dependent on the encoding used for the underlying buffer. - def test_widechar(self): - buf = self.buftype("\U0002030a\U00020347") - memio = self.ioclass(buf) + # XXX: For the Python version of io.StringIO, this is highly + # dependent on the encoding used for the underlying buffer. + def test_widechar(self): + buf = self.buftype(support.u(br"\U0002030a\U00020347")) + memio = self.ioclass(buf) - self.assertEqual(memio.getvalue(), buf) - self.assertEqual(memio.write(buf), len(buf)) - self.assertEqual(memio.tell(), len(buf)) - self.assertEqual(memio.getvalue(), buf) - self.assertEqual(memio.write(buf), len(buf)) - self.assertEqual(memio.tell(), len(buf) * 2) - self.assertEqual(memio.getvalue(), buf + buf) + self.assertEqual(memio.getvalue(), buf) + self.assertEqual(memio.write(buf), len(buf)) + self.assertEqual(memio.tell(), len(buf)) + self.assertEqual(memio.getvalue(), buf) + self.assertEqual(memio.write(buf), len(buf)) + self.assertEqual(memio.tell(), len(buf) * 2) + self.assertEqual(memio.getvalue(), buf + buf) - def test_getstate(self): - memio = self.ioclass() - state = memio.__getstate__() - self.assertEqual(len(state), 4) - self.assertIsInstance(state[0], unicode) - self.assertIsInstance(state[1], str) - self.assertIsInstance(state[2], int) - self.assertTrue(isinstance(state[3], dict) or state[3] is None) - memio.close() - self.assertRaises(ValueError, memio.__getstate__) + def test_getstate(self): + memio = self.ioclass() + state = memio.__getstate__() + self.assertEqual(len(state), 4) + self.assertIsInstance(state[0], unicode) + self.assertIsInstance(state[1], str) + self.assertIsInstance(state[2], int) + self.assertTrue(isinstance(state[3], dict) or state[3] is None) + memio.close() + self.assertRaises(ValueError, memio.__getstate__) - def test_setstate(self): - # This checks whether __setstate__ does proper input validation. - memio = self.ioclass() - memio.__setstate__(("no error", "\n", 0, None)) - memio.__setstate__(("no error", "", 0, {'spam': 3})) - self.assertRaises(ValueError, memio.__setstate__, ("", "f", 0, None)) - self.assertRaises(ValueError, memio.__setstate__, ("", "", -1, None)) - self.assertRaises(TypeError, memio.__setstate__, (b"", "", 0, None)) - # trunk is more tolerant than py3k on the type of the newline param - #self.assertRaises(TypeError, memio.__setstate__, ("", b"", 0, None)) - self.assertRaises(TypeError, memio.__setstate__, ("", "", 0.0, None)) - self.assertRaises(TypeError, memio.__setstate__, ("", "", 0, 0)) - self.assertRaises(TypeError, memio.__setstate__, ("len-test", 0)) - self.assertRaises(TypeError, memio.__setstate__) - self.assertRaises(TypeError, memio.__setstate__, 0) - memio.close() - self.assertRaises(ValueError, memio.__setstate__, ("closed", "", 0, None)) + def test_setstate(self): + # This checks whether __setstate__ does proper input validation. + memio = self.ioclass() + memio.__setstate__(("no error", "\n", 0, None)) + memio.__setstate__(("no error", "", 0, {'spam': 3})) + self.assertRaises(ValueError, memio.__setstate__, ("", "f", 0, None)) + self.assertRaises(ValueError, memio.__setstate__, ("", "", -1, None)) + self.assertRaises(TypeError, memio.__setstate__, (b"", "", 0, None)) + # trunk is more tolerant than py3k on the type of the newline param + #self.assertRaises(TypeError, memio.__setstate__, ("", b"", 0, None)) + self.assertRaises(TypeError, memio.__setstate__, ("", "", 0.0, None)) + self.assertRaises(TypeError, memio.__setstate__, ("", "", 0, 0)) + self.assertRaises(TypeError, memio.__setstate__, ("len-test", 0)) + self.assertRaises(TypeError, memio.__setstate__) + self.assertRaises(TypeError, memio.__setstate__, 0) + memio.close() + self.assertRaises(ValueError, memio.__setstate__, ("closed", "", 0, None)) -class CStringIOPickleTest(PyStringIOPickleTest): - UnsupportedOperation = io.UnsupportedOperation + class CStringIOPickleTest(PyStringIOPickleTest): + UnsupportedOperation = io.UnsupportedOperation - class ioclass(io.StringIO): - def __new__(cls, *args, **kwargs): - return pickle.loads(pickle.dumps(io.StringIO(*args, **kwargs), + class ioclass(io.StringIO): + def __new__(cls, *args, **kwargs): + return pickle.loads(pickle.dumps(io.StringIO(*args, **kwargs), protocol=2)) - def __init__(self, *args, **kwargs): - pass + def __init__(self, *args, **kwargs): + pass def test_main(): - tests = [PyBytesIOTest, PyStringIOTest, CBytesIOTest, CStringIOTest, - PyStringIOPickleTest, CStringIOPickleTest] + tests = [PyBytesIOTest, CBytesIOTest] + if support.have_unicode: + tests += [PyStringIOTest, CStringIOTest, + PyStringIOPickleTest, CStringIOPickleTest] support.run_unittest(*tests) if __name__ == '__main__': diff -r cf70f030a744 Lib/test/test_support.py --- a/Lib/test/test_support.py Wed Jun 18 23:07:46 2014 -0400 +++ b/Lib/test/test_support.py Mon Jun 23 23:07:05 2014 +0300 @@ -498,13 +498,18 @@ # for a discussion of this number). SOCK_MAX_SIZE = 16 * 1024 * 1024 + 1 +is_jython = sys.platform.startswith('java') + try: unicode have_unicode = True except NameError: have_unicode = False -is_jython = sys.platform.startswith('java') +requires_unicode = unittest.skipUnless(have_unicode, 'no unicode support') + +def u(s): + return unicode(s, 'unicode-escape') # FS_NONASCII: non-ASCII Unicode character encodable by # sys.getfilesystemencoding(), or None if there is no such character. diff -r cf70f030a744 Modules/_io/_iomodule.c --- a/Modules/_io/_iomodule.c Wed Jun 18 23:07:46 2014 -0400 +++ b/Modules/_io/_iomodule.c Mon Jun 23 23:07:05 2014 +0300 @@ -312,7 +312,10 @@ return NULL; } - if (!PyUnicode_Check(file) && + if ( +#ifdef Py_USING_UNICODE + !PyUnicode_Check(file) && +#endif !PyBytes_Check(file) && !PyNumber_Check(file)) { PyObject *repr = PyObject_Repr(file); @@ -418,7 +421,11 @@ return NULL; result = raw; +#ifdef Py_USING_UNICODE modeobj = PyUnicode_FromString(mode); +#else + modeobj = PyString_FromString(mode); +#endif if (modeobj == NULL) goto error; @@ -502,6 +509,7 @@ Py_DECREF(raw); +#ifdef Py_USING_UNICODE /* if binary, returns the buffered file */ if (binary) { Py_DECREF(modeobj); @@ -521,6 +529,7 @@ if (PyObject_SetAttrString(wrapper, "mode", modeobj) < 0) goto error; +#endif Py_DECREF(modeobj); return result; @@ -679,7 +688,9 @@ ADD_TYPE(&PyIOBase_Type, "_IOBase"); ADD_TYPE(&PyRawIOBase_Type, "_RawIOBase"); ADD_TYPE(&PyBufferedIOBase_Type, "_BufferedIOBase"); +#ifdef Py_USING_UNICODE ADD_TYPE(&PyTextIOBase_Type, "_TextIOBase"); +#endif /* Implementation of concrete IO objects. */ /* FileIO */ @@ -690,9 +701,11 @@ PyBytesIO_Type.tp_base = &PyBufferedIOBase_Type; ADD_TYPE(&PyBytesIO_Type, "BytesIO"); +#ifdef Py_USING_UNICODE /* StringIO */ PyStringIO_Type.tp_base = &PyTextIOBase_Type; ADD_TYPE(&PyStringIO_Type, "StringIO"); +#endif /* BufferedReader */ PyBufferedReader_Type.tp_base = &PyBufferedIOBase_Type; @@ -710,12 +723,14 @@ PyBufferedRandom_Type.tp_base = &PyBufferedIOBase_Type; ADD_TYPE(&PyBufferedRandom_Type, "BufferedRandom"); +#ifdef Py_USING_UNICODE /* TextIOWrapper */ PyTextIOWrapper_Type.tp_base = &PyTextIOBase_Type; ADD_TYPE(&PyTextIOWrapper_Type, "TextIOWrapper"); /* IncrementalNewlineDecoder */ ADD_TYPE(&PyIncrementalNewlineDecoder_Type, "IncrementalNewlineDecoder"); +#endif /* Interned strings */ if (!(_PyIO_str_close = PyString_InternFromString("close"))) @@ -765,7 +780,11 @@ if (!(_PyIO_str_writable = PyString_InternFromString("writable"))) goto fail; +#ifdef Py_USING_UNICODE if (!(_PyIO_empty_str = PyUnicode_FromStringAndSize(NULL, 0))) +#else + if (!(_PyIO_empty_str = PyString_FromStringAndSize(NULL, 0))) +#endif goto fail; if (!(_PyIO_empty_bytes = PyBytes_FromStringAndSize(NULL, 0))) goto fail; diff -r cf70f030a744 Modules/_io/_iomodule.h --- a/Modules/_io/_iomodule.h Wed Jun 18 23:07:46 2014 -0400 +++ b/Modules/_io/_iomodule.h Mon Jun 23 23:07:05 2014 +0300 @@ -6,18 +6,24 @@ extern PyTypeObject PyIOBase_Type; extern PyTypeObject PyRawIOBase_Type; extern PyTypeObject PyBufferedIOBase_Type; +#ifdef Py_USING_UNICODE extern PyTypeObject PyTextIOBase_Type; +#endif /* Concrete classes */ extern PyTypeObject PyFileIO_Type; extern PyTypeObject PyBytesIO_Type; +#ifdef Py_USING_UNICODE extern PyTypeObject PyStringIO_Type; +#endif extern PyTypeObject PyBufferedReader_Type; extern PyTypeObject PyBufferedWriter_Type; extern PyTypeObject PyBufferedRWPair_Type; extern PyTypeObject PyBufferedRandom_Type; +#ifdef Py_USING_UNICODE extern PyTypeObject PyTextIOWrapper_Type; extern PyTypeObject PyIncrementalNewlineDecoder_Type; +#endif extern int _PyIO_ConvertSsize_t(PyObject *, void *); @@ -45,6 +51,7 @@ extern PyObject *_PyIncrementalNewlineDecoder_decode( PyObject *self, PyObject *input, int final); +#ifdef Py_USING_UNICODE /* Finds the first line ending between `start` and `end`. If found, returns the index after the line ending and doesn't touch `*consumed`. @@ -56,6 +63,7 @@ extern Py_ssize_t _PyIO_find_line_ending( int translated, int universal, PyObject *readnl, Py_UNICODE *start, Py_UNICODE *end, Py_ssize_t *consumed); +#endif /* Return 1 if an EnvironmentError with errno == EINTR is set (and then clears the error indicator), 0 otherwise. diff -r cf70f030a744 Modules/_io/fileio.c --- a/Modules/_io/fileio.c Wed Jun 18 23:07:46 2014 -0400 +++ b/Modules/_io/fileio.c Mon Jun 23 23:07:05 2014 +0300 @@ -182,7 +182,7 @@ PyObject *nameobj, *stringobj = NULL; char *mode = "r"; char *s; -#ifdef MS_WINDOWS +#if defined(MS_WINDOWS) && defined(Py_USING_UNICODE) Py_UNICODE *widename = NULL; #endif int ret = 0; @@ -223,7 +223,7 @@ PyErr_Clear(); } -#ifdef MS_WINDOWS +#if defined(MS_WINDOWS) && defined(Py_USING_UNICODE) if (PyUnicode_Check(nameobj)) widename = PyUnicode_AS_UNICODE(nameobj); if (widename == NULL) @@ -236,6 +236,7 @@ return -1; } else { +#ifdef Py_USING_UNICODE PyObject *u = PyUnicode_FromObject(nameobj); if (u == NULL) @@ -252,6 +253,10 @@ goto error; } name = PyBytes_AS_STRING(stringobj); +#else + PyErr_SetString(PyExc_TypeError, "need string or int"); + return -1; +#endif } } @@ -338,7 +343,7 @@ Py_END_ALLOW_THREADS fd_is_own = 1; if (self->fd < 0) { -#ifdef MS_WINDOWS +#if defined(MS_WINDOWS) && defined(Py_USING_UNICODE) if (widename != NULL) PyErr_SetFromErrnoWithUnicodeFilename(PyExc_IOError, widename); else @@ -1058,7 +1063,11 @@ static PyObject * get_mode(fileio *self, void *closure) { +#ifdef Py_USING_UNICODE return PyUnicode_FromString(mode_string(self)); +#else + return PyString_FromString(mode_string(self)); +#endif } static PyGetSetDef fileio_getsetlist[] = { diff -r cf70f030a744 Modules/_io/stringio.c --- a/Modules/_io/stringio.c Wed Jun 18 23:07:46 2014 -0400 +++ b/Modules/_io/stringio.c Mon Jun 23 23:07:05 2014 +0300 @@ -3,6 +3,8 @@ #include "structmember.h" #include "_iomodule.h" +#ifdef Py_USING_UNICODE + /* Implementation note: the buffer is always at least one character longer than the enclosed string, for proper functioning of _PyIO_find_line_ending. */ @@ -893,3 +895,5 @@ 0, /*tp_alloc*/ stringio_new, /*tp_new*/ }; + +#endif \ No newline at end of file diff -r cf70f030a744 Modules/_io/textio.c --- a/Modules/_io/textio.c Wed Jun 18 23:07:46 2014 -0400 +++ b/Modules/_io/textio.c Mon Jun 23 23:07:05 2014 +0300 @@ -11,6 +11,8 @@ #include "structmember.h" #include "_iomodule.h" +#ifdef Py_USING_UNICODE + /* TextIOBase */ PyDoc_STRVAR(textiobase_doc, @@ -2677,3 +2679,5 @@ 0, /* tp_alloc */ PyType_GenericNew, /* tp_new */ }; + +#endif \ No newline at end of file diff -r cf70f030a744 Modules/_ssl.c --- a/Modules/_ssl.c Wed Jun 18 23:07:46 2014 -0400 +++ b/Modules/_ssl.c Mon Jun 23 23:07:05 2014 +0300 @@ -561,8 +561,12 @@ Py_DECREF(name_obj); goto fail; } +#ifdef Py_USING_UNICODE value_obj = PyUnicode_DecodeUTF8((char *) valuebuf, buflen, "strict"); +#else + value_obj = PyString_FromStringAndSize((char *) valuebuf, buflen); +#endif OPENSSL_free(valuebuf); if (value_obj == NULL) { Py_DECREF(name_obj); diff -r cf70f030a744 Modules/_struct.c --- a/Modules/_struct.c Wed Jun 18 23:07:46 2014 -0400 +++ b/Modules/_struct.c Mon Jun 23 23:07:05 2014 +0300 @@ -1380,6 +1380,7 @@ Py_CLEAR(soself->s_format); soself->s_format = o_format; } +#ifdef Py_USING_UNICODE else if (PyUnicode_Check(o_format)) { PyObject *str = PyUnicode_AsEncodedString(o_format, "ascii", NULL); if (str == NULL) @@ -1387,6 +1388,7 @@ Py_CLEAR(soself->s_format); soself->s_format = str; } +#endif else { PyErr_Format(PyExc_TypeError, "Struct() argument 1 must be string, not %s", diff -r cf70f030a744 Modules/_testcapimodule.c --- a/Modules/_testcapimodule.c Wed Jun 18 23:07:46 2014 -0400 +++ b/Modules/_testcapimodule.c Mon Jun 23 23:07:05 2014 +0300 @@ -1235,7 +1235,12 @@ static PyObject * test_null_strings(PyObject *self) { - PyObject *o1 = PyObject_Str(NULL), *o2 = PyObject_Unicode(NULL); + PyObject *o1 = PyObject_Str(NULL); +#ifdef Py_USING_UNICODE + PyObject *o2 = PyObject_Unicode(NULL); +#else + PyObject *o2 = PyObject_Str(NULL); +#endif PyObject *tuple = PyTuple_Pack(2, o1, o2); Py_XDECREF(o1); Py_XDECREF(o2); @@ -1790,7 +1795,9 @@ METH_NOARGS}, {"test_long_numbits", (PyCFunction)test_long_numbits, METH_NOARGS}, {"test_k_code", (PyCFunction)test_k_code, METH_NOARGS}, +#ifdef Py_USING_UNICODE {"test_empty_argparse", (PyCFunction)test_empty_argparse,METH_NOARGS}, +#endif {"test_null_strings", (PyCFunction)test_null_strings, METH_NOARGS}, {"test_string_from_format", (PyCFunction)test_string_from_format, METH_NOARGS}, {"test_with_docstring", (PyCFunction)test_with_docstring, METH_NOARGS, @@ -1815,6 +1822,8 @@ {"test_long_long_and_overflow", (PyCFunction)test_long_long_and_overflow, METH_NOARGS}, {"test_L_code", (PyCFunction)test_L_code, METH_NOARGS}, +#endif +#ifdef Py_USING_UNICODE {"codec_incrementalencoder", (PyCFunction)codec_incrementalencoder, METH_VARARGS}, {"codec_incrementaldecoder", diff -r cf70f030a744 Modules/datetimemodule.c --- a/Modules/datetimemodule.c Wed Jun 18 23:07:46 2014 -0400 +++ b/Modules/datetimemodule.c Mon Jun 23 23:07:05 2014 +0300 @@ -2555,10 +2555,12 @@ /* If format is zero length, return str(self) */ if (PyString_GET_SIZE(format) == 0) return PyObject_Str((PyObject *)self); +#ifdef Py_USING_UNICODE } else if (PyUnicode_Check(format)) { /* If format is zero length, return str(self) */ if (PyUnicode_GET_SIZE(format) == 0) return PyObject_Unicode((PyObject *)self); +#endif } else { PyErr_Format(PyExc_ValueError, "__format__ expects str or unicode, not %.200s", diff -r cf70f030a744 Modules/operator.c --- a/Modules/operator.c Wed Jun 18 23:07:46 2014 -0400 +++ b/Modules/operator.c Mon Jun 23 23:07:05 2014 +0300 @@ -307,6 +307,7 @@ return NULL; } +#ifdef Py_USING_UNICODE /* Unicode string */ if (PyUnicode_Check(a) && PyUnicode_Check(b)) { rc = _tscmp((const unsigned char *)PyUnicode_AS_DATA(a), @@ -315,7 +316,9 @@ PyUnicode_GET_DATA_SIZE(b)); } /* fallback to buffer interface for bytes, bytesarray and other */ - else { + else +#endif + { Py_buffer view_a; Py_buffer view_b; diff -r cf70f030a744 setup.py --- a/setup.py Wed Jun 18 23:07:46 2014 -0400 +++ b/setup.py Mon Jun 23 23:07:05 2014 +0300 @@ -604,7 +604,10 @@ # _functools exts.append( Extension("_functools", ["_functoolsmodule.c"]) ) # _json speedups - exts.append( Extension("_json", ["_json.c"]) ) + if have_unicode: + exts.append( Extension("_json", ["_json.c"]) ) + else: + missing.append('_json') # Python C API test module exts.append( Extension('_testcapi', ['_testcapimodule.c'], depends=['testcapi_long.h']) )