Skip to content

Commit

Permalink
tests: Stop using open()’s default encoding
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jayman2000 committed Sep 20, 2024
1 parent d92c091 commit ad21065
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 33 deletions.
5 changes: 3 additions & 2 deletions tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,9 @@ def build_temp_workspace(files):
else:
if isinstance(content, Blob):
content = content.text.encode(content.encoding)
mode = 'wb' if isinstance(content, bytes) else 'w'
with open(path, mode) as f:
elif isinstance(content, str):
content = content.encode('utf_8')
with open(path, 'wb') as f:
f.write(content)

return tempdir
Expand Down
23 changes: 14 additions & 9 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,14 +303,14 @@ def test_run_with_implicit_extends_config(self):
(ctx.returncode, ctx.stdout, ctx.stderr), (0, expected_out, ''))

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

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

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

with RunContext(self) as ctx:
Expand All @@ -326,14 +326,14 @@ def test_run_with_user_global_config_file(self):
self.addCleanup(os.environ.__delitem__, 'HOME')
os.environ['HOME'] = home

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

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

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

with RunContext(self) as ctx:
Expand All @@ -346,7 +346,8 @@ def test_run_with_user_xdg_config_home_in_env(self):
with tempfile.TemporaryDirectory('w') as d:
os.environ['XDG_CONFIG_HOME'] = d
os.makedirs(os.path.join(d, 'yamllint'))
with open(os.path.join(d, 'yamllint', 'config'), 'w') as f:
path = os.path.join(d, 'yamllint', 'config')
with open(path, 'w', encoding='utf_8') as f:
f.write('extends: relaxed')
with RunContext(self) as ctx:
cli.run(('-f', 'parsable', os.path.join(self.wd, 'warn.yaml')))
Expand All @@ -356,15 +357,15 @@ def test_run_with_user_xdg_config_home_in_env(self):
def test_run_with_user_yamllint_config_file_in_env(self):
self.addCleanup(os.environ.__delitem__, 'YAMLLINT_CONFIG_FILE')

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

with tempfile.NamedTemporaryFile('w') as f:
with tempfile.NamedTemporaryFile('w', encoding='utf_8') as f:
os.environ['YAMLLINT_CONFIG_FILE'] = f.name
f.write('rules: {trailing-spaces: enable}')
f.flush()
Expand Down Expand Up @@ -508,7 +509,11 @@ def test_run_default_format_output_in_tty(self):
# Create a pseudo-TTY and redirect stdout to it
old_stdout, old_stderr = sys.stdout, sys.stderr
master, slave = pty.openpty()
sys.stdout = sys.stderr = os.fdopen(slave, 'w')
sys.stdout = sys.stderr = os.fdopen(
slave,
'w',
encoding=os.device_encoding(slave)
)

with self.assertRaises(SystemExit) as ctx:
cli.run((path, ))
Expand All @@ -517,7 +522,7 @@ def test_run_default_format_output_in_tty(self):
self.assertEqual(ctx.exception.code, 1)

# Read output from TTY
output = os.fdopen(master, 'r')
output = os.fdopen(master, 'r', encoding=os.device_encoding(master))
flag = fcntl.fcntl(master, fcntl.F_GETFD)
fcntl.fcntl(master, fcntl.F_SETFL, flag | os.O_NONBLOCK)

Expand Down
49 changes: 29 additions & 20 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ def test_extend_on_object(self):
self.assertEqual(len(new.enabled_rules(None)), 2)

def test_extend_on_file(self):
with tempfile.NamedTemporaryFile('w') as f:
with tempfile.NamedTemporaryFile('w', encoding='utf_8') as f:
f.write('rules:\n'
' colons:\n'
' max-spaces-before: 0\n'
Expand All @@ -277,7 +277,7 @@ def test_extend_on_file(self):
self.assertEqual(len(c.enabled_rules(None)), 2)

def test_extend_remove_rule(self):
with tempfile.NamedTemporaryFile('w') as f:
with tempfile.NamedTemporaryFile('w', encoding='utf_8') as f:
f.write('rules:\n'
' colons:\n'
' max-spaces-before: 0\n'
Expand All @@ -296,7 +296,7 @@ def test_extend_remove_rule(self):
self.assertEqual(len(c.enabled_rules(None)), 1)

def test_extend_edit_rule(self):
with tempfile.NamedTemporaryFile('w') as f:
with tempfile.NamedTemporaryFile('w', encoding='utf_8') as f:
f.write('rules:\n'
' colons:\n'
' max-spaces-before: 0\n'
Expand All @@ -318,7 +318,7 @@ def test_extend_edit_rule(self):
self.assertEqual(len(c.enabled_rules(None)), 2)

def test_extend_reenable_rule(self):
with tempfile.NamedTemporaryFile('w') as f:
with tempfile.NamedTemporaryFile('w', encoding='utf_8') as f:
f.write('rules:\n'
' colons:\n'
' max-spaces-before: 0\n'
Expand All @@ -338,7 +338,7 @@ def test_extend_reenable_rule(self):
self.assertEqual(len(c.enabled_rules(None)), 2)

def test_extend_recursive_default_values(self):
with tempfile.NamedTemporaryFile('w') as f:
with tempfile.NamedTemporaryFile('w', encoding='utf_8') as f:
f.write('rules:\n'
' braces:\n'
' max-spaces-inside: 1248\n')
Expand All @@ -353,7 +353,7 @@ def test_extend_recursive_default_values(self):
self.assertEqual(c.rules['braces']['min-spaces-inside-empty'], 2357)
self.assertEqual(c.rules['braces']['max-spaces-inside-empty'], -1)

with tempfile.NamedTemporaryFile('w') as f:
with tempfile.NamedTemporaryFile('w', encoding='utf_8') as f:
f.write('rules:\n'
' colons:\n'
' max-spaces-before: 1337\n')
Expand All @@ -365,8 +365,8 @@ def test_extend_recursive_default_values(self):
self.assertEqual(c.rules['colons']['max-spaces-before'], 1337)
self.assertEqual(c.rules['colons']['max-spaces-after'], 1)

with tempfile.NamedTemporaryFile('w') as f1, \
tempfile.NamedTemporaryFile('w') as f2:
with tempfile.NamedTemporaryFile('w', encoding='utf_8') as f1, \
tempfile.NamedTemporaryFile('w', encoding='utf_8') as f2:
f1.write('rules:\n'
' colons:\n'
' max-spaces-before: 1337\n')
Expand All @@ -383,7 +383,7 @@ def test_extend_recursive_default_values(self):
self.assertEqual(c.rules['colons']['max-spaces-after'], 1)

def test_extended_ignore_str(self):
with tempfile.NamedTemporaryFile('w') as f:
with tempfile.NamedTemporaryFile('w', encoding='utf_8') as f:
f.write('ignore: |\n'
' *.template.yaml\n')
f.flush()
Expand All @@ -393,7 +393,7 @@ def test_extended_ignore_str(self):
self.assertEqual(c.ignore.match_file('test.yaml'), False)

def test_extended_ignore_list(self):
with tempfile.NamedTemporaryFile('w') as f:
with tempfile.NamedTemporaryFile('w', encoding='utf_8') as f:
f.write('ignore:\n'
' - "*.template.yaml"\n')
f.flush()
Expand Down Expand Up @@ -563,7 +563,8 @@ def test_no_ignore(self):
)))

def test_run_with_ignore_str(self):
with open(os.path.join(self.wd, '.yamllint'), 'w') as f:
path = os.path.join(self.wd, '.yamllint')
with open(path, 'w', encoding='utf_8') as f:
f.write('extends: default\n'
'ignore: |\n'
' *.dont-lint-me.yaml\n'
Expand Down Expand Up @@ -617,7 +618,8 @@ def test_run_with_ignore_str(self):
)))

def test_run_with_ignore_list(self):
with open(os.path.join(self.wd, '.yamllint'), 'w') as f:
path = os.path.join(self.wd, '.yamllint')
with open(path, 'w', encoding='utf_8') as f:
f.write('extends: default\n'
'ignore:\n'
' - "*.dont-lint-me.yaml"\n'
Expand Down Expand Up @@ -671,19 +673,22 @@ def test_run_with_ignore_list(self):
)))

def test_run_with_ignore_from_file(self):
with open(os.path.join(self.wd, '.yamllint'), 'w') as f:
path = os.path.join(self.wd, '.yamllint')
with open(path, 'w', encoding='utf_8') as f:
f.write('extends: default\n'
'ignore-from-file: .gitignore\n'
'rules:\n'
' key-duplicates:\n'
' ignore-from-file: .ignore-key-duplicates\n')

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

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

sys.stdout = StringIO()
Expand Down Expand Up @@ -728,13 +733,16 @@ def test_run_with_ignore_from_file(self):
)))

def test_run_with_ignored_from_file(self):
with open(os.path.join(self.wd, '.yamllint'), 'w') as f:
path = os.path.join(self.wd, '.yamllint')
with open(path, 'w', encoding='utf_8') as f:
f.write('ignore-from-file: [.gitignore, .yamlignore]\n'
'extends: default\n')
with open(os.path.join(self.wd, '.gitignore'), 'w') as f:
path = os.path.join(self.wd, '.gitignore')
with open(path, 'w', encoding='utf_8') as f:
f.write('*.dont-lint-me.yaml\n'
'/bin/\n')
with open(os.path.join(self.wd, '.yamlignore'), 'w') as f:
path = os.path.join(self.wd, '.yamlignore')
with open(path, 'w', encoding='utf_8') as f:
f.write('!/bin/*.lint-me-anyway.yaml\n')

sys.stdout = StringIO()
Expand Down Expand Up @@ -793,7 +801,7 @@ def test_run_with_ignore_with_broken_symlink(self):
cli.run(('-f', 'parsable', '.'))
self.assertNotEqual(ctx.returncode, 0)

with open(os.path.join(wd, '.yamllint'), 'w') as f:
with open(os.path.join(wd, '.yamllint'), 'w', encoding='utf_8') as f:
f.write('extends: default\n'
'ignore: |\n'
' *404.yaml\n')
Expand All @@ -811,7 +819,8 @@ def test_run_with_ignore_with_broken_symlink(self):
shutil.rmtree(wd)

def test_run_with_ignore_on_ignored_file(self):
with open(os.path.join(self.wd, '.yamllint'), 'w') as f:
path = os.path.join(self.wd, '.yamllint')
with open(path, 'w', encoding='utf_8') as f:
f.write('ignore: file.dont-lint-me.yaml\n'
'rules:\n'
' trailing-spaces: enable\n'
Expand Down
6 changes: 4 additions & 2 deletions tests/test_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,14 @@ def setUp(self):
self.wd = tempfile.mkdtemp(prefix='yamllint-tests-')

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

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

Expand Down

0 comments on commit ad21065

Please sign in to comment.