Preserve Float Subclass
Numbers are cast to float before format()ing, which prevents custom formatting logic provided by subclasses. tabulate/__init__.py#L1350
Example
from tabulate import tabulate
from prefixed import Float
tabulate([[Float(1)]], floatfmt='h')
ValueError: Unknown format code 'h' for object of type 'float'
Background
Proposals to extend the built-in python formats have been rejected, because subclasses are intended to satisfy this use case.
https://discuss.python.org/t/new-format-specifiers-for-string-formatting-of-floats-with-si-and-iec-prefixes/26914/6
This regression was introduced in version 0.2. 5115cea/tabulate.py#L154
Related to https://github.com/astanin/python-tabulate/issues/297.
Proposal
Only apply the float cast in _format() to strings.
Edit: And decimal align any string by . or \d([^d]) in _afterpoint().
After patching that I also found that the default decimal alignment does not behave as expected. _afterpoint() requires the string to pass _isnumber(), which can fail for custom formats. I would propose removing this restriction and allowing arbitrary strings to be aligned by decimal.
I also had to generalize the e position logic in _afterpoint() to get custom suffixes aligned correctly without decimal points. Aligning on the rightmost digit of the string regardless of the next character aligns prefixes, suffixes, and sandwiches 🥪 (like e).
f0 Q gain Av BW C1 R1 R2 R3
---- ---- ------ ---- ---- ---- ----- ---- ------
700 2 10 3.16 350 100n 1.44k 940 9.09k
701 2 9.64 3.03 350 100n 1.5k 910 9.1k
728 2.52 13.2 4.58 289 100n 1.2k 680 11k
719 2.71 12 4 265 100n 1.5k 560 12k
https://github.com/astanin/python-tabulate/compare/master...deckar01:python-tabulate:361-custom-format
https://pypi.org/project/deckar01-tabulate/0.10.2/