emacs flycheck-mode python3 print statement with file=sys.stderr - python

I am using emacs on Ubuntu 16.04 and added the configuration for flycheck-mode to include the python3 setup below:
Emacs: How do I set flycheck to Python 3?
Answer: https://stackoverflow.com/a/55000284/719016
(custom-set-variables
'(flycheck-python-flake8-executable "python3")
'(flycheck-python-pycompile-executable "python3")
'(flycheck-python-pylint-executable "python3"))
But my python3 buffer still gives me an invalid syntax [E0001] error in a line like below:
print("# My message for the stderr", file=stderr)
The syntax checkers loaded are python-pylint and python-pycompile (for some reason python-flake8 does not seem to be found.
Any ideas why?

Well, if you took the answer that you quoted literally, your configuration isn't getting loaded. The answer suggests putting the config in ~/.emacs.c/custom.el. That's a typo. The correct path is ~/.emacs.d/custom.el. The more correct answer is to put the config in the file pointed to by custom-file. The most correct answer is to never edit the custom file by hand. Instead use the customize facility.
Run M-x customize-group flycheck.
Scroll to the bottom of the buffer and click on "Flycheck executables".
Find the python executables you want to change. (Always use python3 for Python3 stuff, even if you only have Python3 on your system. It'll save you headaches later.)
Scroll to the top of the buffer.
Click "Apply and Save".
Boom. Your settings are saved in the correct "custom.el" file.
Now, load up a Python3 file you want to use flycheck with. If it's not doing what you expect, check things with C-c ! v (aka flycheck-verify-setup.) Confirm individual checkers with C-c ! ? (aka flycheck-describe-checker.) Check the variables you think you're setting with C-h v. Cut-n-paste them from flycheck's website if you have to.
Don't worry about flake8's config file. It will properly cascade as you expect.
And, lastly, as #jenesaisquois suggests:
#!/usr/bin/env python3
import sys
print("# My message for the stderr", file=sys.stderr)

Related

Unexpected keyword arg in decorator : Python [duplicate]

I'm trying to disable warning C0321 ("more than one statement on a single line" -- I often put if statements with short single-line results on the same line), in Pylint 0.21.1 (if it matters: astng 0.20.1, common 0.50.3, and Python 2.6.6 (r266:84292, Sep 15 2010, 16:22:56)).
I've tried adding disable=C0321 in the Pylint configuration file, but Pylint insists on reporting it anyway. Variations on that line (like disable=0321 or disable=C321) are flagged as errors, so Pylint does recognize the option properly. It's just ignoring it.
Is this a Pylint bug, or am I doing something wrong? Is there a way around this?
I'd really like to get rid of some of this noise.
pylint --generate-rcfile shows it like this:
[MESSAGES CONTROL]
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
# multiple time.
#enable=
# Disable the message, report, category or checker with the given id(s). You
# can either give multiple identifier separated by comma (,) or put this option
# multiple time (only on the command line, not in the configuration file where
# it should appear only once).
#disable=
So it looks like your ~/.pylintrc should have the disable= line/s in it inside a section [MESSAGES CONTROL].
Starting from Pylint v. 0.25.3, you can use the symbolic names for disabling warnings instead of having to remember all those code numbers. E.g.:
# pylint: disable=locally-disabled, multiple-statements, fixme, line-too-long
This style is more instructive than cryptic error codes, and also more practical since newer versions of Pylint only output the symbolic name, not the error code.
The correspondence between symbolic names and codes can be found here.
A disable comment can be inserted on its own line, applying the disable to everything that comes after in the same block. Alternatively, it can be inserted at the end of the line for which it is meant to apply.
If Pylint outputs "Locally disabling" messages, you can get rid of them by including the disable locally-disabled first as in the example above.
I had this problem using Eclipse and solved it as follows:
In the pylint folder (e.g. C:\Python26\Lib\site-packages\pylint), hold Shift, right-click and choose to open the windows command in that folder. Type:
lint.py --generate-rcfile > standard.rc
This creates the standard.rc configuration file. Open it in Notepad and under [MESSAGES CONTROL], uncomment
disable= and add the message ID's you want to disable, e.g.:
disable=W0511, C0321
Save the file, and in Eclipse → Window → Preferences → PyDev → *pylint, in the arguments box, type:
--rcfile=C:\Python26\Lib\site-packages\pylint\standard.rc
Now it should work...
You can also add a comment at the top of your code that will be interpreted by Pylint:
# pylint: disable=C0321
Pylint message codes.
Adding e.g. --disable-ids=C0321 in the arguments box does not work.
All available Pylint messages are stored in the dictionary _messages, an attribute of an instance of the pylint.utils.MessagesHandlerMixIn class. When running Pylint with the argument --disable-ids=... (at least without a configuration file), this dictionary is initially empty, raising a KeyError exception within Pylint (pylint.utils.MessagesHandlerMixIn.check_message_id().
In Eclipse, you can see this error-message in the Pylint Console (windows* → show view → Console, select Pylint console from the console options besides the console icon.)
To disable a warning locally in a block, add
# pylint: disable=C0321
to that block.
There are several ways to disable warnings & errors from Pylint. Which one to use has to do with how globally or locally you want to apply the disablement -- an important design decision.
Multiple Approaches
In one or more pylintrc files.
This involves more than the ~/.pylintrc file (in your $HOME directory) as described by Chris Morgan. Pylint will search for rc files, with a precedence that values "closer" files more highly:
A pylintrc file in the current working directory; or
If the current working directory is in a Python module (i.e. it contains an __init__.py file), searching up the hierarchy of Python modules until a pylintrc file is found; or
The file named by the environment variable PYLINTRC; or
If you have a home directory that isn’t /root:
~/.pylintrc; or
~/.config/pylintrc; or
/etc/pylintrc
Note that most of these files are named pylintrc -- only the file in ~ has a leading dot.
To your pylintrc file, add lines to disable specific pylint messages. For example:
[MESSAGES CONTROL]
disable=locally-disabled
Further disables from the pylint command line, as described by Aboo and Cairnarvon. This looks like pylint --disable=bad-builtin. Repeat --disable to suppress additional items.
Further disables from individual Python code lines, as described by Imolit. These look like some statement # pylint: disable=broad-except (extra comment on the end of the original source line) and apply only to the current line. My approach is to always put these on the end of other lines of code so they won't be confused with the block style, see below.
Further disables defined for larger blocks of Python code, up to complete source files.
These look like # pragma pylint: disable=bad-whitespace (note the pragma key word).
These apply to every line after the pragma. Putting a block of these at the top of a file makes the suppressions apply to the whole file. Putting the same block lower in the file makes them apply only to lines following the block. My approach is to always put these on a line of their own so they won't be confused with the single-line style, see above.
When a suppression should only apply within a span of code, use # pragma pylint: enable=bad-whitespace (now using enable not disable) to stop suppressing.
Note that disabling for a single line uses the # pylint syntax while disabling for this line onward uses the # pragma pylint syntax. These are easy to confuse especially when copying & pasting.
Putting It All Together
I usually use a mix of these approaches.
I use ~/.pylintrc for absolutely global standards -- very few of these.
I use project-level pylintrc at different levels within Python modules when there are project-specific standards. Especially when you're taking in code from another person or team, you may find they use conventions that you don't prefer, but you don't want to rework the code. Keeping the settings at this level helps not spread those practices to other projects.
I use the block style pragmas at the top of single source files. I like to turn the pragmas off (stop suppressing messages) in the heat of development even for Pylint standards I don't agree with (like "too few public methods" -- I always get that warning on custom Exception classes) -- but it's helpful to see more / maybe all Pylint messages while you're developing. That way you can find the cases you want to address with single-line pragmas (see below), or just add comments for the next developer to explain why that warning is OK in this case.
I leave some of the block-style pragmas enabled even when the code is ready to check in. I try to use few of those, but when it makes sense for the module, it's OK to do as documentation. However I try to leave as few on as possible, preferably none.
I use the single-line-comment style to address especially potent errors. For example, if there's a place where it actually makes sense to do except Exception as exc, I put the # pylint: disable=broad-except on that line instead of a more global approach because this is a strange exception and needs to be called out, basically as a form of documentation.
Like everything else in Python, you can act at different levels of indirection. My advice is to think about what belongs at what level so you don't end up with a too-lenient approach to Pylint.
This is a FAQ:
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.
4.2 Is there a way to disable a message for a particular module only?
Yes, you can disable or enable (globally disabled) messages at the
module level by adding the corresponding option in a comment at the
top of the file:
# pylint: disable=wildcard-import, method-hidden
# pylint: enable=too-many-lines
You can disable messages by:
numerical ID: E1101, E1102, etc.
symbolic message: no-member, undefined-variable, etc.
the name of a group of checks. You can grab those with pylint --list-groups.
category of checks: C, R, W, etc.
all the checks with all.
See the documentation (or run pylint --list-msgs in the terminal) for the full list of Pylint's messages. The documentation also provide a nice example of how to use this feature.
You can also use the following command:
pylint --disable=C0321 test.py
My Pylint version is 0.25.1.
You just have to add one line to disable what you want to disable.
E.g.,
#pylint: disable = line-too-long, too-many-lines, no-name-in-module, import-error, multiple-imports, pointless-string-statement, wrong-import-order
Add this at the very beginning of your module.
In case this helps someone, if you're using Visual Studio Code, it expects the file to be in UTF-8 encoding. To generate the file, I ran pylint --generate-rcfile | out-file -encoding utf8 .pylintrc in PowerShell.
As per Pylint documentation, the easiest is to use this chart:
C convention-related checks
R refactoring-related checks
W various warnings
E errors, for probable bugs in the code
F fatal, if an error occurred which prevented Pylint from doing further processing.
So one can use:
pylint -j 0 --disable=I,E,R,W,C,F YOUR_FILES_LOC
Sorry for diverging a bit from the initial question, about poster's general preference, which would be better addressed by a global configuration file.
But, as in many popular answers, I tend to prefer seeing in my code what could trigger warnings, and eventually inform contributors as well.
My comment to answer from #imolit needs to stay short, here are some details.
For multiple-statements message, it's probably better to disable it at block or module level, like this
# pylint: disable=multiple-statements
My use-case being now attribute-defined-outside-init in a unittest setup(), I opted for a line-scoped message disabling, using the message code to avoid the line-too-long issue.
class ParserTest(unittest.TestCase):
def setUp(self):
self.parser = create_parser() # pylint: disable=W0201
The correspondance can be found locally with a command like
$ pylint --list-msgs | grep 'outside-init'
:attribute-defined-outside-init (W0201): *Attribute %r defined outside __init__*
Of course, you would similarly retrieve the symbolic name from the code.
Python syntax does permit more than one statement on a line, separated by semicolon (;). However, limiting each line to one statement makes it easier for a human to follow a program's logic when reading through it.
So, another way of solving this issue, is to understand why the lint message is there and not put more than one statement on a line.
Yes, you may find it easier to write multiple statements per line, however, Pylint is for every other reader of your code not just you.
My pylint kept ignoring the disable list in my .pylintrc. Finally, I realized that I was executing:
pylint --disable=all --enable=F,E,W
which was overriding the disable list in my .pylintrc.
The correct command to show only Fatal, Errors, Warnings, is:
pylint --disable=C,R
Edit "C:\Users\Your User\AppData\Roaming\Code\User\settings.json"
and add 'python.linting.pylintArgs' with its lines at the end as shown below:
{
"team.showWelcomeMessage": false,
"python.dataScience.sendSelectionToInteractiveWindow": true,
"git.enableSmartCommit": true,
"powershell.codeFormatting.useCorrectCasing": true,
"files.autoSave": "onWindowChange",
"python.linting.pylintArgs": [
"--load-plugins=pylint_django",
"--errors-only"
],
}

XCode Formatting issue for python files

I have used xcode to create several python scripts. It appears in the editor fine, however, when I attempt to look at the code through the terminal, I'm seeing that new lines are being encoded as "^M". This is problematic, since I am collaborating through github, and the diff features do not work when this is being done.
E.g.:
Source:
#############
#
# test.py
#
# by Author
#
#############
if __name__ == "__main__":
print "This is a test"
When I save this through another editor (PyCharmer) and more it via the console, I get the output as expected. When I create a new file via xcode, past the same text, and save, I get the following:
#############^M#^M# test.py^M#^M# by Author^M#^M#############^Mif __name__ == "__main__":^M print "This is a test"
Out of curiosity, I tried creating a test .cc file, and the same formatting issue did not arise, so if you want bonus points, explaining the inconsistency would be interesting as well.
In the latest Xcode 6, if I create a new external-build-system project, set the build tool to /usr/bin/python or /usr/local/bin/python3, create a new file named test.py in that project, Xcode recognizes its type (which you can see in the File Inspector panel of the assistant editor) as "Default — Python script", and its text settings (which you can also see in the File Inspector) as:
Text Encoding: Unicode (UTF-8)
Line Endings: Default — OS X / Unix (LF)
Indent Using: Spaces
Widths: Tab: 4 Indent: 4
Wrap lines: checked
And I get Python syntax coloring, tab completions, etc.
If that's not right—in particular, if you see Line Endings as "Classic Mac OS (CR)"—you can change it for the current file right there in the panel.
That fixes the current file. It may not fix the next file you create, but try it and see.
If not: In Xcode 4 and 5, you could easily change the default settings for each language, but that no longer seems to be exposed in Xcode 6. However, you may want to try going to the "Text Editing" pane of the "Preferences" dialog, and making sure "Default line endings" is set to "OS X / Unix (LF)", and maybe that "Convert existing files on save" is checked. This will help if you've got your default settings to Classic Mac, but C/ObjC/C++ overriding that with Unix. If, on the other hand, you somehow have a leftover override for Python from an earlier version of Xcode, I'm not sure how you can undo it short of wiping all of your Xcode settings and starting clean.
From a quick search, this answer has a very detailed version of some of the steps involved in configuring Python projects to handle things like the Run and Debug commands and so on, which may also be tangentially helpful.

pylint ignores .pylintrc when run from TextMate

I'm trying to get pylint to give html output when I run Validate syntax on a python file in TextMate. I installed pycheckmate, pylint, and created a .pylintrc file in $HOME that sets the output format to html.
In TextMate's Advanced control panel, in the Shell Variables tab, I have TM_PYCHECKER set to /usr/local/share/python/pylint. If I trigger Validate Syntax, it runs pylint with all the default options, and gives me the output. If I change TM_PYCHECKER to /usr/local/share/python/pylint --rcfile "$HOME/.pylintrc" and Validate Syntax again, I get:
Please install PyChecker, PyFlakes or Pylint for more extensive code
checking.
If I run /usr/local/share/python/pylint from the commandline, without any arguments, the output is html, so I know in that case that it's reading the rcfile. What am I missing?
OK, I think I found the problem: pycheckmate sets --output-format=parseable' as a forced argument to pylint. I found this out by replacing /usr/local/share/python/pylint with a wrapper script that printed out its arguments:
#!/usr/bin/env python
import sys
from pylint import lint
print sys.argv[1:]
lint.Run(sys.argv[1:])
And when I ran it in TextMate I saw this:
['--output-format=parseable', '/Users/smithm5/test.py']
test.py:26 [C] Line too long (90/80)
…
So I dug into /Applications/TextMate.app/Contents/SharedSupport/Bundles/Python.tmbundle/Support/bin/pycheckmate.py itself. Sure enough, it adds that argument, as well as a whole lot of hard-coded html. So to fix it, I removed all the escape() wrappers, set opts = () on line 287 so I could set my own darn opts, and changed line 332 to print line.
A somewhat educated guess: try replacing $HOME by the absolute path to your home directory. Shell variables like $HOME are probably not available to use in TextMate's control panel.
UPDATE: Looking at the pycheckmate.py script included with the Python.tmbundle included with the version of TextMate I have, it appears that it is not possible to include arguments , like --rcfile /path/to/rcfile. The value of TM_PYCHECKER is expected to only be the path to the checker binary with no arguments. But, if you make your own copy of the Python.tmbundle, you should be able to edit pycheckmate.py to do as you wish.

emacs and python updating modules

atm i'm using emacs to write some python code, so far it works quite fine except one problem that is really a bit annoying.
Always when I update something inside a self written module i reevaluate the buffer and the module in the python shell inside emacs doesn't get updated. i always have to end the python process and start it again to get the change. I figured out that emacs copies some things to a tmp dir to execute them, so i guess it has something to do with this.
Maybe someone out there had the same problem and solved it already so help would be appreciated
You have to reload the module manually in the shell in order for it to take effect.
See the documentation here on the Python reload function
I asked a similar question which you can see here
I found a better solution that needs no emacs config:
simply do
$ ipython profile create
that should create ipython profile in
$HOME/.ipython/profile_default/ipython_config.py
then put the following inside
c = get_config()
c.TerminalInteractiveShell.editor = 'emacsclient'
c.InteractiveShellApp.extensions = [
'autoreload'
]
c.InteractiveShellApp.exec_lines = []
c.InteractiveShellApp.exec_lines.append('%load_ext autoreload')
c.InteractiveShellApp.exec_lines.append('%autoreload 2')
then restart emacs. Now each time you save changes to file inside emacs - ipython would reload it automatically
and the following I have in my emacs config
;; ------------------
;; misc python config
;; ------------------
(company-mode -1)
(elpy-enable)
(elpy-use-ipython "ipython")
(setq python-shell-interpreter "ipython" python-shell-interpreter-args "--simple-prompt --pprint")
(setq python-check-command "flake8")
(setq elpy-rpc-backend "jedi")
(setq elpy-rpc-python-command "python")
; https://github.com/gregsexton/ob-ipython/issues/28
(setq python-shell-completion-native-enable nil)
if you want to see my full python config, it's here
You can advise a python-mode.el function to get the desired effect (at least, if I am understanding your request properly). Put the following in your Emacs init file:
(defun py-reload-file (buf)
"Reload buffer's file in Python interpreter."
(let ((file (buffer-file-name buf)))
(if file
(progn
;; Maybe save some buffers
(save-some-buffers (not py-ask-about-save) nil)
(let ((reload-cmd
(if (string-match "\\.py$" file)
(let ((f (file-name-sans-extension
(file-name-nondirectory file))))
(format "if globals().has_key('%s'):\n reload(%s)\nelse:\n import %s\n"
f f f))
(format "execfile(r'%s')\n" file))))
(save-excursion
(set-buffer (get-buffer-create
(generate-new-buffer-name " *Python Command*")))
(insert reload-cmd)
(py-execute-base (point-min) (point-max))))))))
(defadvice py-execute-region
(around reload-in-shell activate)
"After execution, reload in Python interpreter."
(save-window-excursion
(let ((buf (current-buffer)))
ad-do-it
(py-reload-file buf))))
Now, when you're in a python program, you can select a region of code, press C-| to evaluate the region and the python program will be reloaded (or imported if it wasn't previously loaded) in the Python interpreter buffer. The ENTIRE module will be reloaded, not just the region that was selected and you will be prompted to save the python file if it hasn't already been saved. Note that the caveats that were mentioned in the replies to your previous question still apply (e.g. - If you have class instances already created from the imported module, have instantiated other objects, etc, they won't be reloaded). General breakage may occur, so caveat emptor!).
I'd recommend using Elpy as discussed here.
Add the following to your Emacs configuration file:
(defun my-restart-python-console ()
"Restart python console before evaluate buffer or region to avoid various uncanny conflicts, like not reloding modules even when they are changed"
(interactive)
(if (get-buffer "*Python*")
(let ((kill-buffer-query-functions nil)) (kill-buffer "*Python*")))
(elpy-shell-send-region-or-buffer))
(global-set-key (kbd "C-c C-x C-c") 'my-restart-python-console)
restart your Emacs run your code using C-c C-x C-c
In short, this code has the "if clause" for checking if Python buffer is open. This will help to be able to run C-c C-x C-c at any time of development even when there is no Python process already open. Another part is kill-buffer-query-functions which neglects the prompt for killing the Python buffer.

How do I disable a Pylint warning?

I'm trying to disable warning C0321 ("more than one statement on a single line" -- I often put if statements with short single-line results on the same line), in Pylint 0.21.1 (if it matters: astng 0.20.1, common 0.50.3, and Python 2.6.6 (r266:84292, Sep 15 2010, 16:22:56)).
I've tried adding disable=C0321 in the Pylint configuration file, but Pylint insists on reporting it anyway. Variations on that line (like disable=0321 or disable=C321) are flagged as errors, so Pylint does recognize the option properly. It's just ignoring it.
Is this a Pylint bug, or am I doing something wrong? Is there a way around this?
I'd really like to get rid of some of this noise.
pylint --generate-rcfile shows it like this:
[MESSAGES CONTROL]
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
# multiple time.
#enable=
# Disable the message, report, category or checker with the given id(s). You
# can either give multiple identifier separated by comma (,) or put this option
# multiple time (only on the command line, not in the configuration file where
# it should appear only once).
#disable=
So it looks like your ~/.pylintrc should have the disable= line/s in it inside a section [MESSAGES CONTROL].
Starting from Pylint v. 0.25.3, you can use the symbolic names for disabling warnings instead of having to remember all those code numbers. E.g.:
# pylint: disable=locally-disabled, multiple-statements, fixme, line-too-long
This style is more instructive than cryptic error codes, and also more practical since newer versions of Pylint only output the symbolic name, not the error code.
The correspondence between symbolic names and codes can be found here.
A disable comment can be inserted on its own line, applying the disable to everything that comes after in the same block. Alternatively, it can be inserted at the end of the line for which it is meant to apply.
If Pylint outputs "Locally disabling" messages, you can get rid of them by including the disable locally-disabled first as in the example above.
I had this problem using Eclipse and solved it as follows:
In the pylint folder (e.g. C:\Python26\Lib\site-packages\pylint), hold Shift, right-click and choose to open the windows command in that folder. Type:
lint.py --generate-rcfile > standard.rc
This creates the standard.rc configuration file. Open it in Notepad and under [MESSAGES CONTROL], uncomment
disable= and add the message ID's you want to disable, e.g.:
disable=W0511, C0321
Save the file, and in Eclipse → Window → Preferences → PyDev → *pylint, in the arguments box, type:
--rcfile=C:\Python26\Lib\site-packages\pylint\standard.rc
Now it should work...
You can also add a comment at the top of your code that will be interpreted by Pylint:
# pylint: disable=C0321
Pylint message codes.
Adding e.g. --disable-ids=C0321 in the arguments box does not work.
All available Pylint messages are stored in the dictionary _messages, an attribute of an instance of the pylint.utils.MessagesHandlerMixIn class. When running Pylint with the argument --disable-ids=... (at least without a configuration file), this dictionary is initially empty, raising a KeyError exception within Pylint (pylint.utils.MessagesHandlerMixIn.check_message_id().
In Eclipse, you can see this error-message in the Pylint Console (windows* → show view → Console, select Pylint console from the console options besides the console icon.)
To disable a warning locally in a block, add
# pylint: disable=C0321
to that block.
There are several ways to disable warnings & errors from Pylint. Which one to use has to do with how globally or locally you want to apply the disablement -- an important design decision.
Multiple Approaches
In one or more pylintrc files.
This involves more than the ~/.pylintrc file (in your $HOME directory) as described by Chris Morgan. Pylint will search for rc files, with a precedence that values "closer" files more highly:
A pylintrc file in the current working directory; or
If the current working directory is in a Python module (i.e. it contains an __init__.py file), searching up the hierarchy of Python modules until a pylintrc file is found; or
The file named by the environment variable PYLINTRC; or
If you have a home directory that isn’t /root:
~/.pylintrc; or
~/.config/pylintrc; or
/etc/pylintrc
Note that most of these files are named pylintrc -- only the file in ~ has a leading dot.
To your pylintrc file, add lines to disable specific pylint messages. For example:
[MESSAGES CONTROL]
disable=locally-disabled
Further disables from the pylint command line, as described by Aboo and Cairnarvon. This looks like pylint --disable=bad-builtin. Repeat --disable to suppress additional items.
Further disables from individual Python code lines, as described by Imolit. These look like some statement # pylint: disable=broad-except (extra comment on the end of the original source line) and apply only to the current line. My approach is to always put these on the end of other lines of code so they won't be confused with the block style, see below.
Further disables defined for larger blocks of Python code, up to complete source files.
These look like # pragma pylint: disable=bad-whitespace (note the pragma key word).
These apply to every line after the pragma. Putting a block of these at the top of a file makes the suppressions apply to the whole file. Putting the same block lower in the file makes them apply only to lines following the block. My approach is to always put these on a line of their own so they won't be confused with the single-line style, see above.
When a suppression should only apply within a span of code, use # pragma pylint: enable=bad-whitespace (now using enable not disable) to stop suppressing.
Note that disabling for a single line uses the # pylint syntax while disabling for this line onward uses the # pragma pylint syntax. These are easy to confuse especially when copying & pasting.
Putting It All Together
I usually use a mix of these approaches.
I use ~/.pylintrc for absolutely global standards -- very few of these.
I use project-level pylintrc at different levels within Python modules when there are project-specific standards. Especially when you're taking in code from another person or team, you may find they use conventions that you don't prefer, but you don't want to rework the code. Keeping the settings at this level helps not spread those practices to other projects.
I use the block style pragmas at the top of single source files. I like to turn the pragmas off (stop suppressing messages) in the heat of development even for Pylint standards I don't agree with (like "too few public methods" -- I always get that warning on custom Exception classes) -- but it's helpful to see more / maybe all Pylint messages while you're developing. That way you can find the cases you want to address with single-line pragmas (see below), or just add comments for the next developer to explain why that warning is OK in this case.
I leave some of the block-style pragmas enabled even when the code is ready to check in. I try to use few of those, but when it makes sense for the module, it's OK to do as documentation. However I try to leave as few on as possible, preferably none.
I use the single-line-comment style to address especially potent errors. For example, if there's a place where it actually makes sense to do except Exception as exc, I put the # pylint: disable=broad-except on that line instead of a more global approach because this is a strange exception and needs to be called out, basically as a form of documentation.
Like everything else in Python, you can act at different levels of indirection. My advice is to think about what belongs at what level so you don't end up with a too-lenient approach to Pylint.
This is a FAQ:
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.
4.2 Is there a way to disable a message for a particular module only?
Yes, you can disable or enable (globally disabled) messages at the
module level by adding the corresponding option in a comment at the
top of the file:
# pylint: disable=wildcard-import, method-hidden
# pylint: enable=too-many-lines
You can disable messages by:
numerical ID: E1101, E1102, etc.
symbolic message: no-member, undefined-variable, etc.
the name of a group of checks. You can grab those with pylint --list-groups.
category of checks: C, R, W, etc.
all the checks with all.
See the documentation (or run pylint --list-msgs in the terminal) for the full list of Pylint's messages. The documentation also provide a nice example of how to use this feature.
You can also use the following command:
pylint --disable=C0321 test.py
My Pylint version is 0.25.1.
You just have to add one line to disable what you want to disable.
E.g.,
#pylint: disable = line-too-long, too-many-lines, no-name-in-module, import-error, multiple-imports, pointless-string-statement, wrong-import-order
Add this at the very beginning of your module.
In case this helps someone, if you're using Visual Studio Code, it expects the file to be in UTF-8 encoding. To generate the file, I ran pylint --generate-rcfile | out-file -encoding utf8 .pylintrc in PowerShell.
As per Pylint documentation, the easiest is to use this chart:
C convention-related checks
R refactoring-related checks
W various warnings
E errors, for probable bugs in the code
F fatal, if an error occurred which prevented Pylint from doing further processing.
So one can use:
pylint -j 0 --disable=I,E,R,W,C,F YOUR_FILES_LOC
Sorry for diverging a bit from the initial question, about poster's general preference, which would be better addressed by a global configuration file.
But, as in many popular answers, I tend to prefer seeing in my code what could trigger warnings, and eventually inform contributors as well.
My comment to answer from #imolit needs to stay short, here are some details.
For multiple-statements message, it's probably better to disable it at block or module level, like this
# pylint: disable=multiple-statements
My use-case being now attribute-defined-outside-init in a unittest setup(), I opted for a line-scoped message disabling, using the message code to avoid the line-too-long issue.
class ParserTest(unittest.TestCase):
def setUp(self):
self.parser = create_parser() # pylint: disable=W0201
The correspondance can be found locally with a command like
$ pylint --list-msgs | grep 'outside-init'
:attribute-defined-outside-init (W0201): *Attribute %r defined outside __init__*
Of course, you would similarly retrieve the symbolic name from the code.
Python syntax does permit more than one statement on a line, separated by semicolon (;). However, limiting each line to one statement makes it easier for a human to follow a program's logic when reading through it.
So, another way of solving this issue, is to understand why the lint message is there and not put more than one statement on a line.
Yes, you may find it easier to write multiple statements per line, however, Pylint is for every other reader of your code not just you.
My pylint kept ignoring the disable list in my .pylintrc. Finally, I realized that I was executing:
pylint --disable=all --enable=F,E,W
which was overriding the disable list in my .pylintrc.
The correct command to show only Fatal, Errors, Warnings, is:
pylint --disable=C,R
Edit "C:\Users\Your User\AppData\Roaming\Code\User\settings.json"
and add 'python.linting.pylintArgs' with its lines at the end as shown below:
{
"team.showWelcomeMessage": false,
"python.dataScience.sendSelectionToInteractiveWindow": true,
"git.enableSmartCommit": true,
"powershell.codeFormatting.useCorrectCasing": true,
"files.autoSave": "onWindowChange",
"python.linting.pylintArgs": [
"--load-plugins=pylint_django",
"--errors-only"
],
}

Categories

Resources