Skip to content

Conversation

@nitishch
Copy link
Contributor

@nitishch nitishch commented Dec 14, 2017

This issue was happening because - after write in the given case, write_pos and write_end are ending up to be 0. Nothing wrong here. But when doing truncate, we flush writer changes. During that, even when write_pos == write_end, we've to reset write_end to -1. That was not happening.

https://bugs.python.org/issue32228

@methane
Copy link
Member

methane commented Dec 19, 2017

Would you add test case for it?

@nitishch
Copy link
Contributor Author

Thanks @methane. While writing a test case, I realised that my fix, although working, doesn't fix the root cause of the issue. Uploaded the new changes.

@methane
Copy link
Member

methane commented Dec 20, 2017

@methane methane closed this Dec 20, 2017
@methane methane reopened this Dec 20, 2017
@methane
Copy link
Member

methane commented Dec 20, 2017

Hmm, Travis doesn't work... https://travis-ci.org/python/cpython/requests

@methane
Copy link
Member

methane commented Dec 20, 2017

@nitishch Could you close this pull request and create new one with clean git log?

@methane methane requested a review from pitrou December 20, 2017 13:36
Copy link
Member

@methane methane left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but I want IO expert review if possible.

self.assertEqual(f.seek(0, io.SEEK_END), 15)
f.close()

f = io.open(TESTFN, 'r+b')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test_fileio is specifically for FileIO tests, but you are not testing FileIO here, but BufferedIORandom. So your test should go into the relevant test class in test_io.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I think the test should exercise several different buffer sizes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done for both. See if it is ok now.

_bufferedwriter_reset_buf(self);

end:
_bufferedwriter_reset_buf(self);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit skeptical here. Shouldn't the fix go in buffered_flush_and_rewind_unlocked instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought when we are flushing out all dirty writes, we should reset write_end. This function is called in write, seek and in flush_and_rewind. It's usage appears ok to me in all three cases.

I'm just reading through code and trying to understand the behaviour. So I might have very well misunderstood something. Please correct me in that case.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you may well be right... I have not touched this code in a long time, so I prefer to ask.

A couple of things now:

  • can you add a comment here pointing to the issue number and explaning why this is necessary?
  • unrelated, but there's a comment at the beginning of _bufferedwriter_flush_unlocked mentioning restore_pos; that comment is obsolete, so it would be nice to remove it :-)
  • in _io_BufferedWriter_write_impl, there's a fix for issue #6629 which might have become unnecessary with this PR; could you check it?

Copy link
Member

@pitrou pitrou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for tackling this! Buffered I/O is a delicate area. Please read the comments I left.

@bedevere-bot
Copy link

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@nitishch
Copy link
Contributor Author

@methane Since this PR has the reviews, I'll address the reviews in this branch and then create a new PR if that's ok.

@asvetlov
Copy link
Contributor

As an option you can rebase/squash/whatever and git push --force

@methane
Copy link
Member

methane commented Dec 21, 2017

@nitishch And could you try log in on Travis-Ci?
Maybe, Travis blocks running build pull request from non Travis users.

@nitishch
Copy link
Contributor Author

@pitrou I added the test for 3 buffer sizes. Please see if it is ok now.

@nitishch
Copy link
Contributor Author

Travis build seems to be running now for some reason :)

Copy link
Member

@pitrou pitrou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the update. See comments below.

self.assertEqual(f.read(), b"abc")

def test_truncate_after_write(self):
with self.open(support.TESTFN, "wb") as f:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. Can you add a comment referring to the bug entry at the beginning at the test?

# read operation makes sure that pos != raw_pos
f.truncate()
self.assertEqual(f.tell(), buffer_size + 2)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's an extraneous empty line here.

_bufferedwriter_reset_buf(self);

end:
_bufferedwriter_reset_buf(self);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you may well be right... I have not touched this code in a long time, so I prefer to ask.

A couple of things now:

  • can you add a comment here pointing to the issue number and explaning why this is necessary?
  • unrelated, but there's a comment at the beginning of _bufferedwriter_flush_unlocked mentioning restore_pos; that comment is obsolete, so it would be nice to remove it :-)
  • in _io_BufferedWriter_write_impl, there's a fix for issue #6629 which might have become unnecessary with this PR; could you check it?

@@ -0,0 +1 @@
Reset ``write_end`` value after ``truncate()``
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of describing the technical solution, can you describe the issue being fixed?

@bedevere-bot
Copy link

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@nitishch
Copy link
Contributor Author

nitishch commented Dec 22, 2017

I have made the requested changes; please review again.

@pitrou It seems the fix for #6629 is needed. I just reset write_end to its proper value. The current fix doesn't perform any seeks on the raw stream. #6629 does the seek on the raw stream as per the comment. So I didn't remove it.

@bedevere-bot
Copy link

Thanks for making the requested changes!

@pitrou, @methane: please review the changes made to this pull request.

@pitrou
Copy link
Member

pitrou commented Dec 22, 2017

Thanks @nitishch for the changes. The holiday period is arriving and I may not review this again before a few days. I hope you don't mind.

@nitishch
Copy link
Contributor Author

Hi. Any updates on this?

@pitrou
Copy link
Member

pitrou commented Jan 28, 2018

@nitishch thank you very much for doing this, and sorry for the delay. I think this PR is good to go now!

@bedevere-bot
Copy link

@pitrou: Please replace # with GH- in the commit message next time. Thanks!

@miss-islington
Copy link
Contributor

Thanks @nitishch for the PR, and @pitrou for merging it 🌮🎉.. I'm working now to backport this PR to: 3.6.
🐍🍒⛏🤖

@miss-islington
Copy link
Contributor

Sorry, @nitishch and @pitrou, I could not cleanly backport this to 3.6 due to a conflict.
Please backport using cherry_picker on command line.
cherry_picker 059f58ce938d9c3f0286412a4efb1b9131339421 3.6

pitrou pushed a commit to pitrou/cpython that referenced this pull request Jan 28, 2018
…GH-4858)

Ensure that ``truncate()`` preserves the file position (as reported by ``tell()``) after writes longer than the buffer size..
(cherry picked from commit 059f58c)
pitrou added a commit to pitrou/cpython that referenced this pull request Jan 28, 2018
…GH-4858)

Ensure that ``truncate()`` preserves the file position (as reported by ``tell()``) after writes longer than the buffer size..
(cherry picked from commit 059f58c)
@bedevere-bot
Copy link

GH-5389 is a backport of this pull request to the 3.6 branch.

pitrou added a commit that referenced this pull request Jan 28, 2018
… (#5389)

Ensure that ``truncate()`` preserves the file position (as reported by ``tell()``) after writes longer than the buffer size..
(cherry picked from commit 059f58c)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type-bug An unexpected behavior, bug, or error

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants