Skip to content

Commit bf5e960

Browse files
committed
Issue #20289: cgi.FieldStorage() now supports the context management protocol.
1 parent 088ca8b commit bf5e960

File tree

5 files changed

+35
-6
lines changed

5 files changed

+35
-6
lines changed

Doc/library/cgi.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,9 @@ return bytes)::
157157
if not line: break
158158
linecount = linecount + 1
159159

160+
:class:`FieldStorage` objects also support being used in a :keyword:`with`
161+
statement, which will automatically close them when done.
162+
160163
If an error is encountered when obtaining the contents of an uploaded file
161164
(for example, when the user interrupts the form submission by clicking on
162165
a Back or Cancel button) the :attr:`~FieldStorage.done` attribute of the
@@ -182,6 +185,10 @@ A form submitted via POST that also has a query string will contain both
182185
The :attr:`~FieldStorage.file` attribute is automatically closed upon the
183186
garbage collection of the creating :class:`FieldStorage` instance.
184187

188+
.. versionchanged:: 3.5
189+
Added support for the context management protocol to the
190+
:class:`FieldStorage` class.
191+
185192

186193
Higher Level Interface
187194
----------------------

Doc/whatsnew/3.5.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,12 @@ New Modules
136136
Improved Modules
137137
================
138138

139+
cgi
140+
---
141+
142+
* :class:`FieldStorage` now supports the context management protocol.
143+
(Contributed by Berker Peksag in :issue:`20289`.)
144+
139145
code
140146
----
141147

Lib/cgi.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,12 @@ def __del__(self):
566566
except AttributeError:
567567
pass
568568

569+
def __enter__(self):
570+
return self
571+
572+
def __exit__(self, *args):
573+
self.file.close()
574+
569575
def __repr__(self):
570576
"""Return a printable representation."""
571577
return "FieldStorage(%r, %r, %r)" % (

Lib/test/test_cgi.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from test.support import run_unittest, check_warnings
1+
from test.support import check_warnings
22
import cgi
33
import os
44
import sys
@@ -307,6 +307,17 @@ def test_fieldstorage_multipart_w3c(self):
307307
got = getattr(files[x], k)
308308
self.assertEqual(got, exp)
309309

310+
def test_fieldstorage_as_context_manager(self):
311+
fp = BytesIO(b'x' * 10)
312+
env = {'REQUEST_METHOD': 'PUT'}
313+
with cgi.FieldStorage(fp=fp, environ=env) as fs:
314+
content = fs.file.read()
315+
self.assertFalse(fs.file.closed)
316+
self.assertTrue(fs.file.closed)
317+
self.assertEqual(content, 'x' * 10)
318+
with self.assertRaisesRegex(ValueError, 'I/O operation on closed file'):
319+
fs.file.read()
320+
310321
_qs_result = {
311322
'key1': 'value1',
312323
'key2': ['value2x', 'value2y'],
@@ -481,9 +492,5 @@ def test_parse_header(self):
481492
--AaB03x--
482493
"""
483494

484-
485-
def test_main():
486-
run_unittest(CgiTests)
487-
488495
if __name__ == '__main__':
489-
test_main()
496+
unittest.main()

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,9 @@ Core and Builtins
235235
Library
236236
-------
237237

238+
- Issue #20289: cgi.FieldStorage() now supports the context management
239+
protocol.
240+
238241
- Issue #13128: Print response headers for CONNECT requests when debuglevel
239242
> 0. Patch by Demian Brecht.
240243

0 commit comments

Comments
 (0)