[Python-ideas] Re: add !p to pprint.pformat() in str.format() an f-strings

2020-07-25 Thread Serhiy Storchaka

16.07.20 07:34, Charles Machalow пише:

Right now in str.format(), we have !s, !r, and !a to allow us to call str(), 
repr(), and ascii() respectively on the given expression.

I'm proposing that we add a !p conversion to have pprint.pformat() be called to 
convert the given expression to a 'pretty' string.


I do not think it is a good idea. pprint is a kind of toy module. It 
supports only limited set of standard collection classes and is not 
extensible. It does not even know anything about named tuples and 
dataclasses. It does not support multiline reprs. It is inconsistent in 
sorting set items. Its output format looks strange and is not PEP 8 
compatible. It requires specifying the width.

___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/UPYUJEHSYWGVJJLVDCGV4G222GH763MT/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: add !p to pprint.pformat() in str.format() an f-strings

2020-07-24 Thread Jelle Zijlstra
El mar., 21 jul. 2020 a las 17:27, Guido van Rossum ()
escribió:

> A philosophical problem with this is proposal is that it takes a notation
> that is processed by the bytecode compiler and makes it dependent on user
> code to be imported from the stdlib. We only do that in rare cases — IIRC
> the only other case is ‘import’ calling ‘__import__()’.
>
> There's also `__build_class__`, which gets called during class creation.
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/ZYXD5PWFMPIDP5BOFOD2OYCZY6GRAC7A/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: add !p to pprint.pformat() in str.format() an f-strings

2020-07-21 Thread Eric V. Smith


On 7/21/2020 7:36 PM, Rob Cliffe wrote:



On 21/07/2020 21:00, Eric V. Smith wrote:

f-strings call PyObject_Repr directly, without going through builtins.

If we added !p as described here, we'd need to call import every time 
we execute !p, because we don't know if it's been imported yet. At 
runtime, we'd call "pformat()" via sys.modules['pprint'] after the 
import. That could of course be monkey patched.


But I'm still not sure this is a good idea. I can't find the issue on 
bpo where this was mentioned, but some of the issues that spring to 
mind are:


- Most pprint output is multi-line. Is that a good thing with f-strings?
Why not?  f-strings (as of course you know) can already contain 
multiple lines, even if the usage is not frequent.  ISTM this 
objection has no substance.
But with pprint, it's not unusual, it's common. That feels qualitatively 
different to me.


- How to handle parameters to pprint.pformat()?
This doesn't seem insurmountable.  IIUC the relevant parameters are 
indent, width, depth, compact, sort_dicts.  They could be added after 
`!p` separated by some separator - let's say comma for the sake of 
argument - with absent parameters taking the default values.  So e.g.

    !p2        # means indent=2
    !p,60    # means width=60.  Etc.
If the pformat API were ever changed, adding extra parameters would 
not cause backward incompatibility.  Removing parameters or changing 
their order would, but both seem extremely unlikely to me (YMMV) and I 
expect users of !p could live with that.


I can't support embedding all of these params in the format string. 
Format strings are hard enough to understand as it is.


At this point, you'd be better off with calling pprint.pformat() 
explicitely.


f'value={pprint.pformat(value, indent=2, width=60)}'

I might be able to get behind sort of a "pprint context", like a decimal 
context, with a context manager to specify it.




- Is pprint.pformat() extensible enough? Can an object control how it 
is pretty printed?
I'm not sure if I fully understand this objection.  It seems to be 
suggesting a deficiency in the current pprint.pformat.  The proposal 
would not change anything here.
I'm not super familiar with pprint, but IIRC an object can't specify its 
own formatting, can it? If I wrote a dict-like object, not inheriting 
from dict, and I wanted to control how it's pprint'ed, can I do that?


I'm sure there are others.

Could you specify.?

I'll try and find the issues to see what else Raymond and I already wrote.


I'm not saying I'm +1 on the proposal.  Just that there don't seem to 
be any insurmountable obstacles to it.  My greatest unease is an 
implicit import.  Are there other areas of Python where this happens?


I'm not sure. But this part doesn't really bother me. Maybe it should, 
and it would be another reason not to move forward!


Eric

As I've said before, I'd prefer a revamped "pretty formatting" 
library, probably using singledispatch for extensibility. But even 
with that, issues like parameterizing the output remain.


Eric



On Tue, Jul 21, 2020 at 8:04 PM Rob Cliffe via Python-ideas 
mailto:python-ideas@python.org>> wrote:


That seems like a nice idea, but what would happen if pprint had
not
been imported?  NameError?
Rob Cliffe

On 16/07/2020 05:34, Charles Machalow wrote:
> Right now in str.format(), we have !s, !r, and !a to allow us
to call str(), repr(), and ascii() respectively on the given
expression.
>
> I'm proposing that we add a !p conversion to have
pprint.pformat() be called to convert the given expression to a
'pretty' string.
>
> Calling
> ```
> print(f"My dict: {d!p}")
> ```
>
> is a lot more concise than:
>
> ```
> import pprint
> print(f"My dict: {pprint.pformat(d)}")
> ```
>
> We may even be able to have a static attribute stored to
change the various default kwargs of pprint.pformat().


___
Python-ideas mailing list --python-ideas@python.org
To unsubscribe send an email topython-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived 
athttps://mail.python.org/archives/list/python-ideas@python.org/message/UUZLIVS67PU552IMRNP6JBNC5LHACVQ2/
Code of Conduct:http://python.org/psf/codeofconduct/


___
Python-ideas mailing list --python-ideas@python.org
To unsubscribe send an email topython-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived 
athttps://mail.python.org/archives/list/python-ideas@python.org/message/I5PLO5FUYMX45EXEENZF56PAPYJBC7QM/
Code of Conduct:http://python.org/psf/codeofconduct/


___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org

[Python-ideas] Re: add !p to pprint.pformat() in str.format() an f-strings

2020-07-21 Thread Guido van Rossum
A philosophical problem with this is proposal is that it takes a notation
that is processed by the bytecode compiler and makes it dependent on user
code to be imported from the stdlib. We only do that in rare cases — IIRC
the only other case is ‘import’ calling ‘__import__()’. This reversal of
dependency is problematic because it means that core, built-in
functionality could be broken by something a user could inadvertently
change in the file system.

Another problem I have is that pprint is kind of a second-class citizen.
It’s not all that much cared for by core devs I believe, and you can’t
extend it by adding a special method to a class — you have to subclass the
PrettyPrinter class.

All in all I don’t think this is a direction we should take.

— Guido
-- 
--Guido (mobile)
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/ULY3VUSNDLOAUU7DASM7ILXD5ZZNZH6T/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: add !p to pprint.pformat() in str.format() an f-strings

2020-07-21 Thread Rob Cliffe via Python-ideas



On 21/07/2020 21:00, Eric V. Smith wrote:

On 7/21/2020 2:54 PM, Alex Hall wrote:

It should do the import for you. As was proposed:

```
print(f"My dict: {d!p}")
```

should be equivalent to

```
import pprint
print(f"My dict: {pprint.pformat(d)}")
```

The import should happen in the same scope. Modifying the global 
namespace could be confusing.


A quick test shows that adding `import pprint` to 
`pprint.pformat({1:2})` slows things down by about 4% on my machine, 
which I don't think is worth being concerned about. If the dict has 
100 elements, the difference becomes too small to measure.
My first instinct is that monkeypatching the pprint module should 
affect !p, but I see that monkeypatching builtins.repr doesn't affect 
!r, so I'm not sure.

f-strings call PyObject_Repr directly, without going through builtins.

If we added !p as described here, we'd need to call import every time 
we execute !p, because we don't know if it's been imported yet. At 
runtime, we'd call "pformat()" via sys.modules['pprint'] after the 
import. That could of course be monkey patched.


But I'm still not sure this is a good idea. I can't find the issue on 
bpo where this was mentioned, but some of the issues that spring to 
mind are:


- Most pprint output is multi-line. Is that a good thing with f-strings?
Why not?  f-strings (as of course you know) can already contain multiple 
lines, even if the usage is not frequent.  ISTM this objection has no 
substance.


- How to handle parameters to pprint.pformat()?
This doesn't seem insurmountable.  IIUC the relevant parameters are 
indent, width, depth, compact, sort_dicts.  They could be added after 
`!p` separated by some separator - let's say comma for the sake of 
argument - with absent parameters taking the default values.  So e.g.

    !p2        # means indent=2
    !p,60    # means width=60.  Etc.
If the pformat API were ever changed, adding extra parameters would not 
cause backward incompatibility.  Removing parameters or changing their 
order would, but both seem extremely unlikely to me (YMMV) and I expect 
users of !p could live with that.


- Is pprint.pformat() extensible enough? Can an object control how it 
is pretty printed?
I'm not sure if I fully understand this objection.  It seems to be 
suggesting a deficiency in the current pprint.pformat.  The proposal 
would not change anything here.


I'm sure there are others.

Could you specify.?

I'm not saying I'm +1 on the proposal.  Just that there don't seem to be 
any insurmountable obstacles to it.  My greatest unease is an implicit 
import.  Are there other areas of Python where this happens?
As I've said before, I'd prefer a revamped "pretty formatting" 
library, probably using singledispatch for extensibility. But even 
with that, issues like parameterizing the output remain.


Eric



On Tue, Jul 21, 2020 at 8:04 PM Rob Cliffe via Python-ideas 
mailto:python-ideas@python.org>> wrote:


That seems like a nice idea, but what would happen if pprint had not
been imported?  NameError?
Rob Cliffe

On 16/07/2020 05:34, Charles Machalow wrote:
> Right now in str.format(), we have !s, !r, and !a to allow us
to call str(), repr(), and ascii() respectively on the given
expression.
>
> I'm proposing that we add a !p conversion to have
pprint.pformat() be called to convert the given expression to a
'pretty' string.
>
> Calling
> ```
> print(f"My dict: {d!p}")
> ```
>
> is a lot more concise than:
>
> ```
> import pprint
> print(f"My dict: {pprint.pformat(d)}")
> ```
>
> We may even be able to have a static attribute stored to change
the various default kwargs of pprint.pformat().


___
Python-ideas mailing list --python-ideas@python.org
To unsubscribe send an email topython-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived 
athttps://mail.python.org/archives/list/python-ideas@python.org/message/UUZLIVS67PU552IMRNP6JBNC5LHACVQ2/
Code of Conduct:http://python.org/psf/codeofconduct/


___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/I5PLO5FUYMX45EXEENZF56PAPYJBC7QM/
Code of Conduct: http://python.org/psf/codeofconduct/


___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/R6RELE3VBBNWW7CN3H6CFFDXIITUQINJ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: add !p to pprint.pformat() in str.format() an f-strings

2020-07-21 Thread Eric V. Smith


On 7/21/2020 4:59 PM, Rob Cliffe via Python-ideas wrote:



On 21/07/2020 19:54, Alex Hall wrote:

It should do the import for you. As was proposed:

```
print(f"My dict: {d!p}")
```

should be equivalent to

```
import pprint
print(f"My dict: {pprint.pformat(d)}")

You're right, I didn't read it carefully enough.

```

The import should happen in the same scope. Modifying the global 
namespace could be confusing.

You're right again.  It could still break code like this:

from pprint import pprint
...
def myfunc():
    # Code modified to use !p here
    pprint(something) # Oops, pprint is now a module, not a function

unless the import could actually be local to the f-string itself, not 
the surrounding scope
(perhaps similar to the way a list comprehension is implemented as a 
function with its own scope).


I don't totally understand these matters, so I may have got something 
wrong.


You don't need to go through globals, locals, etc. You can do the 
equivalent of:


>>> import pprint
>>> import sys
>>> pprint = 3
>>> sys.modules['pprint'].pprint('hello')
'hello'

Except that "sys" wouldn't be a local/global, either. But of course you 
could still monkeypatch pprint and break this code. There are a million 
ways to break code, I wouldn't worry about how the interpreter would get 
access to the pprint module. Instead, I'd worry about the more troubling 
issues which I raised in an earlier email. Those are the ones that are 
likely to stop this proposal.


Eric
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/TBSKYG5PULPIQGZYA5AEHVJEQUZMV7JU/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: add !p to pprint.pformat() in str.format() an f-strings

2020-07-21 Thread Rob Cliffe via Python-ideas



On 21/07/2020 19:54, Alex Hall wrote:

It should do the import for you. As was proposed:

```
print(f"My dict: {d!p}")
```

should be equivalent to

```
import pprint
print(f"My dict: {pprint.pformat(d)}")

You're right, I didn't read it carefully enough.

```

The import should happen in the same scope. Modifying the global 
namespace could be confusing.

You're right again.  It could still break code like this:

from pprint import pprint
...
def myfunc():
    # Code modified to use !p here
    pprint(something) # Oops, pprint is now a module, not a function

unless the import could actually be local to the f-string itself, not 
the surrounding scope
(perhaps similar to the way a list comprehension is implemented as a 
function with its own scope).


I don't totally understand these matters, so I may have got something wrong.
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/44CJYSVFRU4K5XG54T2TMDCMVBHEJRCQ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: add !p to pprint.pformat() in str.format() an f-strings

2020-07-21 Thread Eric V. Smith

On 7/21/2020 2:54 PM, Alex Hall wrote:

It should do the import for you. As was proposed:

```
print(f"My dict: {d!p}")
```

should be equivalent to

```
import pprint
print(f"My dict: {pprint.pformat(d)}")
```

The import should happen in the same scope. Modifying the global 
namespace could be confusing.


A quick test shows that adding `import pprint` to 
`pprint.pformat({1:2})` slows things down by about 4% on my machine, 
which I don't think is worth being concerned about. If the dict has 
100 elements, the difference becomes too small to measure.
My first instinct is that monkeypatching the pprint module should 
affect !p, but I see that monkeypatching builtins.repr doesn't affect 
!r, so I'm not sure.

f-strings call PyObject_Repr directly, without going through builtins.

If we added !p as described here, we'd need to call import every time we 
execute !p, because we don't know if it's been imported yet. At runtime, 
we'd call "pformat()" via sys.modules['pprint'] after the import. That 
could of course be monkey patched.


But I'm still not sure this is a good idea. I can't find the issue on 
bpo where this was mentioned, but some of the issues that spring to mind 
are:


- Most pprint output is multi-line. Is that a good thing with f-strings?

- How to handle parameters to pprint.pformat()?

- Is pprint.pformat() extensible enough? Can an object control how it is 
pretty printed?


I'm sure there are others. As I've said before, I'd prefer a revamped 
"pretty formatting" library, probably using singledispatch for 
extensibility. But even with that, issues like parameterizing the output 
remain.


Eric



On Tue, Jul 21, 2020 at 8:04 PM Rob Cliffe via Python-ideas 
mailto:python-ideas@python.org>> wrote:


That seems like a nice idea, but what would happen if pprint had not
been imported?  NameError?
Rob Cliffe

On 16/07/2020 05:34, Charles Machalow wrote:
> Right now in str.format(), we have !s, !r, and !a to allow us to
call str(), repr(), and ascii() respectively on the given expression.
>
> I'm proposing that we add a !p conversion to have
pprint.pformat() be called to convert the given expression to a
'pretty' string.
>
> Calling
> ```
> print(f"My dict: {d!p}")
> ```
>
> is a lot more concise than:
>
> ```
> import pprint
> print(f"My dict: {pprint.pformat(d)}")
> ```
>
> We may even be able to have a static attribute stored to change
the various default kwargs of pprint.pformat().


___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/UUZLIVS67PU552IMRNP6JBNC5LHACVQ2/
Code of Conduct: http://python.org/psf/codeofconduct/
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/I5PLO5FUYMX45EXEENZF56PAPYJBC7QM/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: add !p to pprint.pformat() in str.format() an f-strings

2020-07-21 Thread Alex Hall
It should do the import for you. As was proposed:

```
print(f"My dict: {d!p}")
```

should be equivalent to

```
import pprint
print(f"My dict: {pprint.pformat(d)}")
```

The import should happen in the same scope. Modifying the global namespace
could be confusing.

A quick test shows that adding `import pprint` to `pprint.pformat({1:2})`
slows things down by about 4% on my machine, which I don't think is worth
being concerned about. If the dict has 100 elements, the difference becomes
too small to measure.

My first instinct is that monkeypatching the pprint module should affect
!p, but I see that monkeypatching builtins.repr doesn't affect !r, so I'm
not sure.

On Tue, Jul 21, 2020 at 8:04 PM Rob Cliffe via Python-ideas <
python-ideas@python.org> wrote:

> That seems like a nice idea, but what would happen if pprint had not
> been imported?  NameError?
> Rob Cliffe
>
> On 16/07/2020 05:34, Charles Machalow wrote:
> > Right now in str.format(), we have !s, !r, and !a to allow us to call
> str(), repr(), and ascii() respectively on the given expression.
> >
> > I'm proposing that we add a !p conversion to have pprint.pformat() be
> called to convert the given expression to a 'pretty' string.
> >
> > Calling
> > ```
> > print(f"My dict: {d!p}")
> > ```
> >
> > is a lot more concise than:
> >
> > ```
> > import pprint
> > print(f"My dict: {pprint.pformat(d)}")
> > ```
> >
> > We may even be able to have a static attribute stored to change the
> various default kwargs of pprint.pformat().
>
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/UUZLIVS67PU552IMRNP6JBNC5LHACVQ2/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: add !p to pprint.pformat() in str.format() an f-strings

2020-07-21 Thread Rob Cliffe via Python-ideas
That seems like a nice idea, but what would happen if pprint had not 
been imported?  NameError?

Rob Cliffe

On 16/07/2020 05:34, Charles Machalow wrote:

Right now in str.format(), we have !s, !r, and !a to allow us to call str(), 
repr(), and ascii() respectively on the given expression.

I'm proposing that we add a !p conversion to have pprint.pformat() be called to 
convert the given expression to a 'pretty' string.

Calling
```
print(f"My dict: {d!p}")
```

is a lot more concise than:

```
import pprint
print(f"My dict: {pprint.pformat(d)}")
```

We may even be able to have a static attribute stored to change the various 
default kwargs of pprint.pformat().
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/LNQEA6IYBS5B7NMGC3P4JFPCSR33W4C6/
Code of Conduct: http://python.org/psf/codeofconduct/

___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/YWGNW5LVGUIN5ZGAQNKR325VOEYD454L/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: add !p to pprint.pformat() in str.format() an f-strings

2020-07-16 Thread Alex Hall
+1. I imagine I would use this fairly often, particularly in debugging or
interactive sessions. It goes well with the magic `=` in f-strings, e.g.
`print(f"{d=!p}")`.

It's more useful than the others because the manual way requires an import.

It's easy to learn, easy to remember, and fits naturally with the rest.

On Thu, Jul 16, 2020 at 6:43 AM Charles Machalow  wrote:

> Right now in str.format(), we have !s, !r, and !a to allow us to call
> str(), repr(), and ascii() respectively on the given expression.
>
> I'm proposing that we add a !p conversion to have pprint.pformat() be
> called to convert the given expression to a 'pretty' string.
>
> Calling
> ```
> print(f"My dict: {d!p}")
> ```
>
> is a lot more concise than:
>
> ```
> import pprint
> print(f"My dict: {pprint.pformat(d)}")
> ```
>
> We may even be able to have a static attribute stored to change the
> various default kwargs of pprint.pformat().
> ___
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@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/LNQEA6IYBS5B7NMGC3P4JFPCSR33W4C6/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/3MNK735IAGLA62I5AM37VDGXH2OFB26P/
Code of Conduct: http://python.org/psf/codeofconduct/