183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport sys
283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport os
383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport unittest
483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport itertools
583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport select
683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport signal
783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport subprocess
883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport time
983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom array import array
1083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom weakref import proxy
1183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehtry:
1283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    import threading
1383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehexcept ImportError:
1483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    threading = None
1583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
1683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom test import test_support
1783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom test.test_support import TESTFN, run_unittest
1883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom UserList import UserList
1983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
2083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass AutoFileTests(unittest.TestCase):
2183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # file tests for which a test file is automatically set up
2283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
2383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def setUp(self):
2483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.f = open(TESTFN, 'wb')
2583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
2683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def tearDown(self):
2783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if self.f:
2883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.f.close()
2983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        os.remove(TESTFN)
3083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
3183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def testWeakRefs(self):
3283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # verify weak references
3383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        p = proxy(self.f)
3483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        p.write('teststring')
3583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(self.f.tell(), p.tell())
3683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.f.close()
3783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.f = None
3883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertRaises(ReferenceError, getattr, p, 'tell')
3983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
4083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def testAttributes(self):
4183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # verify expected attributes exist
4283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f = self.f
4383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        with test_support.check_py3k_warnings():
4483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            softspace = f.softspace
4583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.name     # merely shouldn't blow up
4683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.mode     # ditto
4783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.closed   # ditto
4883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
4983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        with test_support.check_py3k_warnings():
5083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # verify softspace is writable
5183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.softspace = softspace    # merely shouldn't blow up
5283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
5383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # verify the others aren't
5483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for attr in 'name', 'mode', 'closed':
5583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertRaises((AttributeError, TypeError), setattr, f, attr, 'oops')
5683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
5783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def testReadinto(self):
5883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # verify readinto
5983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.f.write('12')
6083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.f.close()
6183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        a = array('c', 'x'*10)
6283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.f = open(TESTFN, 'rb')
6383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        n = self.f.readinto(a)
6483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual('12', a.tostring()[:n])
6583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
6683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def testWritelinesUserList(self):
6783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # verify writelines with instance sequence
6883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        l = UserList(['1', '2'])
6983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.f.writelines(l)
7083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.f.close()
7183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.f = open(TESTFN, 'rb')
7283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        buf = self.f.read()
7383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(buf, '12')
7483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
7583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def testWritelinesIntegers(self):
7683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # verify writelines with integers
7783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertRaises(TypeError, self.f.writelines, [1, 2, 3])
7883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
7983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def testWritelinesIntegersUserList(self):
8083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # verify writelines with integers in UserList
8183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        l = UserList([1,2,3])
8283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertRaises(TypeError, self.f.writelines, l)
8383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
8483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def testWritelinesNonString(self):
8583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # verify writelines with non-string object
8683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        class NonString:
8783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            pass
8883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
8983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertRaises(TypeError, self.f.writelines,
9083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                          [NonString(), NonString()])
9183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
9283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def testRepr(self):
9383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # verify repr works
9483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertTrue(repr(self.f).startswith("<open file '" + TESTFN))
9583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # see issue #14161
9683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Windows doesn't like \r\n\t" in the file name, but ' is ok
9783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        fname = 'xx\rxx\nxx\'xx"xx' if sys.platform != "win32" else "xx'xx"
9883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        with open(fname, 'w') as f:
9983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.addCleanup(os.remove, fname)
10083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertTrue(repr(f).startswith(
10183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    "<open file %r, mode 'w' at" % fname))
10283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
10383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def testErrors(self):
10483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.f.close()
10583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.f = open(TESTFN, 'rb')
10683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f = self.f
10783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(f.name, TESTFN)
10883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertTrue(not f.isatty())
10983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertTrue(not f.closed)
11083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
11183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertRaises(TypeError, f.readinto, "")
11283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.close()
11383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertTrue(f.closed)
11483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
11583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def testMethods(self):
11683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        methods = ['fileno', 'flush', 'isatty', 'next', 'read', 'readinto',
11783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                   'readline', 'readlines', 'seek', 'tell', 'truncate',
11883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                   'write', '__iter__']
11983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        deprecated_methods = ['xreadlines']
12083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if sys.platform.startswith('atheos'):
12183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            methods.remove('truncate')
12283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
12383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # __exit__ should close the file
12483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.f.__exit__(None, None, None)
12583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertTrue(self.f.closed)
12683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
12783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for methodname in methods:
12883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            method = getattr(self.f, methodname)
12983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # should raise on closed file
13083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertRaises(ValueError, method)
13183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        with test_support.check_py3k_warnings():
13283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            for methodname in deprecated_methods:
13383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                method = getattr(self.f, methodname)
13483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.assertRaises(ValueError, method)
13583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertRaises(ValueError, self.f.writelines, [])
13683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
13783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # file is closed, __exit__ shouldn't do anything
13883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(self.f.__exit__(None, None, None), None)
13983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # it must also return None if an exception was given
14083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
14183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            1 // 0
14283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        except:
14383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(self.f.__exit__(*sys.exc_info()), None)
14483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
14583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def testReadWhenWriting(self):
14683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertRaises(IOError, self.f.read)
14783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
14883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def testNastyWritelinesGenerator(self):
14983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        def nasty():
15083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            for i in range(5):
15183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                if i == 3:
15283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    self.f.close()
15383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                yield str(i)
15483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertRaises(ValueError, self.f.writelines, nasty())
15583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
15683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def testIssue5677(self):
15783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Remark: Do not perform more than one test per open file,
15883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # since that does NOT catch the readline error on Windows.
15983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        data = 'xxx'
16083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for mode in ['w', 'wb', 'a', 'ab']:
16183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            for attr in ['read', 'readline', 'readlines']:
16283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.f = open(TESTFN, mode)
16383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.f.write(data)
16483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.assertRaises(IOError, getattr(self.f, attr))
16583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.f.close()
16683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
16783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.f = open(TESTFN, mode)
16883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.f.write(data)
16983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertRaises(IOError, lambda: [line for line in self.f])
17083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.f.close()
17183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
17283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.f = open(TESTFN, mode)
17383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.f.write(data)
17483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertRaises(IOError, self.f.readinto, bytearray(len(data)))
17583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.f.close()
17683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
17783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for mode in ['r', 'rb', 'U', 'Ub', 'Ur', 'rU', 'rbU', 'rUb']:
17883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.f = open(TESTFN, mode)
17983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertRaises(IOError, self.f.write, data)
18083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.f.close()
18183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
18283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.f = open(TESTFN, mode)
18383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertRaises(IOError, self.f.writelines, [data, data])
18483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.f.close()
18583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
18683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.f = open(TESTFN, mode)
18783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertRaises(IOError, self.f.truncate)
18883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.f.close()
18983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
19083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass OtherFileTests(unittest.TestCase):
19183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
19283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def testOpenDir(self):
19383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        this_dir = os.path.dirname(__file__) or os.curdir
19483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for mode in (None, "w"):
19583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            try:
19683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                if mode:
19783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    f = open(this_dir, mode)
19883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                else:
19983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    f = open(this_dir)
20083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            except IOError as e:
20183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.assertEqual(e.filename, this_dir)
20283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            else:
20383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.fail("opening a directory didn't raise an IOError")
20483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
20583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def testModeStrings(self):
20683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # check invalid mode strings
20783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for mode in ("", "aU", "wU+"):
20883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            try:
20983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                f = open(TESTFN, mode)
21083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            except ValueError:
21183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                pass
21283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            else:
21383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                f.close()
21483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.fail('%r is an invalid file mode' % mode)
21583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
21683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Some invalid modes fail on Windows, but pass on Unix
21783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Issue3965: avoid a crash on Windows when filename is unicode
21883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for name in (TESTFN, unicode(TESTFN), unicode(TESTFN + '\t')):
21983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            try:
22083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                f = open(name, "rr")
22183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            except (IOError, ValueError):
22283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                pass
22383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            else:
22483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                f.close()
22583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
22683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def testStdin(self):
22783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # This causes the interpreter to exit on OSF1 v5.1.
22883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if sys.platform != 'osf1V5':
22983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertRaises(IOError, sys.stdin.seek, -1)
23083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
23183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            print >>sys.__stdout__, (
23283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                '  Skipping sys.stdin.seek(-1), it may crash the interpreter.'
23383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                ' Test manually.')
23483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertRaises(IOError, sys.stdin.truncate)
23583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
23683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def testUnicodeOpen(self):
23783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # verify repr works for unicode too
23883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f = open(unicode(TESTFN), "w")
23983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertTrue(repr(f).startswith("<open file u'" + TESTFN))
24083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f.close()
24183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        os.unlink(TESTFN)
24283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
24383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def testBadModeArgument(self):
24483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # verify that we get a sensible error message for bad mode argument
24583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        bad_mode = "qwerty"
24683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
24783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f = open(TESTFN, bad_mode)
24883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        except ValueError, msg:
24983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if msg.args[0] != 0:
25083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                s = str(msg)
25183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                if TESTFN in s or bad_mode not in s:
25283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    self.fail("bad error message for invalid mode: %s" % s)
25383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # if msg.args[0] == 0, we're probably on Windows where there may
25483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # be no obvious way to discover why open() failed.
25583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
25683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.close()
25783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.fail("no error for invalid mode: %s" % bad_mode)
25883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
25983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def testSetBufferSize(self):
26083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # make sure that explicitly setting the buffer size doesn't cause
26183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # misbehaviour especially with repeated close() calls
26283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for s in (-1, 0, 1, 512):
26383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            try:
26483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                f = open(TESTFN, 'w', s)
26583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                f.write(str(s))
26683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                f.close()
26783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                f.close()
26883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                f = open(TESTFN, 'r', s)
26983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                d = int(f.read())
27083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                f.close()
27183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                f.close()
27283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            except IOError, msg:
27383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.fail('error setting buffer size %d: %s' % (s, str(msg)))
27483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(d, s)
27583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
27683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def testTruncateOnWindows(self):
27783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        os.unlink(TESTFN)
27883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
27983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        def bug801631():
28083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # SF bug <http://www.python.org/sf/801631>
28183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # "file.truncate fault on windows"
28283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f = open(TESTFN, 'wb')
28383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.write('12345678901')   # 11 bytes
28483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.close()
28583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
28683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f = open(TESTFN,'rb+')
28783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            data = f.read(5)
28883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if data != '12345':
28983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.fail("Read on file opened for update failed %r" % data)
29083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if f.tell() != 5:
29183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.fail("File pos after read wrong %d" % f.tell())
29283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
29383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.truncate()
29483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if f.tell() != 5:
29583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.fail("File pos after ftruncate wrong %d" % f.tell())
29683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
29783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.close()
29883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            size = os.path.getsize(TESTFN)
29983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if size != 5:
30083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.fail("File size after ftruncate wrong %d" % size)
30183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
30283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
30383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            bug801631()
30483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        finally:
30583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            os.unlink(TESTFN)
30683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
30783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def testIteration(self):
30883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Test the complex interaction when mixing file-iteration and the
30983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # various read* methods. Ostensibly, the mixture could just be tested
31083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # to work when it should work according to the Python language,
31183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # instead of fail when it should fail according to the current CPython
31283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # implementation.  People don't always program Python the way they
31383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # should, though, and the implemenation might change in subtle ways,
31483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # so we explicitly test for errors, too; the test will just have to
31583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # be updated when the implementation changes.
31683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        dataoffset = 16384
31783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        filler = "ham\n"
31883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        assert not dataoffset % len(filler), \
31983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            "dataoffset must be multiple of len(filler)"
32083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        nchunks = dataoffset // len(filler)
32183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        testlines = [
32283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            "spam, spam and eggs\n",
32383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            "eggs, spam, ham and spam\n",
32483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            "saussages, spam, spam and eggs\n",
32583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            "spam, ham, spam and eggs\n",
32683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            "spam, spam, spam, spam, spam, ham, spam\n",
32783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            "wonderful spaaaaaam.\n"
32883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        ]
32983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        methods = [("readline", ()), ("read", ()), ("readlines", ()),
33083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                   ("readinto", (array("c", " "*100),))]
33183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
33283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
33383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Prepare the testfile
33483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            bag = open(TESTFN, "w")
33583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            bag.write(filler * nchunks)
33683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            bag.writelines(testlines)
33783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            bag.close()
33883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Test for appropriate errors mixing read* and iteration
33983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            for methodname, args in methods:
34083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                f = open(TESTFN)
34183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                if f.next() != filler:
34283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    self.fail, "Broken testfile"
34383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                meth = getattr(f, methodname)
34483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                try:
34583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    meth(*args)
34683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                except ValueError:
34783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    pass
34883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                else:
34983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    self.fail("%s%r after next() didn't raise ValueError" %
35083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                                     (methodname, args))
35183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                f.close()
35283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
35383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Test to see if harmless (by accident) mixing of read* and
35483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # iteration still works. This depends on the size of the internal
35583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # iteration buffer (currently 8192,) but we can test it in a
35683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # flexible manner.  Each line in the bag o' ham is 4 bytes
35783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # ("h", "a", "m", "\n"), so 4096 lines of that should get us
35883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # exactly on the buffer boundary for any power-of-2 buffersize
35983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # between 4 and 16384 (inclusive).
36083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f = open(TESTFN)
36183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            for i in range(nchunks):
36283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                f.next()
36383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            testline = testlines.pop(0)
36483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            try:
36583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                line = f.readline()
36683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            except ValueError:
36783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.fail("readline() after next() with supposedly empty "
36883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                          "iteration-buffer failed anyway")
36983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if line != testline:
37083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.fail("readline() after next() with empty buffer "
37183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                          "failed. Got %r, expected %r" % (line, testline))
37283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            testline = testlines.pop(0)
37383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            buf = array("c", "\x00" * len(testline))
37483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            try:
37583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                f.readinto(buf)
37683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            except ValueError:
37783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.fail("readinto() after next() with supposedly empty "
37883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                          "iteration-buffer failed anyway")
37983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            line = buf.tostring()
38083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if line != testline:
38183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.fail("readinto() after next() with empty buffer "
38283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                          "failed. Got %r, expected %r" % (line, testline))
38383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
38483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            testline = testlines.pop(0)
38583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            try:
38683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                line = f.read(len(testline))
38783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            except ValueError:
38883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.fail("read() after next() with supposedly empty "
38983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                          "iteration-buffer failed anyway")
39083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if line != testline:
39183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.fail("read() after next() with empty buffer "
39283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                          "failed. Got %r, expected %r" % (line, testline))
39383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            try:
39483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                lines = f.readlines()
39583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            except ValueError:
39683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.fail("readlines() after next() with supposedly empty "
39783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                          "iteration-buffer failed anyway")
39883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if lines != testlines:
39983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.fail("readlines() after next() with empty buffer "
40083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                          "failed. Got %r, expected %r" % (line, testline))
40183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Reading after iteration hit EOF shouldn't hurt either
40283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f = open(TESTFN)
40383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            try:
40483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                for line in f:
40583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    pass
40683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                try:
40783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    f.readline()
40883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    f.readinto(buf)
40983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    f.read()
41083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    f.readlines()
41183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                except ValueError:
41283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    self.fail("read* failed after next() consumed file")
41383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            finally:
41483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                f.close()
41583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        finally:
41683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            os.unlink(TESTFN)
41783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
41883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass FileSubclassTests(unittest.TestCase):
41983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
42083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def testExit(self):
42183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # test that exiting with context calls subclass' close
42283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        class C(file):
42383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            def __init__(self, *args):
42483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.subclass_closed = False
42583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                file.__init__(self, *args)
42683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            def close(self):
42783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.subclass_closed = True
42883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                file.close(self)
42983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
43083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        with C(TESTFN, 'w') as f:
43183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            pass
43283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertTrue(f.subclass_closed)
43383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
43483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
43583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh@unittest.skipUnless(threading, 'Threading required for this test.')
43683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass FileThreadingTests(unittest.TestCase):
43783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # These tests check the ability to call various methods of file objects
43883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # (including close()) concurrently without crashing the Python interpreter.
43983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # See #815646, #595601
44083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
44183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def setUp(self):
44283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self._threads = test_support.threading_setup()
44383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.f = None
44483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.filename = TESTFN
44583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        with open(self.filename, "w") as f:
44683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            f.write("\n".join("0123456789"))
44783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self._count_lock = threading.Lock()
44883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.close_count = 0
44983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.close_success_count = 0
45083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.use_buffering = False
45183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
45283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def tearDown(self):
45383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if self.f:
45483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            try:
45583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.f.close()
45683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            except (EnvironmentError, ValueError):
45783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                pass
45883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
45983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            os.remove(self.filename)
46083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        except EnvironmentError:
46183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            pass
46283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        test_support.threading_cleanup(*self._threads)
46383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
46483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def _create_file(self):
46583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if self.use_buffering:
46683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.f = open(self.filename, "w+", buffering=1024*16)
46783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
46883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.f = open(self.filename, "w+")
46983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
47083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def _close_file(self):
47183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        with self._count_lock:
47283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.close_count += 1
47383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.f.close()
47483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        with self._count_lock:
47583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.close_success_count += 1
47683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
47783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def _close_and_reopen_file(self):
47883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self._close_file()
47983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # if close raises an exception thats fine, self.f remains valid so
48083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # we don't need to reopen.
48183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self._create_file()
48283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
48383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def _run_workers(self, func, nb_workers, duration=0.2):
48483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        with self._count_lock:
48583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.close_count = 0
48683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.close_success_count = 0
48783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.do_continue = True
48883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        threads = []
48983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
49083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            for i in range(nb_workers):
49183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                t = threading.Thread(target=func)
49283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                t.start()
49383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                threads.append(t)
49483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            for _ in xrange(100):
49583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                time.sleep(duration/100)
49683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                with self._count_lock:
49783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    if self.close_count-self.close_success_count > nb_workers+1:
49883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                        if test_support.verbose:
49983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                            print 'Q',
50083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                        break
50183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            time.sleep(duration)
50283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        finally:
50383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.do_continue = False
50483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            for t in threads:
50583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                t.join()
50683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
50783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def _test_close_open_io(self, io_func, nb_workers=5):
50883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        def worker():
50983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self._create_file()
51083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            funcs = itertools.cycle((
51183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                lambda: io_func(),
51283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                lambda: self._close_and_reopen_file(),
51383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ))
51483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            for f in funcs:
51583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                if not self.do_continue:
51683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    break
51783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                try:
51883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    f()
51983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                except (IOError, ValueError):
52083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    pass
52183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self._run_workers(worker, nb_workers)
52283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if test_support.verbose:
52383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Useful verbose statistics when tuning this test to take
52483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # less time to run but still ensuring that its still useful.
52583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            #
52683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # the percent of close calls that raised an error
52783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            percent = 100. - 100.*self.close_success_count/self.close_count
52883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            print self.close_count, ('%.4f ' % percent),
52983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
53083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_close_open(self):
53183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        def io_func():
53283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            pass
53383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self._test_close_open_io(io_func)
53483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
53583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_close_open_flush(self):
53683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        def io_func():
53783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.f.flush()
53883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self._test_close_open_io(io_func)
53983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
54083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_close_open_iter(self):
54183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        def io_func():
54283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            list(iter(self.f))
54383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self._test_close_open_io(io_func)
54483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
54583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_close_open_isatty(self):
54683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        def io_func():
54783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.f.isatty()
54883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self._test_close_open_io(io_func)
54983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
55083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_close_open_print(self):
55183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        def io_func():
55283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            print >> self.f, ''
55383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self._test_close_open_io(io_func)
55483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
55583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_close_open_print_buffered(self):
55683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.use_buffering = True
55783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        def io_func():
55883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            print >> self.f, ''
55983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self._test_close_open_io(io_func)
56083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
56183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_close_open_read(self):
56283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        def io_func():
56383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.f.read(0)
56483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self._test_close_open_io(io_func)
56583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
56683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_close_open_readinto(self):
56783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        def io_func():
56883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            a = array('c', 'xxxxx')
56983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.f.readinto(a)
57083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self._test_close_open_io(io_func)
57183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
57283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_close_open_readline(self):
57383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        def io_func():
57483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.f.readline()
57583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self._test_close_open_io(io_func)
57683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
57783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_close_open_readlines(self):
57883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        def io_func():
57983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.f.readlines()
58083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self._test_close_open_io(io_func)
58183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
58283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_close_open_seek(self):
58383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        def io_func():
58483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.f.seek(0, 0)
58583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self._test_close_open_io(io_func)
58683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
58783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_close_open_tell(self):
58883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        def io_func():
58983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.f.tell()
59083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self._test_close_open_io(io_func)
59183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
59283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_close_open_truncate(self):
59383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        def io_func():
59483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.f.truncate()
59583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self._test_close_open_io(io_func)
59683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
59783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_close_open_write(self):
59883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        def io_func():
59983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.f.write('')
60083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self._test_close_open_io(io_func)
60183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
60283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_close_open_writelines(self):
60383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        def io_func():
60483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.f.writelines('')
60583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self._test_close_open_io(io_func)
60683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
60783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
60883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh@unittest.skipUnless(os.name == 'posix', 'test requires a posix system.')
60983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass TestFileSignalEINTR(unittest.TestCase):
61083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def _test_reading(self, data_to_write, read_and_verify_code, method_name,
61183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                      universal_newlines=False):
61283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        """Generic buffered read method test harness to verify EINTR behavior.
61383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
61483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        Also validates that Python signal handlers are run during the read.
61583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
61683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        Args:
61783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            data_to_write: String to write to the child process for reading
61883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                before sending it a signal, confirming the signal was handled,
61983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                writing a final newline char and closing the infile pipe.
62083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            read_and_verify_code: Single "line" of code to read from a file
62183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                object named 'infile' and validate the result.  This will be
62283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                executed as part of a python subprocess fed data_to_write.
62383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            method_name: The name of the read method being tested, for use in
62483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                an error message on failure.
62583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            universal_newlines: If True, infile will be opened in universal
62683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                newline mode in the child process.
62783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        """
62883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if universal_newlines:
62983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Test the \r\n -> \n conversion while we're at it.
63083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            data_to_write = data_to_write.replace('\n', '\r\n')
63183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            infile_setup_code = 'infile = os.fdopen(sys.stdin.fileno(), "rU")'
63283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
63383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            infile_setup_code = 'infile = sys.stdin'
63483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Total pipe IO in this function is smaller than the minimum posix OS
63583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # pipe buffer size of 512 bytes.  No writer should block.
63683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        assert len(data_to_write) < 512, 'data_to_write must fit in pipe buf.'
63783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
63883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        child_code = (
63983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             'import os, signal, sys ;'
64083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             'signal.signal('
64183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                     'signal.SIGINT, lambda s, f: sys.stderr.write("$\\n")) ;'
64283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             + infile_setup_code + ' ;' +
64383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             'assert isinstance(infile, file) ;'
64483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             'sys.stderr.write("Go.\\n") ;'
64583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             + read_and_verify_code)
64683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        reader_process = subprocess.Popen(
64783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                [sys.executable, '-c', child_code],
64883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                stdin=subprocess.PIPE, stdout=subprocess.PIPE,
64983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                stderr=subprocess.PIPE)
65083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Wait for the signal handler to be installed.
65183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        go = reader_process.stderr.read(4)
65283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if go != 'Go.\n':
65383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            reader_process.kill()
65483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.fail('Error from %s process while awaiting "Go":\n%s' % (
65583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    method_name, go+reader_process.stderr.read()))
65683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        reader_process.stdin.write(data_to_write)
65783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        signals_sent = 0
65883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        rlist = []
65983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # We don't know when the read_and_verify_code in our child is actually
66083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # executing within the read system call we want to interrupt.  This
66183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # loop waits for a bit before sending the first signal to increase
66283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # the likelihood of that.  Implementations without correct EINTR
66383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # and signal handling usually fail this test.
66483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        while not rlist:
66583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            rlist, _, _ = select.select([reader_process.stderr], (), (), 0.05)
66683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            reader_process.send_signal(signal.SIGINT)
66783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # Give the subprocess time to handle it before we loop around and
66883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # send another one.  On OSX the second signal happening close to
66983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # immediately after the first was causing the subprocess to crash
67083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            # via the OS's default SIGINT handler.
67183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            time.sleep(0.1)
67283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            signals_sent += 1
67383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            if signals_sent > 200:
67483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                reader_process.kill()
67583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.fail("failed to handle signal during %s." % method_name)
67683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # This assumes anything unexpected that writes to stderr will also
67783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # write a newline.  That is true of the traceback printing code.
67883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        signal_line = reader_process.stderr.readline()
67983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if signal_line != '$\n':
68083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            reader_process.kill()
68183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.fail('Error from %s process while awaiting signal:\n%s' % (
68283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    method_name, signal_line+reader_process.stderr.read()))
68383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # We append a newline to our input so that a readline call can
68483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # end on its own before the EOF is seen.
68583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        stdout, stderr = reader_process.communicate(input='\n')
68683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if reader_process.returncode != 0:
68783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.fail('%s() process exited rc=%d.\nSTDOUT:\n%s\nSTDERR:\n%s' % (
68883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    method_name, reader_process.returncode, stdout, stderr))
68983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
69083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_readline(self, universal_newlines=False):
69183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        """file.readline must handle signals and not lose data."""
69283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self._test_reading(
69383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                data_to_write='hello, world!',
69483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                read_and_verify_code=(
69583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                        'line = infile.readline() ;'
69683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                        'expected_line = "hello, world!\\n" ;'
69783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                        'assert line == expected_line, ('
69883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                        '"read %r expected %r" % (line, expected_line))'
69983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                ),
70083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                method_name='readline',
70183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                universal_newlines=universal_newlines)
70283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
70383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_readline_with_universal_newlines(self):
70483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.test_readline(universal_newlines=True)
70583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
70683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_readlines(self, universal_newlines=False):
70783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        """file.readlines must handle signals and not lose data."""
70883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self._test_reading(
70983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                data_to_write='hello\nworld!',
71083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                read_and_verify_code=(
71183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                        'lines = infile.readlines() ;'
71283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                        'expected_lines = ["hello\\n", "world!\\n"] ;'
71383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                        'assert lines == expected_lines, ('
71483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                        '"readlines returned wrong data.\\n" '
71583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                        '"got lines %r\\nexpected  %r" '
71683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                        '% (lines, expected_lines))'
71783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                ),
71883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                method_name='readlines',
71983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                universal_newlines=universal_newlines)
72083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
72183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_readlines_with_universal_newlines(self):
72283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.test_readlines(universal_newlines=True)
72383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
72483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_readall(self):
72583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        """Unbounded file.read() must handle signals and not lose data."""
72683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self._test_reading(
72783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                data_to_write='hello, world!abcdefghijklm',
72883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                read_and_verify_code=(
72983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                        'data = infile.read() ;'
73083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                        'expected_data = "hello, world!abcdefghijklm\\n";'
73183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                        'assert data == expected_data, ('
73283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                        '"read %r expected %r" % (data, expected_data))'
73383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                ),
73483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                method_name='unbounded read')
73583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
73683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_readinto(self):
73783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        """file.readinto must handle signals and not lose data."""
73883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self._test_reading(
73983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                data_to_write='hello, world!',
74083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                read_and_verify_code=(
74183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                        'data = bytearray(50) ;'
74283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                        'num_read = infile.readinto(data) ;'
74383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                        'expected_data = "hello, world!\\n";'
74483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                        'assert data[:num_read] == expected_data, ('
74583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                        '"read %r expected %r" % (data, expected_data))'
74683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                ),
74783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                method_name='readinto')
74883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
74983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
75083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass StdoutTests(unittest.TestCase):
75183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
75283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_move_stdout_on_write(self):
75383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Issue 3242: sys.stdout can be replaced (and freed) during a
75483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # print statement; prevent a segfault in this case
75583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        save_stdout = sys.stdout
75683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
75783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        class File:
75883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            def write(self, data):
75983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                if '\n' in data:
76083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    sys.stdout = save_stdout
76183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
76283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
76383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            sys.stdout = File()
76483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            print "some text"
76583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        finally:
76683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            sys.stdout = save_stdout
76783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
76883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_del_stdout_before_print(self):
76983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Issue 4597: 'print' with no argument wasn't reporting when
77083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # sys.stdout was deleted.
77183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        save_stdout = sys.stdout
77283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        del sys.stdout
77383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        try:
77483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            print
77583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        except RuntimeError as e:
77683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(str(e), "lost sys.stdout")
77783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        else:
77883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.fail("Expected RuntimeError")
77983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        finally:
78083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            sys.stdout = save_stdout
78183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
78283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_unicode(self):
78383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        import subprocess
78483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
78583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        def get_message(encoding, *code):
78683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            code = '\n'.join(code)
78783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            env = os.environ.copy()
78883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            env['PYTHONIOENCODING'] = encoding
78983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            process = subprocess.Popen([sys.executable, "-c", code],
79083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                                       stdout=subprocess.PIPE, env=env)
79183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            stdout, stderr = process.communicate()
79283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(process.returncode, 0)
79383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            return stdout
79483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
79583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        def check_message(text, encoding, expected):
79683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            stdout = get_message(encoding,
79783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                "import sys",
79883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                "sys.stdout.write(%r)" % text,
79983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                "sys.stdout.flush()")
80083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(stdout, expected)
80183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
80283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # test the encoding
80383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        check_message(u'15\u20ac', "iso-8859-15", "15\xa4")
80483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        check_message(u'15\u20ac', "utf-8", '15\xe2\x82\xac')
80583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        check_message(u'15\u20ac', "utf-16-le", '1\x005\x00\xac\x20')
80683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
80783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # test the error handler
80883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        check_message(u'15\u20ac', "iso-8859-1:ignore", "15")
80983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        check_message(u'15\u20ac', "iso-8859-1:replace", "15?")
81083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        check_message(u'15\u20ac', "iso-8859-1:backslashreplace", "15\\u20ac")
81183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
81283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # test the buffer API
81383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for objtype in ('buffer', 'bytearray'):
81483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            stdout = get_message('ascii',
81583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                'import sys',
81683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                r'sys.stdout.write(%s("\xe9"))' % objtype,
81783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                'sys.stdout.flush()')
81883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(stdout, "\xe9")
81983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
82083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
82183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef test_main():
82283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # Historically, these tests have been sloppy about removing TESTFN.
82383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    # So get rid of it no matter what.
82483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    try:
82583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        run_unittest(AutoFileTests, OtherFileTests, FileSubclassTests,
82683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            FileThreadingTests, TestFileSignalEINTR, StdoutTests)
82783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    finally:
82883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        if os.path.exists(TESTFN):
82983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            os.unlink(TESTFN)
83083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
83183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehif __name__ == '__main__':
83283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    test_main()
833