Title: Add __iter__ support for mock_open
Type: behavior Stage: patch review
Components: Library (Lib) Versions: Python 3.6, Python 3.5, Python 3.4
Status: open Resolution:
Dependencies: Superseder:
Assigned To: michael.foord Nosy List: Arve.Knudsen, José.Luis.Lafuente, berker.peksag, frenzy, gms, kushal.das, michael.foord, mucka, pkoning
Priority: normal Keywords: patch

Created on 2014-04-16 17:56 by michael.foord, last changed 2018-02-15 09:27 by frenzy.

File name Uploaded Description Edit
213.patch michael.foord, 2014-04-16 17:56
mock.diff pkoning, 2014-06-12 17:44 Patch for bug review
testwith.diff pkoning, 2014-06-12 19:02 mock_open test suite patch review
mock_new.diff mucka, 2015-01-29 18:35 review
Messages (6)
msg216522 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2014-04-16 17:56
mock_open returns a mock object suitable for using as a mock file handle. File handles support iteration, so mock_open should support that. If possible it should be integrated with the current read/readlines support (only if possible), so the suggested patch may not be enough.

1.    Want to mock this:
with open(source_file, 'r') as f:             
    for line_num, line_text in enumerate(f):
        print line_text

2.  Tried this:
with patch('', mock_open(read_data='text'), create=True) as p:

3.  enumerate causes a call to __iter__() which is not handled by the mock_open code.

What is the expected output? What do you see instead?

The __iter__ is allowed on the returned file handle

What version of the product are you using? On what operating system?


Please provide any additional information below.

Patch would have mock_open setup handle.__iter__.return_value to a passed in parm or if none, possibly a iter(StringIO(read_data)) on the existing read_data parm to keep the interface unchanged.
msg220371 - (view) Author: Paul Koning (pkoning) Date: 2014-06-12 17:44
I created a fix for this.  This also fixes a second issue in mock_open, which is that readline() raises StopIteration at EOF rather than returning empty strings.  See attached diff.
(Is there a  better procedure for submitting fixes?)
msg220373 - (view) Author: Paul Koning (pkoning) Date: 2014-06-12 19:02
This is the corresponding patch to the test suite.
msg222279 - (view) Author: Arve Knudsen (Arve.Knudsen) Date: 2014-07-04 11:58
I noticed this issue too, thanks for fixing it!
msg234985 - (view) Author: Maciej Zagrabski (mucka) * Date: 2015-01-29 18:35
Provided path did not work for me. Probably because lack of __next__ handler. I noticed that issue when interacting with cvs.reader and cvs.DictReader. After simple modification it seems to work fine.
msg285508 - (view) Author: Georg Sauthoff (gms) Date: 2017-01-15 09:32
For working around this issue on Python 3.5 it is sufficient to overwrite just the `return_value.__iter__` method of the object returned by `mock_open()` with an iterator that calls the mocked `readline()` method until it returns the empty string.

cf. e.g.

This also works in combination with `csv.reader()`, i.e. when calling it with the mocked file object.
Date User Action Args
2018-02-15 09:27:06frenzysetnosy: + frenzy
2017-01-15 09:32:05gmssetmessages: + msg285508
2017-01-15 09:05:03gmssetnosy: + gms
2015-12-14 16:44:23José.Luis.Lafuentesetnosy: + José.Luis.Lafuente
2015-07-17 22:21:43berker.peksagsetnosy: + berker.peksag

versions: + Python 3.6
2015-01-29 18:35:30muckasetfiles: + mock_new.diff
versions: + Python 3.4
nosy: + mucka

messages: + msg234985
2014-07-04 11:58:25Arve.Knudsensetmessages: + msg222279
2014-07-04 11:53:28Arve.Knudsensetnosy: + Arve.Knudsen
2014-06-12 19:02:59pkoningsetfiles: + testwith.diff

messages: + msg220373
2014-06-12 17:44:26pkoningsetfiles: + mock.diff
nosy: + pkoning
messages: + msg220371

2014-04-16 17:56:45michael.foordcreate