33"""
44
55import locale
6+ import subprocess
67import sys
78import textwrap
89import unittest
910from test import support
1011from test .support .script_helper import assert_python_ok , assert_python_failure
12+ from test .support import os_helper
1113
1214
1315MS_WINDOWS = (sys .platform == 'win32' )
@@ -159,8 +161,6 @@ def test_stdio(self):
159161 'stdout: utf-8/namereplace' ,
160162 'stderr: utf-8/backslashreplace' ])
161163
162- # TODO: RUSTPYTHON
163- @unittest .expectedFailure
164164 def test_io (self ):
165165 code = textwrap .dedent ('''
166166 import sys
@@ -171,7 +171,7 @@ def test_io(self):
171171 filename = __file__
172172
173173 out = self .get_output ('-c' , code , filename , PYTHONUTF8 = '1' )
174- self .assertEqual (out , 'UTF -8/strict' )
174+ self .assertEqual (out . lower () , 'utf -8/strict' )
175175
176176 def _check_io_encoding (self , module , encoding = None , errors = None ):
177177 filename = __file__
@@ -193,19 +193,17 @@ def _check_io_encoding(self, module, encoding=None, errors=None):
193193 PYTHONUTF8 = '1' )
194194
195195 if not encoding :
196- encoding = 'UTF -8'
196+ encoding = 'utf -8'
197197 if not errors :
198198 errors = 'strict'
199- self .assertEqual (out , f'{ encoding } /{ errors } ' )
199+ self .assertEqual (out . lower () , f'{ encoding } /{ errors } ' )
200200
201201 def check_io_encoding (self , module ):
202202 self ._check_io_encoding (module , encoding = "latin1" )
203203 self ._check_io_encoding (module , errors = "namereplace" )
204204 self ._check_io_encoding (module ,
205205 encoding = "latin1" , errors = "namereplace" )
206206
207- # TODO: RUSTPYTHON
208- @unittest .expectedFailure
209207 def test_io_encoding (self ):
210208 self .check_io_encoding ('io' )
211209
@@ -215,12 +213,12 @@ def test_pyio_encoding(self):
215213 def test_locale_getpreferredencoding (self ):
216214 code = 'import locale; print(locale.getpreferredencoding(False), locale.getpreferredencoding(True))'
217215 out = self .get_output ('-X' , 'utf8' , '-c' , code )
218- self .assertEqual (out , 'UTF -8 UTF -8' )
216+ self .assertEqual (out , 'utf -8 utf -8' )
219217
220218 for loc in POSIX_LOCALES :
221219 with self .subTest (LC_ALL = loc ):
222220 out = self .get_output ('-X' , 'utf8' , '-c' , code , LC_ALL = loc )
223- self .assertEqual (out , 'UTF -8 UTF -8' )
221+ self .assertEqual (out , 'utf -8 utf -8' )
224222
225223 @unittest .skipIf (MS_WINDOWS , 'test specific to Unix' )
226224 def test_cmd_line (self ):
@@ -268,6 +266,34 @@ def test_optim_level(self):
268266 out = self .get_output ('-X' , 'utf8' , '-E' , '-c' , code )
269267 self .assertEqual (out , '1' )
270268
269+ # TODO: RUSTPYTHON
270+ @unittest .expectedFailure
271+ @unittest .skipIf (MS_WINDOWS ,
272+ "os.device_encoding() doesn't implement "
273+ "the UTF-8 Mode on Windows" )
274+ @support .requires_subprocess ()
275+ def test_device_encoding (self ):
276+ # Use stdout as TTY
277+ if not sys .stdout .isatty ():
278+ self .skipTest ("sys.stdout is not a TTY" )
279+
280+ filename = 'out.txt'
281+ self .addCleanup (os_helper .unlink , filename )
282+
283+ code = (f'import os, sys; fd = sys.stdout.fileno(); '
284+ f'out = open({ filename !r} , "w", encoding="utf-8"); '
285+ f'print(os.isatty(fd), os.device_encoding(fd), file=out); '
286+ f'out.close()' )
287+ cmd = [sys .executable , '-X' , 'utf8' , '-c' , code ]
288+ # The stdout TTY is inherited to the child process
289+ proc = subprocess .run (cmd , text = True )
290+ self .assertEqual (proc .returncode , 0 , proc )
291+
292+ # In UTF-8 Mode, device_encoding(fd) returns "UTF-8" if fd is a TTY
293+ with open (filename , encoding = "utf8" ) as fp :
294+ out = fp .read ().rstrip ()
295+ self .assertEqual (out , 'True utf-8' )
296+
271297
272298if __name__ == "__main__" :
273299 unittest .main ()
0 commit comments