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.)
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.
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.
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
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
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
Flake gives you some options to ignore violations.
My favorite one is to make it explicit and ignore the specific violation inline:
my invalid code # noqa: WS03
And you have the others already cited options.
Ignore all validations in the line:
my invalid code # NOQA
Ignore all validations in the file. Put in its first line:
# flake8: noqa: E121, E131, E241, F403, F405
Or configure to ignore it as a parameter in you flake8 configuration.
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)
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.
For flake8, which is recommended alternative (compare flake8 vs pyflakes here)
Add the first line like:
# flake8: noqa: E121, E131, E241, F403, F405
in general:
# flake8: noqa: <code>[, <code> ...]
This way in one line you can silent the entire file and do it for many ignore statements at once, which is often a case.
Related
Is there a way to stop mypy erroring when it doesn't find any .py files? In essence, this isn't an error. What Im looking to do is hide or silence this one error.
$ poetry run mypy .
There are no .py[i] files in directory '.'
Error: Process completed with exit code 2.
Thanks,
From mypy's source it doesn't look like there is any way to do this from mypy directly. The function that reports the error does provide an argument for ignoring this error, but the argument is only passed from within tests https://github.com/python/mypy/blob/99f4d5af147d364eda1d4b99e79770c171896f13/mypy/find_sources.py#L20-L47.
Without ignoring other errors, as far as I can tell you'd have to submit each path to mypy individually (if you're passing it multiple) and ignore the 2 error code if it reports the error you want to ignore.
Patching mypy would be an another option, but mypy is precompiled through mypyc so you'd have to get rid of the binaries and lose out on a bunch of performance with monkey-patching, or build it yourself with the function changed and install the patched module.
You can install mypy without the binaries, but it's going to be slower.
python3 -m pip install --no-binary mypy -U mypy
Once this is installed, you can create a patch, say mypy-custom.py like so:
import sys
from typing import List, Optional, Sequence
import mypy.main
from mypy.modulefinder import BuildSource
from mypy.fscache import FileSystemCache
from mypy.options import Options
orig_create_source_list = mypy.main.create_source_list
def create_source_list(paths: Sequence[str], options: Options,
fscache: Optional[FileSystemCache] = None,
allow_empty_dir: bool = True) -> List[BuildSource]:
return orig_create_source_list(paths, options, fscache, allow_empty_dir)
mypy.main.create_source_list = create_source_list
mypy.main.main(None, sys.stdout, sys.stderr)
The patched version should be called with:
python mypy-custom.py [<options>] <path>
If you pass a folder without any .py files, you should get an exit code of 0 with the following output:
Nothing to do?!
Success: no issues found in 0 source files
As suggested by #Numerlor, the patch can also be written like so:
import sys
from functools import partial
import mypy.find_sources
from mypy import api
orig_create_source_list = mypy.find_sources.create_source_list
create_source_list = partial(orig_create_source_list, allow_empty_dir=True)
mypy.find_sources.create_source_list = create_source_list
result = api.run(sys.argv[1:])
if result[0]:
print(result[0])
if result[1]:
print(result[1])
exit(result[2])
With this patch, the allow_empty_dir=False option becomes unavailable to the rest of the module, but it doesn't seem to break anything... yet!
The patching method has a major inconvenient of negating the benefit of compiled libraries.
To avoid this, you could use a bash script that checks for the presence of .py files in the directory tree before calling mypy:
#! /bin/bash
if [ -n "$(find "$1" -type f -name '*.py')" ]; then
mypy "$#"
fi
With this, you would have to pass the directory as the first argument, then the options.
If you want the folder to be the last argument, you can substitute "$1" with "${*: -1}" in the find command.
The documentation in section 4.1 clearly states:
https://pylint.readthedocs.io/en/latest/faq.html#message-control
4.1 Is it possible to locally disable a particular message?
Yes, this feature has been added in Pylint 0.11. This may be done by adding “#pylint: disable=some-message,another-one” at the desired block level or at the end of the desired line of code
Great! but it doesn't work. Boo.
I get the the following pylint error for the following line of code
W: 26, 2: Redefining built-in 'zip' (redefined-builtin)
try:
from itertools import izip as zip # pylint: disable=bad-builtin
except ImportError:
pass
But pylint just complains even louder about my attempt to shut it up:
E: 26, 0: Bad option value 'bad-builtin' (bad-option-value)
I've also tried the error code # pylint: disable=W0141, that also produces a similar error.
Any idea what I'm doing wrong?
I have been in a similar situation.
Unsolvable pylint issue
class A:
pass
There are many warnings in pylint for the code above, but I want to talk about old-style-class.
In Python 2.7, you will get an old-style-class error.
Of course, you can change your code like this:
class A(object):
pass
However, you will receive a useless-object-inheritance warning in Python 3.
If you are writing a package compatible with python 2.7 and 3 and using pylint, then you are down.
Unavoidable bad-option-value
Yes, if it is accepted to disable either of old-style-class or useless-object-inheritance in a comment, you can go further.
In Python 2.7:
# pylint: disable=old-style-class
class A:
pass
In Python 3:
# pylint: disable=useless-object-inheritance
class A(object):
pass
Eventually, you will get a bad-option-value, just the same as this question.
Disable bad-option-value
I have tried, but bad-option-value can not be disabled locally in this case.
I have to disable bad-option-value in a pylint configuration file, like .pylintrc.
[TYPECHECK]
disable=bad-option-value
Note: My pylint version is 1.9.4 in python 2.7, 2.2.2 in python 3.
Ah, simple answer, it should be # pylint: disable=bad-option-value which is presented in the error message in parenthesis:
E: 26, 0: Bad option value 'bad-builtin' (bad-option-value)
When you get this message:
W: 26, 2: Redefining built-in 'zip' (redefined-builtin)
You have to disable the exact error message you are getting (the one in parenthesis):
try:
from itertools import izip as zip # pylint: disable=redefined-builtin
except ImportError:
pass
That seems to work fine in pylint 2.5.
It can be annoying if you are testing with multiple versions of python or different venvs and the same code base and you get different errors. Be sure you fix the version to one version across all your builds/tests. It sounds like that may have happened here (not sure where you got bad-builtin from).
Is it possible to change max-line-length settings for one file out of a project (while performing all other checks defined in rc file on it)?
Ideally, it should behave like inline pylint: disable=x comments.
I've tried putting this line at the module level:
# pylint: max-line-length=240
PyLint failed to recognize it:
my_file.py:15: [E0011(unrecognized-inline-option), ] Unrecognized file option 'max-line-length
Edit: I know I can disable line-too-long check entirely, but to be honest I'd like to avoid doing so, just in case anyone would try to extend this module and add lines even longer than they are now.
You can create .pylintrc file in your python script to overwrite pylint settings and put inside
[FORMAT]
max-line-length=240
edit 240 based on your choice.
According to the doc, I think you cannot modify the pylint config in line.
but you can disable the warning for only one or few line(s) with # pylint: disable=line-too-long:
# disable for only one line
ridiculously_long_variable_name = "this is not a ridiculously long and useless python line" # pylint: disable=line-too-long
# disable for few (or more) lines
# pylint: disable=line-too-long
ridiculously_long_variable_name = "this is not a ridiculously long and useless python line"
# pylint: enable=line-too-long
pylint --max-line-length=240
works for me.
You can pass the additional as below:
C:\Python27\Scripts\pylint.exe --max-line-length=240 <PATH TO FILE>
The following Python fragment code gets analyzed by Pylint:
if type(result) is array.array:
read = result.tobytes()
... with the following error for the last line:
E:401,22: Instance of 'int' has no 'tobytes' member\
(but some types could not be inferred) (maybe-no-member)
The result variable is received from an external function. How can I change (correct) the code to make Pylint understand? Or how can I tell it that the result of the function can have other types than int? Or how can I tell it to ignore that particular line? (I favor an answer in this order of the questions)
For some reason, pylint doesn't get 'result' may be of the array type (and will be for sure under the 'if' branch). There is currently no way to tell pylint about that, though it will hopefully be possible at some point. So for now, you can only disable the warning for that specific line by adding # pylint: disable=maybe-no-member after the offending statement or right above it. For example:
if type(result) is array.array:
read = result.tobytes() # pylint: disable=maybe-no-member
or
if type(result) is array.array:
# pylint: disable=maybe-no-member
read = result.tobytes()
I disabled all no-member warnings by passing this command line option to pylint
--disable=E1101
While using PyLint you can generate a configuration pylint file using these command in your terminal
$ pylint --generate-rcfile > .pylintrc
the generated file handles the errors and warnings that you have to check.
for the no member in particular you can go to line 560, you can find that it ignored.
this configurations will be applied to all your code files.
and you can edit this configuration file, to meet your requirements.
Instead of
result.tobytes(),
use
getattr(result, 'tobytes')()
I use restructuredText, and I like what smartypants does for Markdown. Is there a way to enable the same thing for restructuredText?
Have you tried smartypants.py? I don't know how well it's implemented, much less how well it works for your specific use cases, but it does seem to target exactly your goal, unicode-ification of some ascii constructs (however, it runs on HTML, so I guess you'd run it after restructuredText or whatever other "producer of HTML" component).
If that doesn't work well for you, a user has submitted a patch to python-markdown2 which he calls "this SmartyPants patch" -- it's been accepted and since a month ago it's part of the current source tree of python-markdown2 (r259 or better). That may offer smoother sailing (e.g. if you just get and built python-markdown2 as a read-only svn tree). Or, you could wait for the next downloadable release (there hasn't been one since May and this patch was accepted in mid-July), but who knows when that'll happen.
As Alex Martelli says, smartyPants is what I need. However, I was looking for a little more detailed info on how to use it. So here's a Python script that reads the file named in the first command line argument, converts it to HTML, using Pygments for sourcecode, and then passses it through smartypants for prettifying.
#!/usr/bin/python
# EASY-INSTALL-SCRIPT: 'docutils==0.5','rst2html.py'
"""
A minimal front end to the Docutils Publisher, producing HTML.
"""
try:
from ulif.rest import directives_plain
from ulif.rest import roles_plain
from ulif.rest import pygments_directive
import locale
locale.setlocale(locale.LC_ALL, '')
except:
pass
from docutils.core import publish_doctree, publish_from_doctree
from smartypants import smartyPants
import sys
description = ('Personal docutils parser with extra features.')
doctree = publish_doctree(file(sys.argv[1]).read())
result = publish_from_doctree(doctree, writer_name='html')
result = smartyPants(result)
print result