Skip to content
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

f-string conversion with advanced string formatting & None #528

Closed
peterjc opened this issue Sep 10, 2021 · 4 comments · Fixed by #529
Closed

f-string conversion with advanced string formatting & None #528

peterjc opened this issue Sep 10, 2021 · 4 comments · Fixed by #529

Comments

@peterjc
Copy link

peterjc commented Sep 10, 2021

Failing test case using pyupgrade 2.25.0:

$ echo 'a=b=c=None; print("Query:%8s %s %s" % (a, b, c))'  > test.py ; pyupgrade --py36-plus test.py ; cat test.py
Rewriting test.py
a=b=c=None; print(f"Query:{a:>8} {b} {c}")
>>> a=b=c=None; print("Query:%8s %s %s" % (a, b, c))
Query:    None None None
>>> a=b=c=None; print(f"Query:{a:>8} {b} {c}")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported format string passed to NoneType.__format__

The problem is while f"{None}" works, advanced string format arguments do not:

>>> "%8s" % None
'    None'
>>> f"{None:>8}"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported format string passed to NoneType.__format__

Possible workaround:

>>> a=b=c=None; print(f"Query:{str(a):>8} {b} {c}")
Query:    None None None

This issue was found in biopython/biopython#3724

@asottile
Copy link
Owner

sadly I think this is unfixable -- there would need to be type analysis to properly know that "None" is buggy -- the only other option is disabling all alignment conversions

arguably this is a bug in python itself, I see no reason that the padding formatters shouldn't work for None

I'm not sure what the best thing to do here is

:8 is more concise but incorrect:

>>> '{:8}'.format("a")
'a       '
>>> '{:8}'.format(1)
'       1'
>>> '%8s' % ('a',)
'       a'
>>> '%8s' % (1,)
'       1'

an aside, please don't mention flynt -- the author has ripped me off in the past and has generally been an uncooperative and unethical open source maintainer

Repository owner deleted a comment from peterjc Sep 10, 2021
@asottile
Copy link
Owner

I guess the only safe approach is skipping -- #529 implements that

@peterjc
Copy link
Author

peterjc commented Sep 10, 2021

I was also wondering if this was a Python bug too, I had a quick look but didn't find anything on their tracker.

I agree that unless a future version of Python changes this, disabling any conversion with an alignment is safest.

@asottile
Copy link
Owner

we'll see where this goes: https://bugs.python.org/issue45165

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants