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

Make EncodedFile.write() return the return value from inner write() #6558

Merged
merged 1 commit into from
Jan 25, 2020

Conversation

gavento
Copy link
Contributor

@gavento gavento commented Jan 24, 2020

Stream write() methods should/may return the number of characters or bytes written. Encoded file needlessly discarded the value returned from the wrapped stream write.
Fixes #6557

Copy link
Member

@nicoddemus nicoddemus left a comment

Choose a reason for hiding this comment

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

Great work @gavento, thanks! See my suggestions. 👍

Copy link
Contributor

@blueyed blueyed left a comment

Choose a reason for hiding this comment

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

👍 for @nicoddemus's suggestions.

Please squash into a single commit, and force-push then also.

@blueyed
Copy link
Contributor

blueyed commented Jan 24, 2020

Should also have a return with writelines probably:

def writelines(self, linelist):
data = "".join(linelist)
self.write(data)

@gavento
Copy link
Contributor Author

gavento commented Jan 25, 2020

Should also have a return with writelines probably:

def writelines(self, linelist):
data = "".join(linelist)
self.write(data)

Thanks for the pointer, however .writelines in CPython returns None, so I would leave it as is. See the code at https://github.com/python/cpython/blob/master/Lib/_pyio.py#L583

@blueyed
Copy link
Contributor

blueyed commented Jan 25, 2020

Thanks for the pointer, however .writelines in CPython returns None

I'd still make it into a return, in case that would ever change etc.
I think it is good practice in general, and do not think you would need a test.
Feel free to leave it out though, I might do it in a separate PR then.

Make EncodedFile, used for captured output streams, method .write return
the number of characters written. Add test for captured stderr write.
Fixes pytest-dev#6557.

Co-Authored-By: Bruno Oliveira <[email protected]>
@gavento
Copy link
Contributor Author

gavento commented Jan 25, 2020

@blueyed I had another suggestion I would make into a separate PR if you think it useful, that would resolve writelines more generally:
Make EncodedFIle inherit from io.TextIOBase, or io.IOBase directly.

  • That would make it recognizable as a stream, inheriting from IOBase. (I was surprised by that recently).
  • io.IOBase has the canonical writelines implementation, so any change would happen there.
  • There are many more methods in io.TextIOBase but we do not need to define them (they raise unsupported by default). The only ones that would be good - and filelike objects are sort of expected to have regradless of IOBase inheritance - are flush(), writable(), and close() + closed.

blueyed added a commit to blueyed/pytest that referenced this pull request Jan 25, 2020
This is implemented by IOBase already, which additionally checks if the
stream is not closed, and calls `write` per line.

Ref/via: pytest-dev#6558 (comment)
@blueyed blueyed mentioned this pull request Jan 25, 2020
2 tasks
@blueyed
Copy link
Contributor

blueyed commented Jan 25, 2020

@gavento makes sense. I've quickly done #6566, which hopefully will fail (since it apparently does not inherit from IOBase yet).
Feel free to give it a try yourself.

@blueyed blueyed merged commit 6f2943c into pytest-dev:master Jan 25, 2020
@blueyed
Copy link
Contributor

blueyed commented Jan 25, 2020

@gavento just for info: it redirects attribute lookup to the original buffer already: https://github.com/pytest-dev/pytest/pull/6566/files#diff-e4269384a671a462a4824e8b06d4644bR441-R442

@gavento
Copy link
Contributor Author

gavento commented Jan 25, 2020

@gavento just for info: it redirects attribute lookup to the original buffer already: https://github.com/pytest-dev/pytest/pull/6566/files#diff-e4269384a671a462a4824e8b06d4644bR441-R442

Right, 🤦‍♂️ I noticed that elegant piece earlier. In that case, adding inheritance from IOBase would break that and we would need to manually reimplement the relevant methods as redirects. This could be done by some meta-programming or __getattribute__ to save trivial code repetition, but that would make it even more obscure ;)

Other file-like objects already do not inherit IOBase .. but having that inheritance in pytest would be sort of nice.

@gavento gavento deleted the patch-1 branch January 25, 2020 11:20
blueyed added a commit to blueyed/pytest that referenced this pull request Jan 25, 2020
This is implemented by IOBase already, which additionally checks if the
stream is not closed, and calls `write` per line.

Ref/via: pytest-dev#6558 (comment)
blueyed added a commit to blueyed/pytest that referenced this pull request Jan 25, 2020
This is implemented by the underlying stream already, which additionally
checks if the stream is not closed, and calls `write` per line.

Ref/via: pytest-dev#6558 (comment)
blueyed added a commit to blueyed/pytest that referenced this pull request Jan 25, 2020
This is implemented by the underlying stream already, which additionally
checks if the stream is not closed, and calls `write` per line.

Ref/via: pytest-dev#6558 (comment)
blueyed added a commit to blueyed/pytest that referenced this pull request Jan 25, 2020
This is implemented by the underlying stream already, which additionally
checks if the stream is not closed, and calls `write` per line.

Ref/via: pytest-dev#6558 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

In tests, sys.stderr.write does not return the number of characters written
3 participants