Repository: hhatto/autopep8

Issue:
Ignore Settings for W292 Do Not Work
When attempting to disable formatting for W292, autopep8 does not follow the ignore settings provided by any vector.

## Python Code
`test.py`

```python
def fn():
    pass
```

## Command Line and Configuration
`setup.cfg`

```ini
[pycodestyle]
select =
ignore = W292```

Command Line
```shell
$ python3 -m autopep8 --diff test.py -v
enable config: section=pycodestyle, key=select, value=
enable config: section=pycodestyle, key=ignore, value=W292
[file:test.py]
--->  Applying global fix for E265
--->  0 issue(s) to fix {}
--- original/test.py
+++ fixed/test.py
@@ -1,2 +1,2 @@
 def fn():
-    pass
\ No newline at end of file
+    pass
```

## Your Environment
* Python version: 3.7.10
* autopep8 version: 1.5.7
* Platform: macOSX



Discussion:

Patch:
diff --git a/autopep8.py b/autopep8.py
index b20d812..c1f3caf 100755
--- a/autopep8.py
+++ b/autopep8.py
@@ -531,6 +531,7 @@ class FixPEP8(object):
             options and (options.aggressive >= 2 or options.experimental) else
             self.fix_long_line_physically)
         self.fix_e703 = self.fix_e702
+        self.fix_w292 = self.fix_w291
         self.fix_w293 = self.fix_w291
 
     def _fix_source(self, results):
@@ -1737,9 +1738,15 @@ def refactor(source, fixer_names, ignore=None, filename=''):
     Skip if ignore string is produced in the refactored code.
 
     """
+    not_found_end_of_file_newline = source and source.rstrip("\r\n") == source
+    if not_found_end_of_file_newline:
+        input_source = source + "\n"
+    else:
+        input_source = source
+
     from lib2to3 import pgen2
     try:
-        new_text = refactor_with_2to3(source,
+        new_text = refactor_with_2to3(input_source,
                                       fixer_names=fixer_names,
                                       filename=filename)
     except (pgen2.parse.ParseError,
@@ -1752,6 +1759,9 @@ def refactor(source, fixer_names, ignore=None, filename=''):
         if ignore in new_text and ignore not in source:
             return source
 
+    if not_found_end_of_file_newline:
+        return new_text.rstrip("\r\n")
+
     return new_text
 
 
@@ -2990,9 +3000,11 @@ def _execute_pep8(pep8_options, source):
     return checker.report.full_error_results()
 
 
-def _remove_leading_and_normalize(line):
+def _remove_leading_and_normalize(line, with_rstrip=True):
     # ignore FF in first lstrip()
-    return line.lstrip(' \t\v').rstrip(CR + LF) + '\n'
+    if with_rstrip:
+        return line.lstrip(' \t\v').rstrip(CR + LF) + '\n'
+    return line.lstrip(' \t\v')
 
 
 class Reindenter(object):
@@ -3019,8 +3031,11 @@ class Reindenter(object):
                 self.lines.append(line)
             else:
                 # Only expand leading tabs.
-                self.lines.append(_get_indentation(line).expandtabs() +
-                                  _remove_leading_and_normalize(line))
+                with_rstrip = line_number != len(source_lines)
+                self.lines.append(
+                    _get_indentation(line).expandtabs() +
+                    _remove_leading_and_normalize(line, with_rstrip)
+                )
 
         self.lines.insert(0, None)
         self.index = 1  # index into self.lines of next line
@@ -3448,9 +3463,11 @@ def normalize_line_endings(lines, newline):
     """Return fixed line endings.
 
     All lines will be modified to use the most common line ending.
-
     """
-    return [line.rstrip('\n\r') + newline for line in lines]
+    line = [line.rstrip('\n\r') + newline for line in lines]
+    if line and lines[-1] == lines[-1].rstrip('\n\r'):
+        line[-1] = line[-1].rstrip('\n\r')
+    return line
 
 
 def mutual_startswith(a, b):


Test patch:
diff --git a/test/test_autopep8.py b/test/test_autopep8.py
index e90be72..a745d72 100755
--- a/test/test_autopep8.py
+++ b/test/test_autopep8.py
@@ -4419,6 +4419,12 @@ else:
                                              '--select=W292']) as result:
             self.assertEqual(fixed, result)
 
+    def test_w292_ignore(self):
+        line = "1\n2"
+        with autopep8_context(line, options=['--aggressive',
+                                             '--ignore=W292']) as result:
+            self.assertEqual(line, result)
+
     def test_w293(self):
         line = '1\n \n2\n'
         fixed = '1\n\n2\n'
@@ -5503,7 +5509,6 @@ def f():
     def test_exit_code_with_io_error(self):
         line = "import sys\ndef a():\n    print(1)\n"
         with readonly_temporary_file_context(line) as filename:
-            print(filename)
             p = Popen(list(AUTOPEP8_CMD_TUPLE) + ['--in-place', filename],
                       stdout=PIPE, stderr=PIPE)
             p.communicate()
@@ -5662,6 +5667,7 @@ for i in range(3):
                           ['--jobs=3', '--diff'], stdout=PIPE)
                 p.wait()
                 output = p.stdout.read().decode()
+                p.stdout.close()
 
                 actual_diffs = []
                 for filename in files: