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

FakeFileOpen keyword args do not match the __builtin__ equivalents. #5

Closed
GoogleCodeExporter opened this issue Mar 16, 2015 · 4 comments
Labels

Comments

@GoogleCodeExporter
Copy link

I expect to be able to do the following:

#!/usr/bin/python
import fake_filesystem as fakefs

def main():
  fs = fakefs.FakeFilesystem()
  exec('open = fakefs.FakeFileOpen(fs)')
  exec('file = fakefs.FakeFileOpen(fs)')
  open(name='/foo', mode='w', buffering=1)
  file(filename='/bar', mode='w', bufsize=1)

if __name__ == '__main__': main()


I expect to see NO output.  Instead I see:

Traceback (most recent call last):
  File "./test.py", line 13, in <module>
    if __name__ == '__main__': main()
  File "./test.py", line 10, in main
    open(name='/foo', mode='w', buffering=1)
TypeError: __call__() got an unexpected keyword argument 'buffering'


I'm seeing this with the latest sources in Linux.  However, this defect should 
affect all operating systems considering that the Python open and file 
documentation describe the standard named arguments as 'mode' and either 
'buffering' or 'bufsize' (it's different for file and open).  The current code 
only supports named arguments 'flags' and 'bufsize'.
http://docs.python.org/library/functions.html#file
http://docs.python.org/library/functions.html#open


Here is my patch:
me@localhost:~/code/pyfakefs$ hg diff
diff -r 50ec7acd8b72 fake_filesystem.py
--- a/fake_filesystem.py    Sat Jun 11 13:57:58 2011 -0400
+++ b/fake_filesystem.py    Sat May 12 00:09:30 2012 -0700
@@ -2006,6 +2006,54 @@
     return fakefile


+class FakeFileBuiltin(FakeFileOpen):
+  """Faked file() function replacement.
+
+  Returns FakeFile objects in a FakeFilesystem in place of the file() function.
+  """
+  def __call__(self, filename, mode='r', bufsize=-1):
+    """Returns a StringIO object with the contents of the target file object.
+
+    Args:
+      filename: path to target file
+      mode: additional file flags. All r/w/a r+/w+/a+ flags are supported.
+        't', 'b', and 'U' are ignored, e.g., 'wb' is treated as 'w'.
+      bufsize: ignored. (Used for signature compliance with __builtin__.file)
+
+    Returns:
+      a StringIO object containing the contents of the target file
+
+    Raises:
+      IOError: if the target object is a directory, the path is invalid or
+        permission is denied.
+    """
+    return FakeFileOpen.__call__(self, filename, mode, bufsize)
+
+
+class FakeOpenBuiltin(FakeFileOpen):
+  """Faked open() function replacement.
+
+  Returns FakeFile objects in a FakeFilesystem in place of the open() function.
+  """
+  def __call__(self, name, mode='r', buffering=-1):
+    """Returns a StringIO object with the contents of the target file object.
+
+    Args:
+      name: path to target file
+      mode: additional file flags. All r/w/a r+/w+/a+ flags are supported.
+        't', 'b', and 'U' are ignored, e.g., 'wb' is treated as 'w'.
+      buffering: ignored. (Used for signature compliance with __builtin__.open)
+
+    Returns:
+      a StringIO object containing the contents of the target file
+
+    Raises:
+      IOError: if the target object is a directory, the path is invalid or
+        permission is denied.
+    """
+    return FakeFileOpen.__call__(self, name, mode, buffering)
+
+
 def _RunDoctest():
   # pylint: disable-msg=C6204
   import doctest


Here is a dumb test program that demonstrates the named arguments are now 
correct:
#!/usr/bin/python
import fake_filesystem as fakefs

def main():
  fs = fakefs.FakeFilesystem()
  exec('open = fakefs.FakeOpenBuiltin(fs)')
  exec('file = fakefs.FakeFileBuiltin(fs)')
  open(name='/foo', mode='w', buffering=1)
  file(filename='/bar', mode='w', bufsize=1)

if __name__ == '__main__': main()


I would have submitted this patch through mercurial, but the Code Contribution 
page appears to be under construction.

Original issue reported on code.google.com by carl.and...@gmail.com on 12 May 2012 at 7:17

Attachments:

@GoogleCodeExporter
Copy link
Author

Oh, and it looks like open has changed the name of its first argument from 
'filename' to 'name' sometime between Python 2.6 and 2.7.

Original comment by carl.and...@gmail.com on 12 May 2012 at 7:34

@GoogleCodeExporter
Copy link
Author

I'm seeing:
 open(name,mode,buffering) on 2.4, 2.6, 2.7.
 file(name,mode,buffering) on 2.4, 2.6, 2.7.
 open(file,mode,buffering) on 3.1.
(which are the pythons I have immediate access to)
So the documentation for file() is lying - http://bugs.python.org/issue15572 .
It used to lie in the same way about open() but that was fixed at some point on 
2.7 - http://hg.python.org/cpython/rev/5da7924c4775 .

So there is no point having separate FakeOpenBuiltin / FakeFileBuiltin,
but the args of FakeFileOpen.__call__() should be fixed.

3.x:
Correctly documented at http://docs.python.org/dev/library/functions.html#open
Given the arg rename, anyone who passes the path by keyword arg is asking for 
trouble.
I'm not sure if we care about 3.x compatibility at this point - has fakefs been 
tested on 3.x at all?
Also, 3.x open() has many additional args that fakefs doesn't accept.

Original comment by b...@google.com on 7 Aug 2012 at 11:10

@GoogleCodeExporter
Copy link
Author

The builtin open() and file() calls need to work for Pyhon 3's new arguments.

Original comment by dba...@google.com on 21 May 2013 at 9:02

  • Changed state: Started

@GoogleCodeExporter
Copy link
Author

This issue was closed by revision 9576cce51abb.

Original comment by dba...@google.com on 24 May 2013 at 9:51

  • Changed state: Fixed

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