33import unittest
44import warnings
55from test import support
6- from test .support import import_helper , os_helper
6+ from test .support import import_helper , os_helper , warnings_helper
77
88
99_testcapi = import_helper .import_module ('_testcapi' )
1010_testlimitedcapi = import_helper .import_module ('_testlimitedcapi' )
1111_io = import_helper .import_module ('_io' )
1212NULL = None
13+ STDOUT_FD = 1
1314
1415with open (__file__ , 'rb' ) as fp :
1516 FIRST_LINE = next (fp ).decode ()
1819
1920class CAPIFileTest (unittest .TestCase ):
2021 def test_pyfile_fromfd (self ):
21- # Test PyFile_FromFd() which is a thin wrapper
22- # to the built-in open() function
22+ # Test PyFile_FromFd() which is a thin wrapper to _io.open()
2323 pyfile_fromfd = _testlimitedcapi .pyfile_fromfd
2424 filename = __file__
2525 with open (filename , "rb" ) as fp :
@@ -78,9 +78,11 @@ def test_pyfile_getline(self):
7878 self .assertEqual (pyfile_getline (fp , - 1 ),
7979 FIRST_LINE .rstrip ('\n ' ).encode ())
8080 fp .seek (0 )
81- self .assertEqual (pyfile_getline (fp , 0 ), FIRST_LINE .encode ())
81+ self .assertEqual (pyfile_getline (fp , 0 ),
82+ FIRST_LINE .encode ())
8283 fp .seek (0 )
83- self .assertEqual (pyfile_getline (fp , 6 ), FIRST_LINE .encode ()[:6 ])
84+ self .assertEqual (pyfile_getline (fp , 6 ),
85+ FIRST_LINE .encode ()[:6 ])
8486
8587 def test_pyfile_writestring (self ):
8688 # Test PyFile_WriteString(str, file): call file.write(str)
@@ -90,6 +92,8 @@ def test_pyfile_writestring(self):
9092 self .assertEqual (writestr ("a\xe9 \u20ac \U0010FFFF " .encode (), fp ), 0 )
9193 with self .assertRaises (UnicodeDecodeError ):
9294 writestr (b"\xff " , fp )
95+ with self .assertRaises (UnicodeDecodeError ):
96+ writestr ("\udc80 " .encode ("utf-8" , "surrogatepass" ), fp )
9397
9498 text = fp .getvalue ()
9599 self .assertEqual (text , "a\xe9 \u20ac \U0010FFFF " )
@@ -105,14 +109,16 @@ def test_pyfile_writeobject(self):
105109 Py_PRINT_RAW = 1
106110
107111 with io .StringIO () as fp :
108- self .assertEqual (writeobject ("raw\n " , fp , Py_PRINT_RAW ), 0 )
112+ # Test flags=Py_PRINT_RAW
113+ self .assertEqual (writeobject ("raw" , fp , Py_PRINT_RAW ), 0 )
109114 writeobject (NULL , fp , Py_PRINT_RAW )
110115
116+ # Test flags=0
111117 self .assertEqual (writeobject ("repr" , fp , 0 ), 0 )
112118 writeobject (NULL , fp , 0 )
113119
114120 text = fp .getvalue ()
115- self .assertEqual (text , "raw\n <NULL>'repr'<NULL>" )
121+ self .assertEqual (text , "raw<NULL>'repr'<NULL>" )
116122
117123 # invalid file type
118124 for invalid_file in (123 , "abc" , object ()):
@@ -127,6 +133,7 @@ def test_pyobject_asfiledescriptor(self):
127133 # Test PyObject_AsFileDescriptor(obj):
128134 # - Return obj if obj is an integer.
129135 # - Return obj.fileno() otherwise.
136+ # File descriptor must be >= 0.
130137 asfd = _testlimitedcapi .pyobject_asfiledescriptor
131138
132139 self .assertEqual (asfd (123 ), 123 )
@@ -136,13 +143,9 @@ def test_pyobject_asfiledescriptor(self):
136143 self .assertEqual (asfd (fp ), fp .fileno ())
137144
138145 # bool emits RuntimeWarning
139- with warnings . catch_warnings ( record = True ) as warns :
140- warnings . simplefilter ( 'always' , RuntimeWarning )
146+ msg = r"bool is used as a file descriptor"
147+ with warnings_helper . check_warnings (( msg , RuntimeWarning )):
141148 self .assertEqual (asfd (True ), 1 )
142- self .assertEqual (len (warns ), 1 , warns )
143- self .assertEqual (warns [0 ].category , RuntimeWarning )
144- self .assertEqual (str (warns [0 ].message ),
145- "bool is used as a file descriptor" )
146149
147150 class FakeFile :
148151 def __init__ (self , fd ):
@@ -171,7 +174,27 @@ def fileno(self):
171174 def test_pyfile_newstdprinter (self ):
172175 # Test PyFile_NewStdPrinter()
173176 pyfile_newstdprinter = _testcapi .pyfile_newstdprinter
174- STDOUT_FD = 1
177+
178+ file = pyfile_newstdprinter (STDOUT_FD )
179+ self .assertEqual (file .closed , False )
180+ self .assertIsNone (file .encoding )
181+ self .assertEqual (file .mode , "w" )
182+
183+ self .assertEqual (file .fileno (), STDOUT_FD )
184+ self .assertEqual (file .isatty (), os .isatty (STDOUT_FD ))
185+
186+ # flush() is a no-op
187+ self .assertIsNone (file .flush ())
188+
189+ # close() is a no-op
190+ self .assertIsNone (file .close ())
191+ self .assertEqual (file .closed , False )
192+
193+ support .check_disallow_instantiation (self , type (file ))
194+
195+ def test_pyfile_newstdprinter_write (self ):
196+ # Test the write() method of PyFile_NewStdPrinter()
197+ pyfile_newstdprinter = _testcapi .pyfile_newstdprinter
175198
176199 filename = os_helper .TESTFN
177200 self .addCleanup (os_helper .unlink , filename )
@@ -190,29 +213,16 @@ def test_pyfile_newstdprinter(self):
190213 os .dup2 (fd , STDOUT_FD )
191214
192215 file = pyfile_newstdprinter (STDOUT_FD )
193- self .assertEqual (file .closed , False )
194- self .assertIsNone (file .encoding )
195- self .assertEqual (file .mode , "w" )
196-
197- self .assertEqual (file .fileno (), STDOUT_FD )
198- self .assertEqual (file .isatty (), False )
199-
200216 self .assertEqual (file .write ("text" ), 4 )
201- self .assertEqual (file .write ("[\uDC80 ]" ), 8 )
202-
203- # flush() is a no-op
204- self .assertIsNone (file .flush ())
205-
206- # close() is a no-op
207- self .assertIsNone (file .close ())
208- self .assertEqual (file .closed , False )
209-
210- support .check_disallow_instantiation (self , type (file ))
217+ # The surrogate character is encoded with
218+ # the "surrogateescape" error handler
219+ self .assertEqual (file .write ("[\udc80 ]" ), 8 )
211220 finally :
212221 os .dup2 (old_stdout , STDOUT_FD )
222+ os .close (old_stdout )
213223
214224 with open (filename , "r" ) as fp :
215- self .assertEqual (fp .read (), r "text[\udc80]" )
225+ self .assertEqual (fp .read (), "text[\ \ udc80]" )
216226
217227 def test_py_fopen (self ):
218228 # Test Py_fopen() and Py_fclose()
0 commit comments