Repository: jmcgeheeiv/pyfakefs (python)

Issue:
No such file or directory in the fake filesystem: b'/tmp'
**Describe the bug**

pyfakefs complains that `/tmp` directory does not exists, despite the [docs stating](https://jmcgeheeiv.github.io/pyfakefs/release/usage.html#os-temporary-directories) that "_This means that any newly created fake file system will always have either a directory named /tmp when running on Linux or Unix systems_"

**How To Reproduce**
Please have a look at this small repo:
https://github.com/Wenzel/bug_pyfakefs

smply run `python -m pytest -v` to reproduce the bug:
~~~Python3
venv/lib/python3.8/site-packages/pyfakefs/fake_filesystem.py:4624: in open
    return fake_open(file, mode, buffering, encoding, errors,
venv/lib/python3.8/site-packages/pyfakefs/fake_filesystem.py:5202: in __call__
    return self.call(*args, **kwargs)
venv/lib/python3.8/site-packages/pyfakefs/fake_filesystem.py:5263: in call
    file_object = self._init_file_object(file_object,
venv/lib/python3.8/site-packages/pyfakefs/fake_filesystem.py:5330: in _init_file_object
    file_object = self.filesystem.create_file_internally(
venv/lib/python3.8/site-packages/pyfakefs/fake_filesystem.py:2608: in create_file_internally
    self.raise_os_error(errno.ENOENT, parent_directory)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <pyfakefs.fake_filesystem.FakeFilesystem object at 0x7f94c2304ac0>, errno = 2, filename = b'/tmp', winerror = None

    def raise_os_error(self, errno, filename=None, winerror=None):
        """Raises OSError.
        The error message is constructed from the given error code and shall
        start with the error string issued in the real system.
        Note: this is not true under Windows if winerror is given - in this
        case a localized message specific to winerror will be shown in the
        real file system.

        Args:
            errno: A numeric error code from the C variable errno.
            filename: The name of the affected file, if any.
            winerror: Windows only - the specific Windows error code.
        """
        message = self._error_message(errno)
        if (winerror is not None and sys.platform == 'win32' and
                self.is_windows_fs):
            raise OSError(errno, message, filename, winerror)
>       raise OSError(errno, message, filename)
E       FileNotFoundError: [Errno 2] No such file or directory in the fake filesystem: b'/tmp'

venv/lib/python3.8/site-packages/pyfakefs/fake_filesystem.py:1010: FileNotFoundError
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
~~~

Going up in the stacktrace:
![Capture d’écran de 2021-05-11 19-50-46](https://user-images.githubusercontent.com/964610/117861908-448d1c80-b292-11eb-9bb8-d497a53e8bee.png)

We see here that an error is raised because /tmp is not found.

**Your environment**
Please run the following and paste the output.
```bash
Linux-5.4.0-73-generic-x86_64-with-glibc2.29
Python 3.8.5 (default, Jan 27 2021, 15:41:15) 
[GCC 9.3.0]
pyfakefs 4.4.0
```



Thanks for your help !

Pull request description:
Fix handling of byte strings in os.path.exists/isfile/islink/isdir/ismount

- fixes #595

Patch:
diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml
index dd2c94f..32b8cce 100644
--- a/.github/workflows/pythonpackage.yml
+++ b/.github/workflows/pythonpackage.yml
@@ -95,17 +95,3 @@ jobs:
           python -m pyfakefs.tests.performance_test
         fi
       shell: bash
-
-  dockertests:
-    runs-on: ubuntu-latest
-    strategy:
-      fail-fast: false
-      matrix:
-        docker-image: [centos, debian, fedora, ubuntu]
-    steps:
-    - uses: actions/checkout@v2
-    - name: Setup docker container
-      run: |
-        docker build -t pyfakefs -f $GITHUB_WORKSPACE/.github/workflows/dockerfiles/Dockerfile_${{ matrix.docker-image }} . --build-arg github_repo=$GITHUB_REPOSITORY --build-arg github_branch=$(basename $GITHUB_REF)
-    - name: Run tests
-      run: docker run -t pyfakefs
diff --git a/CHANGES.md b/CHANGES.md
index 207d240..85a2ea6 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -8,6 +8,10 @@ The released versions correspond to PyPi releases.
      functionality as `pathlib` and is no longer tested separately;
      the previous behavior broke newer `pathlib` features if `pathlib2`
      was installed (see [#592](../../issues/592))
+    
+### Fixes
+  * correctly handle byte paths in `os.path.exists`
+    (see [#595](../../issues/595))
 
 ## [Version 4.4.0](https://pypi.python.org/pypi/pyfakefs/4.4.0) (2021-02-24)
 Adds better support for Python 3.8 / 3.9.
diff --git a/pyfakefs/fake_filesystem.py b/pyfakefs/fake_filesystem.py
index 7f3c889..1e9bfc8 100644
--- a/pyfakefs/fake_filesystem.py
+++ b/pyfakefs/fake_filesystem.py
@@ -1781,7 +1781,7 @@ class FakeFilesystem:
         """
         if check_link and self.islink(file_path):
             return True
-        file_path = make_string_path(file_path)
+        file_path = to_string(make_string_path(file_path))
         if file_path is None:
             raise TypeError
         if not file_path:
@@ -2928,7 +2928,7 @@ class FakeFilesystem:
         Raises:
           TypeError: if path is None
         """
-        path = make_string_path(path)
+        path = to_string(make_string_path(path))
         if path is None:
             raise TypeError
         try:
@@ -3495,7 +3495,7 @@ class FakePathModule:
             Under Windows also returns True for drive and UNC roots
             (independent of their existence).
         """
-        path = make_string_path(path)
+        path = to_string(make_string_path(path))
         if not path:
             return False
         normed_path = self.filesystem.absnormpath(path)


Test patch:
diff --git a/.github/workflows/dockertests.yml b/.github/workflows/dockertests.yml
new file mode 100644
index 0000000..af77346
--- /dev/null
+++ b/.github/workflows/dockertests.yml
@@ -0,0 +1,19 @@
+name: Dockertests
+
+on:
+  [push]
+
+jobs:
+  dockertests:
+    runs-on: ubuntu-latest
+    strategy:
+      fail-fast: false
+      matrix:
+        docker-image: [centos, debian, fedora, ubuntu]
+    steps:
+    - uses: actions/checkout@v2
+    - name: Setup docker container
+      run: |
+        docker build -t pyfakefs -f $GITHUB_WORKSPACE/.github/workflows/dockerfiles/Dockerfile_${{ matrix.docker-image }} . --build-arg github_repo=$GITHUB_REPOSITORY --build-arg github_branch=$(basename $GITHUB_REF)
+    - name: Run tests
+      run: docker run -t pyfakefs
diff --git a/pyfakefs/tests/fake_filesystem_test.py b/pyfakefs/tests/fake_filesystem_test.py
index d9b841f..adbd50d 100644
--- a/pyfakefs/tests/fake_filesystem_test.py
+++ b/pyfakefs/tests/fake_filesystem_test.py
@@ -857,8 +857,8 @@ class FakePathModuleTest(TestCase):
     def check_abspath(self, is_windows):
         # the implementation differs in Windows and Posix, so test both
         self.filesystem.is_windows_fs = is_windows
-        filename = u'foo'
-        abspath = u'!%s' % filename
+        filename = 'foo'
+        abspath = '!%s' % filename
         self.filesystem.create_file(abspath)
         self.assertEqual(abspath, self.path.abspath(abspath))
         self.assertEqual(abspath, self.path.abspath(filename))
@@ -914,10 +914,14 @@ class FakePathModuleTest(TestCase):
     def test_isabs_with_drive_component(self):
         self.filesystem.is_windows_fs = False
         self.assertFalse(self.path.isabs('C:!foo'))
+        self.assertFalse(self.path.isabs(b'C:!foo'))
         self.assertTrue(self.path.isabs('!'))
+        self.assertTrue(self.path.isabs(b'!'))
         self.filesystem.is_windows_fs = True
         self.assertTrue(self.path.isabs('C:!foo'))
+        self.assertTrue(self.path.isabs(b'C:!foo'))
         self.assertTrue(self.path.isabs('!'))
+        self.assertTrue(self.path.isabs(b'!'))
 
     def test_relpath(self):
         path_foo = '!path!to!foo'
@@ -957,46 +961,53 @@ class FakePathModuleTest(TestCase):
         self.assertFalse(self.path.samefile(file_path1, file_path2))
         self.assertTrue(
             self.path.samefile(file_path1, '!foo!..!foo!bar!..!bar!baz'))
+        self.assertTrue(
+            self.path.samefile(file_path1, b'!foo!..!foo!bar!..!bar!baz'))
 
     def test_exists(self):
         file_path = 'foo!bar!baz'
+        file_path_bytes = b'foo!bar!baz'
         self.filesystem.create_file(file_path)
         self.assertTrue(self.path.exists(file_path))
+        self.assertTrue(self.path.exists(file_path_bytes))
         self.assertFalse(self.path.exists('!some!other!bogus!path'))
 
     def test_lexists(self):
         file_path = 'foo!bar!baz'
+        file_path_bytes = b'foo!bar!baz'
         self.filesystem.create_dir('foo!bar')
         self.filesystem.create_symlink(file_path, 'bogus')
         self.assertTrue(self.path.lexists(file_path))
+        self.assertTrue(self.path.lexists(file_path_bytes))
         self.assertFalse(self.path.exists(file_path))
+        self.assertFalse(self.path.exists(file_path_bytes))
         self.filesystem.create_file('foo!bar!bogus')
         self.assertTrue(self.path.exists(file_path))
 
     def test_dirname_with_drive(self):
         self.filesystem.is_windows_fs = True
-        self.assertEqual(u'c:!foo',
-                         self.path.dirname(u'c:!foo!bar'))
+        self.assertEqual('c:!foo',
+                         self.path.dirname('c:!foo!bar'))
         self.assertEqual(b'c:!',
                          self.path.dirname(b'c:!foo'))
-        self.assertEqual(u'!foo',
-                         self.path.dirname(u'!foo!bar'))
+        self.assertEqual('!foo',
+                         self.path.dirname('!foo!bar'))
         self.assertEqual(b'!',
                          self.path.dirname(b'!foo'))
-        self.assertEqual(u'c:foo',
-                         self.path.dirname(u'c:foo!bar'))
+        self.assertEqual('c:foo',
+                         self.path.dirname('c:foo!bar'))
         self.assertEqual(b'c:',
                          self.path.dirname(b'c:foo'))
-        self.assertEqual(u'foo',
-                         self.path.dirname(u'foo!bar'))
+        self.assertEqual('foo',
+                         self.path.dirname('foo!bar'))
 
     def test_dirname(self):
         dirname = 'foo!bar'
         self.assertEqual(dirname, self.path.dirname('%s!baz' % dirname))
 
     def test_join_strings(self):
-        components = [u'foo', u'bar', u'baz']
-        self.assertEqual(u'foo!bar!baz', self.path.join(*components))
+        components = ['foo', 'bar', 'baz']
+        self.assertEqual('foo!bar!baz', self.path.join(*components))
 
     def test_join_bytes(self):
         components = [b'foo', b'bar', b'baz']
@@ -1031,8 +1042,10 @@ class FakePathModuleTest(TestCase):
 
     def test_getsize_file_non_zero_size(self):
         file_path = 'foo!bar!baz'
+        file_path_bytes = b'foo!bar!baz'
         self.filesystem.create_file(file_path, contents='1234567')
         self.assertEqual(7, self.path.getsize(file_path))
+        self.assertEqual(7, self.path.getsize(file_path_bytes))
 
     def test_getsize_dir_empty(self):
         # For directories, only require that the size is non-negative.
@@ -1053,6 +1066,7 @@ class FakePathModuleTest(TestCase):
     def test_isdir(self):
         self.filesystem.create_file('foo!bar')
         self.assertTrue(self.path.isdir('foo'))
+        self.assertTrue(self.path.isdir(b'foo'))
         self.assertFalse(self.path.isdir('foo!bar'))
         self.assertFalse(self.path.isdir('it_dont_exist'))
 
@@ -1071,6 +1085,7 @@ class FakePathModuleTest(TestCase):
         self.filesystem.create_file('foo!bar')
         self.assertFalse(self.path.isfile('foo'))
         self.assertTrue(self.path.isfile('foo!bar'))
+        self.assertTrue(self.path.isfile(b'foo!bar'))
         self.assertFalse(self.path.isfile('it_dont_exist'))
 
     def test_get_mtime(self):
@@ -1079,6 +1094,7 @@ class FakePathModuleTest(TestCase):
         self.assertEqual(10, test_file.st_mtime)
         test_file.st_mtime = 24
         self.assertEqual(24, self.path.getmtime('foo!bar1.txt'))
+        self.assertEqual(24, self.path.getmtime(b'foo!bar1.txt'))
 
     def test_get_mtime_raises_os_error(self):
         self.assertFalse(self.path.exists('it_dont_exist'))
@@ -1095,6 +1111,8 @@ class FakePathModuleTest(TestCase):
         # comments in Python/Lib/posixpath.py.
         self.assertTrue(self.path.islink('foo!link_to_file'))
         self.assertTrue(self.path.isfile('foo!link_to_file'))
+        self.assertTrue(self.path.islink(b'foo!link_to_file'))
+        self.assertTrue(self.path.isfile(b'foo!link_to_file'))
 
         self.assertTrue(self.path.isfile('foo!regular_file'))
         self.assertFalse(self.path.islink('foo!regular_file'))
@@ -1111,9 +1129,11 @@ class FakePathModuleTest(TestCase):
     def test_ismount(self):
         self.assertFalse(self.path.ismount(''))
         self.assertTrue(self.path.ismount('!'))
+        self.assertTrue(self.path.ismount(b'!'))
         self.assertFalse(self.path.ismount('!mount!'))
         self.filesystem.add_mount_point('!mount')
         self.assertTrue(self.path.ismount('!mount'))
+        self.assertTrue(self.path.ismount(b'!mount'))
         self.assertTrue(self.path.ismount('!mount!'))
 
     def test_ismount_with_drive_letters(self):