Browse Source

Fixed #34642 -- Added File.open() support for *args and **kwargs.

Yves Weissig 1 year ago
parent
commit
369b498219
5 changed files with 27 additions and 5 deletions
  1. 1 0
      AUTHORS
  2. 2 2
      django/core/files/base.py
  3. 7 2
      docs/ref/files/file.txt
  4. 2 1
      docs/releases/5.0.txt
  5. 15 0
      tests/files/tests.py

+ 1 - 0
AUTHORS

@@ -1053,6 +1053,7 @@ answer newbie questions, and generally made Django that much better:
     Yoong Kang Lim <yoongkang.lim@gmail.com>
     Yury V. Zaytsev <yury@shurup.com>
     Yusuke Miyazaki <miyazaki.dev@gmail.com>
+    Yves Weissig <yves@weissig.me>
     yyyyyyyan <contact@yyyyyyyan.tech>
     Zac Hatfield-Dodds <zac.hatfield.dodds@gmail.com>
     Zachary Voase <zacharyvoase@gmail.com>

+ 2 - 2
django/core/files/base.py

@@ -105,11 +105,11 @@ class File(FileProxyMixin):
     def __exit__(self, exc_type, exc_value, tb):
         self.close()
 
-    def open(self, mode=None):
+    def open(self, mode=None, *args, **kwargs):
         if not self.closed:
             self.seek(0)
         elif self.name and os.path.exists(self.name):
-            self.file = open(self.name, mode or self.mode)
+            self.file = open(self.name, mode or self.mode, *args, **kwargs)
         else:
             raise ValueError("The file cannot be reopened.")
         return self

+ 7 - 2
docs/ref/files/file.txt

@@ -46,11 +46,12 @@ The ``File`` class
 
         The read/write mode for the file.
 
-    .. method:: open(mode=None)
+    .. method:: open(mode=None, *args, **kwargs)
 
         Open or reopen the file (which also does ``File.seek(0)``).
         The ``mode`` argument allows the same values
-        as Python's built-in :func:`python:open()`.
+        as Python's built-in :func:`python:open()`. ``*args`` and ``**kwargs``
+        are passed after ``mode`` to Python's built-in :func:`python:open`.
 
         When reopening a file, ``mode`` will override whatever mode the file
         was originally opened with; ``None`` means to reopen with the original
@@ -58,6 +59,10 @@ The ``File`` class
 
         It can be used as a context manager, e.g. ``with file.open() as f:``.
 
+        .. versionchanged:: 5.0
+
+            Support for passing ``*args`` and ``**kwargs`` was added.
+
     .. method:: __iter__()
 
         Iterate over the file yielding one line at a time.

+ 2 - 1
docs/releases/5.0.txt

@@ -352,7 +352,8 @@ Error Reporting
 File Storage
 ~~~~~~~~~~~~
 
-* ...
+* :meth:`.File.open` now passes all positional (``*args``) and keyword
+  arguments (``**kwargs``) to Python's built-in :func:`python:open`.
 
 File Uploads
 ~~~~~~~~~~~~

+ 15 - 0
tests/files/tests.py

@@ -200,6 +200,21 @@ class FileTests(unittest.TestCase):
             self.assertIs(locks.unlock(f1), True)
             self.assertIs(locks.unlock(f2), True)
 
+    def test_open_supports_full_signature(self):
+        called = False
+
+        def opener(path, flags):
+            nonlocal called
+            called = True
+            return os.open(path, flags)
+
+        file_path = Path(__file__).parent / "test.png"
+        with open(file_path) as f:
+            test_file = File(f)
+
+        with test_file.open(opener=opener):
+            self.assertIs(called, True)
+
 
 class NoNameFileTestCase(unittest.TestCase):
     """