Convert format and % strings to f-strings#8958
Conversation
|
And of course I jumped the gun because I see #8955 not yet merged. |
@taldcroft - You're welcome to merge it, or approve so I can do it. Dropping python 3.5 for 4.0 was agreed a while ago, and it's also in the APE. |
| if sp.returncode != 0: | ||
| raise OSError('Running setup.py build_ext --inplace failed ' | ||
| 'with error code {0}: try rerunning this command ' | ||
| 'with error code {}: try rerunning this command ' |
There was a problem hiding this comment.
Is there a specific logic why the latter 3 cases keep the .format() syntax while the first one is converted, or does pyupgrade simply not handle multi-line statements?
There was a problem hiding this comment.
Indeed it looks like pyupgrade doesn't do multi-line statements. Grr.
There was a problem hiding this comment.
it's intentionally timid -- it doesn't want to make your lines longer which might anger flake8
|
About merging, presumably it needs to pass all the CI tests first. It does pass locally on my laptop. |
|
As long as the 3.5 test setup is included, CircleCI will never make it to the 3.6 tests. But the Travis failures all seem to be due to the |
|
Tested with Python 3.6 + 3.8b1 on my Mac as well. |
|
the crash in Here's the diff if you want to apply it: $ git diff | cat
diff --git a/astropy/utils/console.py b/astropy/utils/console.py
index a8040906d..c89da247b 100644
--- a/astropy/utils/console.py
+++ b/astropy/utils/console.py
@@ -256,7 +256,7 @@ def _color_text(text, color):
return text
color_code = color_mapping.get(color, '0;39')
- return '\033[{0}m{1}\033[0m'.format(color_code, text)
+ return f'\033[{color_code}m{text}\033[0m'
def _decode_preferred_encoding(s):
@@ -425,12 +425,12 @@ def human_time(seconds):
seconds = int(seconds)
if seconds < 60:
- return ' {0:2d}s'.format(seconds)
+ return f' {seconds:2d}s'
for i in range(len(units) - 1):
unit1, limit1 = units[i]
unit2, limit2 = units[i + 1]
if seconds >= limit1:
- return '{0:2d}{1}{2:2d}{3}'.format(
+ return '{:2d}{}{:2d}{}'.format(
seconds // limit1, unit1,
(seconds % limit1) // limit2, unit2)
return ' ~inf'
@@ -482,10 +482,10 @@ def human_file_size(size):
str_value = str_value[:2]
else:
str_value = str_value[:3]
- return "{0:>3s}{1}".format(str_value, suffix)
+ return f"{str_value:>3s}{suffix}"
-class _mapfunc(object):
+class _mapfunc:
"""
A function wrapper to support ProgressBar.map().
"""
@@ -648,10 +648,10 @@ class ProgressBar:
else:
t = ((time.time() - self._start_time) * (1.0 - frac)) / frac
prefix = ' ETA '
- write(' {0:>4s}/{1:>4s}'.format(
+ write(' {:>4s}/{:>4s}'.format(
human_file_size(value),
self._human_total))
- write(' ({:>6.2%})'.format(frac))
+ write(f' ({frac:>6.2%})')
write(prefix)
if t is not None:
write(human_time(t))
@@ -685,7 +685,7 @@ class ProgressBar:
# Calculate percent completion, and update progress bar
frac = (value/self._total)
self._widget.value = frac * 100
- self._widget.description = ' ({:>6.2%})'.format(frac)
+ self._widget.description = f' ({frac:>6.2%})'
def _silent_update(self, value=None):
pass |
| # Figure out what the current language is set to. | ||
| return locale.getlocale(locale.LC_TIME) | ||
|
|
||
| class LocaleTime(object): |
There was a problem hiding this comment.
I think it would be better to omit the extern files from the update.
There was a problem hiding this comment.
extern should definitely be left alone for any updates, as we try to simply copy paste their released versions as is for to have a good reference as ease of maintenance.
| # The wrapper applies to so many of the __ methods that it's easier to | ||
| # just exclude the ones it doesn't apply to | ||
| exclude = set(['__new__', '__array_finalize__', '__array_wrap__', | ||
| exclude = {'__new__', '__array_finalize__', '__array_wrap__', |
There was a problem hiding this comment.
While I like these kind of cleanups I would prefer if the indentation (for the following lines) would be changed appropriately.
There was a problem hiding this comment.
yeah this is a bit of a microbug / nice-to-have in pyupgrade -- I haven't gotten around to fixing it because I use autopep8 / this calling construct which avoids 14-space / arbitrary-space indents
|
I re-did this from scratch using a hacked version of pyupgrade at e477316 to convert format and % strings to modern formatting, including f-strings where possible. The hack bit was to essentially de-select all upgrades except for string formatting ones. That removes (at least from initial quick inspection) all the issues with indentation, and also makes the scope of this PR more contained. |
|
For the record: |
|
@taldcroft - can the tool understand the narrative docs too? if yes, could you run in on the code snippets in there, either as part of this PR or a separate one? |
|
@bsipocz - I'd rather leave the narrative docs as a separate PR. 255 files is already big enough, and some custom code would be needed for the narrative docs as the tool is expecting only parsable Python code. |
|
There is already conflict. I'd say, either we get this in soon, or break it into smaller pieces by submodule. |
|
From experience you'll frustrate contributors less by landing it all in one PR (especially if patches tend to span multiple modules) as they'll only have to deal with conflicts once |
|
I'm happy to hit merge once this is rebased and agree that now that it's done, we don't need to split up to multiple PRs (e.g. I'm happy to help sort out other PRs that get conflicts due to this). |
|
OK, this is now re-processed using current master. |
bsipocz
left a comment
There was a problem hiding this comment.
I've skimmed through the diff again, and it mostly looks OK. Once the two things I suggest are removed, I'm happy to merge.
| return '' | ||
| regex = '|'.join(re_escape(stuff) for stuff in to_convert) | ||
| regex = '(?P<%s>%s' % (directive, regex) | ||
| regex = f'(?P<{directive}>{regex}' |
There was a problem hiding this comment.
please remove changes to stuff in extern
There was a problem hiding this comment.
Argh, made a small mistake in my grepping that let this through, will fix.
|
|
||
| if param.default is param.empty: | ||
| raise ModelDefinitionError( | ||
| 'The bounding_box method for {0} is not correctly ' |
There was a problem hiding this comment.
I'm a bit worried how painful these changes will be for #8769, maybe skip this file.
|
Once more... and in the interest of reproducibility here is what I typed (laying bare my unsophisticated approach): |
|
OK, well, I take the blame if this messes something up due to the merging, but based on the 5 rockets, I go ahead and merge now. |
|
@taldcroft - should the recommendation in
in first place? |
Convert format and % strings to f-strings
Convert format and % strings to f-strings
Convert format and % strings to f-strings
This used a hacked version of
pyupgradeate477316to convert format and % strings to modern formatting, including f-strings where possible. The hack bit was to essentially de-select all upgrades except for string formatting ones.Not included are multiline statements for reasons discussed below.