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

Don't report trailing-whitespaces within strings #7342

Merged
merged 5 commits into from
Aug 31, 2022

Conversation

DanielNoord
Copy link
Collaborator

  • Add yourself to CONTRIBUTORS if you are a new contributor.
  • Add a ChangeLog entry describing what your PR does.
  • If it's a new feature, or an important bug fix, add a What's New entry in
    doc/whatsnew/<current release.rst>.
  • Write a good description on what the PR does.

Type of Changes

Type
βœ“ πŸ› Bug fix

Description

Closes #3822.

@DanielNoord DanielNoord added the False Positive 🦟 A message is emitted but nothing is wrong with the code label Aug 23, 2022
Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com>
@DanielNoord
Copy link
Collaborator Author

Ah too bad. That function is also responsible for other messages. Back to the drawing board.

@DanielNoord DanielNoord marked this pull request as draft August 23, 2022 08:38
@github-actions

This comment has been minimized.

@coveralls
Copy link

coveralls commented Aug 23, 2022

Pull Request Test Coverage Report for Build 2910662722

  • 8 of 8 (100.0%) changed or added relevant lines in 1 file are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage decreased (-0.0003%) to 95.304%

Totals Coverage Status
Change from base Build 2907900553: -0.0003%
Covered Lines: 16925
Relevant Lines: 17759

πŸ’› - Coveralls

@DanielNoord DanielNoord marked this pull request as ready for review August 23, 2022 10:12
@@ -676,7 +667,14 @@ def check_lines(self, lines: str, lineno: int) -> None:
split_lines = self.specific_splitlines(lines)

for offset, line in enumerate(split_lines):
self.check_line_ending(line, lineno + offset)
if not line.endswith("\n"):
Copy link
Member

Choose a reason for hiding this comment

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

It seems like the check is done on every line, but it could be done only on the last line ? Also what about cross platform line ending (\r\n and \r) for Windows and Mac ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm not sure. I just had to extract this out of the method because there was no simple way to not call the check of trailing-whitespace. I'll try out your suggestion but since we don't have any issues about this I don't think we should also change the line endings that are checked in this PR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Oh never mind.

I can't extract this. We need to be able to skip the trailing-whitespace check if we added the missing-final-newline. We can do something with a emitted_final_newline variable but I think checking if emitted_final_newline is as quick as if line.endswith("\n") and the current code is a bit clearer.

Copy link
Member

Choose a reason for hiding this comment

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

We need to be able to skip the trailing-whitespace check if we added the missing-final-newline.

How about we loop on split_lines[:-1] and handle the last line separately ? I don't like knowingly making a check O(n) when it could be O(1)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I don't think there is a good way without duplicating a big part of code + the comment? There is also the option to do something like offset == len(split_lines) but then again, I'm not sure an endswith is that much slower.

Copy link
Member

Choose a reason for hiding this comment

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

What about something like this ?

for offset, line in enumerate(split_lines[-1]):
    self.check_trailing_whitespace_ending(last_line, lineno + offset, line_start):
last_line =  split_lines[-1][1]
offset =  split_lines[-1][0]
if not last_line.endswith("\n"):
    self.add_message("missing-final-newline", line=lineno + offset)
else:
    self.check_trailing_whitespace_ending(last_line, lineno + offset, line_start):

def check_trailing_whitespace_ending(...)
    # We don't test for trailing whitespaces in strings
    # See https://github.com/PyCQA/pylint/issues/6936
    # and https://github.com/PyCQA/pylint/issues/3822
    if tokens.type(line_start) == tokenize.STRING:
        return
    ...

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This also doesn't work since split_lines isn't always full, so split_lines[-1] can return an IndexError 😠

I don't think there is anyway to do this without adding additional if statements and assignments which kind of defeat the purpose of calling endswith once.

@@ -676,7 +667,14 @@ def check_lines(self, lines: str, lineno: int) -> None:
split_lines = self.specific_splitlines(lines)

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
last_line = split_lines[-1][1]
offset = split_lines[-1][0]
if not last_line.endswith("\n"):
self.add_message("missing-final-newline", line=lineno + offset)

@github-actions
Copy link
Contributor

πŸ€– According to the primer, this change has no effect on the checked open source code. πŸ€–πŸŽ‰

This comment was generated for commit 87da717

Copy link
Member

@Pierre-Sassoulas Pierre-Sassoulas left a comment

Choose a reason for hiding this comment

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

I took some time to check the code around this and while I still think something that should be 0(1) is O(n) changing if would require changing the strange regex that I don't understand and seems to match trailing white spaces by also matching \n ... (?!) So it might be possible but it's not going to be easy. Also currently this code is "not broken" so I'm going "not touch it" and trust you on this one πŸ˜„

@DanielNoord DanielNoord merged commit ac8641e into pylint-dev:main Aug 31, 2022
@DanielNoord DanielNoord added this to the 2.15.1 milestone Aug 31, 2022
@DanielNoord DanielNoord deleted the whitespace branch August 31, 2022 07:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
False Positive 🦟 A message is emitted but nothing is wrong with the code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Inconsistent treatment of trailing whitespace in multiline strings
3 participants