| import os |
| import unittest |
| from test import support |
| from test.support import import_helper, os_helper |
| |
| _testcapi = import_helper.import_module('_testcapi') |
| |
| NULL = None |
| |
| |
| class CAPIFileTest(unittest.TestCase): |
| def test_py_fopen(self): |
| # Test Py_fopen() and Py_fclose() |
| |
| with open(__file__, "rb") as fp: |
| source = fp.read() |
| |
| for filename in (__file__, os.fsencode(__file__)): |
| with self.subTest(filename=filename): |
| data = _testcapi.py_fopen(filename, "rb") |
| self.assertEqual(data, source[:256]) |
| |
| data = _testcapi.py_fopen(os_helper.FakePath(filename), "rb") |
| self.assertEqual(data, source[:256]) |
| |
| filenames = [ |
| os_helper.TESTFN, |
| os.fsencode(os_helper.TESTFN), |
| ] |
| if os_helper.TESTFN_UNDECODABLE is not None: |
| filenames.append(os_helper.TESTFN_UNDECODABLE) |
| filenames.append(os.fsdecode(os_helper.TESTFN_UNDECODABLE)) |
| if os_helper.TESTFN_UNENCODABLE is not None: |
| filenames.append(os_helper.TESTFN_UNENCODABLE) |
| for filename in filenames: |
| with self.subTest(filename=filename): |
| try: |
| with open(filename, "wb") as fp: |
| fp.write(source) |
| except OSError: |
| # TESTFN_UNDECODABLE cannot be used to create a file |
| # on macOS/WASI. |
| filename = None |
| continue |
| try: |
| data = _testcapi.py_fopen(filename, "rb") |
| self.assertEqual(data, source[:256]) |
| finally: |
| os_helper.unlink(filename) |
| |
| # embedded null character/byte in the filename |
| with self.assertRaises(ValueError): |
| _testcapi.py_fopen("a\x00b", "rb") |
| with self.assertRaises(ValueError): |
| _testcapi.py_fopen(b"a\x00b", "rb") |
| |
| # non-ASCII mode failing with "Invalid argument" |
| with self.assertRaises(OSError): |
| _testcapi.py_fopen(__file__, b"\xc2\x80") |
| with self.assertRaises(OSError): |
| # \x98 is invalid in cp1250, cp1251, cp1257 |
| # \x9d is invalid in cp1252-cp1255, cp1258 |
| _testcapi.py_fopen(__file__, b"\xc2\x98\xc2\x9d") |
| # UnicodeDecodeError can come from the audit hook code |
| with self.assertRaises((UnicodeDecodeError, OSError)): |
| _testcapi.py_fopen(__file__, b"\x98\x9d") |
| |
| # invalid filename type |
| for invalid_type in (123, object()): |
| with self.subTest(filename=invalid_type): |
| with self.assertRaises(TypeError): |
| _testcapi.py_fopen(invalid_type, "rb") |
| |
| if support.MS_WINDOWS: |
| with self.assertRaises(OSError): |
| # On Windows, the file mode is limited to 10 characters |
| _testcapi.py_fopen(__file__, "rt+, ccs=UTF-8") |
| |
| # CRASHES _testcapi.py_fopen(NULL, 'rb') |
| # CRASHES _testcapi.py_fopen(__file__, NULL) |
| |
| |
| if __name__ == "__main__": |
| unittest.main() |