-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DRAFT: Apply pyupgrade. #51
Conversation
Oh wow, another splendid idea! But I agree with your notes regarding options, config file first, and the AST check challenge. Also, I'm not sure if you meant this by "pass options in", but I think this should be off by default and activated using a command line / configuration file option. |
src/darker/__main__.py
Outdated
@@ -125,14 +125,42 @@ def format_edited_parts( | |||
# 10. A re-formatted Python file which produces an identical AST was | |||
# created successfully - write an updated file or print the diff | |||
# if there were any changes to the original | |||
result_str = pyup(result_str, edited_lines, edited_linenums) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with your note about pyupgrade changes being better done before Black reformatting, maybe even as the first thing before isort.
src/darker/__main__.py
Outdated
|
||
pyup_opcodes = diff_and_get_opcodes(edited_lines, content) | ||
pyupgrade_chunks = list(opcodes_to_chunks(pyup_opcodes, edited_lines, content)) | ||
pyup_chosen_lines: List[str] = list(choose_lines(pyupgrade_chunks, edited_linenums)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
edited_linenums
isn't necessarily correct any more at this point. If Black has e.g. divided a long line on multiple lines, every line number after that gets shifted. This would cause wrong pyupgrade changes to be selected and desired ones skipped. This is why changes by all tools (pyupgrade, isort, Black) need to be done first, and only then the diff be calculated between the user's original version and the automatically modified one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that what I was thinking, or recomputing the diff WRT the revision after each tool.
I think the problem with (all tools) then (compute diff), is you may end up with chunks larger than you wants.
say original
a = set((1, 2))
b = c
user edit
- b = c
+ b = d
(black + pyupgrade) then (compute diff), will change both lines, which you don't want to apply.
Though,
(black, diff) should be applied, then (pyupgrade, diff) should not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's also the additional potential problem of tools which may change the order of lines in code. isort
is an example of such a tool, and that's why Darker just includes modifications from it as part of the starting point, and compares Black results to that. I wonder if any of the rules in pyupgrade
could potentially also change the order of lines in the source code?
Here's an illustration of what code reordering would cause if such changes would be attempted to apply to only modified lines:
Let's say I have this module committed to the HEAD
of my repository:
1 import os
2 import black
3 import sys
I then manually correct the first line to import os
without the extra space:
*1 import os
2 import black
3 import sys
Run isort:
isort myfile.py
Get this as a result:
1 import os
*2 import sys
*3
*4 import black
Git shows the difference:
git diff -U0
git diff -U0|cat
diff --git a/imp.py b/imp.py
index 61a152d..1ed0c5e 100644
--- a/imp.py
+++ b/imp.py
@@ -1,2 +1 @@
-import os
-import black
+import os
@@ -3,0 +3,2 @@ import sys
+
+import black
Only the first chunk falls on line 1 (the only edited line) and would be applied by a Darker-like tool. The result would be:
1 import os
2 import sys
So I would actually lose my Black import as a result of applying sorted imports partially.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
from my look at upgrade that does nto seem to be the case, it really appears to do AST node replacements, so I would not be too worried.
Thanks !
Yes, off by default would be my preference I think. And the you can opt-in on per-repo config files. |
@Carreau do you still think this patch would fit Darker's purpose? If so, we probably need to try and rebase on |
@Carreau, I rebased this on |
096c525
to
e1fcd1f
Compare
75685fb
to
8d1ceef
Compare
0a69c95
to
b6d3edd
Compare
f330bc8
to
720c44e
Compare
185047d
to
fcc55c3
Compare
fcaf05c
to
0d5ede9
Compare
5761f7e
to
bf3656f
Compare
Just seeing how it looks like, we would of course need to pass options in, so i'm thinking only once there is a config file; likely. So far there's just a function to call `pyupgrade` on given source code. Applying it to modified lines needs to be implemented, probably best by refactoring `_reformat_single_file()` so it can be used for different source-modifying tools. It also does use pyupgrade private internal API, and the author has explicitly stated they they were not willing to have public API beyond the CLI. We should also likely run this _before_ black; maybe even before isort ? not sure if it might remove imports... But at least it does not pass the ast unchange part.
Flynt support in #308 has been merged. We can now resume implementing pyupgrade support. |
Moving to version 1.8.0. There are a plenty of changes for 1.7.0 already, I now prefer to get it out first. |
flynt
#308flynt
#308 has been mergedflynt
#308 fits directly or needs to be adjusted(pyupgrade is "a tool (and pre-commit hook) to automatically upgrade syntax for newer versions of the language.")
Just seeing how it looks like, we would of course need to pass options in, so i'm thinking only once there is a config file; likely.
This is likely incorrect as the edited lines could likely be off once Black has been ran as it can rewrap stuff.
It also does use pyupgrade private internal API, and the author has explicitly stated they they were not willing to have public API beyond the CLI.
We should also likely run this before Black; maybe even before isort? Not sure if it might remove imports... But at least it does not pass the AST unchange part.
Late for today, just submitting in case you decide to also write the same thing.