Title: str.format() gives poor diagnostic on placeholder mismatch
Type: enhancement Stage: needs patch
Components: Library (Lib) Versions: Python 3.6
Status: open Resolution:
Dependencies: Superseder:
Assigned To: eric.smith Nosy List: Mariatta, eric.smith, ezio.melotti, franciscouzo, roysmith, terry.reedy, tshepang
Priority: normal Keywords: easy, patch

Created on 2014-06-29 14:37 by roysmith, last changed 2016-09-29 21:43 by Mariatta.

File name Uploaded Description Edit
format.patch franciscouzo, 2016-09-09 07:53 review
Messages (6)
msg221846 - (view) Author: Roy Smith (roysmith) Date: 2014-06-29 14:37
msg221847 - (view) Author: Roy Smith (roysmith) Date: 2014-06-29 14:41
(ugh, hit return too soon)

>>> '{1}'.format()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: tuple index out of range

This is a confusing error message.  The user hasn't written any tuples, so a message about a tuple index out of range will just leave them scratching their head.  We should either return a more specific subclass of IndexError, or at least a more descriptive text describing what went wrong.

See for background.
msg221855 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2014-06-29 16:02
IndexError should be caught and replaced with something like
ValueError('format string requests argument not passed') or
TypeError('arguments do not match format string') or more specific
TypeError('format string requests at least %d positional arguments, only %d passed')
In Roy's example (a good testcase), the numbers would be 1 and 0.
msg222514 - (view) Author: Tshepang Lekhonkhobe (tshepang) * Date: 2014-07-07 20:50
@terry would a change like this be accepted in 2.7 and 3.4?
msg222524 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2014-07-07 21:46
I don't think we can change the exception type in a bugfix release, if ever. I don't see much point in changing the exception type: it's just churn.

I'm +1 for a better error message. I'm -0 on changing the error message in a bugfix release.
msg222545 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2014-07-08 05:15
After reading Eric's comments and checking the signature of .format and rereading the Format String Syntax section, I have changed my mind. The signature of .format is "S.format(*args, **kwargs) -> str" and args is a tuple. So the user asks for creation of a tuple by calling .format. The only unusual part is the the user also provides indexes into the args tuple, but the doc is clear enough that ints passed as specification field names select positional arguments. I  think the current message is correct enough to leave alone in current releases. An improved message might be

IndexError("Replacement index %d out of range for positional args tuple")

This uses 'replacement index' as a contraction of 'integer passed as replacement field name'.
Date User Action Args
2016-09-29 21:43:45Mariattasetnosy: + Mariatta
2016-09-09 12:00:54eric.smithsetassignee: eric.smith
versions: + Python 3.6, - Python 3.5
2016-09-09 07:55:17franciscouzosetnosy: + franciscouzo
2016-09-09 07:53:56franciscouzosetfiles: + format.patch
keywords: + patch
2014-07-08 05:15:02terry.reedysettype: behavior -> enhancement
messages: + msg222545
versions: - Python 2.7, Python 3.4
2014-07-07 21:46:30eric.smithsetmessages: + msg222524
2014-07-07 20:50:24tshepangsetmessages: + msg222514
2014-07-07 20:44:00tshepangsetnosy: + tshepang
2014-07-05 12:50:55ezio.melottisetkeywords: + easy
nosy: + ezio.melotti
components: + Library (Lib)
2014-06-29 16:02:43terry.reedysetversions: + Python 3.4, Python 3.5
nosy: + terry.reedy, eric.smith

messages: + msg221855

stage: needs patch
2014-06-29 14:41:02roysmithsettype: behavior
messages: + msg221847
versions: + Python 2.7
2014-06-29 14:37:28roysmithcreate