Skip to content

Commit 80daca8

Browse files
yaythomasmrbean-bremen
authored andcommitted
Open binary no encoding
On open() binary mode should not allow an encoding argument. If encoding is passed with binary mode, raise: ValueError(binary mode doesn\'t take an encoding argument) Closes #664.
1 parent 4dc8615 commit 80daca8

File tree

3 files changed

+63
-1
lines changed

3 files changed

+63
-1
lines changed

CHANGES.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ The released versions correspond to PyPi releases.
77
* correctly handle file system space for files opened in write mode
88
(see [#660](../../issues/660))
99
* correctly handle reading/writing pipes via file
10-
(see [#661](../../issues/661))
10+
(see [#661](../../issues/661))
11+
* disallow `encoding` argument on binary `open()`
12+
(see [#664](../../issues/664))
1113

1214
## [Version 4.5.4](https://pypi.python.org/pypi/pyfakefs/4.5.4) (2022-01-12)
1315
Minor bugfix release.

pyfakefs/fake_filesystem.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5571,6 +5571,10 @@ def call(self, file_: Union[AnyStr, int],
55715571
ValueError: for an invalid mode or mode combination
55725572
"""
55735573
binary = 'b' in mode
5574+
5575+
if binary and encoding:
5576+
raise ValueError("binary mode doesn't take an encoding argument")
5577+
55745578
newline, open_modes = self._handle_file_mode(mode, newline, open_modes)
55755579

55765580
file_object, file_path, filedes, real_path = self._handle_file_arg(

pyfakefs/tests/fake_filesystem_vs_real_test.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,50 @@ def assertFileHandleBehaviorsMatch(self, path, mode, data):
399399
self.fail('Behaviors do not match for %s:\n %s' %
400400
(path, '\n '.join(differences)))
401401

402+
def assertFileHandleOpenBehaviorsMatch(self, *args, **kwargs):
403+
"""Compare open() function invocation between real and fake.
404+
405+
Runs open(*args, **kwargs) on both real and fake.
406+
407+
Args:
408+
*args: args to pass through to open()
409+
**kwargs: kwargs to pass through to open().
410+
411+
Returns:
412+
None.
413+
414+
Raises:
415+
AssertionError if underlying open() behavior differs from fake.
416+
"""
417+
real_err = None
418+
fake_err = None
419+
try:
420+
with open(*args, **kwargs):
421+
pass
422+
except Exception as e: # pylint: disable-msg=W0703
423+
real_err = e
424+
425+
try:
426+
with self.fake_open(*args, **kwargs):
427+
pass
428+
except Exception as e: # pylint: disable-msg=W0703
429+
fake_err = e
430+
431+
# default equal in case one is None and other is not.
432+
is_exception_equal = (real_err == fake_err)
433+
if real_err and fake_err:
434+
# exception __eq__ doesn't evaluate equal ever, thus manual check.
435+
is_exception_equal = (type(real_err) is type(fake_err) and
436+
real_err.args == fake_err.args)
437+
438+
if not is_exception_equal:
439+
msg = (
440+
"Behaviors don't match on open with args %s & kwargs %s.\n" %
441+
(args, kwargs))
442+
real_err_msg = 'Real open results in: %s\n' % repr(real_err)
443+
fake_err_msg = 'Fake open results in: %s\n' % repr(fake_err)
444+
self.fail(msg + real_err_msg + fake_err_msg)
445+
402446
# Helpers for checks which are not straight method calls.
403447
@staticmethod
404448
def _access_real(path):
@@ -635,6 +679,18 @@ def test_builtin_open_modes(self):
635679
self.assertFileHandleBehaviorsMatch('write', 'wb', 'other contents')
636680
self.assertFileHandleBehaviorsMatch('append', 'ab', 'other contents')
637681

682+
# binary cannot have encoding
683+
self.assertFileHandleOpenBehaviorsMatch('read', 'rb', encoding='enc')
684+
self.assertFileHandleOpenBehaviorsMatch(
685+
'write', mode='wb', encoding='enc')
686+
self.assertFileHandleOpenBehaviorsMatch('append', 'ab', encoding='enc')
687+
688+
# text can have encoding
689+
self.assertFileHandleOpenBehaviorsMatch('read', 'r', encoding='utf-8')
690+
self.assertFileHandleOpenBehaviorsMatch('write', 'w', encoding='utf-8')
691+
self.assertFileHandleOpenBehaviorsMatch(
692+
'append', 'a', encoding='utf-8')
693+
638694

639695
def main(_):
640696
unittest.main()

0 commit comments

Comments
 (0)