Como faço para o PyLint reconhecer membros numpy?


163

Estou executando o PyLint em um projeto Python. O PyLint faz muitas reclamações sobre não conseguir encontrar membros entorpecidos. Como posso evitar isso, evitando pular as verificações de associação.

Do código:

import numpy as np

print np.zeros([1, 4])

Que, quando executado, obtenho o esperado:

[[0. 0. 0. 0.]]

No entanto, o pylint me fornece este erro:

E: 3, 6: O módulo 'numpy' não possui um membro 'zeros' (nenhum membro)

Para versões, estou usando o pylint 1.0.0 (astroid 1.0.1, comum 0.60.0) e tentando trabalhar com o numpy 1.8.0.

Respostas:


75

Se você estiver usando o Visual Studio Code com a excelente extensão Python de Don Jayamanne , adicione uma configuração de usuário à lista de permissões numpy:

{
    // whitelist numpy to remove lint errors
    "python.linting.pylintArgs": [
        "--extension-pkg-whitelist=numpy"
    ]
}

2
Isso ajudou! no VSCode 1.12.2, confirmou que funciona no Windows 10 x64.
Simara

8
Eu precisava de mais: "python.linting.pylintArgs": ["--ignored-modules = numpy", "--ignored-classes = numpy", "--extension-pkg-whitelist = numpy"]
Peter

2
A solução da @Peter trabalhando no Windows 7 x64 e no Visual Studio Code 1.15.1 !!
BSP

3
A publicação do @BSP Peter não resolve o problema, ignora-o. Se eu pudesse downvote este comentário eu faria ..
Jonathan H

4
Isso não está mais funcionando para mim com o pylint 2.3.0.
Guillochon

58

Eu tive o mesmo problema aqui, mesmo com as últimas versões de todos os pacotes relacionados ( astroid 1.3.2, logilab_common 0.63.2, pylon 1.4.0).

A seguinte solução funcionou como um encanto: eu adicionei numpyà lista de módulos ignorados modificando meu pylintrcarquivo, na [TYPECHECK]seção:

[TYPECHECK]

ignored-modules = numpy

Dependendo do erro, você também pode precisar adicionar a seguinte linha (ainda na [TYPECHECK] section):

ignored-classes = numpy

2
No linux com pylint 1.4.4, astroid 1.3.8 e Python 3.4.3, isso funcionou, mas tive que colocar a extension-pkg-whitelist=numpylinha sob o [MASTER]cabeçalho do arquivo .pylintrc. O pylint parece ser um software bastante frágil e requer o toque de um especialista para mantê-lo trabalhando em tarefas básicas.
Eric Leschinski 24/03

12
Esta não é uma boa solução. Tudo o que faz é desativar completamente a verificação pylint da existência de qualquer membro. Idealmente, você gostaria de reconhecê-los adequadamente, e é o que as outras soluções fazem.
iFreilicht 24/10

1
@iFreilicht É uma medida de segurança. No tempo de execução, as definições do módulo podem mudar dinamicamente; mas habilitar isso no pylint envolveria a execução de código arbitrário. No entanto, eu ainda esperaria algum tipo de nota na resposta sobre --extension-pkg-whitelist, que realmente realiza a importação para o módulo especificado.
Zev Spitz

43

Eu estava recebendo o mesmo erro para um pequeno projeto numpy no qual estava trabalhando e decidi que ignorar os módulos numpy seria bom. Eu criei um .pylintrcarquivo com:

$ pylint --generate-rcfile > ~/.pylintrc

e seguindo os conselhos de paduwan e j_houg, modifiquei os seguintes setores:

[MASTER]

# A comma-separated list of package or module names from where C extensions may
# be loaded. Extensions are loading into the active Python interpreter and may
# run arbitrary code
extension-pkg-whitelist=numpy

e

[TYPECHECK]

# List of module names for which member attributes should not be checked
# (useful for modules/projects where namespaces are manipulated during runtime
# and thus existing member attributes cannot be deduced by static analysis. It
# supports qualified module names, as well as Unix pattern matching.
ignored-modules=numpy

# List of classes names for which member attributes should not be checked
# (useful for classes with attributes dynamically set). This supports can work
# with qualified names.
ignored-classes=numpy

e "corrigiu" meu problema.


6
Você tem certeza de que também precisou adicioná-lo às duas ignored-*entradas? Para mim, apenas adicionar um módulo à lista de permissões de extensão funciona perfeitamente.
iFreilicht 24/10

39

Nas versões recentes do pylint, você pode adicionar --extension-pkg-whitelist=numpyao seu comando pylint. Eles haviam corrigido esse problema em uma versão anterior de maneira insegura. Agora, se você deseja que eles analisem com mais cuidado um pacote fora da biblioteca padrão, você deve explicitamente colocá-lo na lista de permissões. Veja aqui.


2
O link "Veja aqui" está inoperante. A solução ainda está funcionando, mas é difícil entender o porquê. Seria bom adicionar um trecho do problema vinculado.
GergelyPolonkai

"Veja aqui" link foi corrigido (agora referente ao mesmo assunto no github)
David Clarke

Parece que funciona para módulos e pacotes, mas não para nomes de classes.
22617 Ian A. Mason

17

Como esse é o principal resultado do google, me deu a impressão de que você deve ignorar esses avisos em todos os arquivos:

O problema foi corrigido nas fontes do pylint / astroid no mês passado https://bitbucket.org/logilab/astroid/commits/83d78af4866be5818f193360c78185e1008fd29e, mas ainda não estão nos pacotes do Ubuntu.

Para obter as fontes, apenas

hg clone https://bitbucket.org/logilab/pylint/
hg clone https://bitbucket.org/logilab/astroid
mkdir logilab && touch logilab/__init__.py
hg clone http://hg.logilab.org/logilab/common logilab/common
cd pylint && python setup.py install

em que a última etapa provavelmente exigirá um sudoe, é claro, você precisará clonar o mercurial.


Eu diria que você não precisa clonar o novo logilab / common, mas que você precisa instalar o novo logilab / astroid. Reinstalando o logilab / astroid e o logilab / pylint, ele resolve o problema para mim.
paugier

7
Quais versões vocês estão usando? Estou no astroid 1.3.2 e no pylint 1.4.0 e ainda assim o problema com esse código from numpy import ceilresulta em E: 1, 0: No name 'ceil' in module 'numpy' (no-name-in-module) eu verifiquei o commit mencionado acima e parece que essas alterações estão na versão do astroid que eu tenho.
Zach Dwiel

2
Fez exatamente como sugerido no Xubuntu 14.04 e isso resultou em um pylint que não funciona: py2.7.egg / pylint / lint.py ", linha 866, em check_astroid_module astroid.close () AttributeError: o objeto 'Module' não tem atributo ' fechar '
bli

3
Talvez seja uma regressão - parece ter havido um release destinado a corrigir o problema. De qualquer maneira, eu abri uma nova edição sobre isso em bitbucket.org/logilab/pylint/issue/453/…
dstromberg

4
Aparentemente, isso ainda não está corrigido no pylint 1.4.2, astroid 1.3.4: # Module 'numpy' has no 'zeros' member (no-member)
Bill Bill

12

Para ignorar todos os erros gerados pelos atributos de numpy.core, agora podemos usar:

$ pylint a.py --generated-members=numpy.*

Como outra solução, adicione esta opção ao arquivo ~ / .pylintrc ou / etc / pylintrc :

[TYPECHECK]

# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E1101 when accessed. Python regular
# expressions are accepted.
generated-members=numpy.*

Para o código de questão mencionado até agora, isso parece redundante, mas ainda é importante para outros módulos, ie. netifaces e etc.


Eu tive o mesmo problema ao usar patsy.dmatrices. Adicionando generated-members=patsy.dmatricesresolveu meu problema.
Jonas Dahlbæk

12

Se você não quiser adicionar mais configurações, adicione este código ao seu arquivo de configuração, em vez de 'lista branca'.

{
"python.linting.pylintArgs": ["--generate-members"],
}

9
Você deve mencionar que isso se aplica muito especificamente ao código VS.
quer

Ele irá imprimirpylint: error: no such option: --generate-members
Spaceship222

8

Houve muitos erros diferentes relatados sobre isso nos últimos anos, ou seja, https://bitbucket.org/logilab/pylint/issue/58/false-positive-no-member-on-numpy-imports

Sugiro desativar as linhas onde as reclamações ocorrem.

# pylint: disable=E1103
print np.zeros([1, 4])
# pylint: enable=E1103

10
Eu uso tanto o numpy que posso desabilitar a verificação de não-membro em todo o arquivo; no entanto, quero evitar isso.
Alphadelta14

2
-1 Só porque a resposta de @ bijancn deve agora substituir esta.
usar o seguinte código

@LondonRob isso não acontece. O problema ainda existe no 1.4.2. A solução da paduwan é melhor, pois não requer a adição de fragmentos hacky ao seu código.
precisa saber é o seguinte

7

Provavelmente, está confuso com o método abstruso de importação de métodos do numpy. Ou seja, zerosé de fato numpy.core.multiarray.zeros, importado numpy com declaração

from .core import *

por sua vez importado com

from .numeric import *

e em numérico você encontrará

zeros = multiarray.zeros

Eu acho que ficaria confuso no lugar do PyLint!

Veja este bug para o lado do PyLint.


Eu gostaria de poder importar métodos únicos como esse, mas eu uso muitas funções e isso tornaria as importações uma bagunça enorme.
Alphadelta14

@ Alphadelta14 Seria uma enorme bagunça até encontrar todos eles. Veja a sugestão no link no final da minha resposta.
alko

2
Esse link SO faz o PyLint ignorar a importação de alguns módulos. Não tenho tanta certeza de que isso suprimiria erros de nenhum membro para esses arquivos. Eu também gostaria de evitar o patch do meu PyLint, se possível.
Alphadelta14

@ Alphadelta14 Acho que você deve esperar um patch para o PyLint então.
alko

4

Eu tive que adicionar isso na parte superior de qualquer arquivo em que eu uso muito o numpy.

# To ignore numpy errors:
#     pylint: disable=E1101

Caso alguém no eclipse esteja tendo problemas com Pydev e pylint ...


4

Na resposta Extensão à j_hougs, agora você pode adicionar os módulos em questão a esta linha no .pylintrc, que já está preparado vazio na geração:

extension-pkg-whitelist=numpy

você pode gerar uma amostra .pylintrc fazendo:

pylint --generate-rcfile > .pylintrc

e edite a linha mencionada


4

Isso foi finalmente resolvido no Pylint 1.8.2. Funciona imediatamente, não são necessários ajustes no pylintrc!


3

Esta é a pseudo-solução que eu criei para esse problema.

#pylint: disable=no-name-in-module
from numpy import array as np_array, transpose as np_transpose, \
      linspace as np_linspace, zeros as np_zeros
from numpy.random import uniform as random_uniform
#pylint: enable=no-name-in-module

Então, em seu código, em vez de chamar numpyfunções como np.arraye np.zerose assim por diante, você iria escrever np_array, np_zerosetc. As vantagens desta abordagem vs. outras abordagens sugeridas em outras respostas:

  • A desativação / ativação do pylint está restrita a uma pequena região do seu código
  • Isso significa que você não precisa cercar todas as linhas que invocam uma função numpy com uma diretiva pylint.
  • Você não está desativando o erro do pylint em todo o arquivo, o que pode mascarar outros problemas com o seu código.

A clara desvantagem é que você precisa importar explicitamente todas as funções numpy usadas. A abordagem poderia ser elaborada mais adiante. Você pode definir seu próprio módulo, chamá-lo, numpy_importercomo segue

""" module: numpy_importer.py
       explicitely import numpy functions while avoiding pylint errors  
"""
#pylint: disable=unused-import
#pylint: disable=no-name-in-module
from numpy import array, transpose, zeros  #add all things you need  
from numpy.random import uniform as random_uniform
#pylint: enable=no-name-in-module

Em seguida, o código do aplicativo pode importar apenas este módulo (em vez de numpy) como

import numpy_importer as np 

e usar os nomes, como de costume: np.zeros, np.arrayetc.

A vantagem disso é que você terá um único módulo no qual todas numpyas importações relacionadas serão feitas de uma vez por todas e, em seguida, importá-lo com essa linha única, onde quiser. Ainda assim, você deve ter cuidado para numpy_importernão importar nomes que não existem, numpypois esses erros não serão detectados pelo pylint.


2

Eu tive esse problema com numpy, scipy, sklearn, nipy, etc., e o resolvi envolvendo o epylint da seguinte forma:

$ cat epylint.py

#!/usr/bin/python

"""
Synopsis: epylint wrapper that filters a bunch of false-positive warnings and errors
Author: DOHMATOB Elvis Dopgima <gmdopp@gmail.com> <elvis.dohmatob@inria.fr>

"""

import os
import sys
import re
from subprocess import Popen, STDOUT, PIPE

NUMPY_HAS_NO_MEMBER = re.compile("Module 'numpy(?:\..+)?' has no '.+' member")
SCIPY_HAS_NO_MEMBER = re.compile("Module 'scipy(?:\..+)?' has no '.+' member")
SCIPY_HAS_NO_MEMBER2 = re.compile("No name '.+' in module 'scipy(?:\..+)?'")
NIPY_HAS_NO_MEMBER = re.compile("Module 'nipy(?:\..+)?' has no '.+' member")
SK_ATTR_DEFINED_OUTSIDE_INIT = re.compile("Attribute '.+_' defined outside __init__")
REL_IMPORT_SHOULD_BE = re.compile("Relative import '.+', should be '.+")
REDEFINING_NAME_FROM_OUTER_SCOPE = re.compile("Redefining name '.+' from outer scope")

if __name__ == "__main__":
    basename = os.path.basename(sys.argv[1])
    for line in Popen(['epylint', sys.argv[1], '--disable=C,R,I'  # filter thesew arnings
                       ], stdout=PIPE, stderr=STDOUT, universal_newlines=True).stdout:
        if line.startswith("***********"):
            continue
        elif line.startswith("No config file found,"):
            continue
        elif "anomalous-backslash-in-string," in line:
            continue
        if NUMPY_HAS_NO_MEMBER.search(line):
            continue
        if SCIPY_HAS_NO_MEMBER.search(line):
            continue
        if SCIPY_HAS_NO_MEMBER2.search(line):
            continue
        if "Used * or ** magic" in line:
            continue
        if "No module named" in line and "_flymake" in line:
            continue
        if SK_ATTR_DEFINED_OUTSIDE_INIT.search(line):
            continue
        if "Access to a protected member" in line:
            continue
        if REL_IMPORT_SHOULD_BE.search(line):
            continue
        if REDEFINING_NAME_FROM_OUTER_SCOPE.search(line):
            continue
        if NIPY_HAS_NO_MEMBER.search(line):
            continue
        # XXX extend by adding more handles for false-positives here
        else:
            print line,

Esse script simplesmente executa epylint e raspa sua saída para filtrar avisos e erros falso-positivos. Você pode estendê-lo adicionando mais casos elif.

NB: Se isso se aplica a você, modifique seu pychechers.sh para que fique assim

#!/bin/bash

epylint.py "$1" 2>/dev/null
pyflakes "$1"
pep8 --ignore=E221,E701,E202 --repeat "$1"
true

(Obviamente, você deve primeiro executar o epylint.py)

Aqui está um link para o meu .emacs https://github.com/dohmatob/mydotemacs . Espero que isso seja útil para alguém.


2

Isso parece funcionar em pelo menos o Pylint 1.1.0:

[TYPECHECK]

ignored-classes=numpy

2

Esta solução funcionou para mim

Basicamente, vá para Selecione o ícone de engrenagem na parte inferior esquerda => Configuração => Configuração da área de trabalho => Extensão => Configuração do Python => Clique em qualquer Settings.json => adicione isso no arquivo "python.linting.pylintArgs": [" --extension-pkg-whitelist = numpy "] Estou usando o VS 1.27.2


2

Eu tive o mesmo problema com um módulo diferente ( kivy.properties) que é um módulo C embrulhado numpy.

Usando o VSCode V1.38.0, a solução aceita interrompeu todo o processo para o projeto. Portanto, embora tenha realmente removido o falso positivo no-name-in-module, na verdade não melhorou a situação.

A melhor solução para mim foi usar o --ignored-modulesargumento no módulo incorreto. O problema é que passar qualquer argumento via python.linting.pylintArgsapaga as configurações padrão do VSCode , portanto, você também precisa redefini-las. Isso me deixou com o seguinte arquivo settings.json:

{
    "python.pythonPath": "C:\\Python\\Python37\\python.exe",
    "python.linting.pylintEnabled": true,
    "python.linting.enabled": true,
    "python.linting.pylintArgs": [
        "--ignored-modules=kivy.properties",
        "--disable=all",
        "--enable=F,E,unreachable,duplicate-key,unnecessary-semicolon,global-variable-not-assigned,unused-variable,binary-op-exception,bad-format-string,anomalous-backslash-in-string,bad-open-mode"
    ]
}

"python.linting.pylintArgs": [ "--generate-membros = kivy.properties"]
yee

1

Um pouco de copiar e colar da resposta anterior para resumir o que está funcionando (pelo menos para mim: debian-jessie)

  1. Em algumas versões mais antigas, pylinthavia um problema que impedia o trabalho com o numpy (e outros pacotes similares).

  2. Agora esse problema foi resolvido, mas os pacotes C externos (interfaces python para o código C - como numpy-) estão desativados por padrão por razões de segurança.

  3. Você pode criar uma lista branca, para permitir pylintusá-los no arquivo ~/.pylintrc.

Comando básico a ser executado: # SOMENTE se você ainda não possui um arquivo .pylintrc em sua casa $ pylint --generate-rcfile> .pylintrc

Em seguida, abra o arquivo e adicione os pacotes que você deseja depois extension-pkg-whitelist=separados por vírgula. Você pode ter o mesmo comportamento usando a opção --extension-pkg-whitelist=numpyna linha de comando.

Se você ignorar alguns pacotes na [TYPECHECK]seção, isso significa que pylintnunca mostrará erros relacionados a esses pacotes. Na prática, pylintnão dirá nada sobre esses pacotes.


0

Eu tenho trabalhado em um patch para pilotar para resolver o problema com membros dinâmicos em bibliotecas como numpy. Ele adiciona uma opção "dynamic-modules" que força a verificar se os membros existem durante o tempo de execução, fazendo uma importação real do módulo. Consulte a edição nº 413 no logilab / pylint . Há também uma solicitação pull, veja o link em um dos comentários.


É assim que o pydev resolve (uma lista especial de módulos para inspeção de carga). Como está indo esse trabalho?
Epu

0

Uma resposta rápida: atualize o Pylint para 1.7.1 (use o conda-forge fornecido com o Pylint 1.7.1 se você usar o conda para gerenciar pacotes)

Encontrei um problema semelhante no GitHub pylint aqui e alguém respondeu que tudo estava bem após a atualização para a 1.7.1.


0

Não tenho certeza se essa é uma solução, mas no VSCode, uma vez que escrevi explicitamente nas configurações do usuário para ativar o pylint, todos os módulos foram reconhecidos.

{
    "python.linting.pep8Enabled": true,
    "python.linting.pylintEnabled": true
}

0

Ultimamente (desde que algo mudou em spyder, pylint ou?), Tenho recebido erros E1101 ("nenhum membro") da análise de código estático do spyder nos símbolos astropy.constants. Não faço ideia do porquê.

Minha solução simplista para todos os usuários em um sistema Linux ou Unix (o Mac provavelmente é semelhante) é criar um / etc / pylintrc da seguinte maneira:

[TYPECHECK]
ignored-modules=astropy.constants

Obviamente, isso poderia ser colocado em um arquivo $ HOME / .pylintrc pessoal. E, eu poderia ter atualizado um arquivo existente.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.