Skip to content

str and repr with pretty=True #921

@skirpichev

Description

@skirpichev

Currently we have following implementations:

def __repr__(s):
if s.context.pretty:
return str(s)
return "mpf('%s')" % to_str(s._mpf_, s.context._repr_digits)
def __str__(s): return to_str(s._mpf_, s.context._str_digits)

_repr_digits digits - enough to ensure that eval-repr round-trip will work. But that's not guarantied for str() output, here is an example:

>>> from mpmath import *
>>> mp.prec=128
>>> r = mpf('0.5269770260116541560356928630345245874084'); r
mpf('0.5269770260116541560356928630345245874084')
>>> str(r)
'0.52697702601165415603569286303452458741'
>>> eval(repr(r)) == r
True
>>> mpf(str(r)) == r
False

Unfortunately, we use str()-like output for repr() too, if mp.pretty is enabled. That's especially odd in the CLI interface:

$ python -m mpmath --no-ipython --prec 128 --pretty
>>> 0.5269770260116541560356928630345245874084
0.52697702601165415603569286303452458741
>>> 0.52697702601165415603569286303452458741
0.52697702601165415603569286303452458741

I suggest treat this as a bug and change repr() to always use _repr_digits digits. You should be able to recreate value exactly from the repr() output.

Unfortunately, that breaks a lot of doctests (but almost no tests, only some in test_cli.py). Another option might be a new context flag to control this behavior.

BTW, we also might think about repr() vs str() difference, do we need this at all? E.g. neither CPython nor gmpy2 have different conventions for repr() and str() (except for printing mpfr prefix in the gmpy2). Instead, since 3.1 the CPython uses a shortest decimal representative for the given number. Maybe we should do same? CPython issue: python/cpython#45921

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