Search code examples
pythonpython-3.xpython-2.7string-formatting

How to convert all the printf-styles in a module to formatting style in python?


I am trying to convert a module from python version 2.x to python version 3.x. To do that I am using 2to3 converter. However since I couldn't find any parameter in this converter to change also %s or printf-style to str.format() style I just tried to use pyupgrade package as follows:

pyupgrade /path/to/myfile.py

However this one also does not make any change. Do you have any idea or suggestion if there is a converter to do this?

Ex.

limit=None
ll = 23
limitQuery = 'LIMIT %s,%s'% (limit, ll)
print(limitQuery)

after running this command it does not change: pyupgrade /Users/Eli/Desktop/test.py


Solution

  • The project either has some bugs in this area, or they deliberately ignore code not meeting minimal formatting requirements.

    Your sample fails because there are no spaces between the ' and % characters:

    $ echo "limitQuery = 'LIMIT %s,%s'% (limit, ll)" | pyupgrade -
    limitQuery = 'LIMIT %s,%s'% (limit, ll)
    

    When you add a space, the project converts the syntax correctly:

    $ echo "limitQuery = 'LIMIT %s,%s' % (limit, ll)" | pyupgrade -
    limitQuery = 'LIMIT {},{}'.format(limit, ll)
    

    I've filed a bug report with the project. They have confirmed that this is deliberate:

    this is one of the timid parts of pyupgrade, if your code is not well formatted to begin with it won't try to fix it for you.

    Hopefully this will be made explicit in the documentation.

    To work around this, you could run the black code formatter on the code first; black will enforce PEP 8 standards and insert that space for you:

    $ echo "limitQuery = 'LIMIT %s,%s'% (limit, ll)" | black -q - | pyupgrade -
    limitQuery = "LIMIT {},{}".format(limit, ll)