mirror of
https://fuchsia.googlesource.com/third_party/github.com/pylint-dev/pylint
synced 2024-09-22 00:24:37 +00:00
fede47a625
For example when a ``disable=line-too-long`` directive is at the end of a long commented line, it no longer disables the emission of ``line-too-long`` message for lines that follow. Close #1742
375 lines
12 KiB
ReStructuredText
375 lines
12 KiB
ReStructuredText
**************************
|
|
What's New In Pylint 1.8
|
|
**************************
|
|
|
|
:Release: 1.8
|
|
:Date: 2017-12-15
|
|
|
|
|
|
Summary -- Release highlights
|
|
=============================
|
|
|
|
* None so far
|
|
|
|
New checkers
|
|
============
|
|
|
|
* A new check was added, ``shallow-copy-environ``.
|
|
|
|
This warning message is emitted when shallow copy of os.environ is created.
|
|
Shallow copy of os.environ doesn't work as people may expect. os.environ
|
|
is not a dict object but rather a proxy object, so any changes made
|
|
on copy may have unexpected effects on os.environ
|
|
|
|
Instead of copy.copy(os.environ) method os.environ.copy() should be used.
|
|
|
|
See https://bugs.python.org/issue15373 for details.
|
|
|
|
.. code-block:: python
|
|
|
|
import copy
|
|
import os
|
|
wrong_env_copy = copy.copy(os.environ) # will emit pylint warning
|
|
wrong_env_copy['ENV_VAR'] = 'new_value' # changes os.environ
|
|
assert os.environ['ENV_VAR'] == 'new_value'
|
|
|
|
good_env_copy = dict(os.environ) # the right way
|
|
good_env_copy['ENV_VAR'] = 'different_value' # doesn't change os.environ
|
|
assert os.environ['ENV_VAR'] == 'new_value'
|
|
|
|
* A new check was added, ``keyword-arg-before-vararg``.
|
|
|
|
This warning message is emitted when a function is defined with a keyword
|
|
argument appearing before variable-length positional arguments (*args).
|
|
This may lead to args list getting modified if keyword argument's value is
|
|
not provided in the function call assuming it will take default value provided
|
|
in the definition.
|
|
|
|
.. code-block:: python
|
|
|
|
def foo(a, b=3, *args):
|
|
print(a, b, args)
|
|
|
|
# Case1: a=0, b=2, args=(4,5)
|
|
foo(0,2,4,5) # 0 2 (4,5) ==> Observed values are same as expected values
|
|
|
|
# Case2: a=0, b=<default_value>, args=(4,5)
|
|
foo(0,4,5) # 0 4 (5,) ==> args list got modified as well as the observed value of b
|
|
|
|
# Case3: Syntax Error if tried as follows
|
|
foo(0,b=2,4,5) # syntax error
|
|
|
|
* A new check was added, ``simplify-boolean-expression``.
|
|
|
|
This message is emitted when ``consider-using-ternary`` check would emit
|
|
not equivalent code, due to truthy element being falsy in boolean context.
|
|
|
|
.. code-block:: python
|
|
|
|
value = condition and False or other_value
|
|
|
|
This flawed construct may be simplified to:
|
|
|
|
.. code-block:: python
|
|
|
|
value = other_value
|
|
|
|
* A new check was added, ``bad-thread-instantiation``.
|
|
|
|
This message is emitted when the threading.Thread class does not
|
|
receive the target argument, but receives just one argument, which
|
|
is by default the group parameter.
|
|
|
|
In the following example, the instantiation will fail, which is definitely
|
|
not desired:
|
|
|
|
.. code-block:: python
|
|
|
|
import threading
|
|
threading.Thread(lambda: print(1)) # Oups, this is the group parameter
|
|
|
|
* A new Python 3 checker was added to warn about accessing functions that have been
|
|
removed from the itertools module ``izip``, ``imap``, ``iflter``, ``izip_longest``, and ``ifilterfalse``.
|
|
|
|
.. code-block:: python
|
|
|
|
from itertools import izip
|
|
print(list(izip([1, 2], [3])))
|
|
|
|
Instead use ``six.moves`` to import a Python 2 and Python 3 compatible function:
|
|
|
|
.. code-block:: python
|
|
|
|
from six.moves import zip
|
|
print(list(zip([1, 2], [3])))
|
|
|
|
* A new Python 3 checker was added to warn about accessing deprecated fields from
|
|
the types module like ``ListType`` or ``IntType``
|
|
|
|
.. code-block:: python
|
|
|
|
from types import ListType
|
|
print(isinstance([], ListType))
|
|
|
|
Instead use the declarations in the builtin namespace:
|
|
|
|
.. code-block:: python
|
|
|
|
print(isinstance([], list))
|
|
|
|
* A new Python 3 checker was added to warn about declaring a ``next`` method that
|
|
would have implemented the ``Iterator`` protocol in Python 2 but is now a normal
|
|
method in Python 3.
|
|
|
|
.. code-block:: python
|
|
|
|
class Foo(object):
|
|
def next(self):
|
|
return 42
|
|
|
|
Instead implement a ``__next__`` method and use ``six.Iterator`` as a base class
|
|
or alias ``next`` to ``__next__``:
|
|
|
|
.. code-block:: python
|
|
|
|
class Foo(object):
|
|
def __next__(self):
|
|
return 42
|
|
next = __next__
|
|
|
|
* Three new Python 3 checkers were added to warn about using dictionary methods
|
|
in non-iterating contexts.
|
|
|
|
For example, the following are returning iterators in Python 3::
|
|
|
|
.. code-block:: python
|
|
|
|
d = {}
|
|
d.keys()[0]
|
|
d.items()[0]
|
|
d.values() + d.keys()
|
|
|
|
* A new Python 3 porting check was added, ``non-ascii-bytes-literals``
|
|
|
|
This message is emitted whenever we detect that a bytes string contain
|
|
non-ASCII characters, which results in a SyntaxError on Python 3.
|
|
|
|
* A new warning, ``raising-format-tuple``, will catch situations where the
|
|
intent was likely raising an exception with a formatted message string,
|
|
but the actual code did omit the formatting and instead passes template
|
|
string and value parameters as separate arguments to the exception
|
|
constructor. So it detects things like
|
|
|
|
.. code-block:: python
|
|
|
|
raise SomeError('message about %s', foo)
|
|
raise SomeError('message about {}', foo)
|
|
|
|
which likely were meant instead as
|
|
|
|
.. code-block:: python
|
|
|
|
raise SomeError('message about %s' % foo)
|
|
raise SomeError('message about {}'.format(foo))
|
|
|
|
This warning can be ignored on projects which deliberately use lazy
|
|
formatting of messages in all user-facing exception handlers.
|
|
|
|
* Following the recommendations of PEP479_ ,a new Python 3.0 checker was added to warn about raising a ``StopIteration`` inside
|
|
a generator. Raising a ``StopIteration`` inside a generator may be due a direct call
|
|
to ``raise StopIteration``:
|
|
|
|
.. code-block:: python
|
|
|
|
def gen_stopiter():
|
|
yield 1
|
|
yield 2
|
|
yield 3
|
|
raise StopIteration
|
|
|
|
Instead use a simple ``return`` statement
|
|
|
|
.. code-block:: python
|
|
|
|
def gen_stopiter():
|
|
yield 1
|
|
yield 2
|
|
yield 3
|
|
return
|
|
|
|
Raising a ``StopIteration`` may also be due to the call to ``next`` function with a generator
|
|
as argument:
|
|
|
|
.. code-block:: python
|
|
|
|
def gen_next_raises_stopiter():
|
|
g = gen_ok()
|
|
while True:
|
|
yield next(g)
|
|
|
|
In this case, surround the call to ``next`` with a try/except block:
|
|
|
|
.. code-block:: python
|
|
|
|
def gen_next_raises_stopiter():
|
|
g = gen_ok()
|
|
while True:
|
|
try:
|
|
yield next(g)
|
|
except StopIteration:
|
|
return
|
|
|
|
The check about raising a StopIteration inside a generator is also valid if the exception
|
|
raised inherit from StopIteration.
|
|
Close #1385
|
|
|
|
.. _PEP479: https://www.python.org/dev/peps/pep-0479
|
|
|
|
* A new Python checker was added to warn about using a ``+`` operator inside call of logging methods
|
|
when one of the operands is a literal string:
|
|
|
|
.. code-block:: python
|
|
|
|
import logging
|
|
var = "123"
|
|
logging.log(logging.INFO, "Var: " + var)
|
|
|
|
Instead use formatted string and positional arguments :
|
|
|
|
.. code-block:: python
|
|
|
|
import logging
|
|
var = "123"
|
|
logging.log(logging.INFO, "Var: %s", var)
|
|
|
|
* A new Python checker was added to warn about ``inconsistent-return-statements``. A function or a method
|
|
has inconsistent return statements if it returns both explicit and implicit values :
|
|
|
|
.. code-block:: python
|
|
|
|
def mix_implicit_explicit_returns(arg):
|
|
if arg < 10:
|
|
return True
|
|
elif arg < 20:
|
|
return
|
|
|
|
According to PEP8_, if any return statement returns an expression,
|
|
any return statements where no value is returned should explicitly state this as return None,
|
|
and an explicit return statement should be present at the end of the function (if reachable).
|
|
Thus, the previous function should be written:
|
|
|
|
.. code-block:: python
|
|
|
|
def mix_implicit_explicit_returns(arg):
|
|
if arg < 10:
|
|
return True
|
|
elif arg < 20:
|
|
return None
|
|
|
|
Close #1267
|
|
|
|
.. _PEP8: https://www.python.org/dev/peps/pep-0008
|
|
|
|
Other Changes
|
|
=============
|
|
|
|
* Fixing u'' string in superfluous-parens message.
|
|
|
|
* Configuration options of invalid name checker are significantly redesigned.
|
|
Predefined rules for common naming styles were introduced. For typical
|
|
setups, user friendly options like ``--function-naming-style=camelCase`` may
|
|
be used in place of hand-written regular expressions. Default linter config
|
|
enforce PEP8-compatible naming style. See documentation for details.
|
|
|
|
* Raise meaningful exception in case of invalid reporter class (output format)
|
|
being selected.
|
|
|
|
* The docparams extension now allows a property docstring to document both
|
|
the property and the setter. Therefore setters can also have no docstring.
|
|
|
|
* The docparams extension now understands property type syntax.
|
|
|
|
.. code-block:: python
|
|
|
|
class Foo(object):
|
|
@property
|
|
def foo(self):
|
|
"""My Sphinx style docstring description.
|
|
|
|
:type: int
|
|
"""
|
|
return 10
|
|
|
|
.. code-block:: python
|
|
|
|
class Foo(object):
|
|
@property
|
|
def foo(self):
|
|
"""int: My Numpy and Google docstring style description."""
|
|
return 10
|
|
|
|
* In case of ``--output-format=json``, the dictionary returned holds a new key-value pair.
|
|
The key is ``message-id`` and the value the message id.
|
|
|
|
* Spelling checker has a new configuration parameter ``max-spelling-suggestions``, which
|
|
affects maximum count of suggestions included in emitted message.
|
|
|
|
* The **invalid-name** check contains the name of the template that caused the failure.
|
|
|
|
For the given code, **pylint** used to emit ``invalid-name`` in the form ``Invalid constant name var``,
|
|
without offering any context why ``var`` is not such a good name.
|
|
|
|
With this change, it is now more clear what should be improved for a name to be accepted according to
|
|
its corresponding template.
|
|
|
|
* New configuration flag, ``suggestion-mode`` was introduced. When enabled, pylint would
|
|
attempt to emit user-friendly suggestions instead of spurious errors for some known
|
|
false-positive scenarios. Flag is enabled by default.
|
|
|
|
* ``superfluous-parens`` is no longer wrongly emitted for logical statements involving ``in`` operator
|
|
(see example below for what used to be false-positive).
|
|
|
|
.. code-block:: python
|
|
|
|
foo = None
|
|
if 'bar' in (foo or {}):
|
|
pass
|
|
|
|
* Redefinition of dummy function is now possible. ``function-redefined`` message won't be emitted anymore when
|
|
dummy functions are redefined.
|
|
|
|
* ``missing-param-doc`` and ``missing-type-doc`` are no longer emitted when
|
|
``Args`` and ``Keyword Args`` are mixed in Google docstring.
|
|
|
|
* Fix of false positive ``useless-super-delegation`` message when
|
|
parameters default values are different from those used in the base class.
|
|
|
|
* Fix of false positive ``useless-else-on-loop`` message when break statements
|
|
are deeply nested inside loop.
|
|
|
|
* The Python 3 porting checker no longer emits multiple `no-absolute-import` per file.
|
|
|
|
* The Python 3 porting checker respects disabled checkers found in the config file.
|
|
|
|
* Modules, classes, or methods consist of compound statements that exceed the ``docstring-min-length``
|
|
are now correctly emitting `missing-docstring`
|
|
|
|
* Fix no ``wrong-import-order`` message emitted on ordering of first and third party libraries.
|
|
With this fix, pylint distinguishes first and third party modules when checking
|
|
import order.
|
|
|
|
* Fix the ignored ``pylint disable=fixme`` directives for comments following
|
|
the last statement in a file.
|
|
|
|
* Fix ``line-too-long`` message deactivated by wrong disable directive.
|
|
The directive ``disable=fixme`` doesn't deactivate anymore the emission
|
|
of ``line-too-long`` message for long commented lines.
|
|
|
|
* If the rcfile specified on the command line doesn't exist, then an
|
|
IOError exception is raised.
|
|
|
|
* Fix the wrong scope of ``disable=`` directive after a commented line.
|
|
For example when a ``disable=line-too-long`` directive is at the end of a
|
|
long commented line, it no longer disables the emission of ``line-too-long``
|
|
message for lines that follow.
|