Skip to content
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

Cannot os.remove a file after calling os.DirEntry.stat() on it #502

Closed
radoslawg opened this issue Nov 13, 2019 · 3 comments
Closed

Cannot os.remove a file after calling os.DirEntry.stat() on it #502

radoslawg opened this issue Nov 13, 2019 · 3 comments
Labels

Comments

@radoslawg
Copy link

Describe the bug
When a os.scandir() is followed by stat() function on a file, pyfakefs refuses to os.remove the file ending with Except.

How To Reproduce
Consider following testcase:

def test_perm_bug(fs):
    fs.create_file('\\phonyDir\\testfile', contents='test')
    x = os.scandir('\\phonyDir')
    for z in x:
        print(z.stat().st_size)
    x.close()
    os.remove('\\phonyDir\\testfile')

it ends with

c:\home\mojepliki\python\dupfinder\lib\site-packages\pyfakefs\fake_filesystem.py:4143: in remove
    self.filesystem.remove(path)
c:\home\mojepliki\python\dupfinder\lib\site-packages\pyfakefs\fake_filesystem.py:3028: in remove
    self.remove_object(norm_path)
c:\home\mojepliki\python\dupfinder\lib\site-packages\pyfakefs\fake_filesystem.py:2295: in remove_object
    target_directory.remove_entry(basename)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <pyfakefs.fake_filesystem.FakeDirectory object at 0x000002D3BC0F3788>
pathname_name = 'testfile', recursive = True

    def remove_entry(self, pathname_name, recursive=True):
        """Removes the specified child file or directory.
    
        Args:
            pathname_name: Basename of the child object to remove.
            recursive: If True (default), the entries in contained directories
                are deleted first. Used to propagate removal errors
                (e.g. permission problems) from contained entries.
    
        Raises:
            KeyError: if no child exists by the specified name.
            OSError: if user lacks permission to delete the file,
                or (Windows only) the file is open.
        """
        pathname_name = self._normalized_entryname(pathname_name)
        entry = self.get_entry(pathname_name)
        if self.filesystem.is_windows_fs:
            if entry.st_mode & PERM_WRITE == 0:
                self.filesystem.raise_os_error(errno.EACCES, pathname_name)
            if self.filesystem.has_open_file(entry):
                self.filesystem.raise_os_error(errno.EACCES, pathname_name)
        else:
            if (not is_root() and (self.st_mode & (PERM_WRITE | PERM_EXE) !=
                                   PERM_WRITE | PERM_EXE)):
                self.filesystem.raise_os_error(errno.EACCES, pathname_name)
    
        if recursive and isinstance(entry, FakeDirectory):
            while entry.contents:
                entry.remove_entry(list(entry.contents)[0])
        elif entry.st_nlink == 1:
            self.filesystem.change_disk_usage(
                -entry.size, pathname_name, entry.st_dev)
    
        self.st_nlink -= 1
        entry.st_nlink -= 1
>       assert entry.st_nlink >= 0
E       assert -1 >= 0
E        +  where -1 = <pyfakefs.fake_filesystem.FakeFile object at 0x000002D3BC0F3548>.st_nlink

c:\home\mojepliki\python\dupfinder\lib\site-packages\pyfakefs\fake_filesystem.py:738: AssertionError

Your enviroment

Windows-10-10.0.18362-SP0
Python 3.7.5 (tags/v3.7.5:5c02a39a0b, Oct 15 2019, 00:11:34) [MSC v.1916 64 bit (AMD64)]
pyfakefs 3.6.1

Workaround is to use os.stat() instead of os.DirEntry.stat() .

@mrbean-bremen
Copy link
Member

Thanks for the report - looks really strange...

@radoslawg
Copy link
Author

Maybe I'm missing something, but I cannot find any clue in python documentation. Also, it works on real fs, so it seems it is limited only to pyfakefs .

mrbean-bremen added a commit to mrbean-bremen/pyfakefs that referenced this issue Nov 13, 2019
- st_nlink of the file object was set to 0 (instead of the stat result)
- fixes pytest-dev#502
@mrbean-bremen
Copy link
Member

Yes, it's a bug in pyfakefs (Windows only) - I'm on it. Good catch!

mrbean-bremen added a commit to mrbean-bremen/pyfakefs that referenced this issue Nov 13, 2019
- st_nlink of the file object was set to 0 (instead of the stat result)
- fixes pytest-dev#502
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants