Skip to content

Commit c256c01

Browse files
committed
Fix patching "open" calls in modules with a name ending with "io"
- adapted test that sometimes fail due to timing issue - fixes #569
1 parent 1b57df8 commit c256c01

7 files changed

+39
-6
lines changed

CHANGES.md

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ The released versions correspond to PyPi releases.
33

44
## Version 4.4.0 (as yet unreleased)
55

6+
### Fixes
7+
* `open` calls had not been patched for modules with a name ending with "io"
8+
(see [#569](../../issues/569))
9+
610
## [Version 4.3.1](https://pypi.python.org/pypi/pyfakefs/4.3.1) (2020-11-23)
711

812
This is an update to the performance release, with more setup caching and the

pyfakefs/fake_filesystem.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -4563,7 +4563,8 @@ def open(self, file, mode='r', buffering=-1, encoding=None,
45634563
stack = traceback.extract_stack(limit=2)
45644564
module_name = os.path.splitext(stack[0].filename)[0]
45654565
module_name = module_name.replace(os.sep, '.')
4566-
if any([module_name.endswith(sn) for sn in self.skip_names]):
4566+
if any([module_name == sn or module_name.endswith('.' + sn)
4567+
for sn in self.skip_names]):
45674568
return io.open(file, mode, buffering, encoding, errors,
45684569
newline, closefd, opener)
45694570
fake_open = FakeFileOpen(self.filesystem)

pyfakefs/fake_filesystem_unittest.py

-2
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,6 @@ def __init__(self, additional_skip_names=None,
432432
self._skip_names = self.SKIPNAMES.copy()
433433
# save the original open function for use in pytest plugin
434434
self.original_open = open
435-
self.fake_open = None
436435
self.patch_open_code = patch_open_code
437436

438437
if additional_skip_names is not None:
@@ -701,7 +700,6 @@ def _refresh(self):
701700
if hasattr(self.fake_modules[name], 'skip_names'):
702701
self.fake_modules[name].skip_names = self._skip_names
703702
self.fake_modules[PATH_MODULE] = self.fake_modules['os'].path
704-
self.fake_open = fake_filesystem.FakeFileOpen(self.fs)
705703
for name in self._unfaked_module_classes:
706704
self.unfaked_modules[name] = self._unfaked_module_classes[name]()
707705

pyfakefs/tests/fake_filesystem_unittest_test.py

+8
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
from unittest import TestCase, mock
3333

3434
import pyfakefs.tests.import_as_example
35+
import pyfakefs.tests.logsio
3536
from pyfakefs import fake_filesystem_unittest, fake_filesystem
3637
from pyfakefs.extra_packages import pathlib
3738
from pyfakefs.fake_filesystem import OSType
@@ -343,6 +344,13 @@ def test_open_fails(self):
343344
with self.assertRaises(OSError):
344345
pyfakefs.tests.import_as_example.open_this_file()
345346

347+
def test_open_patched_in_module_ending_with_io(self):
348+
# regression test for #569
349+
file_path = '/foo/bar'
350+
self.fs.create_file(file_path, contents=b'abc')
351+
contents = pyfakefs.tests.logsio.file_contents(file_path)
352+
self.assertEqual(b'abc', contents)
353+
346354

347355
class AdditionalSkipNamesTest(fake_filesystem_unittest.TestCase):
348356
"""Make sure that modules in additional_skip_names are not patched.

pyfakefs/tests/fake_open_test.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1895,7 +1895,7 @@ def test_chdir_uses_open_fd_as_path(self):
18951895
# unclear behavior with PyPi
18961896
self.skip_real_fs()
18971897
self.assert_raises_os_error(
1898-
[errno.ENOTDIR, errno.EBADF], self.os.chdir, 10)
1898+
[errno.ENOTDIR, errno.EBADF], self.os.chdir, 500)
18991899
dir_path = self.make_path('foo', 'bar')
19001900
self.create_dir(dir_path)
19011901

pyfakefs/tests/fake_stat_time_test.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -334,8 +334,8 @@ def check_open_write_flush_close_w_mode(self):
334334
"""
335335
before, opened, written, flushed, closed = self.open_write_flush()
336336

337-
self.assertLessExceptWindows(before.st_ctime, opened.st_ctime)
338-
self.assertLessExceptWindows(written.st_ctime, flushed.st_ctime)
337+
self.assertLessEqual(before.st_ctime, opened.st_ctime)
338+
self.assertLessEqual(written.st_ctime, flushed.st_ctime)
339339
self.assertEqual(opened.st_ctime, written.st_ctime)
340340
self.assertEqual(flushed.st_ctime, closed.st_ctime)
341341

pyfakefs/tests/logsio.py

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License");
2+
# you may not use this file except in compliance with the License.
3+
# You may obtain a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS,
9+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
# See the License for the specific language governing permissions and
11+
# limitations under the License.
12+
13+
"""
14+
Example module that is used for a regression test where a module with
15+
a name ending with "io" was skipped from patching (see #569).
16+
"""
17+
18+
19+
def file_contents(path):
20+
"""Return the contents of the given path as byte array."""
21+
with open(path, 'rb') as f:
22+
return f.read()

0 commit comments

Comments
 (0)