Repository: spyder-ide/spyder

Issue:
Spyder comments (Ctrl+1 and Ctrl+4) generate pep8 warnings
_From [bentkows...@gmail.com](https://code.google.com/u/114523486630528179401/) on 2014-04-07T06:47:08Z_

Spyder Version:  2.2.5
Python Version:  2.7.5+
Qt Version    :  4.8.4, PyQt4 (API v2) 4.10.3 on Linux
IPython >=0.13  :  0.13.2 (OK)
matplotlib >=1.0:  1.2.1 (OK)
pep8 >=0.6      :  1.5.4 (OK)
pyflakes >=0.5.0:  0.8.1 (OK)
pylint >=0.25   :  1.1.0 (OK)
rope >=0.9.2    :  0.9.4 (OK)
sphinx >=0.6.6  :  1.2.2 (OK)
sympy >=0.7.0   :  0.7.3 (OK) 

* What steps will reproduce the problem?

  1. I updated Spyder2 and the whole bundle around it (rope, pylint, sphinx etc.) with PIP -U [...]
  2. It seems there as some update to PEP8 guidelines regarding commenting with #  (PEP8 E265).
  3. Say, I have commented a line:

         #somefunc(arg1, arg2)

     I get a warning "E265 block comment should start with '# '". Adding a space:

         # somefunc(arg1, arg2)

     removes the warning. Ctr+4 adds a line:

         #===================================

     at the beginning and end of the block commented out. This brings a warning as well.

* What is the expected output? What do you see instead?

  No false positive error message. 

* Please provide any additional information below

  Probably it's not a problem for people using software deposited in repos, but with time it will come up.

_Original issue: http://code.google.com/p/spyderlib/issues/detail?id=1785_



Discussion:
_From [contrebasse](https://code.google.com/u/contrebasse/) on 2014-04-11T06:25:16Z_

The warning is correct, the problem lies with spyder's autocomment, it should add a space after the #.

The problem is to know if the space should be removed when removing the comment.

_From [bentkows...@gmail.com](https://code.google.com/u/114523486630528179401/) on 2014-04-11T06:42:27Z_

A workaround would be adding not just the '#' sign but a 'special Spyder comment sequence', e.g. "# %" ("hash-space-proc"). But on the other hand that's looks just dirty :-(

Spyder can warn about a gap being not a multiplication of 4. That could be used to count the gap size and auto adjust it, if the removed hash was the first character in the line.

 P.

_From [contrebasse](https://code.google.com/u/contrebasse/) on 2014-04-11T14:25:22Z_

Having a number of space multiple of 4 (or 2 since it is an configuration option) would not work for continuation lines.

The issue can be fixed for Ctrl+4, however.

_From [ccordoba12](https://code.google.com/u/ccordoba12/) on 2014-04-16T09:13:50Z_

Joseph, if you can help us to solve this one it'd be great.

**Status:** HelpNeeded  
  **Labels:** Cat-Editor  

_From [ccordoba12](https://code.google.com/u/ccordoba12/) on 2015-01-01T15:21:16Z_

**Status:** Accepted  
  **Labels:** MS-v2.3.3  

_From [ccordoba12](https://code.google.com/u/ccordoba12/) on 2015-01-08T15:16:16Z_

**Labels:** -MS-v2.3.3 MS-v2.4  

Why can't we just make Ctrl-1 add and remove '# ' (with a space)? If there is no space, just remove '#', but always add '# '. I think that would work well with most code that follows PEP8 conventions. 

Ctrl-1 also leads to problems when you are commenting out indented blocks:

``` python
for i in range(10):
#    print(i)  # this is how the line looks when commented out using Ctrl-1
    # print(i)  # this is how the line should look if following PEP8
    print(i)  # so that the indent makes sense
```

Using Ctrl-1 above gives a PEP8 error: `E115 expected an indented block (comment)`.

---

So if Ctrl-1 worked by adding / removing '# ' before the first non-whitespace character in the line, that would fix both problems?

The problem is not adding `#`, but to know how to remove it without breaking the code. It should work even if the user added a comment manually at any place.

Imagine that the user manually added `#`(with no additional space) at the beginning of an indented line. Removing `#` at the beginning of the line with would be wrong because print(2) would be indented by 3 spaces instead of 4:

``` python
if True:
    print(1)
#    print(2)
```

We could check the surrounding block and try to guess the correct behavior, but I'm not sure we could do it without doing it wrong in some tricky corner cases.
But we are open to suggestions !

But according to PEP8, block comments should be indented [at the same level as the code](https://www.python.org/dev/peps/pep-0008/#block-comments). So the only time this would create problems is when people are not following PEP8 conventions to begin with. Maybe adding "Use '# ' for comments" as an option somewhere in configurations would work?

For the problem that you point out above, it would be useful if `Shift - Tab` worked even when lines are not multiples of four (it works this way in Geany for example). That way you could fix indentation with `Shift - Tab`, `Tab`.

Spyder shouldn't break code even if people are not following pep8.

I agree about Shift-Tab, it could be improved, but I don't think it's a solution for the uncommenting problem.

Do you know what other python editors do in this case ?

Just tested this with PyCharm. 

For the most part, it indents and unindents at the level of the code using '# ' (with a space) for indentation:

``` python
if True:
    print(1)
    # print(2)
```

If you select code that spans several different levels of indentation, it adds '# ' at the first level:

``` python
if True:
    print(1)
    # if True:
    #     print(2)
```

In both cases, it unindents by removing '# '.

For the case you pointed out above, it gives you a PEP8 warning, and unindenting still works by removing '# ', resulting in:

``` python
if True:
    print(1)
  print(2)
```

Thanks for testing.
The last case is strange, I'd expect to get 3 spaces before `print(2)` instead of 2, is it really like this in pycharm or just a typo when copying the result ?

@spyder-ide/core-developers Any idea ?

It's really like this. I think it always removes '# ' (with a space), if there is a space.

I actually think that that is the easiest to implement, cause we dont check for corner cases at all.. simply `#` is removed and inserted always. 

@Nodd I would prefer doing something like that cause is predictable, if we start playing with how to understand other cases we will end with weird code...

@andfoy, please work on this one.
Any update ?
Nop. sorry. We'll take a look at this after we release Spyder 3.2
Want me to have a look ? (I don't know much about Python yet, but this doesn't look like a huge challenge)
Sure, please go ahead. Any help is appreciated!

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
@@ -2258,14 +2258,15 @@ def toggle_comment(self):
 
     def comment(self):
         """Comment current line or selection."""
-        self.add_prefix(self.comment_string)
+        self.add_prefix(self.comment_string + " ")
 
     def uncomment(self):
         """Uncomment current line or selection."""
         self.remove_prefix(self.comment_string)
+        self.remove_prefix(" ")
 
     def __blockcomment_bar(self):
-        return self.comment_string + '='*(79-len(self.comment_string))
+        return self.comment_string + ' ' + '=' * (78 - len(self.comment_string))
 
     def transform_to_uppercase(self):
         """Change to uppercase current line or selection."""


Test patch: