标签归档:pyflakes

我如何让Pyflakes忽略声明?

问题:我如何让Pyflakes忽略声明?

我们的许多模块都始于:

try:
    import json
except ImportError:
    from django.utils import simplejson as json  # Python 2.4 fallback.

…这是整个文件中唯一的Pyflakes警告:

foo/bar.py:14: redefinition of unused 'json' from line 12

我如何让Pyflakes忽略这一点?

(通常我会去阅读文档,但是链接断开了。如果没有人回答,我只会阅读源代码。)

A lot of our modules start with:

try:
    import json
except ImportError:
    from django.utils import simplejson as json  # Python 2.4 fallback.

…and it’s the only Pyflakes warning in the entire file:

foo/bar.py:14: redefinition of unused 'json' from line 12

How can I get Pyflakes to ignore this?

(Normally I’d go read the docs but the link is broken. If nobody has an answer, I’ll just read the source.)


回答 0

如果您可以改用flake8-包裹pyflakes和pep8 checker-则以

# NOQA

(其中的空格非常大-代码末尾与之间的2个空格,在代码与文本#之间的一个空格NOQA)将告诉检查程序忽略该行上的任何错误。

If you can use flake8 instead – which wraps pyflakes as well as the pep8 checker – a line ending with

# NOQA

(in which the space is significant – 2 spaces between the end of the code and the #, one between it and the NOQA text) will tell the checker to ignore any errors on that line.


回答 1

我知道这是在不久前被质疑的,并且已经得到答复。

但是我想补充一下我通常使用的内容:

try:
    import json
    assert json  # silence pyflakes
except ImportError:
    from django.utils import simplejson as json  # Python 2.4 fallback.

I know this was questioned some time ago and is already answered.

But I wanted to add what I usually use:

try:
    import json
    assert json  # silence pyflakes
except ImportError:
    from django.utils import simplejson as json  # Python 2.4 fallback.

回答 2

是的,不幸的是dimod.org和所有好东西都一起倒了。

看一下pyflakes代码,在我看来pyflakes是经过设计的,因此可以很容易地将其用作“嵌入式快速检查器”。

为了实现忽略功能,您将需要编写自己的调用pyflakes检查器。

在这里您可以找到一个主意:http : //djangosnippets.org/snippets/1762/

请注意,以上代码段仅用于同一行中的注释位置。为了忽略整个块,您可能需要在块docstring中添加’pyflakes:ignore’并基于node.doc进行过滤。

祝好运!


我正在使用Pocket-lint进行各种静态代码分析。以下是在Pocket-Lint中忽略pyflakes所做的更改:https ://code.launchpad.net/~adiroiban/pocket-lint/907742/+merge/102882

Yep, unfortunately dimod.org is down together with all goodies.

Looking at the pyflakes code, it seems to me that pyflakes is designed so that it will be easy to use it as an “embedded fast checker”.

For implementing ignore functionality you will need to write your own that calls the pyflakes checker.

Here you can find an idea: http://djangosnippets.org/snippets/1762/

Note that the above snippet only for for comments places on the same line. For ignoring a whole block you might want to add ‘pyflakes:ignore’ in the block docstring and filter based on node.doc.

Good luck!


I am using pocket-lint for all kind of static code analysis. Here are the changes made in pocket-lint for ignoring pyflakes: https://code.launchpad.net/~adiroiban/pocket-lint/907742/+merge/102882


回答 3

引用github问题票证

尽管此修复程序仍在进行中,但是如果您想知道,可以通过以下方法解决:

try:
    from unittest.runner import _WritelnDecorator
    _WritelnDecorator; # workaround for pyflakes issue #13
except ImportError:
    from unittest import _WritelnDecorator

用所需的实体(模块,函数,类)替换_unittest和_WritelnDecorator

deemoowoor

To quote from the github issue ticket:

While the fix is still coming, this is how it can be worked around, if you’re wondering:

try:
    from unittest.runner import _WritelnDecorator
    _WritelnDecorator; # workaround for pyflakes issue #13
except ImportError:
    from unittest import _WritelnDecorator

Substitude _unittest and _WritelnDecorator with the entities (modules, functions, classes) you need

deemoowoor


回答 4

这是pyflakes的Monkey补丁,添加了# bypass_pyflakes注释选项。

passive_pyflakes.py

#!/usr/bin/env python

from pyflakes.scripts import pyflakes
from pyflakes.checker import Checker


def report_with_bypass(self, messageClass, *args, **kwargs):
    text_lineno = args[0] - 1
    with open(self.filename, 'r') as code:
        if code.readlines()[text_lineno].find('bypass_pyflakes') >= 0:
            return
    self.messages.append(messageClass(self.filename, *args, **kwargs))

# monkey patch checker to support bypass
Checker.report = report_with_bypass

pyflakes.main()

如果将其另存为bypass_pyflakes.py,则可以将其调用为python bypass_pyflakes.py myfile.py

http://chase-seibert.github.com/blog/2013/01/11/bypass_pyflakes.html

Here is a monkey patch for pyflakes that adds a # bypass_pyflakes comment option.

bypass_pyflakes.py

#!/usr/bin/env python

from pyflakes.scripts import pyflakes
from pyflakes.checker import Checker


def report_with_bypass(self, messageClass, *args, **kwargs):
    text_lineno = args[0] - 1
    with open(self.filename, 'r') as code:
        if code.readlines()[text_lineno].find('bypass_pyflakes') >= 0:
            return
    self.messages.append(messageClass(self.filename, *args, **kwargs))

# monkey patch checker to support bypass
Checker.report = report_with_bypass

pyflakes.main()

If you save this as bypass_pyflakes.py, then you can invoke it as python bypass_pyflakes.py myfile.py.

http://chase-seibert.github.com/blog/2013/01/11/bypass_pyflakes.html


回答 5

您也可以使用导入__import__。它不是pythonic,但是pyflakes不再警告您。请参阅的文档__import__

try:
    import json
except ImportError:
    __import__('django.utils', globals(), locals(), ['json'], -1)

You can also import with __import__. It’s not pythonic, but pyflakes does not warn you anymore. See documentation for __import__ .

try:
    import json
except ImportError:
    __import__('django.utils', globals(), locals(), ['json'], -1)

回答 6

我创建了一个带有一些awk魔术的shell脚本来帮助我。有了这个的所有生产线import typingfrom typing import#$(后者是我在这里使用一个特殊的注释)被排除($1是Python脚本的文件名):

result=$(pyflakes -- "$1" 2>&1)

# check whether there is any output
if [ "$result" ]; then

    # lines to exclude
    excl=$(awk 'BEGIN { ORS="" } /(#\$)|(import +typing)|(from +typing +import )/ { print sep NR; sep="|" }' "$1")

    # exclude lines if there are any (otherwise we get invalid regex)
    [ "$excl" ] &&
        result=$(awk "! /^[^:]+:(${excl}):/" <<< "$result")

fi

# now echo "$result" or such ...

基本上,它会记录行号并动态创建一个正则表达式。

I created a little shell script with some awk magic to help me. With this all lines with import typing, from typing import or #$ (latter is a special comment I am using here) are excluded ($1 is the file name of the Python script):

result=$(pyflakes -- "$1" 2>&1)

# check whether there is any output
if [ "$result" ]; then

    # lines to exclude
    excl=$(awk 'BEGIN { ORS="" } /(#\$)|(import +typing)|(from +typing +import )/ { print sep NR; sep="|" }' "$1")

    # exclude lines if there are any (otherwise we get invalid regex)
    [ "$excl" ] &&
        result=$(awk "! /^[^:]+:(${excl}):/" <<< "$result")

fi

# now echo "$result" or such ...

Basically it notes the line numbers and dynamically creates a regex out it.


PyLint,PyChecker或PyFlakes?[关闭]

问题:PyLint,PyChecker或PyFlakes?[关闭]

我想在以下工具上获得一些反馈:

  • 特征;
  • 适应性
  • 易用性和学习曲线。

I would like to get some feedback on these tools on :

  • features;
  • adaptability;
  • ease of use and learning curve.

回答 0

好吧,我有点好奇,所以我问了问题后就自己测试了3 ;-)

好的,这不是一个很认真的评论,但是我可以这样说:

我在以下脚本上尝试使用默认设置的工具(这很重要,因为您几乎可以选择检查规则):

#!/usr/local/bin/python
# by Daniel Rosengren modified by e-satis

import sys, time
stdout = sys.stdout

BAILOUT = 16
MAX_ITERATIONS = 1000

class Iterator(object) :

    def __init__(self):

        print 'Rendering...'
        for y in xrange(-39, 39): 
            stdout.write('\n')
            for x in xrange(-39, 39):
                if self.mandelbrot(x/40.0, y/40.0) :
                    stdout.write(' ')
                else:
                    stdout.write('*')


    def mandelbrot(self, x, y):
        cr = y - 0.5
        ci = x
        zi = 0.0
        zr = 0.0

        for i in xrange(MAX_ITERATIONS) :
            temp = zr * zi
            zr2 = zr * zr
            zi2 = zi * zi
            zr = zr2 - zi2 + cr
            zi = temp + temp + ci

            if zi2 + zr2 > BAILOUT:
                return i

        return 0

t = time.time()
Iterator() 
print '\nPython Elapsed %.02f' % (time.time() - t)

结果是 :

  • PyChecker这很麻烦,因为它会编译模块以对其进行分析。如果您不希望代码运行(例如,它执行SQL查询),那就不好了。
  • PyFlakes应该是精简版。确实,它决定代码是完美的。我正在寻找非常严重的东西,所以我认为我不会去做。
  • PyLint 一直很健谈,对代码的评分为3/10(天哪,我是个肮脏的编码器!)。

优点PyLint

  • 非常描述性和准确的报告。
  • 检测一些代码气味。在这里,它告诉我放弃类来编写带有函数的内容,因为在这种特定情况下,OO方法是无用的。我知道的东西,但是没想到计算机会告诉我:-p
  • 经过完全校正的代码运行得更快(没有类,没有引用绑定…)。
  • 由法国队制造。好的,这不是每个人的优点,但是我喜欢它;-)

缺点PyLint

  • 有些规则确实很严格。我知道您可以更改它,并且默认值是匹配PEP8,但是写“ for x in seq”是否构成犯罪?显然可以,因为您不能用少于3个字母写一个变量名。我会改变的。
  • 非常健谈。准备好使用眼睛。

更正的脚本(带有惰性文档字符串和变量名):

#!/usr/local/bin/python
# by Daniel Rosengren, modified by e-satis
"""
Module doctring
"""


import time
from sys import stdout

BAILOUT = 16
MAX_ITERATIONS = 1000

def mandelbrot(dim_1, dim_2):
    """
    function doc string
    """
    cr1 = dim_1 - 0.5
    ci1 = dim_2
    zi1 = 0.0
    zr1 = 0.0

    for i in xrange(MAX_ITERATIONS) :
        temp = zr1 * zi1
        zr2 = zr1 * zr1
        zi2 = zi1 * zi1
        zr1 = zr2 - zi2 + cr1
        zi1 = temp + temp + ci1

        if zi2 + zr2 > BAILOUT:
            return i

    return 0

def execute() :
    """
    func doc string
    """
    print 'Rendering...'
    for dim_1 in xrange(-39, 39): 
        stdout.write('\n')
        for dim_2 in xrange(-39, 39):
            if mandelbrot(dim_1/40.0, dim_2/40.0) :
                stdout.write(' ')
            else:
                stdout.write('*')


START_TIME = time.time()
execute()
print '\nPython Elapsed %.02f' % (time.time() - START_TIME)

编辑:

多亏鲁迪格·沃尔夫(Rudiger Wolf)的帮助,我发现pep8它的功能完全符合其名称:匹配PEP8。它发现了PyLint没有的语法语法。但是PyLint发现了与PEP8没有特别联系但有趣的东西。两种工具都很有趣且互补。

最终,我将同时使用这两种方法,因为它们确实很容易安装(通过软件包或setuptools),并且输出文本也很容易链接。

让您对它们的输出有一点了解:

pep8

./python_mandelbrot.py:4:11: E401 multiple imports on one line
./python_mandelbrot.py:10:1: E302 expected 2 blank lines, found 1
./python_mandelbrot.py:10:23: E203 whitespace before ':'
./python_mandelbrot.py:15:80: E501 line too long (108 characters)
./python_mandelbrot.py:23:1: W291 trailing whitespace
./python_mandelbrot.py:41:5: E301 expected 1 blank line, found 3

PyLint

************* Module python_mandelbrot
C: 15: Line too long (108/80)
C: 61: Line too long (85/80)
C:  1: Missing docstring
C:  5: Invalid name "stdout" (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)
C: 10:Iterator: Missing docstring
C: 15:Iterator.__init__: Invalid name "y" (should match [a-z_][a-z0-9_]{2,30}$)
C: 17:Iterator.__init__: Invalid name "x" (should match [a-z_][a-z0-9_]{2,30}$)

[...] and a very long report with useful stats like :

Duplication
-----------

+-------------------------+------+---------+-----------+
|                         |now   |previous |difference |
+=========================+======+=========+===========+
|nb duplicated lines      |0     |0        |=          |
+-------------------------+------+---------+-----------+
|percent duplicated lines |0.000 |0.000    |=          |
+-------------------------+------+---------+-----------+

Well, I am a bit curious, so I just tested the 3 myself right after asking the question ;-)

Ok, this is not a very serious review but here is what I can say :

I tried the tools with the default settings (it’s important because you can pretty much choose your check rules) on the following script :

#!/usr/local/bin/python
# by Daniel Rosengren modified by e-satis

import sys, time
stdout = sys.stdout

BAILOUT = 16
MAX_ITERATIONS = 1000

class Iterator(object) :

    def __init__(self):

        print 'Rendering...'
        for y in xrange(-39, 39): 
            stdout.write('\n')
            for x in xrange(-39, 39):
                if self.mandelbrot(x/40.0, y/40.0) :
                    stdout.write(' ')
                else:
                    stdout.write('*')


    def mandelbrot(self, x, y):
        cr = y - 0.5
        ci = x
        zi = 0.0
        zr = 0.0

        for i in xrange(MAX_ITERATIONS) :
            temp = zr * zi
            zr2 = zr * zr
            zi2 = zi * zi
            zr = zr2 - zi2 + cr
            zi = temp + temp + ci

            if zi2 + zr2 > BAILOUT:
                return i

        return 0

t = time.time()
Iterator() 
print '\nPython Elapsed %.02f' % (time.time() - t)

As a result :

  • PyChecker is troublesome because it compiles the module to analyze it. If you don’t want your code to run (e.g, it performs a SQL query), that’s bad.
  • PyFlakes is supposed to be lite. Indeed, it decided that the code was perfect. I am looking for something quite severe so I don’t think I’ll go for it.
  • PyLint has been very talkative and rated the code 3/10 (OMG, I’m a dirty coder !).

Strongs points of PyLint:

  • Very descriptive and accurate report.
  • Detect some code smells. Here it told me to drop my class to write something with functions because the OO approach was useless in this specific case. Something I knew, but never expected a computer to tell me :-p
  • The fully corrected code run faster (no class, no reference binding…).
  • Made by a French team. Ok it’s not a plus for everybody, but I like it ;-)

Cons of PyLint:

  • Some rules are really strict. I know that you can change it and that the default is to match PEP8, but is it such a crime to write ‘for x in seq’? Apparently yes because you can’t write a variable name with less than 3 letters. I will change that.
  • Very very talkative. Be ready to use your eyes.

Corrected script (with lazy doc strings and variable names) :

#!/usr/local/bin/python
# by Daniel Rosengren, modified by e-satis
"""
Module doctring
"""


import time
from sys import stdout

BAILOUT = 16
MAX_ITERATIONS = 1000

def mandelbrot(dim_1, dim_2):
    """
    function doc string
    """
    cr1 = dim_1 - 0.5
    ci1 = dim_2
    zi1 = 0.0
    zr1 = 0.0

    for i in xrange(MAX_ITERATIONS) :
        temp = zr1 * zi1
        zr2 = zr1 * zr1
        zi2 = zi1 * zi1
        zr1 = zr2 - zi2 + cr1
        zi1 = temp + temp + ci1

        if zi2 + zr2 > BAILOUT:
            return i

    return 0

def execute() :
    """
    func doc string
    """
    print 'Rendering...'
    for dim_1 in xrange(-39, 39): 
        stdout.write('\n')
        for dim_2 in xrange(-39, 39):
            if mandelbrot(dim_1/40.0, dim_2/40.0) :
                stdout.write(' ')
            else:
                stdout.write('*')


START_TIME = time.time()
execute()
print '\nPython Elapsed %.02f' % (time.time() - START_TIME)

EDIT :

Thanks to Rudiger Wolf, I discovered pep8 that does exactly what its name suggests: matching PEP8. It has found several syntax no-nos that PyLint did not. But PyLint found stuff that was not specifically linked to PEP8 but interesting. Both tools are interesting and complementary.

Eventually I will use both since there are really easy to install (via packages or setuptools) and the output text is so easy to chain.

To give you a little idea of their output:

pep8:

./python_mandelbrot.py:4:11: E401 multiple imports on one line
./python_mandelbrot.py:10:1: E302 expected 2 blank lines, found 1
./python_mandelbrot.py:10:23: E203 whitespace before ':'
./python_mandelbrot.py:15:80: E501 line too long (108 characters)
./python_mandelbrot.py:23:1: W291 trailing whitespace
./python_mandelbrot.py:41:5: E301 expected 1 blank line, found 3

PyLint:

************* Module python_mandelbrot
C: 15: Line too long (108/80)
C: 61: Line too long (85/80)
C:  1: Missing docstring
C:  5: Invalid name "stdout" (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)
C: 10:Iterator: Missing docstring
C: 15:Iterator.__init__: Invalid name "y" (should match [a-z_][a-z0-9_]{2,30}$)
C: 17:Iterator.__init__: Invalid name "x" (should match [a-z_][a-z0-9_]{2,30}$)

[...] and a very long report with useful stats like :

Duplication
-----------

+-------------------------+------+---------+-----------+
|                         |now   |previous |difference |
+=========================+======+=========+===========+
|nb duplicated lines      |0     |0        |=          |
+-------------------------+------+---------+-----------+
|percent duplicated lines |0.000 |0.000    |=          |
+-------------------------+------+---------+-----------+

回答 1

pep8最近被添加到PyPi。

  • pep8-Python样式指南检查器
  • pep8是用于根据PEP 8中的某些样式约定检查Python代码的工具。

现在,根据pep8检查代码非常容易。

参见http://pypi.python.org/pypi/pep8

pep8 was recently added to PyPi.

  • pep8 – Python style guide checker
  • pep8 is a tool to check your Python code against some of the style conventions in PEP 8.

It is now super easy to check your code against pep8.

See http://pypi.python.org/pypi/pep8