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

"--diff" option doesn't add a newline at the end of the file using 20.8b1 #1662

Closed
kimadeline opened this issue Aug 31, 2020 · 2 comments · Fixed by #1897
Closed

"--diff" option doesn't add a newline at the end of the file using 20.8b1 #1662

kimadeline opened this issue Aug 31, 2020 · 2 comments · Fixed by #1897
Labels
T: bug Something isn't working

Comments

@kimadeline
Copy link

Describe the bug

Running black --diff on a file without an ending newline will not add it to the diff when using 20.8b1.

To Reproduce Steps to reproduce the behavior:

  1. Take this file:
monday_temperatures = [9.1, 8.8, 7.5]
print(len(monday_temperatures))
  1. Run black --diff myfile.py
  2. Observed output:
PS C:\Users\kimiguel\Documents\Sandbox\black-newline> black --diff .\myfile.py
would reformat myfile.py
All done! ✨ 🍰 ✨
1 file would be reformatted.

Expected behavior

For black --diff to add a newline at the end of the file in the diff, which was the behaviour in 19.10b0:

PS C:\Users\kimiguel\Documents\Sandbox\black-newline> black --diff .\myfile.py
--- myfile.py   2020-08-31 22:20:31.166889 +0000
+++ myfile.py   2020-08-31 22:34:25.251541 +0000
@@ -1,2 +1,3 @@
 monday_temperatures = [9.1, 8.8, 7.5]
 print(len(monday_temperatures))
+
reformatted myfile.py
All done! ✨ 🍰 ✨
1 file reformatted.

Environment (please complete the following information):

  • Version: black, version 20.8b1
  • OS and Python version: Windows, Python 3.8.5

Does this bug also happen on master?

This also happens on black, version 20.8b2.dev10+g1d2d726.

Additional context

Running black myfile.py correctly without --diff adds a newline at the end of the file.

@ichard26
Copy link
Collaborator

ichard26 commented Sep 2, 2020

Just dropping by to add some information (I honestly have no idea why this was changed and how to make everyone happy):

@TBBle
Copy link
Contributor

TBBle commented Jan 1, 2021

Looking at #526, it seems to me that the diff format being generated for "add a final newline" was incorrect (it was somehow counting the final 0-byte additional line) but the applied solution just hid the problem by dropping the added newline entirely, invalidating the output of --diff against black --check.

The correct format (per the Diffutils docs) is that an incomplete line is followed by a line starting with \, e.g., comparing a file with a copy of itself after black is run on it...

$ diff -u file.py  file-fixed.py
--- file.py     2021-01-02 01:56:04.859518400 +1100
+++ file-fixed.py       2021-01-02 01:56:46.597961900 +1100
@@ -1 +1 @@
-# Comment without newline
\ No newline at end of file
+# Comment without newline

The fix should be as simple as making the call to splitlines() be splitlines(keepends=True), since looking at the difflib docs, it expects the newlines in the strings, and hence should be able to report the difference correctly.

Sadly, difflib.unified_diff doesn't actually report incomplete lines in the documented format:

> py -3
Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:54:40) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import difflib
>>> list(difflib.unified_diff(["# Comment without newline"], ["# Comment with newline\n"]))
['--- \n', '+++ \n', '@@ -1 +1 @@\n', '-# Comment without newline', '+# Comment with newline\n']

That value needs to be

['--- \n', '+++ \n', '@@ -1 +1 @@\n', '-# Comment without newline\n', '\ ...\n', '+# Comment with newline\n']

So as well as making it splitlines(True), the result needs to be patched so that any line that doesn't end in \n has the \n added, and a new element inserted after it with \ <Some optional text>.

That should make git apply happy.

Edit: I took a couple of hours and implemented the above in #1897, and now I get output identical to diff for my test-files.

Edit2: I just thought to look, and this is a known issue with difflib.unified_diff from 2008.

JelleZijlstra pushed a commit that referenced this issue Feb 22, 2021
Fixes: #1662

Work-around for https://bugs.python.org/issue2142

The test has to slightly mess with its input data, because the utility
functions default to ensuring the test data has a final newline, which
defeats the point of the test.

Signed-off-by: Paul "TBBle" Hampson <Paul.Hampson@Pobox.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T: bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants