.. image:: http://unmaintained.tech/badge.svg :target: http://unmaintained.tech/ :alt: No Maintenance Intended
sixer is a tool adding Python 3 support to a Python 2 project. It was written to produces patches to port OpenStack to Python 3. It is focused on supporting Python 2.7 and 3.4.
It uses basic regular expressions to find code which needs to be modified. It emits warnings when code was not patched or looks suspicious.
sixer project at Github <https://github.com/vstinner/sixer>
_ (source, bug tracker)sixer in the Python Cheeseshop (PyPI) <https://pypi.python.org/pypi/sixer>
_See also the six module documentation <https://pythonhosted.org/six/>
_.
::
sixer.py [--write] [options] <all|operation1[,operation2,...]> <directories or filenames>
sixer.py displays the name of patched files. It displays warnings for suspicious code which may have to be ported manually.
The first parameter can be a list of operations separated by commas. Use
"all"
to apply all operations. Operation prefixed by -
are excluded.
For example, "all,-iteritems"
applies all operations except iteritems
.
For directories, sixer.py searchs for .py
files in all subdirectories.
By default, sixer uses a dry run: files are not modified. Add --write
(or
-w
) option to modify files in place. It's better to use sixer in a project
managed by a source control manager (ex: git) to see differences and revert
unwanted changes. The original files are not kept.
Use --help
to see all available options.
See below for the list of available operations.
all
:
basestring
:
basestring
with six.string_types
,
add import six
dict0
:
dict.keys()[0]
with list(dict.keys())[0]
dict.values()[0]
and dict.items()[0]
0
dict_add
:
dict.keys() + list2
with list(dict.keys()) + list2
dict.values() + list2
and dict.items() + list2
except
:
except ValueError, exc:
with except ValueError as exc:
except (TypeError, ValueError), exc:
with
except (TypeError, ValueError) as exc:
has_key
:
dict.has_key(key)
with key in dict
iteritems
:
dict.iteritems()
with six.iteritems(dict)
,
add import six
itervalues
:
dict.itervalues()
with six.itervalues(dict)
,
add import six
iterkeys
:
for key in dict.iterkeys():
with for key in dict:
dict.iterkeys()
with six.iterkeys(dict)
,
add import six
itertools
:
replace itertools.ifilter
with six.moves.filter
,
add import six
similar change for ifilterfalse()
, imap()
, izip()
and
izip_longest()
of the itertools
module
long
:
123L
with 123
(decimal)0xABl
with 0xAB
(hexadecimal)0600L
with 0o600
(octal)(int, long)
with six.integer_types
long(1)
with 1
next
:
iter.next()
with next(iter)
print
:
print msg
with print(msg)
print msg,
with print(msg, end=' ')
and add from __future__ import print_function
importprint
with print()
and add from __future__ import print_function
importprint >>sys.stderr, "hello"'
with print("hello", file=sys.stderr)
and add from __future__ import print_function
importraise
:
raise exc[0], exc[1], exc[2]
with six.reraise(*exc)
, add import six
raise exc_type, exc_value, exc_tb
with six.reraise(exc_type, exc_value, exc_tb)
, add import six
raise exc, msg
with raise exc(msg)
, add import six
six_moves
:
replace Python 2 imports with imports from six.moves
,
add import six
. Python 2 modules:
BaseHTTPServer
ConfigParser
Cookie
HTMLParser
Queue
SimpleHTTPServer
SimpleXMLRPCServer
__builtin__
cPickle
cookielib
htmlentitydefs
httplib
repr
xmlrpclib
replace Python 2 functions with six.moves.<function>
,
add import six
. Python 2 functions:
raw_input()
reduce()
reload()
replace unichr()
with six.unichr()
, add import six
string
:
string.xxx(str, ...)
with str.xxx(...)
where .xxx
is a string method. For example, replace string.upper("abc")
with
"abc".upper()
.string.atof(str)
with float(str)
string.atoi(str)
and string.atol(str)
with int(str)
stringio
:
StringIO.StringIO
with six.StringIO
,
add import six
cStringIO.StringIO
with moves.cStringIO
,
add from six import moves
from StringIO import StringIO
with from six import StringIO
from cStringIO import StringIO
with from six.moves import cStringIO as StringIO
six.BytesIO
(or io.BytesIO
if you don't support Python 2.6) when bytes are expected on Python 3unicode
:
unicode
with six.text_type
, add import six
(str, unicode)
with six.string_types
, add import six
urllib
:
six.moves.urllib
,
add import six
xrange
:
xrange()
with range()
and
add from six.moves import range
To install sixer, type::
pip3 install sixer
sixer requires Python 3, it doesn't work on Python 2.
When an operation uses six
, import six
may be added. sixer repects
OpenStack coding style rules to add the import: imports grouped by standard
library, third party and application imports; and imports must be are sorted.
Since the project is implemented with regular expressions, it can produce false positives (invalid changes). For example, some operations replace patterns in strings, comments or function names even if it doesn't make sense.
Try also the 2to6 project which may be more reliable.
To run tests, type tox
. Type pip install -U tox
to install or update
the tox
program.
Or run tests manually: type python3 tests.py
.
six module documentation <https://pythonhosted.org/six/>
_2to6 <https://github.com/limodou/2to6>
_modernize <https://pypi.python.org/pypi/modernize>
_Language differences and workarounds <http://python3porting.com/differences.html>
_getpython3 <http://getpython3.com/>
_Version 1.6.1 (2018-10-24)
Version 1.6 (2016-07-25)
dict0
now also matches any integer index, not only 0
long
now also replaces long(1)
with 1
Version 1.5 (2016-05-30)
ConfigParser.ConfigParser
with
configparser.ConfigParser
, not with configparser.configparser
octal
operation, it produces too many false positivesVersion 1.4 (2016-03-11)
six.next()
Version 1.3 (2016-02-11)
string
operation. For example, replace string.upper("abc")
with
"abc".upper()
.print
now also replaces print >>sys.stderr, "hello"'
with print("hello", file=sys.stderr)
Version 1.2 (2015-11-26)
octal
operation: replace 0123
with 0o123
print
operation: replace print msg
with print(msg)
,
handle also other print statements (but not all of them yet)has_key
operation: replace dict.has_key(key)
with key in dict
long
now also handles octal and hexadecimal numbers. For example,
0xffL
is replaced with 0xff
, and 0600l
is replace with
0o600
.except
now handles also exception with dots
(ex: except select.error, exc:
)iterkeys
now replaces for key in dict.iterkeys():
with
for key in dict:
to avoid the usage of six.except
and raise
regex to match also expressions without
spaces after commasVersion 1.1 (2015-10-22)
--third-party
command line optionVersion 1.0 (2015-10-16)
--write
to really
modify files inplace.long
operation now also replaces (int, long)
with
six.integer_types
itertools
now also replaces ifilterfalse()
, izip()
and
izip_longest()
of the itertools
modulesix_moves
now also replaces unichr(ch)
with six.unichr(ch)
-
prefix.
For example, all,-iteritems
applies all operations except
iteritems
.Version 0.8 (2015-10-03)
unicode
operation also replaces (str, unicode)
with
six.string_types
long
also replaces 1l
(lower case L suffix for long numbers)Version 0.7 (2015-09-29)
dict0
, dict_add
and except
operationssix_moves
now also patches reduce()
and reload()
. For example,
reduce()
is replaced with six.moves.reduce()
.six_moves
now also patches mock.patch()
. For example,
with mock.patch('__builtin__.open'): ...
is replaced with
with mock.patch('six.moves.builtin.open'): ...
urllib
now also replaces from ... import ...
imports.
For example, from urllib import quote
is replaced with
from six.moves.urllib.parse import quote
.Version 0.6 (2015-09-11)
urllib2.urlparse.urlparse
(import urllib2
) is now
replaced with urllib.parse.urlparse
(from six.moves import urllib
).Version 0.5 (2015-07-08)
Version 0.4 (2015-06-09)
stringio
operation now also replaces cStringIO and
from StringIO import StringIO
Version 0.3.1 (2015-05-27)
Version 0.3 (2015-05-27)
Version 0.2 (2015-05-12):
Version | Tag | Published |
---|---|---|
1.6.1 | 4yrs ago | |
1.6 | 7yrs ago | |
1.5 | 7yrs ago | |
1.4 | 7yrs ago |