Repository navigation
Incorrect exception in Table value formatting if type and format mismatch #2868
Copy link
Copy link
Closed
Description
In the following example:
In [4]: from astropy.table import Table
In [5]: t = Table()
In [6]: t['a'] = ['a','b','c']
In [7]: t['a'].format = "%9.5f"
In [8]: print(t)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-8-d6c4f5caf31e> in <module>()
----> 1 print(t)
/Volumes/Raptor/Library/Python/3.4/lib/python/site-packages/astropy-1.0.dev9579-py3.4-macosx-10.8-x86_64.egg/astropy/table/table.py in __unicode__(self)
664
665 def __unicode__(self):
--> 666 lines, n_header = self.formatter._pformat_table(self)
667 return '\n'.join(lines)
668 if six.PY3:
/Volumes/Raptor/Library/Python/3.4/lib/python/site-packages/astropy-1.0.dev9579-py3.4-macosx-10.8-x86_64.egg/astropy/table/pprint.py in _pformat_table(self, table, max_lines, max_width, show_name, show_unit, html, tableid)
296 for col in six.itervalues(table.columns):
297 lines, n_header = self._pformat_col(col, max_lines, show_name,
--> 298 show_unit)
299 cols.append(lines)
300
/Volumes/Raptor/Library/Python/3.4/lib/python/site-packages/astropy-1.0.dev9579-py3.4-macosx-10.8-x86_64.egg/astropy/table/pprint.py in _pformat_col(self, col, max_lines, show_name, show_unit)
148 """
149 outs = {} # Some values from _pformat_col_iter iterator that are needed here
--> 150 col_strs = list(self._pformat_col_iter(col, max_lines, show_name, show_unit, outs))
151 col_width = max(len(x) for x in col_strs)
152
/Volumes/Raptor/Library/Python/3.4/lib/python/site-packages/astropy-1.0.dev9579-py3.4-macosx-10.8-x86_64.egg/astropy/table/pprint.py in _pformat_col_iter(self, col, max_lines, show_name, show_unit, outs)
239 format_func(col.format, col[(i,) + multidim1]))
240 else:
--> 241 col_str = format_func(col.format, col[i])
242 yield col_str
243 elif i == i0:
/Volumes/Raptor/Library/Python/3.4/lib/python/site-packages/astropy-1.0.dev9579-py3.4-macosx-10.8-x86_64.egg/astropy/table/pprint.py in _auto_format_func(format_, val)
62 except:
63 raise ValueError('Unable to parse format string {0}'
---> 64 .format(format_))
65 _format_funcs[format_] = format_func
66 return out
ValueError: Unable to parse format string %9.5f
The exception is misleading. The issue is that the value needs to be a float. The 'proper' exception for this in Python is:
In [9]: "%9.5f" % 'a'
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-9-55c5d51877aa> in <module>()
----> 1 "%9.5f" % 'a'
TypeError: a float is required
The current error makes it sound like the format is malformed.
Reactions are currently unavailable
Activity
astrofrog commentedon Aug 19, 2014
I think we should only catch
ValueErrorfor parsing issues, but leave theTypeErrors. It would also be nice ideally if we could escalate the error higher up and give the column for which the issue occurred, or maybe instead print out the offending value in addition to format (to help identify where it went wrong).cherti commentedon Sep 6, 2014
Taking this one.
astrofrog commentedon Sep 6, 2014
@cherti - great, let me know if you have any questions!
mhvk commentedon Sep 8, 2014
Hmm, I'm actually not sure this is that easy to resolve, as the way it is determined whether the format is sensible is by trying to format a table item, and this process is repeated for all different ways we allow the format to be set. So, which exception should be passed on? I guess in principle, one could pass on all, but they are different for new and old-style formats:
mhvk commentedon Sep 8, 2014
p.s. The file to look at is
astropy/table/pprint.py, near the top, where one has:But at the very least one could change the error message itself, to notice that the format could also be incompatible with the table data type.
astrofrog commentedon Sep 8, 2014
I think @cherti is working on a solution that includes trying to catch most common mistakes with a
formatproperty setter when the dtype is notnp.object.astrofrog commentedon Sep 8, 2014
But for the more general case you are right that we will need to find a way to have it work with both formatting styles!
cherti commentedon Sep 8, 2014
Indeed. I'd like to catch a mismatched format upon setting it as it can only be set when we already know the dtype of the column.
This should work for most cases, except dtype=np.object, for what we need to resort to execptions within print.
Trying
'{9.5f}'for a column list['a', 'b', 'c']seems to throw a type error for me.I'm using
format_.format(val)for formatting and it seems to throw a TypeError (at least the error comes up on a way where I am only catching TypeErrors). I'll look into that, but it wouldn't be a problem to catchIndexErrorsas well and raise aTypeError. The set of possibilities to format output should be finite and not too large, I suppose.cherti commentedon Sep 8, 2014
Nevermind, error on my side, as it seems.
cherti commentedon Sep 8, 2014
I have switched the formatting entirely from the %-version over to the .format()-version in the code parts I am working on, throwing the TypeError at the user seems appropriate to me, only requires catching the IndexErrors thrown.
cherti commentedon Sep 8, 2014
@mhvk
Can you state a line for the code snippet from pprint.py? I cannot find it in my file here.
astrofrog commentedon Sep 8, 2014
@cherti - we need to support the
%syntax as well as the{...}syntax to remain backward compatible unfortunately. Any solution we come up with has to be backward-compatible. If it's not possible to catch all cases then at least making the error message more explicit will help.cherti commentedon Sep 8, 2014
Ah,
'%9.5f'only works forformat % float()and{9.5f}only works forformat.format(float())?In this case, we of course have to keep both for backwards compatibility. Are there more ways other than these two that we must support?
2 remaining items
astrofrog commentedon Sep 8, 2014
@cherti - great, and just for info, you can run all the table tests with:
this runs all the tests in astropy.table. They should all pass, except if they are checking the content/type of the exception you are raising (in which case it's ok if they change of course).
mhvk commentedon Sep 8, 2014
@cherti - the snippet I gave is from the latest development version; it includes #2898.
I do like the idea of (also) testing the format upon setting it, rather than during the printing phase.
cherti commentedon Oct 26, 2014
submitted pull request here:
#3055
embray commentedon Jul 31, 2015
I wonder if this still needs fixing, since the previous attempt to fix it has been abandoned.
astrofrog commentedon Jul 31, 2015
@embray - I think it still needs fixing
cherti commentedon Aug 4, 2015
Is this PR[0] entirely abandoned or still to be merged? I think this issue would be fixed by that PR.
[0] #3261
embray commentedon Aug 18, 2015
@cherti I have about a billion open PRs, and just forgot about #3261 completely, but thanks for pointing it out. I'll see if I can rebase it and get that going again.