Skip to content

Unsupported format string passed to mpf.__format__ #915

Closed

Description

@ant1sir
$ python
Python 3.12.3 (main, Feb  4 2025, 14:48:35) [GCC 13.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import mpmath
>>> mpmath.__version__
'1.3.0'
>>> val = mpmath.mpf('0.1')
>>> f"{val:.016f}"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported format string passed to mpf.__format__
>>> 

Can you fix this bug?

Activity

  1. skirpichev commented on Feb 27, 2025

    @skirpichev
    Collaborator

    Could you reproduce this bug on development version of the mpmath?

  2. added
    pendingThe issue will be closed if no feedback is provided
    on Feb 27, 2025
  3. WarrenWeckesser commented on Feb 27, 2025

    @WarrenWeckesser
    Contributor

    Here's what I get with the development version and Python 3.12.8:

    In [1]: import mpmath
    
    In [2]: mpmath.__version__
    Out[2]: '1.4.0a5.dev2+g5e57cb8'
    
    In [3]: val = mpmath.mpf('0.1')
    
    In [4]: f"{val:.016f}"
    ---------------------------------------------------------------------------
    ValueError                                Traceback (most recent call last)
    Cell In[4], line 1
    ----> 1 f"{val:.016f}"
    
    File ~/repos/git/forks/mpmath/mpmath/ctx_mp_python.py:428, in _mpf.__format__(s, format_spec)
        360 """
        361 ``mpf`` objects allow for formatting similar to Python floats:
        362 
       (...)
        424 
        425 """
        427 _, _, (prec, _) = s._ctxdata
    --> 428 return format_mpf(s._mpf_, format_spec, prec)
    
    File ~/repos/git/forks/mpmath/mpmath/libmp/libmpf.py:1804, in format_mpf(num, format_spec, prec)
       1803 def format_mpf(num, format_spec, prec):
    -> 1804     format_dict = read_format_spec(format_spec)
       1806     sign, digits = format_digits(num, format_dict, prec)
       1808     nchars = len(digits) + len(sign)
    
    File ~/repos/git/forks/mpmath/mpmath/libmp/libmpf.py:1485, in read_format_spec(format_spec)
       1483         format_dict['precision'] = 6
       1484 else:
    -> 1485     raise ValueError("Invalid format specifier '{}'".format(format_spec))
       1487 return format_dict
    
    ValueError: Invalid format specifier '.016f'
    

    The format works with a Python float:

    In [5]: val = 0.1
    
    In [6]: f"{val:.016f}"
    Out[6]: '0.1000000000000000'
    
  4. ant1sir commented on Feb 27, 2025

    @ant1sir
    Author

    Are you satisfied with Warren's answer?

  5. added
    bugan unexpected problem or unintended behavior
    and removed
    pendingThe issue will be closed if no feedback is provided
    on Feb 28, 2025
  6. self-assigned this
    on Feb 28, 2025
  7. added this to the 1.4 milestone on Feb 28, 2025
  8. added a commit that references this issue on Feb 28, 2025
    70dae90
  9. skirpichev commented on Feb 28, 2025

    @skirpichev
    Collaborator

    @WarrenWeckesser, thanks (I asked from phone). PR is ready: #916

  10. skirpichev commented on Feb 28, 2025

    @skirpichev
    Collaborator

    But see python/cpython#130662

    Maybe we shouldn't replicate this Python feature.

  11. added 3 commits that reference this issue on Feb 28, 2025
    375e293
    c1197d6
    849e185
  12. ant1sir commented on Feb 28, 2025

    @ant1sir
    Author
    1. In the realm of arbitrary precision numbers, I think there is no such thing as meaningless leading or trailing zero.
      A leading or trailing zero is supposed to be a correctly computed digit.
      For example, 1.000000000000000 is different from 1.000000000000000123463563456.
    2. Presentation is important for readability and clarity.
      Leading or trailing zeros can be used to justify a table of numbers left or right respectively.
      For example, to me the following table could be improved.
      +---------+--------------------+
      | float | mpf |
      +---------+--------------------+
      | -1.00 | 0.3678794411714423 |
      | -0.75 | 0.4723665527410147 |
      | -0.50 | 0.6065306597126334 |
      | -0.25 | 0.7788007830714049 |
      | 0.00 | 1.000000000000000 |
      | 0.25 | 1.284025416687741 |
      | 0.50 | 1.648721270700128 |
      | 0.75 | 2.117000016612675 |
      +---------+--------------------+
      Should be
      +---------+--------------------+
      | float | mpf |
      +---------+--------------------+
      | -1.00 | 0.3678794411714423 |
      | -0.75 | 0.4723665527410147 |
      | -0.50 | 0.6065306597126334 |
      | -0.25 | 0.7788007830714049 |
      | 0.00 | 1.0000000000000000 |
      | 0.25 | 1.284025416687741X |
      | 0.50 | 1.648721270700128Y |
      | 0.75 | 2.117000016612675Z |
      +---------+--------------------+
      where X, Y, and Y are the relevant digits in each row.
  13. 9 remaining items

  14. skirpichev commented on Mar 4, 2025

    @skirpichev
    Collaborator

    Reopened, until python/cpython#130662 will be fixed. Meanwhile 849e185 was reverted in #936.

  15. removed their assignment
    on Apr 6, 2025
  16. removed this from the 1.4 milestone on Apr 13, 2025
  17. added this to the 1.4 milestone on Jun 2, 2025
  18. self-assigned this
    on Jun 3, 2025
  19. added a commit that references this issue on Jun 3, 2025
    08a7a2f
  20. removed their assignment
    on Jun 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugan unexpected problem or unintended behavior

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions