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
|
Fixers
======
Fixers come in two types: Default_ and Opt-in_. Default fixers should not break
code except for corner cases, and are idempotent (applying them more than once
to given source code will make no changes after the first application). Opt-in
fixers are allowed to break these rules.
Python 2 code from Python 2.6 and older will be upgraded to code that is
compatible with Python 2.6, 2.7, and Python 3.
If code is using a feature unique to Python 2.7, it will not be downgraded to
work with Python 2.6. For example, ``dict.viewitems()`` usage will not be
removed to make the code compatible with Python 2.6.
Some fixers rely on the latest release of the `six project`_ to work
(see `Fixers requiring six`_).
If you wish to turn off these fixers to avoid an external dependency on ``six``,
then use the ``--no-six`` flag.
Fixers use the API defined by fissix. For details of how this works, and how to
implement your own fixers, see `Creating a fixer, at python3porting.com
<https://web.archive.org/web/20200903114908/python3porting.com/fixers.html#creating-a-fixer>`_.
``python -m modernize`` will try to load fixers whose full dotted-path is specified
as a ``-f`` argument, but will fail if they are not found. By default, fixers
will not be found in the current directory; use ``--fixers-here`` to make
``python -m modernize`` look for them there, or see the `Python tutorial on
modules <https://docs.python.org/3/tutorial/modules.html>`_ (in particular,
the parts on the `search path
<https://docs.python.org/3/tutorial/modules.html#the-module-search-path>`_
and `packages <https://docs.python.org/3/tutorial/modules.html#packages>`_)
for more info on how Python finds modules.
Default
-------
A default fixer will be enabled when:
- Either no ``-f``/``--fix`` options are used, or ``-f default``/``--fix=default``
is used, or the fixer is listed explicitly in an ``-f``/``--fix`` option; and
- The fixer is not listed in an ``-x``/``--nofix`` option; and
- For fixers that are dependent on the `six project`_, ``--no-six`` is *not* specified
(see `Fixers requiring six`_).
The ``-x``/``--nofix`` and ``--no-six`` options always override fixers specified
using ``-f``/``--fix``. The ``--six-unicode`` and ``--future-unicode`` options
also disable fixers that are not applicable for those options.
Fixers requiring six
++++++++++++++++++++
The `six project`_ provides the ``six`` module which contains various tidbits in
helping to support Python 2/3 code. All ``six``-related fixers assume the latest
version of ``six`` is installed.
.. attribute:: basestring
Replaces all references to :func:`basestring` with :data:`six.string_types`.
.. versionadded:: 0.4
.. attribute:: dict_six
Fixes various methods on the ``dict`` type for getting all keys, values, or
items. E.g.::
x.values()
x.itervalues()
x.viewvalues()
becomes::
list(x.values())
six.itervalues(x)
six.viewvalues(x)
Care is taken to only call ``list()`` when not in an iterating context
(e.g. not the iterable for a ``for`` loop).
.. attribute:: filter
When a call to :func:`filter <python2:filter>` is discovered, ``from six.moves import filter`` is
added to the module. Wrapping the use in a call to ``list()`` is done when
necessary.
.. attribute:: imports_six
Uses :mod:`six.moves` to fix various renamed modules, e.g.::
import ConfigParser
ConfigParser.ConfigParser()
becomes::
import six.moves.configparser
six.moves.configparser.ConfigParser()
The modules in Python 2 whose renaming in Python 3 is supported are:
- ``__builtin__``
- ``_winreg``
- ``BaseHTTPServer``
- ``CGIHTTPServer``
- ``ConfigParser``
- ``copy_reg``
- ``Cookie``
- ``cookielib``
- ``cPickle``
- ``Dialog``
- ``dummy_thread``
- ``FileDialog``
- ``gdbm``
- ``htmlentitydefs``
- ``HTMLParser``
- ``httplib``
- ``Queue``
- ``repr``
- ``robotparser``
- ``ScrolledText``
- ``SimpleDialog``
- ``SimpleHTTPServer``
- ``SimpleXMLRPCServer``
- ``SocketServer``
- ``thread``
- ``Tix``
- ``tkColorChooser``
- ``tkCommonDialog``
- ``Tkconstants``
- ``Tkdnd``
- ``tkFileDialog``
- ``tkFont``
- ``Tkinter``
- ``tkMessageBox``
- ``tkSimpleDialog``
- ``ttk``
- ``xmlrpclib``
.. versionadded:: 0.4
.. attribute:: input_six
Changes::
input(x)
raw_input(x)
to::
from six.moves import input
eval(input(x))
input(x)
.. versionadded:: 0.4
.. attribute:: int_long_tuple
Changes ``(int, long)`` or ``(long, int)`` to :data:`six.integer_types`.
.. versionadded:: 0.4
.. attribute:: map
If a call to :func:`map <python2:map>` is discovered, ``from six.moves import map`` is added to
the module. Wrapping the use in a call to ``list()`` is done when necessary.
.. attribute:: metaclass
Changes::
class Foo:
__metaclass__ = Meta
to::
import six
class Foo(six.with_metaclass(Meta)):
pass
.. seealso::
:func:`six.with_metaclass`
.. attribute:: raise_six
Changes ``raise E, V, T`` to ``six.reraise(E, V, T)``.
.. attribute:: unicode_type
Changes all reference of :func:`unicode <python2:unicode>` to
:data:`six.text_type`.
.. attribute:: urllib_six
Changes::
from urllib import quote_plus
quote_plus('hello world')
to::
from six.moves.urllib.parse import quote_plus
quote_plus('hello world')
.. attribute:: unichr
Changes all reference of :func:`unichr <python2:unichr>` to
:data:`six.unichr`.
.. attribute:: xrange_six
Changes::
w = xrange(x)
y = range(z)
to::
from six.moves import range
w = range(x)
y = list(range(z))
Care is taken not to call ``list()`` when ``range()`` is used in an iterating
context.
.. attribute:: zip
If :func:`zip <python2:zip>` is called, ``from six.moves import zip`` is added to the module.
Wrapping the use in a call to ``list()`` is done when necessary.
``fissix`` fixers
+++++++++++++++++
Some :doc:`fixers from fissix <fissix:fixers>`
in Python's standard library are run by default unmodified as their
transformations are Python 2 compatible.
- :attr:`apply <fissix:apply>`
- :attr:`except <fissix:except>`
- :attr:`exec <fissix:exec>`
- :attr:`execfile <fissix:execfile>`
- :attr:`exitfunc <fissix:exitfunc>`
- :attr:`funcattrs <fissix:funcattrs>`
- :attr:`has_key <fissix:has_key>`
- :attr:`idioms <fissix:idioms>`
- :attr:`long <fissix:long>`
- :attr:`methodattrs <fissix:methodattrs>`
- :attr:`ne <fissix:ne>`
- :attr:`numliterals <fissix:numliterals>`
- :attr:`operator <fissix:operator>`
- :attr:`paren <fissix:paren>`
- :attr:`reduce <fissix:reduce>`
- :attr:`repr <fissix:repr>`
- :attr:`set_literal <fissix:set_literal>`
- :attr:`standarderror <fissix:standarderror>`
- :attr:`sys_exc <fissix:sys_exc>`
- :attr:`throw <fissix:throw>`
- :attr:`tuple_params <fissix:tuple_params>`
- :attr:`types <fissix:types>`
- :attr:`ws_comma <fissix:ws_comma>`
- :attr:`xreadlines <fissix:xreadlines>`
Fixers with no dependencies
+++++++++++++++++++++++++++
.. attribute:: file
Changes all calls to :func:`file <python2:file>` to :func:`open <python2:open>`.
.. versionadded:: 0.4
.. attribute:: import
Changes implicit relative imports to explicit relative imports and adds
``from __future__ import absolute_import``.
.. versionadded:: 0.4
.. attribute:: next
Changes all method calls from ``x.next()`` to ``next(x)``.
.. attribute:: print
Changes all usage of the ``print`` statement to use the :func:`print` function
and adds ``from __future__ import print_function``.
.. attribute:: raise
Changes comma-based ``raise`` statements from::
raise E, V
raise (((E, E1), E2), E3), V
to::
raise E(V)
raise E(V)
Opt-in
------
To specify an opt-in fixer while also running all the default fixers, make sure
to specify the ``-f default`` or ``--fix=default`` option, e.g.::
python -m modernize -f default -f modernize.fixes.fix_open
.. attribute:: classic_division
When a use of the division operator -- ``/`` -- is found, add
``from __future__ import division`` and change the operator to ``//``.
If ``from __future__ import division`` is already present, this fixer is
skipped.
This is intended for use in programs where ``/`` is conventionally only used
for integer division, or where it is intended to do a manual pass after running
``python -m modernize`` to look for cases that should not have been changed to ``//``.
The results of division on non-integers may differ after running this fixer:
for example, ``3.5 / 2 == 1.75``, but ``3.5 // 2 == 1.0``.
Some objects may override the ``__div__`` method for a use other than division,
and thus would break when changed to use a ``__floordiv__`` method instead.
This fixer is opt-in because it may change the meaning of code as described
above.
.. versionadded:: 1.0
.. attribute:: open
When a call to :func:`open <python2:open>` is discovered, add ``from io import open`` at the top
of the module so as to use :func:`io.open` instead. This fixer is opt-in because it
changes what object is returned by a call to ``open()``.
.. versionadded:: 0.4
.. _six project: https://six.readthedocs.io/
|