144

Here's the output. These are utf-8 strings I believe... some of these can be NoneType but it fails immediately, before ones like that...

instr = "'%s', '%s', '%d', '%s', '%s', '%s', '%s'" % softname, procversion, int(percent), exe, description, company, procurl

TypeError: not enough arguments for format string

Its 7 for 7 though?

y2k
  • 59,444
  • 25
  • 58
  • 84

4 Answers4

254

You need to put the format arguments into a tuple (add parentheses):

instr = "'%s', '%s', '%d', '%s', '%s', '%s', '%s'" % (softname, procversion, int(percent), exe, description, company, procurl)

What you currently have is equivalent to the following:

intstr = ("'%s', '%s', '%d', '%s', '%s', '%s', '%s'" % softname), procversion, int(percent), exe, description, company, procurl

Example:

>>> "%s %s" % 'hello', 'world'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: not enough arguments for format string
>>> "%s %s" % ('hello', 'world')
'hello world'
Andrew Clark
  • 180,281
  • 26
  • 249
  • 286
  • 3
    That worked..sort of. I was trying to use %s formatting to avoid the NoneType error, but I'm getting it still. Related: http://stackoverflow.com/questions/1338690/good-way-of-handling-nonetype-objects-when-printing-in-python – y2k Jun 21 '12 at 20:30
  • Won't be useful to the OP, given the age, but just in case still useful to someone: a simple workaround where a variable may be none is to guard against that with a ternary statement - i.e. "%s %s" % (a if a is not None else "", b) if we are worried about a possibly being None. So even if a is None we still aren't passing None to the format operator and causing problems. – Blair May 14 '20 at 16:59
183

Note that the % syntax for formatting strings is becoming outdated. If your version of Python supports it, you should write:

instr = "'{0}', '{1}', '{2}', '{3}', '{4}', '{5}', '{6}'".format(softname, procversion, int(percent), exe, description, company, procurl)

This also fixes the error that you happened to have.

Simeon Visser
  • 106,727
  • 18
  • 159
  • 164
  • Does this work for the logging module as well? Is this kind of interpolation understood by it? – AllTradesJack Aug 20 '14 at 18:35
  • @joshsvoss: yes, there are a few links mentioned here that discuss the possibilities: http://bugs.python.org/issue14031 – Simeon Visser Aug 20 '14 at 21:22
  • 4
    @SimeonVisser, why is this becoming outdated? If you, for example, use one variable to store format string and you want to put string with replaced values in same variable you get just a tad bit cleaner code with **format_string %= ('bla', 'bla', 'bla')**. Care to elaborate or point to some useful link about this? – Djuka Jun 03 '15 at 17:40
  • .format() was added because this is quite common and it shouldn't require an operator to do. Your example is nice but difficult to explain to a newcomer. The notation a = a.format(1,2,3) is much more explicit and easier to understand/teach. I don't have a link but this is the main reason why format() was introduced (ease of understanding). – Simeon Visser Jun 03 '15 at 19:09
  • 1
    Also, format() supports more explicit ways of expressing what happens, such as "{a} {b}".format(a='3', b='4'). – Simeon Visser Jun 03 '15 at 19:12
  • 1
    I'm using python 3.6.5 and the percent sign operator still can be used... – Hzzkygcs Jun 08 '18 at 07:39
  • @KhunRan: it hasn't been removed but there are now better ways to express what you wish to format, such as `.format()` and f-strings. – Simeon Visser Jun 08 '18 at 10:56
  • Nine years after this opinion was written, `%` still works (in Python 3.8.6). – David Grayson Jan 13 '21 at 21:27
22

I got the same error when using % as a percent character in my format string. The solution to this is to double up the %%.

Harsha Biyani
  • 5,322
  • 7
  • 32
  • 48
Bruce Jakeway
  • 229
  • 2
  • 3
  • 4
    Providing some code examples of how your solution works, and how it fails without it, etc. might be useful. See [How do I write a good answer?](https://stackoverflow.com/help/how-to-answer). Note that this is a 5 year old question, so you should add an answer only if it provides significantly more information than those already there. – Ramon Jul 06 '17 at 18:51
  • I got a variation of this error due to typo: `"foo: %(foo)s, bar: s(bar)% baz: %(baz)s" % {"foo": "FOO", "bar": "BAR", "baz": "BAZ"}` – Akavall Mar 20 '18 at 17:57
  • For python3 this "solution" is wrong -> Invalid syntax – JonyD Jun 17 '19 at 16:44
0

I had the same issue I was using a raw query for a specific reason and this was to add double quotes in TIME_FORMAT function.

User.objects.raw(
            f'SELECT f1,f2,TIME_FORMAT(SEC_TO_TIME(SUM(TIME_TO_SEC(end_time) - TIME_TO_SEC(start_time))),"%%H:%%i") AS log FROM users GROUP BY start_dt')
Hardik Raval
  • 1,783
  • 16
  • 25