Repository: spyder-ide/spyder

Issue:
Internal console error when selecting Source -> Next warning/error (or Previous warning/error)
## Description of your problem
When running master branch, get the following in the Internal console when selecting Source -> Next warning/error:
>>> Traceback (most recent call last):
  File "/home/cheryl/spyder/spyder/plugins/editor.py", line 2151, in go_to_next_warning
    position = editor.go_to_next_warning()
  File "/home/cheryl/spyder/spyder/widgets/sourcecode/codeeditor.py", line 1433, in go_to_next_warning
    self.__show_code_analysis_results(line_number, data.code_analysis)
AttributeError: 'CodeEditor' object has no attribute '_CodeEditor__show_code_analysis_results'

**What steps will reproduce the problem?**

1.   Open source in Editor.
2.   From the menu, select Source -> Next warning/error
3. 

**What is the expected output? What do you see instead?**


**Please provide any additional information below**


## Versions and main components

* Spyder Version:  4.0.0.dev0
* Python Version:  3.6.2
* Qt Version:
* PyQt Version:
* Operating system:


## Dependencies

Please go to the menu entry `Help > Optional Dependencies` (or
`Help > Dependencies`), press the button `Copy to clipboard`
and paste the contents below:



Discussion:
I have researched this issue and found that PR#3463 changed `__show_code_analysis_results` to `show_code_analysis_results`, but didn't update `go_to_next_warning` and `go_to_previous_warning`.

I'm submitting a PR with a fix.

This is for 4.0.0 only.

Resolving patch:
diff --git a/spyder/widgets/sourcecode/codeeditor.py b/spyder/widgets/sourcecode/codeeditor.py
--- a/spyder/widgets/sourcecode/codeeditor.py
+++ b/spyder/widgets/sourcecode/codeeditor.py
@@ -1430,7 +1430,7 @@ def go_to_next_warning(self):
                 break
         line_number = block.blockNumber()+1
         self.go_to_line(line_number)
-        self.__show_code_analysis_results(line_number, data.code_analysis)
+        self.show_code_analysis_results(line_number, data.code_analysis)
         return self.get_position('cursor')
 
     def go_to_previous_warning(self):
@@ -1447,7 +1447,7 @@ def go_to_previous_warning(self):
                 break
         line_number = block.blockNumber()+1
         self.go_to_line(line_number)
-        self.__show_code_analysis_results(line_number, data.code_analysis)
+        self.show_code_analysis_results(line_number, data.code_analysis)
         return self.get_position('cursor')
 
 


Test patch:
diff --git a/spyder/widgets/sourcecode/tests/test_warnings.py b/spyder/widgets/sourcecode/tests/test_warnings.py
new file mode 100644
--- /dev/null
+++ b/spyder/widgets/sourcecode/tests/test_warnings.py
@@ -0,0 +1,81 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright © Spyder Project Contributors
+# Licensed under the terms of the MIT License
+#
+'''
+Tests for editor codeanalysis warnings.
+'''
+
+# Third party imports
+import pytest
+
+# Local imports
+from spyder.utils.qthelpers import qapplication
+from spyder.widgets.sourcecode.codeeditor import CodeEditor
+from spyder.py3compat import to_binary_string
+from spyder.utils.codeanalysis import check_with_pyflakes, check_with_pep8
+
+
+# --- Fixtures
+# -----------------------------------------------------------------------------
+def construct_editor(*args, **kwargs):
+    app = qapplication()
+    editor = CodeEditor(parent=None)
+    kwargs['language'] = 'Python'
+    editor.setup_editor(*args, **kwargs)
+
+    text = ("def some_function():\n"
+            "    \n"  # W293 trailing spaces
+            "    a = 1 # a comment\n"  # E261 two spaces before inline comment
+            "\n"
+            "    a += s\n"  # Undefined variable s
+            "    return a\n"
+            )
+    editor.set_text(text)
+    source_code = to_binary_string(editor.toPlainText())
+    results = check_with_pyflakes(source_code) + check_with_pep8(source_code)
+    editor.process_code_analysis(results)
+
+    return editor
+
+
+def test_adding_warnings():
+    """Test that warning are saved in the blocks of the editor."""
+    editor = construct_editor()
+
+    block = editor.textCursor().block()
+    line_count = editor.document().blockCount()
+
+    warnings = []
+    for i in range(line_count):
+        data = block.userData()
+        if data:
+            warnings.append((i+1, data.code_analysis[0][0]))
+        block = block.next()
+
+    expected_warnings = {2: 'W293', 3: 'E261', 5: 'undefined name'}
+    for i, warning in warnings:
+        assert expected_warnings[i] in warning
+
+
+def test_move_warnings():
+    editor = construct_editor()
+
+    # Move between warnings
+    editor.go_to_next_warning()
+    assert 2 == editor.get_cursor_line_number()
+
+    editor.go_to_next_warning()
+    assert 3 == editor.get_cursor_line_number()
+
+    editor.go_to_previous_warning()
+    assert 2 == editor.get_cursor_line_number()
+
+    # Test cycling behaviour
+    editor.go_to_line(5)
+    editor.go_to_next_warning()
+    assert 2 == editor.get_cursor_line_number()
+
+    editor.go_to_previous_warning()
+    assert 5 == editor.get_cursor_line_number()