2015-02-10 3 views
31

Мы были давними поклонниками pylint. Его статический анализ стал важной частью всех наших проектов python и сэкономил массу времени, преследуя непонятные ошибки. Но после обновления от 1.3 -> 1.4 почти все скомпилированные c-расширения приводят к ошибкам E1101 (без членов).pylint 1.4 сообщает E1101 (не входит) на всех расширениях C

Проекты, которые ранее проходили отлично, через pylint 1.3 теперь жалуются почти на каждый элемент расширения C с E1101. Мы были вынуждены отключить ошибки E1101, но это существенно умаляет полезность pylint.

Например, это вполне допустимо использование lxml пакета

r"""valid.py: demonstrate pylint 1.4 error""" 
from lxml import etree 
print etree.Element('mydoc') 

Выполнить это через pylint, и он сообщает:

$ pylint -rn valid.py 
No config file found, using default configuration 
************* Module valid 
E: 3, 6: Module 'lxml.etree' has no 'Element' member (no-member) 

Но это вполне допустимо:

$ python valid.py 
<Element mydoc at 7fddf67b1ba8> 

Вот где это становится действительно странно. Очень небольшая горстка расширений C, кажется, работают просто отлично через pylint, например .:

r"""valid2.py: this one works fine""" 
import sqlite3 
print sqlite3.version 

$ pylint -rn valid2.py 
No config file found, using default configuration 

Мой вопрос, кто-нибудь еще видел это? И если да, согласитесь ли вы поделиться своим обходом/решением?

Мы экспериментировали с попытками создания плагинов для подавления этих предупреждений (http://docs.pylint.org/plugins.html#enter-plugin), но мы возникли трудности изготовления головы или хвосты документы - и astroid базового класса убер-комплекс и бросает вызов нашей попытки его перехватить.

Для настоящих бонусных баллов (и нашей вечной благодарности) мы хотели бы понять, что изменилось в pylint. Мы будем рады исправить код (или, по крайней мере, опубликовать документ с лучшей практикой для авторов расширения C), который удовлетворит pylint.

детали платформы

$ pylint --version 
No config file found, using default configuration 
pylint 1.4.0, 
astroid 1.3.2, common 0.63.2 
Python 2.7.5 (default, Jul 1 2013, 18:09:11) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] 

ответ

38

Вскоре после размещения на мой вопрос, я нашел ответ. Фактически это изменение было сделано специально в качестве меры безопасности. Pylint импортирует модули для эффективного определения действительных методов и атрибутов. Было решено, что импорт c-расширений, которые не являются частью python stdlib, является угрозой безопасности и может вносить вредоносный код.

Это было сделано в выпуске Astroid 1.3.1 https://mail.python.org/pipermail/code-quality/2014-November/000394.html

только расширения C из надежных источников (стандартная библиотека) являются загружены в процессе изучения Python для построения AST из живого модуля ,

Существует четыре решения, если вы хотите использовать pylint для проектов, которые импортируют расширения non-stdlib c.

1) Отключите безопасность, используя опцию командной строки --unsafe-load-any-extension=y. Эта функция недокументирована и классифицируется как скрытый вариант (https://mail.python.org/pipermail/code-quality/2014-November/000439.html).

2) Отключите безопасность, используя установку pylint.rcunsafe-load-any-extensions=yes. Это рекомендуется по опции 1 и включает полную документацию в файл pylint.rc по умолчанию (созданный с помощью --generate-rcfile).

3) Укажите список имен пакетов или модулей, которым вы доверяете, чтобы быть загруженным pylint в файле pylint.rc, используя опцию extension-pkg-whitelist=.

4) Создайте плагин для управления АСТ (я понятия не имею, как это осуществить, но он регулярно обсуждается в списке рассылки pylint).

Мы выбрали вариант 3. Мы добавили следующую строку в наш файл проекта pylint.rc:

extension-pkg-whitelist=lxml 
+0

Спасибо очень много. Однако я должен отметить, что вариант 3, к сожалению, не работает с некоторыми пакетами STL, например, «многопроцессорность». – 4ae1e1

+0

Для # 4 эта документация, по-видимому, напрямую касается того, как исправить ложные положительные 'no-member' - http://docs.pylint.org/plugins.html –

+0

@SpainTrain Link мертв. – ppperry

5

@ user590028, спасибо большое за ответ! Я просто столкнулся с этой проблемой с библиотеками win32api, win32evtlog, win32file, win32gui и win32process, и ваше решение сработало.

Я использовал другой метод, который я думаю, стоит разместить здесь, который должен назвать pylint и передать белый список пакетов в качестве параметра:

pylint --extension-pkg-whitelist=win32api,win32evtlog,win32file,win32gui,win32process myfile.py 
+1

Ваше приветствие. fyi - 'extension-pkg-whitelist' был вариантом 3, и тот, который мы выбрали. – user590028

+2

Я просто хочу, чтобы люди знали, что вы можете передать его как параметр командной строки для pylint. – twasbrillig