Skip to content

bpo-33927: Add support for same infile and outfile to json.tool#7865

Closed
remilapeyre wants to merge 13 commits into
python:mainfrom
remilapeyre:bugfix/json.tool-same-infile-outfile
Closed

bpo-33927: Add support for same infile and outfile to json.tool#7865
remilapeyre wants to merge 13 commits into
python:mainfrom
remilapeyre:bugfix/json.tool-same-infile-outfile

Conversation

@remilapeyre

@remilapeyre remilapeyre commented Jun 22, 2018

Copy link
Copy Markdown

@remilapeyre remilapeyre force-pushed the bugfix/json.tool-same-infile-outfile branch from e18835f to 04b2ade Compare June 22, 2018 22:09
@rhettinger rhettinger self-assigned this Jun 24, 2018
@rhettinger

Copy link
Copy Markdown
Contributor

This doesn't look like the right solution to me. You may need to skip the argparse.FileType() and move the opening and closing logic into the with-statements. That will allow "python3 -m json.tool example.json example.json" and fix the other minor fd leaks mentioned in the bug report.

@remilapeyre

remilapeyre commented Jun 24, 2018

Copy link
Copy Markdown
Author

Hi @rhettinger, thanks for the comments.

fix the other minor fd leaks mentioned in the bug report.

I'm not sure to follow, if I understand Pablo's remark in https://bugs.python.org/issue33927#msg320326 the problem is about the leaked fd outfile when an exception is raised before the second with statement. This happens when both fd points to the same file, outfile being opened in 'w' mode, the content of the file gets destroyed before it could be read.

When this happens, the second fd has been open by argparse.FileType() but is never closed hence the leak. As I understand it, this never happens with the first fd since an exception can't be raised before the first with statement and it can therefore stay as argparse.FileType().

Both leaks shown by Pablo seems to be fixed by this patch:

➜  debug git:(bugfix/json.tool-same-infile-outfile) ✗ touch invalid_file.dat
➜  debug git:(bugfix/json.tool-same-infile-outfile) ✗ ./python.exe -m json.tool invalid_file.dat nofile.dat
Expecting value: line 1 column 1 (char 0)
➜  debug git:(bugfix/json.tool-same-infile-outfile) ✗ echo '{"foo":"bar"}'>valid.dat
➜  debug git:(bugfix/json.tool-same-infile-outfile) ✗ ./python.exe -m json.tool valid.dat valid.dat        
➜  debug git:(bugfix/json.tool-same-infile-outfile) ✗ cat valid.dat 
{
    "foo": "bar"
}

Am I missing something?

Comment thread Lib/json/tool.py Outdated
@4383

4383 commented Jun 26, 2018

Copy link
Copy Markdown
Contributor

Looks good to me!

$ wget https://raw.githubusercontent.com/remilapeyre/cpython/23593fb76c999ed96583b87d5d4873d5383215a2/Lib/json/tool.py
...
2018-06-26 21:58:05 (56,5 MB/s) - «tool.py» enregistré [1601/1601]
$ echo '{"foo": "bar"}' > test.json
$ python tool.py test.json 
{
    "foo": "bar"
}
$ python tool.py test.json test.json 
$ cat test.json 
{
    "foo": "bar"
}
$ echo '{"foo": "bar"}' | python tool.py 
{
    "foo": "bar"
}
$ python tool.py test.json /bla/test.json 
usage: python -m json.tool [-h] [--sort-keys] [infile] [outfile]
python -m json.tool: error: can't open '/bla/test.json': [Errno 2] No such file or directory: '/bla/test.json'

@4383

4383 commented Jun 26, 2018

Copy link
Copy Markdown
Contributor

The CI failed due to a timeout...

@remilapeyre remilapeyre force-pushed the bugfix/json.tool-same-infile-outfile branch from 23593fb to 04b2ade Compare June 27, 2018 08:43
@remilapeyre

Copy link
Copy Markdown
Author

Indeed, I ran it again and all is good now.

@4383

4383 commented Jun 27, 2018

Copy link
Copy Markdown
Contributor

Consider to reference these changes in a new entry to the Misc.
https://devguide.python.org/committing/#what-s-new-and-news-entries

@4383

4383 commented Jun 27, 2018

Copy link
Copy Markdown
Contributor

LGTM! Thanks for your contrib!

@remilapeyre

Copy link
Copy Markdown
Author

Hi @rhettinger , I think test_no_fd_leak_infile_outfile and test_no_fd_leak_same_infile_outfile on c9d43c Lib/json/tool.py and 106f4b Lib/json/tool.py should convince you that this patch is enough to prevent leakage in both cases mentionned by pablogsal.

@remilapeyre remilapeyre force-pushed the bugfix/json.tool-same-infile-outfile branch from 106f4bc to ed871c6 Compare June 29, 2018 20:15

@matrixise matrixise left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hi Rémi,

Thank you for your contribution but I think you need to improve your PR.
Have a nice day,

Thank you

Comment thread Lib/test/test_json/test_tool.py Outdated
Comment thread Lib/test/test_json/test_tool.py Outdated
Comment thread Lib/test/test_json/test_tool.py Outdated
Comment thread Lib/test/test_json/test_tool.py Outdated
Comment thread Lib/test/test_json/test_tool.py Outdated
Comment thread Lib/json/tool.py Outdated
@rhettinger

Copy link
Copy Markdown
Contributor

Can you please fix the file conflicts?

@remilapeyre

Copy link
Copy Markdown
Author

Hi @rhettinger, I resolved the conflix. One thing I changed is that infile is now read fully rather than one line at a time when json_lines is True (e606980#diff-e94945dd18482591faf1e294b029a6afR39) but I don't expect this to be an issue.

@remilapeyre

Copy link
Copy Markdown
Author

@rhettinger, the resolved the conflicts with master, can you review the changes again?

@vstinner vstinner left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

There is PR #11992 which is similar but looks simpler.

Comment thread Lib/json/tool.py Outdated
@bedevere-bot

Copy link
Copy Markdown

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.

@vstinner

Copy link
Copy Markdown
Member

There is PR #11992 which is similar but looks simpler.

Oh sorry, these two PR have a different purpose.

Comment thread Lib/json/tool.py Outdated
Comment thread Lib/json/tool.py
@4383

4383 commented Feb 22, 2019

Copy link
Copy Markdown
Contributor

Thoughts?

@vstinner

Copy link
Copy Markdown
Member

What do you think about this?

I like -i option of the sed command: "sed -i file" modify file in-place, "sed file" writes the output into stdout.

man sed

       -i[SUFFIX], --in-place[=SUFFIX]

              edit files in place (makes backup if SUFFIX supplied)

I prefer to explicitly ask to modify the file in-place, rather than using black magic to try to support this uncommon case.

If -i/--in-place is used, you can read the full content in memory.

I disagree with changing the behavior (always load full data in memory) by default.

@remilapeyre

Copy link
Copy Markdown
Author

Hi @vstinner, I made the changes requested to read infile only when --in-place is used. Can you review again?

@vstinner

Copy link
Copy Markdown
Member

Hi @vstinner, I made the changes requested to read infile only when --in-place is used. Can you review again?

I don't have the bandwidth to review it. @matrixise @4383: Would you mind to review it.

@remilapeyre: Once someone will approve the PR, I will have a new look if you want ;-)

@4383

4383 commented Feb 25, 2019

Copy link
Copy Markdown
Contributor

Hi @vstinner, I made the changes requested to read infile only when --in-place is used. Can you review again?

I don't have the bandwidth to review it. @matrixise @4383: Would you mind to review it.

@remilapeyre: Once someone will approve the PR, I will have a new look if you want ;-)

@vstinner @remilapeyre Tomorrow I can review it and send my feed back.

Comment thread Lib/json/tool.py Outdated
Comment thread Lib/json/tool.py Outdated
Comment thread Lib/json/tool.py
Comment thread Lib/json/tool.py Outdated
@rhettinger rhettinger removed their assignment Jun 1, 2019
@remilapeyre remilapeyre requested a review from matrixise May 28, 2020 22:27
Comment thread Lib/json/tool.py Outdated
@matrixise

Copy link
Copy Markdown
Member

@remilapeyre Do you want to finish this PR, I could continue the review with you. Have a nice day.

Comment thread Misc/NEWS.d/next/Library/2018-06-27-14-46-03.bpo-33927.felCrI.rst Outdated
Rémi Lapeyre and others added 2 commits November 7, 2021 22:02
Co-authored-by: Inada Naoki <songofacandy@gmail.com>
Co-authored-by: Inada Naoki <songofacandy@gmail.com>
@methane

methane commented Jan 18, 2022

Copy link
Copy Markdown
Member

I close this because #29273 is merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants