| 
									
										
										
										
											2025-01-06 13:43:09 +01:00
										 |  |  | import os | 
					
						
							|  |  |  | import unittest | 
					
						
							|  |  |  | from test import support | 
					
						
							|  |  |  | from test.support import import_helper, os_helper | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | _testcapi = import_helper.import_module('_testcapi') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-07 23:13:08 +02:00
										 |  |  | NULL = None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-06 13:43:09 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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), | 
					
						
							|  |  |  |         ] | 
					
						
							| 
									
										
										
										
											2025-01-07 23:13:08 +02:00
										 |  |  |         if os_helper.TESTFN_UNDECODABLE is not None: | 
					
						
							|  |  |  |             filenames.append(os_helper.TESTFN_UNDECODABLE) | 
					
						
							|  |  |  |             filenames.append(os.fsdecode(os_helper.TESTFN_UNDECODABLE)) | 
					
						
							| 
									
										
										
										
											2025-01-06 13:43:09 +01:00
										 |  |  |         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) | 
					
						
							| 
									
										
										
										
											2025-01-07 23:13:08 +02:00
										 |  |  |                 except OSError: | 
					
						
							|  |  |  |                     # TESTFN_UNDECODABLE cannot be used to create a file | 
					
						
							|  |  |  |                     # on macOS/WASI. | 
					
						
							|  |  |  |                     filename = None | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 try: | 
					
						
							| 
									
										
										
										
											2025-01-06 13:43:09 +01:00
										 |  |  |                     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): | 
					
						
							| 
									
										
										
										
											2025-01-07 23:13:08 +02:00
										 |  |  |             _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") | 
					
						
							| 
									
										
										
										
											2025-01-06 13:43:09 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # 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") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-07 23:13:08 +02:00
										 |  |  |         # CRASHES _testcapi.py_fopen(NULL, 'rb') | 
					
						
							|  |  |  |         # CRASHES _testcapi.py_fopen(__file__, NULL) | 
					
						
							| 
									
										
										
										
											2025-01-06 13:43:09 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if __name__ == "__main__": | 
					
						
							|  |  |  |     unittest.main() |