Skip to content

Open binary no encoding #665

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ The released versions correspond to PyPi releases.
* correctly handle file system space for files opened in write mode
(see [#660](../../issues/660))
* correctly handle reading/writing pipes via file
(see [#661](../../issues/661))
(see [#661](../../issues/661))
* disallow `encoding` argument on binary `open()`
(see [#664](../../issues/664))

## [Version 4.5.4](https://pypi.python.org/pypi/pyfakefs/4.5.4) (2022-01-12)
Minor bugfix release.
Expand Down
4 changes: 4 additions & 0 deletions pyfakefs/fake_filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -5571,6 +5571,10 @@ def call(self, file_: Union[AnyStr, int],
ValueError: for an invalid mode or mode combination
"""
binary = 'b' in mode

if binary and encoding:
raise ValueError("binary mode doesn't take an encoding argument")

newline, open_modes = self._handle_file_mode(mode, newline, open_modes)

file_object, file_path, filedes, real_path = self._handle_file_arg(
Expand Down
56 changes: 56 additions & 0 deletions pyfakefs/tests/fake_filesystem_vs_real_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,50 @@ def assertFileHandleBehaviorsMatch(self, path, mode, data):
self.fail('Behaviors do not match for %s:\n %s' %
(path, '\n '.join(differences)))

def assertFileHandleOpenBehaviorsMatch(self, *args, **kwargs):
"""Compare open() function invocation between real and fake.

Runs open(*args, **kwargs) on both real and fake.

Args:
*args: args to pass through to open()
**kwargs: kwargs to pass through to open().

Returns:
None.

Raises:
AssertionError if underlying open() behavior differs from fake.
"""
real_err = None
fake_err = None
try:
with open(*args, **kwargs):
pass
except Exception as e: # pylint: disable-msg=W0703
real_err = e

try:
with self.fake_open(*args, **kwargs):
pass
except Exception as e: # pylint: disable-msg=W0703
fake_err = e

# default equal in case one is None and other is not.
is_exception_equal = (real_err == fake_err)
if real_err and fake_err:
# exception __eq__ doesn't evaluate equal ever, thus manual check.
is_exception_equal = (type(real_err) is type(fake_err) and
real_err.args == fake_err.args)

if not is_exception_equal:
msg = (
"Behaviors don't match on open with args %s & kwargs %s.\n" %
(args, kwargs))
real_err_msg = 'Real open results in: %s\n' % repr(real_err)
fake_err_msg = 'Fake open results in: %s\n' % repr(fake_err)
self.fail(msg + real_err_msg + fake_err_msg)

# Helpers for checks which are not straight method calls.
@staticmethod
def _access_real(path):
Expand Down Expand Up @@ -635,6 +679,18 @@ def test_builtin_open_modes(self):
self.assertFileHandleBehaviorsMatch('write', 'wb', 'other contents')
self.assertFileHandleBehaviorsMatch('append', 'ab', 'other contents')

# binary cannot have encoding
self.assertFileHandleOpenBehaviorsMatch('read', 'rb', encoding='enc')
self.assertFileHandleOpenBehaviorsMatch(
'write', mode='wb', encoding='enc')
self.assertFileHandleOpenBehaviorsMatch('append', 'ab', encoding='enc')

# text can have encoding
self.assertFileHandleOpenBehaviorsMatch('read', 'r', encoding='utf-8')
self.assertFileHandleOpenBehaviorsMatch('write', 'w', encoding='utf-8')
self.assertFileHandleOpenBehaviorsMatch(
'append', 'a', encoding='utf-8')


def main(_):
unittest.main()
Expand Down