Package: sixer
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(source, bug tracker)sixer in the Python Cheeseshop (PyPI)See also thesix module documentation.Usagesixer.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 exceptiteritems.For directories, sixer.py searchs for.pyfiles 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--helpto see all available options.See below for the list of available operations.Operationsall:combine all operations all togetherbasestring:replacebasestringwithsix.string_types,
addimport sixdict0:replacedict.keys()[0]withlist(dict.keys())[0]same fordict.values()[0]anddict.items()[0]note: the pattern matches any integer index, not only0dict_add:replacedict.keys() + list2withlist(dict.keys())+ list2same fordict.values() + list2anddict.items() + list2except:Replaceexcept ValueError, exc:withexcept ValueError as exc:Replaceexcept (TypeError, ValueError), exc:withexcept (TypeError, ValueError) as exc:has_key:Replacedict.has_key(key)withkey in dictiteritems:replacedict.iteritems()withsix.iteritems(dict),
addimport sixitervalues:replacedict.itervalues()withsix.itervalues(dict),
addimport sixiterkeys:Replacefor key indict.iterkeys():withfor key in dict:Replacedict.iterkeys()withsix.iterkeys(dict),
addimport sixitertools:replaceitertools.ifilterwithsix.moves.filter,
addimport sixsimilar change forifilterfalse(),imap(),izip()andizip_longest()of theitertoolsmodulelong:replace123Lwith123(decimal)replace0xABlwith0xAB(hexadecimal)replace0600Lwith0o600(octal)replace(int, long)withsix.integer_typesreplacelong(1)with1next:replaceiter.next()withnext(iter)print:Replaceprint msgwithprint(msg)Replaceprint msg,withprint(msg, end=' ')and addfrom __future__ import print_functionimportReplaceprintwithprint()and addfrom __future__ import print_functionimportReplaceprint >>sys.stderr, "hello"'withprint("hello",file=sys.stderr)and addfrom __future__ import print_functionimportraise:replaceraise exc[0], exc[1], exc[2]withsix.reraise(*exc), addimport sixreplaceraise exc_type, exc_value, exc_tbwithsix.reraise(exc_type, exc_value, exc_tb), addimport sixreplaceraise exc, msgwithraise exc(msg), addimport sixsix_moves:replace Python 2 imports with imports fromsix.moves,
addimport six. Python 2 modules:BaseHTTPServerConfigParserCookieHTMLParserQueueSimpleHTTPServerSimpleXMLRPCServer__builtin__cPicklecookielibhtmlentitydefshttplibreprxmlrpclibreplace Python 2 functions withsix.moves.<function>,
addimport six. Python 2 functions:raw_input()reduce()reload()replaceunichr()withsix.unichr(), addimport sixstring:replacestring.xxx(str,...)withstr.xxx(...)where.xxxis a string method. For example, replacestring.upper("abc")with"abc".upper().replacestring.atof(str)withfloat(str)replacestring.atoi(str)andstring.atol(str)withint(str)stringio:replaceStringIO.StringIOwithsix.StringIO,
addimport sixreplacecStringIO.StringIOwithmoves.cStringIO,
addfrom six import movesreplacefrom StringIO import StringIOwithfrom six import StringIOreplacefrom cStringIO import StringIOwithfrom six.moves import cStringIO as StringIOlater you may have to replace it withsix.BytesIO(orio.BytesIOif you don’t support Python 2.6) when bytes are expected on Python 3unicode:replaceunicodewithsix.text_type, addimport sixreplace(str, unicode)withsix.string_types, addimport sixurllib:replace Python 2 urllib and urllib2 withsix.moves.urllib,
addimport sixxrange:replacexrange()withrange()and
addfrom six.moves import rangedon’t add the import if all ranges have 1024 items or lessInstallationTo install sixer, type:pip3 install sixersixer requires Python 3, it doesn’t work on Python 2.Adding the six importWhen an operation usessix,import sixmay 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.LimitationsSince 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.TestsTo run tests, typetox. Typepip install-Utoxto install or update
thetoxprogram.Or run tests manually: typepython3 tests.py.Resources to port code to Python 3six module documentation2to6modernizePython 3 porting book:Language differences and workaroundsgetpython3ChangelogVersion 1.6.1 (2018-10-24)Project homepage moved to:https://github.com/vstinner/sixerVersion 1.6 (2016-07-25)dict0now also matches any integer index, not only0longnow also replaceslong(1)with1Version 1.5 (2016-05-30)six_moves: replaceConfigParser.ConfigParserwithconfigparser.ConfigParser, not withconfigparser.configparserremove theoctaloperation, it produces too many false positivesVersion 1.4 (2016-03-11)display the name of applied operations in the final summaryIssue #4: Don’t emit warning onsix.next()Version 1.3 (2016-02-11)addstringoperation. For example, replacestring.upper("abc")with"abc".upper().printnow also replacesprint >>sys.stderr, "hello"'withprint("hello",file=sys.stderr)Version 1.2 (2015-11-26)addoctaloperation: replace0123with0o123addprintoperation: replaceprint msgwithprint(msg),
handle also other print statements (but not all of them yet)addhas_keyoperation: replacedict.has_key(key)withkey in dictlongnow also handles octal and hexadecimal numbers. For example,0xffLis replaced with0xff, and0600lis replace with0o600.exceptnow handles also exception with dots
(ex:except select.error, exc:)iterkeysnow replacesfor key indict.iterkeys():withfor key in dict:to avoid the usage of six.Enhanceexceptandraiseregex to match also expressions without
spaces after commasVersion 1.1 (2015-10-22)add--third-partycommand line optionemit a warning instead of failing with an error if we failed to find the
best place to add an importfix also code to detect third-party modules, don’t check for the prefix
but the full name (ex: “numpypy” is not detected as third-party if only
“numpy” is known)Version 1.0 (2015-10-16)sixer doesn’t modify files by default anymore. Add--writeto really
modify files inplace.longoperation now also replaces(int, long)withsix.integer_typesitertoolsnow also replacesifilterfalse(),izip()andizip_longest()of theitertoolsmodulesix_movesnow also replacesunichr(ch)withsix.unichr(ch)command line: it’s now possible to exclude an operation using-prefix.
For example,all,-iteritemsapplies all operations exceptiteritems.Version 0.8 (2015-10-03)urllib now emits a warning on unknown symbol, instead of raising an
exceptionWrite warnings to stderr instead of stdout and exit with error code 1
if a filename doesn’t exist or a directory doesn’t contain any .py fileunicodeoperation also replaces(str, unicode)withsix.string_typesWhen removing an import, don’t remove the empty line following the import
if the empty line is followed by a second importlongalso replaces1l(lower case L suffix for long numbers)Version 0.7 (2015-09-29)Add newdict0,dict_addandexceptoperationsAdd –app command line option to specify the Python module of the
application, to help sorting importsCode adding new imports respect better OpenStack coding style on imports.
For example, it adds two empty lines after imports, instead of a single
line.Display the name of the operation which modified filesDisplay also the name of the operation in warningssix_movesnow also patchesreduce()andreload(). For example,reduce()is replaced withsix.moves.reduce().six_movesnow also patchesmock.patch(). For example,withmock.patch('__builtin__.open'):...is replaced withwithmock.patch('six.moves.builtin.open'):...urllibnow also replacesfrom ... import ...imports.
For example,from urllib import quoteis replaced withfrom six.moves.urllib.parse import quote.Version 0.6 (2015-09-11)Add “itertools” operationFix xrange() regex to not modify “from six.moves import xrange” and
“moves.xrange(n)”Fix urllib for urllib or urlparse module get from the urllib2 module.
For example,urllib2.urlparse.urlparse(import urllib2) is now
replaced withurllib.parse.urlparse(from six.moves import urllib).Version 0.5 (2015-07-08)six_moves: support “import module as name” syntax and add cPickle moduleAdd –to-stdout, –quiet and –max-range command line optionsEmit a warning if the directory does not contain any .py file or
if the path does not existTest also directly the sixer.py programVersion 0.4 (2015-06-09)sixer.py now accepts multiple filenames on the command line, but
operations becomes the first command line parameterthestringiooperation now also replaces cStringIO andfrom StringIO import StringIOurllib: replace also urlparse.symbolsix_moves: support more modules: Cookie, HTMLParser, SimpleHTTPServer,
cookielib, xmlrpclib, etc.Refactor operations as classes to cleanup the codeVersion 0.3.1 (2015-05-27)Fix the “all” operationsix_moves knows more modulesurllib: add pathname2url, don’t touch urllib2.parse_http_list()Version 0.3 (2015-05-27)First command line parameter can now be a filenameAdd “all”, “basestring”, “iterkeys”, “six_moves”, “stringio”
and “urllib” operationsEnhance the knownledge tables for modules (stdlib, third parties,
applications)Ignore unparsable import lines when adding an importVersion 0.2 (2015-05-12):First public release