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

format-string inconsistencies and bugs #4042

Closed
twmr opened this issue Jan 23, 2021 · 1 comment · Fixed by #4794
Closed

format-string inconsistencies and bugs #4042

twmr opened this issue Jan 23, 2021 · 1 comment · Fixed by #4794
Labels
Enhancement ✨ Improvement to a component
Milestone

Comments

@twmr
Copy link
Contributor

twmr commented Jan 23, 2021

At work we stumbled upon a bug in an old code, that used % formatting, but the fmt string was wrong, because it didn't contain any replacement fields. It would be nice if pylint could warn about format strings without any replacement fields.

Current behavior

def demo(param):
    print("1asfasfdsf dasfdadfsdf" % param)  # no warning (code like this line was used in our code-base)
    print("2asfasfdsf dasfdadfsdf" % ())  # no warning
    print("3asfasfdsf dasfdadfsdf" % [])  # pylint outputs too-many-format-args

    # this line raises when you run the script using cpython
    print("4asfasfdsf dasfdadfsdf" % None)  # pylint outputs too-many-format-args

demo(())
demo.py:4:10: E1305: Too many arguments for format string (too-many-format-args)
demo.py:7:10: E1305: Too many arguments for format string (too-many-format-args)

When using .format the behavior is a bit different (both in cpython as well as in pylint)

def demo(param):
    print("1asfasfdsf dasfdadfsdf".format(param))  # pylint outputs too-many-format-args
    print("2asfasfdsf dasfdadfsdf".format(()))  # pylint outputs too-many-format-args
    print("3asfasfdsf dasfdadfsdf".format([]))  # pylint outputs too-many-format-args
    print("4asfasfdsf dasfdadfsdf".format(None))  # pylint outputs too-many-format-args

demo(())

Contrary to the first example, this one doesn't raise an exception when you run it using cpython. However, pylint considers all print function calls as invalid, which is wrong, because cpython doesn't raise.

demo_usint_dot_format.py:2:10: E1305: Too many arguments for format string (too-many-format-args)
demo_usint_dot_format.py:3:10: E1305: Too many arguments for format string (too-many-format-args)
demo_usint_dot_format.py:4:10: E1305: Too many arguments for format string (too-many-format-args)
demo_usint_dot_format.py:7:10: E1305: Too many arguments for format string (too-many-format-args)

Expected behavior

I don't understand why python supports format strings without any replacement fields. Maybe because if the fmt string and the args passed to e.g. .format are determined dynamically.

Anyway, I think pylint should output an error (e.g. bad-format-string) if the format string is a string without any replacement fields (as in the examples above).

Things I want to mention but I don't care about them:

There is an inconsistency between lists and tuples if used as format string args:

    print("2asfasfdsf dasfdadfsdf" % ())  # no warning
    print("3asfasfdsf dasfdadfsdf" % [])  # pylint outputs too-many-format-args

There are differences between % formating and .format formatting in pylint.

pylint --version output

pylint 2.6.0
astroid 2.4.2
Python 3.8.6 | packaged by conda-forge | (default, Oct  7 2020, 19:08:05) 
[GCC 7.5.0]
@hippo91
Copy link
Contributor

hippo91 commented Jan 30, 2021

@thisch thanks for this report. It makes sense.

@hippo91 hippo91 added the Enhancement ✨ Improvement to a component label Jan 30, 2021
DanielNoord added a commit to DanielNoord/pylint that referenced this issue Aug 3, 2021
This adds a checker that checks strings with '%' or format() applied to them.
If no variables to be replaced are found the warning is emitted.
Closes pylint-dev#4042
Pierre-Sassoulas added a commit that referenced this issue Aug 4, 2021
* Add ``format-string-without-interpolation`` checker
This adds a checker that checks strings with '%' or format() applied to them.
If no variables to be replaced are found the warning is emitted.
Closes #4042

Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
@Pierre-Sassoulas Pierre-Sassoulas added this to the 2.10.0 milestone Aug 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Enhancement ✨ Improvement to a component
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants