защита Пилинта от самопредставления
У меня есть этот тестовый файл:
"""module docstring"""
class Aclass:
"""class docstring"""
def __init__(self, attr=None, attr2=None):
self.attr = attr
self.attr2 = attr2
def __repr__(self):
return 'instance_of the Aclass {self.attr}.'
def __str__(self):
return 'The A with: {self.attr}.'
def init_a():
"""function docstring"""
a_inst = Aclass()
attr = 1
attr2 = 2
a_inst.attr2 = attr2
# should be: a_inst.attr = attr, but have a typo
attr = attr
и я проверяю его, используя pylint, и вывод показывает, что все в порядке.
$ pylint test.py
--------------------------------------------------------------------
Your code has been rated at 10.00/10 (previous run: 10.00/10, +0.00)
Исходя из пометки, я ожидаю флага о подозрительном использовании на языке программного обеспечения, потому что я не знаю, когда этот код a=1; a=a
может быть полезен.
И я хочу увидеть какое-то предупреждение, например: неиспользованная переменная или самоназначение и т.д. Есть ли способ использовать точку? (Я знаю о Пихарме и сонаркебе). Пример правил сонара.
public void foo() {
int x = 3;
x = x;
}
Such assignments are useless, and may indicate a logic error or typo.
подробности о pylint
pylint 2.3.1
astroid 2.2.5
Python 3.6.5 (default, May 5 2019, 22:05:54)
[GCC 6.3.0 20170516]
ОБНОВЛЕНИЕ Добавил в версию Пилинт 2.4
Ответы
Ответ 1
Я ознакомился с правилами Pylint и не нашел ничего, что могло бы помочь вам решить эту проблему. Что я обнаружил, так это то, что вы можете написать свой собственный инструмент проверки и сделать Pylint, используя его:
$ pylint yourpieceofcode.py --load-plugins=checker
checker.py:
from pylint.checkers import BaseChecker
from pylint.interfaces import IAstroidChecker
class SelfAssignChecker(BaseChecker):
__implements__ = IAstroidChecker
name = 'self-assign-returns'
priority = -1
msgs = {
'W5555': (
'Self assignment (%s).',
'self-assign',
'useless assignment.'
),
}
def visit_assign(self, node):
names = []
for child in node.get_children():
if not hasattr(child, 'name'):
return
if child.name not in names:
names.append(child.name)
else:
self.add_message("self-assign", node=node, args=child.name)
def register(linter):
linter.register_checker(SelfAssignChecker(linter))
Док здесь ! :)
Проверено на вашем файле test.py
Выход:
$ pylint --load-plugins=checker test.py
************* Module test
test.py:25:0: C0304: Final newline missing (missing-final-newline)
test.py:25:4: W5555: Self assignment (attr). (self-assign)
------------------------------------------------------------------
Your code has been rated at 8.57/10 (previous run: 9.29/10, -0.71)
Пилинт версия:
$ pylint --version
pylint 2.3.1
astroid 2.2.5
Python 3.6.7 (default, Oct 22 2018, 11:32:17)
[GCC 8.2.0]
Ответ 2
фактически вы использовали attr в своем def, присвоив ему значение attr = 1
а затем присвоили его снова, используя attr = attr
.
если вы удалите последнюю строку attr = attr
вы получите это предупреждение:
test.py:21:4: W0612: Unused variable 'attr' (unused-variable)
Я думаю, что это такая ошибка в pylint, если я правильно понимаю ситуацию, так как я нашел только ссылки на "назначения для себя /cls", но не для "назначения себя".
Ответ 3
Почему это было бы предупреждение, в первую очередь ниже приведен совершенно правильный код
In [7]: a = 1
In [8]: a = a
Даже pycodestyle
преемник pep8
не показывает предупреждение для кода выше :)