No newline at end of file python как исправить
Перейти к содержимому

No newline at end of file python как исправить

  • автор:

PEP8 «No newline at end of file»

It means exactly what it says. There is no recognizable newline at the end of the file. The last character is the ) . or maybe a TAB, or SPACE, or a line terminator for a different platform. Solution: open the file in an editor, add a newline at the end, save and close the file.

Apr 23, 2022 at 2:57
I’ve tried that, I had a new line after it and I get «blank line contains whitespace» error
Apr 23, 2022 at 3:00
So get rid of the whitespace!!
Apr 23, 2022 at 3:01

@Ryu That’s a different error. Ultimately what you should do is set up your editor to do all of this for you: add a trailing newline if there isn’t one, and strip trailing whitespace. For example for Atom, there’s a package called whitespace that’ll do that.

Apr 23, 2022 at 3:03
Solved. Thanks for your help. I wasn’t using my common sense
Apr 23, 2022 at 3:03

2 Answers 2

It means exactly what it says. There is no recognizable newline at the end of the file. The last character is the ) . or maybe a TAB , or SPACE , or a line terminator for a different platform.

Solution: open the file in an editor, add a newline at the end, save and close the file.

I’ve tried that, I had a new line after it and I get «blank line contains whitespace» error.

So what you had was a line consisting of white space (SPACE or TAB characters) followed by a newline. Use your editor to get rid of that line.

The style checker wants the last line of the file to end with the newline character, and to have no trailing whitespace on that line.

git blame

When you add it to git, you see the message complaining about no newline:

diff --git a/lib/file.dart b/lib/file.dart
new file mode 100644
index 0000000..7fc9f98
--- /dev/null
+++ b/lib/file.dart
@@ -0,0 +1,3 @@
+class Foo + const Foo();
+>
\ No newline at end of file

Why does it matter?

Let’s add another class:

We can see that the editor shows the new lines in green, but git has another opinion on this:

diff --git a/lib/file.dart b/lib/file.dart
index 7fc9f98..87a89ce 100644
--- a/lib/file.dart
+++ b/lib/file.dart
@@ -1,3 +1,5 @@
class Foo const Foo();
->
\ No newline at end of file
+>
+
+class Bar <>
\ No newline at end of file

It considers the line with > deleted and a new line of > added. This is because technically the newline character is a part of the line it terminates.

A sequence of zero or more non- characters plus a terminating character.

I guess it is just to have the simplest definition of a line.

So in our file a single-character pseudo-line of > was replaced with a two-character line of > and newline.

When showing the lines’ history, the editor (Android Studio in my case) is forgiving enough to show the 3rd line as unchanged:

What it does is running git blame with -w option that ignores all whitespace changes including newline characters.

But this virtue is not granted. Many tools will show what really happened:

$ git blame file.dart
f02f999d (Alexey Inkin 2022-07-14 10:25:25 +0400 1) class Foo f02f999d (Alexey Inkin 2022-07-14 10:25:25 +0400 2) const Foo();
d0cb21dd (Alexey Inkin 2022-07-14 10:31:18 +0400 3) >
d0cb21dd (Alexey Inkin 2022-07-14 10:31:18 +0400 4)
d0cb21dd (Alexey Inkin 2022-07-14 10:31:18 +0400 5) class Bar <>

wc -l

wc -l command is the most common way to count lines in your code. Following the definition, it just counts the number of newlines in a file.

So if you don’t end a file with a newline, most UNIX tools will show you have one less line.

This answer goes deeper on inconvenient scenarios without newline.

The Solution

The solution is to always end all of your text files with a newline:

When committing, you don’t get a no-newline warning:

diff --git a/lib/file_with_newline.dart b/lib/file_with_newline.dart
new file mode 100644
index 0000000..c57d1e3
--- /dev/null
+++ b/lib/file_with_newline.dart
@@ -0,0 +1,3 @@
+class Foo + const Foo();
+>

Your diff is pristine:

Your blame looks the same with or without -w option:

60c0a7c0 (Alexey Inkin 2022-07-14 11:04:03 +0400 1) class Foo 60c0a7c0 (Alexey Inkin 2022-07-14 11:04:03 +0400 2) const Foo();
60c0a7c0 (Alexey Inkin 2022-07-14 11:04:03 +0400 3) >
f496ee14 (Alexey Inkin 2022-07-14 11:05:51 +0400 4)
f496ee14 (Alexey Inkin 2022-07-14 11:05:51 +0400 5) class Bar <>

And you get paid for every line you author:

$ wc -l * 
4 file.dart
5 file_with_newline.dart

Linter

In many languages there is a linter rule to flag unterminated lines. In Dart, use eol_at_end_of_file lint.

Read this for linter configuration.

Command

If your language does not support such lint, or you want to check non-code files, use a custom command to find files not ending with newline (credit):

find . -type f | xargs -L1 bash -c 'test "$(tail -c1 "$0")" && echo "No newline at end of $0"'

It works like this:

  • find prints all file names recursively.
  • . is where to start from, the current directory in this case. You can also add your code directory here. You can add multiple directories separated by space.
  • -type f limits the results to ordinary files and not directories.
  • | takes the output of the previous command and directs it as input to the following command instead of printing. This is called piping.
  • xargs takes lines from input and runs a given command on them.
  • -L1 means to run the command on each input line separately (otherwise it glues them).
  • bash -c ‘test «$(tail -c1 «$0″)» && echo «No newline at end of $0″‘ is what xargs runs on each input line (file path). So effectively this is ran for each file:
bash -c 'test "$(tail -c1 "$0")" && echo "No newline at end of $0"' file_path 
  • bash -c string means to run string as a command and make everything after it available to that command as positional arguments. Here string is
    ‘test «$(tail -c1 «$0″)» && echo «No new line at end of $0″‘
    After the string comes file_path , so it is available to that command as the positional argument of $0 . So bash will effectively run this:
test "$(tail -c1 "file_path")" && echo "No newline at end of file_path"
  • test with a string after it checks if that string is not empty. It exits with a non-zero code (error) if it is empty and a zero code (OK) otherwise. && only continues to the next command if the previous one exited with zero code. It means that
    echo «No newline at and of file_path» will only be printed if the string passed to test is not empty.
  • «$(something)» means that something will be executed as a command, and its output inserted between the quotes. It means to execute
    tail -c1 «file_path» and to to pass its result as an argument to test .
  • tail -c1 «file_path» takes the last 1 byte from the given file. So it is either newline character or some other byte. And this byte is what is passed to test as an argument. A string beginning with a newline character is treated by test as empty, no matter how long it is. So for newline character test exits with a non-zero code. Any other character means a non-empty string, it makes test exit with zero code and to continue to echo .

GitHub workflow

You can make GitHub to run this check for you on each commit. For this, add this to your workflow:

And never end your Medium stories with newline. It is a byte-level unit. All rich documents have many sorts of wrappers for their content units and never deal with bytes including newline

No Newline at End of File

Have you ever seen “No newline at end of file” in your git diffs? Us, too.

~/.dotfiles% git diff diff --git a/vimrc b/vimrc index 7e31913..a8b5f95 100644 --- a/vimrc +++ b/vimrc @@ -2,4 +2,4 @@ let configs = split(glob("~/.vim/configs/*"), "\n") for filename in configs execute 'source ' filename -endfor +endfor \ No newline at end of file 

Why does this happen and what does it mean?

Try it in your shell

Here I have made a text file and, by definition, a non-text file:

~% echo foo > text-file ~% od -c text-file 0000000 f o o \n 0000004 ~% wc -l text-file 1 text-file ~% echo -n foo > binary-file ~% od -c binary-file 0000000 f o o 0000003 ~% wc -l binary-file 0 binary-file 

If you open each file in vim, they will display similarly. The intuition behind what vim is doing is “separate each line with a line break”, which is different from “display each \n as a line break”.

However, the binary-file will cause vim to display [noeol] in its status line (with the default status line).

History lesson

This comes from an old C decision that has been passed down through Unix history:

A source file that is not empty shall end in a new-line character, which shall not be immediately preceded by a backslash character.

Since this is a “shall” clause, we must emit a diagnostic message for a violation of this rule.

So, it turns out that, according to POSIX, every text file (including Ruby and JavaScript source files) should end with a \n , or “newline” (not “a new line”) character. This acts as the eol , or the “end of line” character. It is a line “terminator”.

Following the rules in your editor

You can make sure you follow this rule easily:

  • For Vim users, you’re all set out of the box! Just don’t change your eol setting.
  • For Emacs users, add (setq require-final-newline t) to your .emacs or .emacs.d/init.el file.
  • For Android Studio, RubyMine, PyCharm, and other IntelliJ, set “Ensure line feed at file end on Save” under “Editor.”
  • For Atom, you’re also all set out of the box. Keep that via the Whitespace plugin.
  • For VS Code, set «files.insertFinalNewline»: true .
  • For Sublime, set the ensure_newline_at_eof_on_save option to true .
  • For TextMate, you can install the Avian Missing Bundle and add TM_STRIP_WHITESPACE_ON_SAVE = true to your .tm_properties file.

What’s next

If this satisfied your curiosity, you might also enjoy:

If you enjoyed this post, you might also like:

  1. Wrap Existing Text at 80 Characters in Vim
  2. Opt-In, Project-Specific Vim Spell-Checking and Word Completion
  3. How to Git with Unity

Three people gather around a teammate's computer to help her out

Could your team use a boost?

Ensure your team is moving as quickly as you need it to with thoughtbot’s Team Augmentation. Our expert designers and developers embed in teams to hit tough goals while strengthening collaboration and communication.

© 2023 thoughtbot, inc. The design of a robot and thoughtbot are registered trademarks of thoughtbot, inc. Privacy Policy

What’s the point in adding a new line to the end of a file?

I thought this would be a C-programmers-only problem, but github displays a message in the commit view:

\ No newline at end of file 

for a PHP file. I understand the preprocessor thing explained in this thread, but what has this to do with PHP? Is it the same include() thing or is it related to the \r\n vs \n topic? What is the point in having a new line at the end of a file?

asked Aug 14, 2011 at 19:29
Philipp Stephan Philipp Stephan
3,270 2 2 gold badges 15 15 silver badges 8 8 bronze badges
Duplicate from SO: stackoverflow.com/questions/729692/…
Dec 31, 2018 at 12:55

If you cat the file, the next prompt will be appended to the final «line» if it does not end with a newline.

Jul 4, 2019 at 1:24

7 Answers 7

It’s not about adding an extra newline at the end of a file, it’s about not removing the newline that should be there.

A text file, under unix, consists of a series of lines, each of which ends with a newline character ( \n ). A file that is not empty and does not end with a newline is therefore not a text file.

Utilities that are supposed to operate on text files may not cope well with files that don’t end with a newline; historical Unix utilities might ignore the text after the last newline, for example. GNU utilities have a policy of behaving decently with non-text files, and so do most other modern utilities, but you may still encounter odd behavior with files that are missing a final newline¹.

With GNU diff, if one of the files being compared ends with a newline but not the other, it is careful to note that fact. Since diff is line-oriented, it can’t indicate this by storing a newline for one of the files but not for the others — the newlines are necessary to indicate where each line in the diff file starts and ends. So diff uses this special text \ No newline at end of file to differentiate a file that didn’t end in a newline from a file that did.

By the way, in a C context, a source file similarly consists of a series of lines. More precisely, a translation unit is viewed in an implementation-defined as a series of lines, each of which must end with a newline character (n1256 §5.1.1.1). On unix systems, the mapping is straightforward. On DOS and Windows, each CR LF sequence ( \r\n ) is mapped to a newline ( \n ; this is what always happens when reading a file opened as text on these OSes). There are a few OSes out there which don’t have a newline character, but instead have fixed- or variable-sized records; on these systems, the mapping from files to C source introduces a \n at the end of each record. While this isn’t directly relevant to unix, it does mean that if you copy a C source file that’s missing its final newline to a system with record-based text files, then copy it back, you’ll either end up with the incomplete last line truncated in the initial conversion, or an extra newline tacked onto it during the reverse conversion.

¹ Example: the output of GNU sort on non-empty files always ends with a newline. So if the file foo is missing its final newline, you’ll find that sort foo | wc -c reports one more byte than cat foo | wc -c . The read builtin of sh is required to return false if the end-of-file is reached before the end of the line is reached, so you’ll find that loops such as while IFS= read -r line; do . ; done skip an unterminated line altogether.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *