Skip to content

Commit 4d7be6d

Browse files
Jayman2000adrienverge
authored andcommitted
tests: Stop using open()’s default encoding
In general, using open()’s default encoding is a mistake [1]. This change makes sure that every time open() is called, the encoding parameter is specified. Specifically, it makes it so that all tests succeed when run like this: python -X warn_default_encoding -W error::EncodingWarning -m unittest discover [1]: <https://peps.python.org/pep-0597/#using-the-default-encoding-is-a-common-mistake>
1 parent fd58e6b commit 4d7be6d

File tree

4 files changed

+50
-33
lines changed

4 files changed

+50
-33
lines changed

tests/common.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,9 @@ def build_temp_workspace(files):
150150
else:
151151
if isinstance(content, Blob):
152152
content = content.text.encode(content.encoding)
153-
mode = 'wb' if isinstance(content, bytes) else 'w'
154-
with open(path, mode) as f:
153+
elif isinstance(content, str):
154+
content = content.encode('utf_8')
155+
with open(path, 'wb') as f:
155156
f.write(content)
156157

157158
return tempdir

tests/test_cli.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -283,14 +283,14 @@ def test_run_with_implicit_extends_config(self):
283283
(ctx.returncode, ctx.stdout, ctx.stderr), (0, expected_out, ''))
284284

285285
def test_run_with_config_file(self):
286-
with open(os.path.join(self.wd, 'config'), 'w') as f:
286+
with open(os.path.join(self.wd, 'config'), 'w', encoding='utf_8') as f:
287287
f.write('rules: {trailing-spaces: disable}')
288288

289289
with RunContext(self) as ctx:
290290
cli.run(('-c', f.name, os.path.join(self.wd, 'a.yaml')))
291291
self.assertEqual(ctx.returncode, 0)
292292

293-
with open(os.path.join(self.wd, 'config'), 'w') as f:
293+
with open(os.path.join(self.wd, 'config'), 'w', encoding='utf_8') as f:
294294
f.write('rules: {trailing-spaces: enable}')
295295

296296
with RunContext(self) as ctx:
@@ -306,14 +306,14 @@ def test_run_with_user_global_config_file(self):
306306
self.addCleanup(os.environ.__delitem__, 'HOME')
307307
os.environ['HOME'] = home
308308

309-
with open(config, 'w') as f:
309+
with open(config, 'w', encoding='utf_8') as f:
310310
f.write('rules: {trailing-spaces: disable}')
311311

312312
with RunContext(self) as ctx:
313313
cli.run((os.path.join(self.wd, 'a.yaml'), ))
314314
self.assertEqual(ctx.returncode, 0)
315315

316-
with open(config, 'w') as f:
316+
with open(config, 'w', encoding='utf_8') as f:
317317
f.write('rules: {trailing-spaces: enable}')
318318

319319
with RunContext(self) as ctx:
@@ -326,7 +326,8 @@ def test_run_with_user_xdg_config_home_in_env(self):
326326
with tempfile.TemporaryDirectory('w') as d:
327327
os.environ['XDG_CONFIG_HOME'] = d
328328
os.makedirs(os.path.join(d, 'yamllint'))
329-
with open(os.path.join(d, 'yamllint', 'config'), 'w') as f:
329+
path = os.path.join(d, 'yamllint', 'config')
330+
with open(path, 'w', encoding='utf_8') as f:
330331
f.write('extends: relaxed')
331332
with RunContext(self) as ctx:
332333
cli.run(('-f', 'parsable', os.path.join(self.wd, 'warn.yaml')))
@@ -336,15 +337,15 @@ def test_run_with_user_xdg_config_home_in_env(self):
336337
def test_run_with_user_yamllint_config_file_in_env(self):
337338
self.addCleanup(os.environ.__delitem__, 'YAMLLINT_CONFIG_FILE')
338339

339-
with tempfile.NamedTemporaryFile('w') as f:
340+
with tempfile.NamedTemporaryFile('w', encoding='utf_8') as f:
340341
os.environ['YAMLLINT_CONFIG_FILE'] = f.name
341342
f.write('rules: {trailing-spaces: disable}')
342343
f.flush()
343344
with RunContext(self) as ctx:
344345
cli.run((os.path.join(self.wd, 'a.yaml'), ))
345346
self.assertEqual(ctx.returncode, 0)
346347

347-
with tempfile.NamedTemporaryFile('w') as f:
348+
with tempfile.NamedTemporaryFile('w', encoding='utf_8') as f:
348349
os.environ['YAMLLINT_CONFIG_FILE'] = f.name
349350
f.write('rules: {trailing-spaces: enable}')
350351
f.flush()
@@ -488,7 +489,11 @@ def test_run_default_format_output_in_tty(self):
488489
# Create a pseudo-TTY and redirect stdout to it
489490
old_stdout = sys.stdout
490491
master, slave = pty.openpty()
491-
sys.stdout = os.fdopen(slave, 'w')
492+
sys.stdout = os.fdopen(
493+
slave,
494+
'w',
495+
encoding=os.device_encoding(slave)
496+
)
492497

493498
with self.assertRaises(SystemExit) as ctx:
494499
cli.run((path, ))
@@ -497,7 +502,7 @@ def test_run_default_format_output_in_tty(self):
497502
self.assertEqual(ctx.exception.code, 1)
498503

499504
# Read output from TTY
500-
output = os.fdopen(master, 'r')
505+
output = os.fdopen(master, 'r', encoding=os.device_encoding(master))
501506
os.set_blocking(master, False)
502507

503508
out = output.read().replace('\r\n', '\n')

tests/test_config.py

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ def test_extend_on_object(self):
259259
self.assertEqual(len(new.enabled_rules(None)), 2)
260260

261261
def test_extend_on_file(self):
262-
with tempfile.NamedTemporaryFile('w') as f:
262+
with tempfile.NamedTemporaryFile('w', encoding='utf_8') as f:
263263
f.write('rules:\n'
264264
' colons:\n'
265265
' max-spaces-before: 0\n'
@@ -278,7 +278,7 @@ def test_extend_on_file(self):
278278
self.assertEqual(len(c.enabled_rules(None)), 2)
279279

280280
def test_extend_remove_rule(self):
281-
with tempfile.NamedTemporaryFile('w') as f:
281+
with tempfile.NamedTemporaryFile('w', encoding='utf_8') as f:
282282
f.write('rules:\n'
283283
' colons:\n'
284284
' max-spaces-before: 0\n'
@@ -297,7 +297,7 @@ def test_extend_remove_rule(self):
297297
self.assertEqual(len(c.enabled_rules(None)), 1)
298298

299299
def test_extend_edit_rule(self):
300-
with tempfile.NamedTemporaryFile('w') as f:
300+
with tempfile.NamedTemporaryFile('w', encoding='utf_8') as f:
301301
f.write('rules:\n'
302302
' colons:\n'
303303
' max-spaces-before: 0\n'
@@ -319,7 +319,7 @@ def test_extend_edit_rule(self):
319319
self.assertEqual(len(c.enabled_rules(None)), 2)
320320

321321
def test_extend_reenable_rule(self):
322-
with tempfile.NamedTemporaryFile('w') as f:
322+
with tempfile.NamedTemporaryFile('w', encoding='utf_8') as f:
323323
f.write('rules:\n'
324324
' colons:\n'
325325
' max-spaces-before: 0\n'
@@ -339,7 +339,7 @@ def test_extend_reenable_rule(self):
339339
self.assertEqual(len(c.enabled_rules(None)), 2)
340340

341341
def test_extend_recursive_default_values(self):
342-
with tempfile.NamedTemporaryFile('w') as f:
342+
with tempfile.NamedTemporaryFile('w', encoding='utf_8') as f:
343343
f.write('rules:\n'
344344
' braces:\n'
345345
' max-spaces-inside: 1248\n')
@@ -354,7 +354,7 @@ def test_extend_recursive_default_values(self):
354354
self.assertEqual(c.rules['braces']['min-spaces-inside-empty'], 2357)
355355
self.assertEqual(c.rules['braces']['max-spaces-inside-empty'], -1)
356356

357-
with tempfile.NamedTemporaryFile('w') as f:
357+
with tempfile.NamedTemporaryFile('w', encoding='utf_8') as f:
358358
f.write('rules:\n'
359359
' colons:\n'
360360
' max-spaces-before: 1337\n')
@@ -366,8 +366,8 @@ def test_extend_recursive_default_values(self):
366366
self.assertEqual(c.rules['colons']['max-spaces-before'], 1337)
367367
self.assertEqual(c.rules['colons']['max-spaces-after'], 1)
368368

369-
with tempfile.NamedTemporaryFile('w') as f1, \
370-
tempfile.NamedTemporaryFile('w') as f2:
369+
with tempfile.NamedTemporaryFile('w', encoding='utf_8') as f1, \
370+
tempfile.NamedTemporaryFile('w', encoding='utf_8') as f2:
371371
f1.write('rules:\n'
372372
' colons:\n'
373373
' max-spaces-before: 1337\n')
@@ -384,7 +384,7 @@ def test_extend_recursive_default_values(self):
384384
self.assertEqual(c.rules['colons']['max-spaces-after'], 1)
385385

386386
def test_extended_ignore_str(self):
387-
with tempfile.NamedTemporaryFile('w') as f:
387+
with tempfile.NamedTemporaryFile('w', encoding='utf_8') as f:
388388
f.write('ignore: |\n'
389389
' *.template.yaml\n')
390390
f.flush()
@@ -394,7 +394,7 @@ def test_extended_ignore_str(self):
394394
self.assertEqual(c.ignore.match_file('test.yaml'), False)
395395

396396
def test_extended_ignore_list(self):
397-
with tempfile.NamedTemporaryFile('w') as f:
397+
with tempfile.NamedTemporaryFile('w', encoding='utf_8') as f:
398398
f.write('ignore:\n'
399399
' - "*.template.yaml"\n')
400400
f.flush()
@@ -564,7 +564,8 @@ def test_no_ignore(self):
564564
)))
565565

566566
def test_run_with_ignore_str(self):
567-
with open(os.path.join(self.wd, '.yamllint'), 'w') as f:
567+
path = os.path.join(self.wd, '.yamllint')
568+
with open(path, 'w', encoding='utf_8') as f:
568569
f.write('extends: default\n'
569570
'ignore: |\n'
570571
' *.dont-lint-me.yaml\n'
@@ -618,7 +619,8 @@ def test_run_with_ignore_str(self):
618619
)))
619620

620621
def test_run_with_ignore_list(self):
621-
with open(os.path.join(self.wd, '.yamllint'), 'w') as f:
622+
path = os.path.join(self.wd, '.yamllint')
623+
with open(path, 'w', encoding='utf_8') as f:
622624
f.write('extends: default\n'
623625
'ignore:\n'
624626
' - "*.dont-lint-me.yaml"\n'
@@ -672,19 +674,22 @@ def test_run_with_ignore_list(self):
672674
)))
673675

674676
def test_run_with_ignore_from_file(self):
675-
with open(os.path.join(self.wd, '.yamllint'), 'w') as f:
677+
path = os.path.join(self.wd, '.yamllint')
678+
with open(path, 'w', encoding='utf_8') as f:
676679
f.write('extends: default\n'
677680
'ignore-from-file: .gitignore\n'
678681
'rules:\n'
679682
' key-duplicates:\n'
680683
' ignore-from-file: .ignore-key-duplicates\n')
681684

682-
with open(os.path.join(self.wd, '.gitignore'), 'w') as f:
685+
path = os.path.join(self.wd, '.gitignore')
686+
with open(path, 'w', encoding='utf_8') as f:
683687
f.write('*.dont-lint-me.yaml\n'
684688
'/bin/\n'
685689
'!/bin/*.lint-me-anyway.yaml\n')
686690

687-
with open(os.path.join(self.wd, '.ignore-key-duplicates'), 'w') as f:
691+
path = os.path.join(self.wd, '.ignore-key-duplicates')
692+
with open(path, 'w', encoding='utf_8') as f:
688693
f.write('/ign-dup\n')
689694

690695
sys.stdout = StringIO()
@@ -729,13 +734,16 @@ def test_run_with_ignore_from_file(self):
729734
)))
730735

731736
def test_run_with_ignored_from_file(self):
732-
with open(os.path.join(self.wd, '.yamllint'), 'w') as f:
737+
path = os.path.join(self.wd, '.yamllint')
738+
with open(path, 'w', encoding='utf_8') as f:
733739
f.write('ignore-from-file: [.gitignore, .yamlignore]\n'
734740
'extends: default\n')
735-
with open(os.path.join(self.wd, '.gitignore'), 'w') as f:
741+
path = os.path.join(self.wd, '.gitignore')
742+
with open(path, 'w', encoding='utf_8') as f:
736743
f.write('*.dont-lint-me.yaml\n'
737744
'/bin/\n')
738-
with open(os.path.join(self.wd, '.yamlignore'), 'w') as f:
745+
path = os.path.join(self.wd, '.yamlignore')
746+
with open(path, 'w', encoding='utf_8') as f:
739747
f.write('!/bin/*.lint-me-anyway.yaml\n')
740748

741749
sys.stdout = StringIO()
@@ -794,7 +802,7 @@ def test_run_with_ignore_with_broken_symlink(self):
794802
cli.run(('-f', 'parsable', '.'))
795803
self.assertNotEqual(ctx.returncode, 0)
796804

797-
with open(os.path.join(wd, '.yamllint'), 'w') as f:
805+
with open(os.path.join(wd, '.yamllint'), 'w', encoding='utf_8') as f:
798806
f.write('extends: default\n'
799807
'ignore: |\n'
800808
' *404.yaml\n')
@@ -812,7 +820,8 @@ def test_run_with_ignore_with_broken_symlink(self):
812820
shutil.rmtree(wd)
813821

814822
def test_run_with_ignore_on_ignored_file(self):
815-
with open(os.path.join(self.wd, '.yamllint'), 'w') as f:
823+
path = os.path.join(self.wd, '.yamllint')
824+
with open(path, 'w', encoding='utf_8') as f:
816825
f.write('ignore: file.dont-lint-me.yaml\n'
817826
'rules:\n'
818827
' trailing-spaces: enable\n'

tests/test_module.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,14 @@ def setUp(self):
2828
self.wd = tempfile.mkdtemp(prefix='yamllint-tests-')
2929

3030
# file with only one warning
31-
with open(os.path.join(self.wd, 'warn.yaml'), 'w') as f:
31+
path = os.path.join(self.wd, 'warn.yaml')
32+
with open(path, 'w', encoding='utf_8') as f:
3233
f.write('key: value\n')
3334

3435
# file in dir
3536
os.mkdir(os.path.join(self.wd, 'sub'))
36-
with open(os.path.join(self.wd, 'sub', 'nok.yaml'), 'w') as f:
37+
path = os.path.join(self.wd, 'sub', 'nok.yaml')
38+
with open(path, 'w', encoding='utf_8') as f:
3739
f.write('---\n'
3840
'list: [ 1, 1, 2, 3, 5, 8] \n')
3941

0 commit comments

Comments
 (0)