On Thu, Sep 17, 2020 at 9:32 PM Wes Turner <wes.turner@gmail.com> wrote:
There are a number of refactoring tools for Python.
From https://github.com/beat-no/roper#alternatives :




On Thu, Sep 17, 2020 at 8:27 PM Steven D'Aprano <steve@pearwood.info> wrote:
On Thu, Sep 17, 2020 at 11:47:03PM -0000, Joseph Perez wrote:

> Thus `f"{:a + b}" == "a + b"`.


I don't know how well IDEs like VisualStudio and PyCharm do refactoring, 

Using the same example from the Bowler issue:

-  print(f'bar is {bar}, not {zar}')
-  print('bar is {bar}, not {zar}'.format(bar=bar, zar=zar))

..both rope and Pycharm are currently smart enough to refactor the part in the curly braces:

  • f'bar is {bar}, not {zar}' → f'bar is {bar_new}, not {zar}'
  • .format(bar=bar, zar=zar) → .format(bar=bar_new, zar=zar)
As far as I know, none of these tools know how to do the renaming of the FIRST bar to bar_new:

  • f'bar is {bar}, not {zar}' → f'bar_new is {bar_new}, not {zar}'
  • .format(bar=bar, zar=zar) → .format(bar_new=bar_new, zar=zar)
It seems to me that rather than modifying Python to create special
syntax for no-ops to be used as directives for the benefit of IDEs, it
would be better for IDEs to get together and work on a common syntax for
directives which can be included in regular comments.


The effort for this just doesn't seem worth it. All IDEs have find and replace (pycharm's is very nice). And even python developers who eschew the IDE use SOMETHING to write their code... whether it's vim or notepad++ or vscode (people tell me it's not an IDE) or emacs or whatever, and that something invariably provides find and replace functionality (vim has the :substitute command. notepad++ has ctr+r. Microsoft Word has ctl+h ;) ).

But if you really want it or need it in a situation where find and replace isn't a great option, you can hack a utility function using the 3.8 syntax:

def nameof(x):
    return x.split("=", 1)[0]

...and use it in a nested fstring:

>>> f"{nameof('{foo=}')}"

Now refactoring can work like a charm for single variables:

  • f'{nameof(f"{bar=}")} is {bar}, not {zar}' → f'{nameof(f"{bar_new=}")} is {bar_new}, not {zar}'
The OP example doesn't look fantastic, but it works:

>>> f"{nameof(f'{a=}')} + {nameof(f'{b=}')}" == "a + b"


"I've never met a Kentucky man who wasn't either thinking about going home or actually going home." - Happy Chandler