- CPython has __str__ and __repr__, IPython has obj._repr_fmt_(), MarkupSafe has obj.__html__(), https://github.com/tommikaikkonen/prettyprinter has @register_pretty

Neither __str__ nor __repr__ have any round-trip guarantee/expectation (they're not suitable for serialization/deserialization // marshal/unmarshal / dump/load).

Monkeypatching the __str__ or __repr__ of a builtin is generally undesirable because that's global and not thread safe.

Could you use the locale module for this number formatting regional preference (inf as unicode inf)?
https://docs.python.org/3/library/locale.html
LC_INFINITY=unicode

https://docs.python.org/3/library/locale.html#locale.LC_NUMERIC
> Locale category for formatting numbers. The functions format(), atoi(), atof() and str() of the locale module are affected by that category. All other numeric formatting operations are not affected.


... From "[Python-ideas] Draft PEP on string interpolation" (=> f-strings) https://groups.google.com/d/msg/python-ideas/6tfm3e2UtDU/euvlY6uWAwAJ :

```quote

* Does it always just read LC_ALL='utf8' (or where do I specify that global/thread/frame-local?)
[...]

Jinja2 uses MarkupSafe, with a class named Markup:

    class Markup():
        def __html__()
        def __html_format__()

IPython can display objects with _repr_fmt_() callables,
which TBH I prefer because it's not name mangled
and so more easily testable. [3,4]

Existing IPython rich display methods [5,6,7,8]

    _mime_map = dict(
        _repr_png_="image/png",
        _repr_jpeg_="image/jpeg",
        _repr_svg_="image/svg+xml",
        _repr_html_="text/html",
        _repr_json_="application/json",
        _repr_javascript_="application/javascript",
    )

    # _repr_latex_ = "text/latex"
    # _repr_retina_ = "image/png"


Suggested IPython methods

- [ ] _repr_shell_
  - [ ] single_quote_shell_escape
  - [ ] double_quote_shell_escape
- [ ] _repr_sql_ (*NOTE: SQL variants, otherworldly-escaping dependency / newb errors)


[1] https://pypi.python.org/pypi/MarkupSafe
[2] https://github.com/mitsuhiko/markupsafe
[3] https://ipython.org/ipython-doc/dev/config/integrating.html
[4] https://ipython.org/ipython-doc/dev/config/integrating.html#rich-display
[5] https://github.com/ipython/ipython/blob/master/IPython/utils/capture.py
[6] https://github.com/ipython/ipython/blob/master/IPython/utils/tests/test_capture.py
[7] https://github.com/ipython/ipython/blob/master/IPython/core/display.py
[8] https://github.com/ipython/ipython/blob/master/IPython/core/tests/test_display.py


* IPython: _repr_fmt_()
* MarkupSafe: __html__()

```

On Sun, Mar 15, 2020 at 11:00 PM Steven D'Aprano <steve@pearwood.info> wrote:
On Sun, Mar 15, 2020 at 06:27:43PM -0700, Christopher Barker wrote:

> Anyway, Python now has two different ways to "turn this into a string":,
> __str__ and __repr__. I think the OP is suggesting a third, for "pretty
> version". But then maybe folks would want a fourth or fifth, or .....
>
> maybe we should, instead, think about updating the __str__ for standard
> types.
>
> Is there any guarantee (or even string expectation) that the __str__ for an
> object won't change?

I think there is a strong expectation, even if there's no formal
guarantee, that the str and repr of builtins and stdlib objects will be
reasonably stable. If they change, it will break doctests and make a
huge amount of documentation, blogposts, tutorials, books etc out of
date.

That's not to say that we can't do it, just that we shouldn't be too
flippant about it. A few releases back (3.5? 3.4? I forget...) we
changed the default float repr:

    python2.5 -c "print 2.0/3"
    0.666666666667
    python3.5 -c "print(2.0/3)"
    0.6666666666666666

One advantage of that is that some values are displayed with the nearest
human-readable exact value, instead the actual value.

One disadvantage of that is that some values are displayed with the
nearest human-readable exact value, instead of the actual value :-)


> I've always wondered why the standard str(some object) wasn't pretty to
> begin with.

Define "pretty". The main reason I don't use the pprint module at the
moment is that it formats things like lists into a single long, thin
column which is *less* attractive than the unformatted list:

    py> pprint.pprint(list(range(200)))
    [0,
     1,
     2,
     3,
     ...
     198,
     199]

I've inserted the ellipsis for brevity, the real output is 200 rows
tall.

When it comes to floats, depending on what I'm doing, I may consider any
of these to be "pretty":

* the minimum number of digits which are sufficient to round trip;
* the mathematically exact value, which could take a lot of digits;
* some short number of digits, say, 5, that is "close enough".


--
Steven
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-leave@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/IC6VE64XCU52S3LKYHESOORTWIHETMP3/
Code of Conduct: http://python.org/psf/codeofconduct/