Skip to content

bpo-34070: only check for isatty when buffering < 0 #8187

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

Merged
merged 1 commit into from
Oct 19, 2018

Conversation

Dav1dde
Copy link
Contributor

@Dav1dde Dav1dde commented Jul 8, 2018

https://bugs.python.org/issue34070

Only check for isatty when buffering actually requires the check (buffering < 0)

https://bugs.python.org/issue34070

@the-knights-who-say-ni
Copy link

Hello, and thanks for your contribution!

I'm a bot set up to make sure that the project can legally accept your contribution by verifying you have signed the PSF contributor agreement (CLA).

Unfortunately our records indicate you have not signed the CLA. For legal reasons we need you to sign this before we can look at your contribution. Please follow the steps outlined in the CPython devguide to rectify this issue.

When your account is ready, please add a comment in this pull request
and a Python core developer will remove the CLA not signed label
to make the bot check again.

Thanks again for your contribution, we look forward to reviewing it!

@Dav1dde
Copy link
Contributor Author

Dav1dde commented Jul 8, 2018

CLA signed.

@serhiy-storchaka
Copy link
Member

Would be nice to add tests.

Python implementation in _pyio.py may need a change too.

@Dav1dde
Copy link
Contributor Author

Dav1dde commented Jul 9, 2018

I'll look into tests.

The Python implementation in Lib/_pyio.py should be fine:

 209try:
 210line_buffering = False
 211if buffering == 1 or buffering < 0 and raw.isatty():
 212buffering = -1
 213line_buffering = True

Since it is left to right. But maybe I am missing something else here?

Regarding CLA: It is signed, I got the copy via E-Mail and my Github account is linked in the Python Bugtracker .. I'll double check it again (maybe it takes a while?).

Also regarding the Misc/News, is that worth a news entry, it's just a rather small bugfix/improvement?

@serhiy-storchaka
Copy link
Member

A news entry may save hours for somebody if his program will fail when run on different computer with older Python because of this change.

The Python implementation looks fine to me too.

@@ -388,7 +388,7 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode,
goto error;

/* buffering */
{
if (buffering < 0) {
Copy link
Member

Choose a reason for hiding this comment

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

I would prefer to have an else block to initialize isatty variable, even if it's not used in practice. ("else { isatty = 0; }"). Or initialize the variable to 0 when it's declared?

It should prevent warning from dummy compilers.

Copy link
Member

Choose a reason for hiding this comment

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

Or add

if (isatty) {
    buffering = 1;
}

and simplify the condition (buffering == 1 || (buffering < 0 && isatty)) below to just (buffering == 1).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed. isatty is now initialized and the redundant buffering < 0 below has been removed.

@Dav1dde
Copy link
Contributor Author

Dav1dde commented Jul 11, 2018

I changed the code you commented on, I turned the now redundant buffering < 0 && isatty into just isatty and assigned 0 as a default to isatty.

I also added a news entry, I hope that is proper English and makes sense for a bystander.

I am still having troubles with writing tests for this though. My initial idea was to replace the FileIO class with my own "spy" like so:

        FileIO = self.io.FileIO

        class SpyFileIO(FileIO):
            _isatty = False

            def isatty(self):
                SpyFileIO._isatty = True
                return False

        self.io.FileIO = SpyFileIO
        try:
            f = self.open(TESTFN, 'w', buffering=-1)
        finally:
            self.io.FileIO = FileIO
            f.close()

        self.assertTrue(SpyFileIO._isatty)

This works fine for the _pyio module, but it does not work for _io - the C module. I assume because the C module doesn't look up the reference from the module for the FileIO type every time (please correct me when I am wrong!). I don't have a better idea on how I could verify the desired behaviour in a test than monkey patch FileIO here. Please point me in the right direction.

Copy link
Member

@serhiy-storchaka serhiy-storchaka left a comment

Choose a reason for hiding this comment

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

LGTM without tests. Thanks @Dav1dde!

Just a small formatting nit.

@@ -0,0 +1,2 @@
Make sure to only check if the handle is a tty, when opening
a file with `buffering=-1`.
Copy link
Member

Choose a reason for hiding this comment

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

Use double backquotes:

``buffering=-1``

This is a reStructuredText, not Markdown.

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!

Sorry about that, haven't been doing enough Python recently :(

@Dav1dde
Copy link
Contributor Author

Dav1dde commented Sep 11, 2018

Any news on this? Anything I should do?

@vstinner vstinner merged commit 8deab96 into python:master Oct 19, 2018
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.

5 participants