summaryrefslogtreecommitdiff
path: root/doc/whatsnew/1.8.rst
blob: 7e84a884658b2a86d1641e4de79c1ec01d6eeae2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
**************************
  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.