Missing whitespace around operator как исправить

Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Ошибки оформления — синтаксис и линтер

Основы Python

Ошибки

Если программа на Python написана синтаксически некорректно, то интерпретатор выводит на экран соответствующее сообщение. Также он указывает на файл и строчку, где произошла ошибка.

Синтаксическая ошибка возникает в том случае, когда код записали с нарушением грамматических правил. В естественных языках грамматика важна, но текст с ошибками обычно можно понять и прочитать. В программировании все строго. Мельчайшее нарушение — и программа даже не запустится. Примером может быть забытая ;, неправильно расставленные скобки и другие детали.

Вот пример кода с синтаксической ошибкой:

print('Hodor)

Если запустить код выше, то мы увидим следующее сообщение:

$ python index.py
File "index.py", line 1
    print('Hodor)
                            ^
SyntaxError: EOL while scanning string literal

С одной стороны, ошибки синтаксиса — самые простые, потому что они связаны с грамматическими правилами написания кода, а не со смыслом кода. Их легко исправить: нужно лишь найти нарушение в записи. С другой стороны, интерпретатор не всегда может четко указать на это нарушение. Поэтому бывает, что забытую скобку нужно поставить не туда, куда указывает сообщение об ошибке.

Ошибки линтера

Мы уже научились писать простые программы, и поэтому можно немного поговорить о том, как писать их правильно.

Код нужно оформлять определенным образом, чтобы он был понятным и простым в поддержке. Существуют специальные наборы правил, которые описывают различные аспекты написания кода — их называют стандартами кодирования. В Python стандарт один — PEP8. Он отвечает практически на все вопросы о том, как оформлять ту или иную часть кода. Этот документ содержит все правила, которых нужно придерживаться. Новичкам мы советуем завести привычку заглядывать в стандарт PEP8 и писать код по нему.

Сегодня не нужно помнить все правила из стандарта, потому что существуют специальные программы, которые проверяют код автоматически и сообщают о нарушениях. Такие программы называются линтерами. Они проверяют код на соответствие стандартам. В Python их достаточно много, и наиболее популярный из них — flake8.

Взгляните на пример:

result = 1+ 3

Линтер будет ругаться на нарушение правила: E225 missing whitespace around operator. По стандарту, все операторы всегда должны отделяться пробелами от операндов.

Выше мы увидели правило E225 — это одно из большого количества правил. Другие правила описывают отступы, названия, скобки, математические операции, длину строчек и множество иных аспектов. Каждое отдельное правило кажется неважным и мелким, но вместе они составляют основу хорошего кода. Список всех правил flake8 доступен в этой документации.

Вы уже знакомы с линтером, потому что в практических заданиях платформа Хекслета проверяет ваш код с помощью него. Скоро вы начнете использовать его и за пределами Хекслета, когда будете реализовывать учебные проекты. Вы настроите линтер, и он будет проверять код уже в реальной разработке и сообщать вам о нарушениях.


Дополнительные материалы

  1. Как читать вывод тестов в Python

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Your Vim plugin was wrong when you asked in 2013… but right in 2010, when it was authored. PEP 8 has changed on several occasions, and the answer to your question has changed as well.

Originally, PEP 8 contained the phrase:

Use spaces around arithmetic operators

Under that rule,

range(a, b+1)

is unambiguously wrong and should be written as

range(a, b + 1)

That is the rule that pycodestyle (the Python linter, previously known as pep8.py, that the asker’s Vim plugin uses under the hood) implemented for several years.

However, this was changed in April 2012. The straightforward language that left no room for discretion was replaced with this much woollier advice:

If operators with different priorities are used, consider adding whitespace around the operators with the lowest priority(ies). Use your own judgment; however, never use more than one space, and always have the same amount of whitespace on both sides of a binary operator.

Confusingly, the examples that illustrate this rule were originally left unchanged (and hence in contradiction to the prose). This was eventually fixed, but not very well, and the examples remain confusing, seeming to imply a much stricter and less subjective rule than the prose does.

There is still a rule requiring whitespace around some particular operators:

Always surround these binary operators with a single space on either side: assignment ( = ), augmented assignment ( += , -= etc.), comparisons ( == , < , > , != , <> , <= , >= , in , not in , is , is not ), Booleans ( and , or , not ).

but note that this rule is explicit about which operators it refers to and arithmetic operators like + are not in the list.

Thus the PEP, in its current form, does not dictate whether or not you should use spaces around the + operator (or other arithmetic operators like * and / and **). You are free to “use your own judgement”.

By the way, the pycodestyle linter changed its behaviour in late 2012 to reflect the change in the PEP, separating the rules about using whitespace around operators into two error codes, E225 (for failure to use whitespace around the operators that PEP 8 still requires whitespace around), which is on by default, and E226 (for failure to use whitespace around arithmetic operators), which is ignored by default. The question asker here must’ve been using a slightly outdated version of the linter when he asked this question in 2013, given the error that he saw.

Python’s PEP8 code specification, so record the common PEP8 code specification problems and solutions, learn it, and continue to update when you encounter it, develop good habits, and write standardized code!

PEP 8: no newline at end of file

Solution: You need to start a new line at the end of the code and move the cursor to the last carriage return

  • PEP 8: indentation is not a multiple of four
    Solution: Indent is not a multiple of 4, check indent

  • PEP 8: over-indented
    Solution: Excessive indentation, check indentation

  • PEP 8: missing whitespace after’,’
    Solution: There are fewer spaces after the comma, just add spaces, similar to the semicolon or colon after the missing spaces

  • PEP 8: multiple imports on one line
    Solution: Do not refer to multiple libraries in one sentence, for example:import socket, urllib.errorIt is best written as:import socket import urllib.error

  • PEP 8: blank line at end of line
    Solution: There are more spaces at the end of the code, just delete the spaces

  • PEP 8: at least two spaces before inline comment
    Solution: There must be at least two spaces between the code and the comment

  • PEP 8: block comment should start with ‘#’
    Solution: The comment should start with # plus a space

  • PEP 8: inline comment should start with ‘#’
    Solution: The comment should start with # plus a space

  • PEP 8: module level import not at top of file
    Solution: import is not at the top of the file, there may be other code before

  • PEP 8: expected 2 blank lines,found 0
    Solution: Two blank lines are needed, add two blank lines

  • PEP 8: function name should be lowercase
    Solution: Change the function name to lower case

  • PEP 8: missing whitespace around operator
    Solution: Operators (’=’, ‘>’, ‘<’, etc.) lack spaces before and after, just add

  • PEP 8: unexpected spaces around keyword / parameter equals
    Solution: Unexpected spaces appear around the keyword / parameter equal sign, just remove the spaces

  • PEP 8: multiple statements on one line (colon)
    Solution: The multi-line statement is written to one line, for example:if x == 2: print('OK')Write in two lines

  • PEP 8: line too long (82 > 79 characters)
    Solution: The maximum length limit of each line is exceeded 79

  • PEP 8: Simplify chained comparison
    can simplify chain comparisons (for example:if a >= 0 and a <= 9: Can be abbreviated as:if 0 <= a <= 9:


  • If you want to selectively ignore the warning message of the PEP8 code style, you can use the following methods: (Cultivate good habits and write standardized code! It is not recommended to ignore!)

    ①Move the mouse to the place where the warning message appears, pressalt+Enter, Choose to ignore (Ignore) this error:

    ②Select one by oneFile – Settings – Editor – Inspections, Found under PythonPEP8 coding style violation Options, in the lower right cornerIgnore errors Click the plus sign to add the warning message ID that needs to be ignored (see the appendix for ID information), for example, you want to ignoreindentation contains mixed spaces and tabsFor this warning, just add its ID:E101 Just

    Appendix: All warning messages and corresponding IDs, official address: https://pep8.readthedocs.io/en/latest/intro.html#error-codes

    code sample message
    E1 Indentation
    E101 indentation contains mixed spaces and tabs
    E111 indentation is not a multiple of four
    E112 expected an indented block
    E113 unexpected indentation
    E114 indentation is not a multiple of four (comment)
    E115 expected an indented block (comment)
    E116 unexpected indentation (comment)
    E117 over-indented
    E121 (*^) continuation line under-indented for hanging indent
    E122 (^) continuation line missing indentation or outdented
    E123 (*) closing bracket does not match indentation of opening bracket’s line
    E124 (^) closing bracket does not match visual indentation
    E125 (^) continuation line with same indent as next logical line
    E126 (*^) continuation line over-indented for hanging indent
    E127 (^) continuation line over-indented for visual indent
    E128 (^) continuation line under-indented for visual indent
    E129 (^) visually indented line with same indent as next logical line
    E131 (^) continuation line unaligned for hanging indent
    E133 (*) closing bracket is missing indentation
    E2 Whitespace
    E201 whitespace after ‘(‘
    E202 whitespace before ‘)’
    E203 whitespace before ‘:’
    E211 whitespace before ‘(‘
    E221 multiple spaces before operator
    E222 multiple spaces after operator
    E223 tab before operator
    E224 tab after operator
    E225 missing whitespace around operator
    E226 (*) missing whitespace around arithmetic operator
    E227 missing whitespace around bitwise or shift operator
    E228 missing whitespace around modulo operator
    E231 missing whitespace after ‘,’, ‘;’, or ‘:’
    E241 (*) multiple spaces after ‘,’
    E242 (*) tab after ‘,’
    E251 unexpected spaces around keyword / parameter equals
    E261 at least two spaces before inline comment
    E262 inline comment should start with ‘# ‘
    E265 block comment should start with ‘# ‘
    E266 too many leading ‘#’ for block comment
    E271 multiple spaces after keyword
    E272 multiple spaces before keyword
    E273 tab after keyword
    E274 tab before keyword
    E275 missing whitespace after keyword
    E3 Blank line
    E301 expected 1 blank line, found 0
    E302 expected 2 blank lines, found 0
    E303 too many blank lines (3)
    E304 blank lines found after function decorator
    E305 expected 2 blank lines after end of function or class
    E306 expected 1 blank line before a nested definition
    E4 Import
    E401 multiple imports on one line
    E402 module level import not at top of file
    E5 Line length
    E501 (^) line too long (82 > 79 characters)
    E502 the backslash is redundant between brackets
    E7 Statement
    E701 multiple statements on one line (colon)
    E702 multiple statements on one line (semicolon)
    E703 statement ends with a semicolon
    E704 (*) multiple statements on one line (def)
    E711 (^) comparison to None should be ‘if cond is None:’
    E712 (^) comparison to True should be ‘if cond is True:’ or ‘if cond:’
    E713 test for membership should be ‘not in’
    E714 test for object identity should be ‘is not’
    E721 (^) do not compare types, use ‘isinstance()’
    E722 do not use bare except, specify exception instead
    E731 do not assign a lambda expression, use a def
    E741 do not use variables named ‘l’, ‘O’, or ‘I’
    E742 do not define classes named ‘l’, ‘O’, or ‘I’
    E743 do not define functions named ‘l’, ‘O’, or ‘I’
    E9 Runtime
    E901 SyntaxError or IndentationError
    E902 IOError
    W1 Indentation warning
    W191 indentation contains tabs
    W2 Whitespace warning
    W291 trailing whitespace
    W292 no newline at end of file
    W293 blank line contains whitespace
    W3 Blank line warning
    W391 blank line at end of file
    W5 Line break warning
    W503 (*) line break before binary operator
    W504 (*) line break after binary operator
    W505 (*^) doc line too long (82 > 79 characters)
    W6 Deprecation warning
    W601 .has_key() is deprecated, use ‘in’
    W602 deprecated form of raising exception
    W603 ‘<>’ is deprecated, use ‘!=’
    W604 backticks are deprecated, use ‘repr()’
    W605 invalid escape sequence ‘x’
    W606 ‘async’ and ‘await’ are reserved keywords starting with Python 3.7

    Темные силы не дремлют. Они пробираются в дивное королевство Python и используют черную магию, чтобы осквернить главную реликвию — чистый код. Однако опасны не только злые чары.

    Сегодня я расскажу о страшных чудовищах, которые, возможно, уже обжились в вашем коде и готовы устанавливать свои правила. Здесь нужен герой, который защитит безмятежный мир от злобных тварей. И именно вы станете тем, кто сразится с ними!

    Всем героям, однако, нужно магическое снаряжение, которое верой и правдой послужит им в грандиозных битвах. К счастью, с нами будет линтер wemake-python-styleguide. Он станет тем самым острым оружием и надежным соратником.

    Все готово, выступаем в поход!

    Пожиратели пространства

    А вот и первые проблемы. Жители стали замечать, как нечто лакомится пробелами, а операторы обретают причудливые формы:

    x = 1
    x -=- x
    print(x)
    # => 2
    
    o = 2
    o+=+o
    print(o)
    # => 4
    
    print(3 --0-- 5 == 8)
    # => True

    Эти странные операторы состоят из совершенно обычных и дружественных нам -= и -. Посмотрим, сможет ли наш линтер найти их:

      5:5      E225  missing whitespace around operator
      x -=- x
          ^
    
      5:5      WPS346 Found wrong operation sign
      x -=- x
          ^
    
      10:2     E225  missing whitespace around operator
      o+=+o
       ^
    
      14:10    E225  missing whitespace around operator
      print(3 --0-- 5 == 8)
               ^
    
      14:10    WPS346 Found wrong operation sign
      print(3 --0-- 5 == 8)
               ^
    
      14:11    WPS345 Found meaningless number operation
      print(3 --0-- 5 == 8)
                ^
    
      14:12    E226  missing whitespace around arithmetic operator
      print(3 --0-- 5 == 8)
                 ^
    
      14:13    WPS346 Found wrong operation sign
      print(3 --0-- 5 == 8)
                  ^

    Настала пора обнажить меч и принять бой:

    x = 1
    x += x
    
    o = 2
    o += o
    
    print(3 + 5 == 8)

    Враг повержен, и сразу вернулись прежние чистота и ясность!

    Загадочные точки

    Теперь жители сообщают о появлении странных глифов. О, смотрите-ка, вот и они!

    print(0..__eq__(0))
    # => True
    
    print(....__eq__(((...))))
    # => True

    Что же здесь происходит? Кажется, там замешаны типы данных float и Ellipsis, но лучше удостовериться.

      21:7     WPS609 Found direct magic attribute usage: __eq__
      print(0..__eq__(0))
            ^
    
      21:7     WPS304 Found partial float: 0.
      print(0..__eq__(0))
            ^
    
      24:7     WPS609 Found direct magic attribute usage: __eq__
      print(....__eq__(((...))))
            ^

    Ага, теперь понятно. Действительно, эти точки — краткая запись значений типа float (в первом случае) и Ellipsis (во втором). И в обоих случаях происходит обращение к методу, также через точку. Давайте посмотрим, что же скрывалось за этими знаками:

    print(0.0 == 0)
    print(... == ...)

    На этот раз все обошлось, но впредь не сравнивайте константы друг с другом, дабы не накликать беду.

    Кривая дорожка

    А между тем у нас новая напасть — значения из некоторых веток в функции никогда не возвращаются. Давайте разберемся, в чем дело.

    def some_func():
        try:
           return 'from_try'
        finally:
           return 'from_finally'
    
    some_func()
    # => 'from_finally'

    Функция не возвращает значение 'from_try' из-за закравшейся в код ошибки. «Как ее исправить?» — изумленно спросите вы.

    31:5 WPS419 Found `try`/`else`/`finally` with multiple return paths
     try:
     ^

    Оказывается, wemake-python-styleguide знает ответ: никогда не возвращайте значение из ветки finally. Послушаемся совета.

    def some_func():
      try:
          return 'from_try'
      finally:
          print('now in finally')

    Мрачный СИ-луэт прошлого

    Древнее существо пробуждается. Уже несколько десятилетий никто не видел его, но теперь оно вернулось.

    a = [(0, 'Hello'), (1, 'world')]
    for ['>']['>'>'>'], x in a:
        print(x)

    Что тут происходит? Известно, что в циклах можно распаковывать разные значения: почти любые валидные в Python выражения.

    Правда, многое из этого примера нам не следовало бы делать:

      44:1     WPS414 Found incorrect unpacking target
      for ['>']['>'>'>'], x in a:
      ^
    
      44:5     WPS405 Found wrong `for` loop variable definition
      for ['>']['>'>'>'], x in a:
          ^
    
      44:11    WPS308 Found constant compare
      for ['>']['>'>'>'], x in a:
                ^
    
      44:14    E225  missing whitespace around operator
      for ['>']['>'>'>'], x in a:
                   ^
    
      44:21    WPS111 Found too short name: x
      for ['>']['>'>'>'], x in a:
                          ^

    Теперь разберемся с ['>']['>'>'>']. Похоже, что данное выражение можно просто переписать как ['>'][0], поскольку у выражения '>' > '>' значение False. А False и 0 — одно и тоже.

    Проблема решена.

    Метки Темного Колдуна

    Насколько сложным может быть выражение на Python? Наверняка такие конструкции — происки злых сил. Это Темный Колдун оставляет свои замысловатые метки во всех классах, к которым прикасается:

    class _:
        # Видите эти четыре метки?
        _: [(),...,()] = {((),...,()): {(),...,()}}[((),...,())]
    
    print(_._) # и этот оператор выглядит знакомо 
    # => {(), Ellipsis}

    Что же за ними скрывается? Похоже, у каждой метки свое значение:

    • Объявление и указание типа: _: [(),...,()] =.
    • Определение словаря, где значение — набор данных: = { ((),...,()): {(),...,()} }.
    • Ключ: [((),...,())].

    В мире людей подобная запись не имеет никакого смысла и безвредна, однако в королевстве Python она может стать оружием в злых руках. Давайте ее уберем:

      55:5     WPS122 Found all unused variables definition: _
      _: [(),...,()] = {((),...,()): {(),...,()}}[((),...,())]
      ^
    
      55:5     WPS221 Found line with high Jones Complexity: 19
      _: [(),...,()] = {((),...,()): {(),...,()}}[((),...,())]
      ^
    
      55:36    WPS417 Found non-unique item in hash: ()
      _: [(),...,()] = {((),...,()): {(),...,()}}[((),...,())]
                                     ^
    
      57:7     WPS121 Found usage of a variable marked as unused: _
      print(_._)  # и этот оператор выглядит знакомо 
            ^

    Теперь, когда мы удалили или зарефакторили это выражение (со значением 19 по метрике сложности Jones Complexity), от метки Темного Колдуна в бедном классе не осталось и следа. Очередные ростки зла уничтожены.

    Однако теперь наши классы связались с какими-то дурными типами, и те оказывают на них пагубное влияние.

    Сейчас классы выдают очень странные результаты:

    class Example(type((lambda: 0.)())):
     ...
    
    print(Example(1) + Example(3))
    # => 4.0

    Почему 1 + 3 равно 4.0, а не 4? Чтобы это выяснить, рассмотрим поближе часть с type((lambda: 0.)()):

    • (lambda: 0.)() просто равно 0., а это просто иная запись 0.0.
    • type(0.0) возвращает тип float.
    • когда мы пишем Example(1), это значение преобразуется в Example(1.0) внутри класса.
    • Example(1.0) + Example(3.0) = Example(4.0).

    Давайте убедимся, что наш линтер-клинок по-прежнему остр:

      63:15    WPS606 Found incorrect base class
      class Example(type((lambda: 0.)())):
                    ^
    
      63:21    WPS522 Found implicit primitive in a form of lambda
      class Example(type((lambda: 0.)())):
                          ^
    
      63:29    WPS304 Found partial float: 0.
      class Example(type((lambda: 0.)())):
                                  ^
    
      64:5     WPS428 Found statement that has no effect
      ...
      ^
    
      64:5     WPS604 Found incorrect node inside `class` body
      ...
      ^

    Со всем разобрались, теперь наши классы в безопасности. Можем двигаться дальше.

    Иллюзии

    Иногда на пути встречаются выражения такие похожие, но такие разные. Вот и мы столкнулись с таким примером в коде. Выглядит, как самое обычное выражение-генератор, но на самом деле это кое-что совсем другое.

    a = ['a', 'b']
    print(set(x + '!' for x in a))
    # => {'b!', 'a!'}
    
    print(set((yield x + '!') for x in a))
    # => {'b!', None, 'a!'}

    Это одно из хтонических чудовищ Python — да, они все-таки существуют и тут. Учитывая, что в python3.8 такая конструкция приведет к SyntaxError, yield и yield from следует использовать только в функциях-генераторах.

    А вот и отчет об инциденте:

      73:7     C401  Unnecessary generator - rewrite as a set comprehension.
      print(set(x + '!' for x in a))
            ^
    
      76:7     C401  Unnecessary generator - rewrite as a set comprehension.
      print(set((yield x + '!') for x in a))
            ^
    
      76:11    WPS416 Found `yield` inside comprehension
      print(set((yield x + '!') for x in a))

    И давайте перепишем обработку, как нам предлагают.

    print({x + '!' for x in a})

    Эта задачка была сложна, но и мы не лыком шиты. Что же дальше?

    Злобный двойник email

    Если нужно записать адрес электронной почты, то используем строку, ведь так? А вот и нет!

    Для решения обычных задач существуют необычные способы. А у обычных типов данных есть злые двойники. Сейчас мы выясним, кто есть кто.

    class G:
        def __init__(self, s):
            self.s = s
        def __getattr__(self, t):
            return G(self.s + '.' + str(t))
        def __rmatmul__(self, other):
            return other + '@' + self.s
    
    username, example = 'username', G('example')
    print(username@example.com)
    # => username@example.com

    Разберемся, как это работает.

    • в Python @ — это оператор, который можно переопределить с помощью магических методов __matmul__ и __rmatmul__.
    • выражение .com означает обращение к свойству com; переопределяется методом __getattr__.

    Этот пример значительно отличается от остальных тем, что он-то на самом деле корректный. Просто вот такой необычный. Вероятно, пользоваться им мы не будем, но в бестиарий запишем.

    Сила заблуждений

    В нашем королевстве настали смутные времена. Тьма наделила жителей сомнительными способностями. Это раскололо содружество разработчиков и привело к серьезным разногласиям.

    Способности эти воистину страшные, ибо теперь вам дано программировать в строках:

    from math import radians
    for angle in range(360):
        print(f'{angle=} {(th:=radians(angle))=:.3f}')
        print(th)
    
    # => angle=0 (th:=radians(angle))=0.000
    # => 0.0
    # => angle=1 (th:=radians(angle))=0.017
    # => 0.017453292519943295
    # => angle=2 (th:=radians(angle))=0.035
    # => 0.03490658503988659

    Что происходит в этом примере?

    • f'{angle=} — это способ записи f'angle={angle} в новых версиях (python3.8+).
    • (th:=radians(angle)) — это операция присваивания значения; да, теперь можно так делать и внутри строки.
    • =:.3f указывает на формат вывода: возвращается значение, округленное до третьего знака
    • метод print(th) отрабатывает, так как (th:=radians(angle)) имеет локальную область видимости в части кода, где находится вся строка.

    Стоит ли использовать f-строки? Как хотите.

    Стоит ли определять переменные в f-строках? Ни в коем случае.

    А вот дружеское напоминание о том, что еще можно (но, наверное, не нужно) написать с помощью f-строк:

    print(f"{getattr(__import__('os'), 'eman'[None:None:-1])}")
    # => posix

    Всего лишь импортируем модуль внутри строки, ничего такого, идем дальше.

    К счастью, в реальном коде наше оружие сразу почует неладное и засветится, аки знаменитый меч Жало:

      105:1    WPS221 Found line with high Jones Complexity: 16
      print(f"{getattr(__import__('os'), 'eman'[None:None:-1])}")
      ^
    
      105:7    WPS305 Found `f` string
      print(f"{getattr(__import__('os'), 'eman'[None:None:-1])}")
            ^
    
      105:18   WPS421 Found wrong function call: __import__
      print(f"{getattr(__import__('os'), 'eman'[None:None:-1])}")
                       ^
    
      105:36   WPS349 Found redundant subscript slice
      print(f"{getattr(__import__('os'), 'eman'[None:None:-1])}")
                                         ^

    И еще кое-что: f-строки нельзя использовать как переменные docstrings:

    def main():
        f"""My name is {__file__}/{__name__}!"""
    
    print(main().__doc__)
    # => None

    Заключение

    Мы сразились со многими жуткими монстрами, расплодившимися в коде, и сделали королевство Python прекраснее. Вы герой, гордитесь собой!

    Это было невероятное приключение. И я надеюсь, что вы узнали что-то новое для себя, что поможет в грядущих сражениях. Мир нуждается в вас!

    На сегодня все. Удачи на тракте, пусть звезды ярко освещают ваш путь!

    Полезные ссылки

    • Python code disasters
    • wtf, python?
    • wemake-python-styleguide

    А вы, вольные жители Python королевства, встречались с подобной черной магией в вашем коде? Удалось ли справиться с ней? Или битва еще не завершена (или вовсе проиграна)? Если вам нужна помощь бывалых магов и чародеев Python, то приходите к нам на Moscow Python Conf++ 27 марта 2020 года. У нас будут проверенные рецепты по борьбе с плохим и старым кодом от Владимира Филонова (доклад + 2 часа практики), Кирилла Борисова и Левона Авакяна.

    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

    Closed

    moylop260 opened this issue

    Sep 14, 2016

    · 5 comments


    · Fixed by #3577

    Comments

    @moylop260

    Steps to reproduce

    1. Use the following code var = 3+0
    2. Run flake8 --show-source --select=E226 file.py
    3. See the outuput: file.py:1:6: E226 missing whitespace around arithmetic operator
    4. Run pylint -d invalid-name,missing-docstring file.py

    Current behaviour

    Not emit messages.

    Expected behaviour

    Should we emit the message of missing whitespace around operator?

    pylint –version output

    pylint 1.6.4,
    astroid 1.4.8
    Python 2.7.10 (default, Oct 23 2015, 19:19:21)
    [GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.5)]

    @AWhetter

    I agree that we should have a message for this.

    @PCManticore

    I think we don’t have to mimic any flake8 or PEP 8 message for that matter, it would be an effort spent on things which are already handled quite well by other tools. I use pep8 in combination with pylint all the time, since I don’t expect pylint to follow PEP 8 to the heart. That is, if anyone is willing to provide the code for such a check, I would not mind adding in, but I don’t want to spend time on implementing it either.

    @Pierre-Sassoulas

    We’re not going to merge new formatting check as black and other tools handle this better than pylint and we removed bad-whitespace in #3577 and bad-continuation in #3571.

    @Ashark

    It looks strange this bug is closed.
    For those who came from google and want to enable such warning in vs code, I just switched to flake8 with such settings.json:

    {
        "python.linting.enabled": true,
        "python.linting.flake8Enabled": true,
        "python.linting.flake8Args": [
        ],
    }

    And in panel I now can see the error I want:
    image

    @Pierre-Sassoulas

    I’d suggest using black to autoformat your code, you don’t have to waste time adding a linter to warn about whitespaces around operator then also waste time by fixing them manually.

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