[Python-ideas] Re: Allowing `str.format` to format one or more parameters instead of all parameters

2023-04-28 Thread Greg Ewing

On 29/04/23 6:59 am, Bruce Leban wrote:
To take this further, suppose you write 'Hello {username} from 
{company}'.format(userdata).format(companydata) where the user has set 
their name to "Dr. {secret} Evil" where {secret} is something in 
companydata that should not be exposed.


More generally, a format string should be treated as code, and
doing anything that could result in untrusted user data being
treated as code is a Bad Idea.

--
Greg
___
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/55PB23XWOLEGM7OWEGPH7ZVAK7MWRIFE/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Allowing `str.format` to format one or more parameters instead of all parameters

2023-04-28 Thread Bruce Leban
On Tue, Apr 25, 2023 at 6:16 PM Joao S. O. Bueno  wrote:

>
> Worst case scenario, one goes from one non-running program to a running
> program producing partially incorrect output. Any legacy code that was not
> working in the first place, is obviously, clearly, not critical for anyone,
> otherwise it would have been fixed already.
>

Worst case scenario: use of this feature introduces bugs. For example,
security holes.

Generally, formatting and parsing are not idempotent and you should not
reformat or reparse already processed strings. See
http://google-gruyere.appspot.com/ to learn more about the pitfalls and in
particular
http://google-gruyere.appspot.com/part5#5__information_disclosure_bug_3


On Fri, Apr 28, 2023 at 8:49 AM MRAB  wrote:

>
> What happens if you do '{open}...{close}'.partial_format(open='{close}'?
> You get '{close}...{close}', and you're going to have a problem using
> that as a format string and replacing only the second '{close}'.
>

To take this further, suppose you write 'Hello {username} from
{company}'.format(userdata).format(companydata) where the user has set
their name to "Dr. {secret} Evil" where {secret} is something in companydata
that should not be exposed. The presence of this bug is going to be very
hard to find.

This seems like an obvious case of a non-solution to a non-problem that's
actually worse than no solution at all.

--- Bruce
___
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/M3QBMY22VKGOTDXMBBA6ED54ETUVFNDH/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Allowing `str.format` to format one or more parameters instead of all parameters

2023-04-28 Thread Matthias Görgens
I suggest you guys implement this as a library, if you want it.

You don't need to make your `partial_format` a method, it can just be a
normal function.

There's no need to fiddle with the built-in string or format function for
this.

On Fri, 28 Apr 2023, 22:27 Matsuoka Takuo,  wrote:

> What if it's done not by format method but by a separete method, say,
> format_partially or something?  The method is different from format
> also in that it should leave "{{" and "}}" unaltered.
>
> On Fri, 28 Apr 2023 at 00:05, Matthias Görgens
>  wrote:
> >
> > Does it have any use case that's not already served by functools.partial?
>
> I guess you mean given
>
>   partially_formatted_string = unformatted_string.format(color="blue")
>
> that
>
>   partially_formatted_string.format
>
> would be equivalent to
>
>   partial(unformatted_string.format, color="blue")
>
> However, I think a partially formatted string can help since it will
> have other methods than format as well.  For instance, given
>
>   unformatted_string = '{color}{text}'
>
> doing the following thing only with functools.partial could require
> more care than you would be willing to give.
>
>   string = (unformatted_string.format(color="blue")
> + unformatted_string
> ).format(text="Spanish", color="red")
>
> (One of the easiest ways might be
>
> ```
> from functools import partial
> from operator import call
>
> format_ = unformatted_string.format
> string = "".join(map(partial(call, text="Spanish"),
>  (partial(format_, color="blue"),
>   partial(format_, color="red"), )))
> ```
>
> However, note the following, more straight-forward code doesn't work:
>
> ```
> string = "".join(map(partial(call, text="Spanish", color="red"),
>  (partial(format_, color="blue"),
>   format_, )))
> ```
> )
>
> Now, how about this?
>
> ```
> format_ = '{a}{b}{c}'.format
>
> string = ((format_(a=a0) + format_(b=b0)).format(c=c0)
>   + (format_(a=a1) + format_(c=c1)).format(b=b1)
>   + (format_(b=b2) + format_(c=c2)).format(a=a2)
>   ).format(a=a3, b=b3, c=c3)
> ```
>
> (For instance, the following code fails:
>
> ```
> from itertools import chain
>
> string = "".join(map(partial(call, a=a3, b=b3, c=c3),
>  chain.from_iterable(
>  map(map,
>  (partial(partial, c=c0),
>   partial(partial, b=b1),
>   partial(partial, a=a2), ),
>  ((partial(format_, a=a0),
>partial(format_, b=b0), ),
>   (partial(format_, a=a1),
>partial(format_, c=c1), ),
>   (partial(format_, b=b2),
>partial(format_, c=c2), ), ))
>  )))
> ```
> )
>
> Best regards,
> Takuo Matsuoka
> ___
> 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/K5RPB4XOQROYTWQHI5A4DVTKB2RNY6OC/
> 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/BOTC5QLWI462NSNQCP6UT3FJ24Y2PMZS/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Allowing `str.format` to format one or more parameters instead of all parameters

2023-04-28 Thread MRAB

On 2023-04-28 15:25, Matsuoka Takuo wrote:

What if it's done not by format method but by a separete method, say,
format_partially or something?  The method is different from format
also in that it should leave "{{" and "}}" unaltered.

On Fri, 28 Apr 2023 at 00:05, Matthias Görgens
 wrote:


Does it have any use case that's not already served by functools.partial?


I guess you mean given

   partially_formatted_string = unformatted_string.format(color="blue")

that

   partially_formatted_string.format

would be equivalent to

   partial(unformatted_string.format, color="blue")

However, I think a partially formatted string can help since it will
have other methods than format as well.  For instance, given

   unformatted_string = '{color}{text}'

doing the following thing only with functools.partial could require
more care than you would be willing to give.

   string = (unformatted_string.format(color="blue")
 + unformatted_string
 ).format(text="Spanish", color="red")

(One of the easiest ways might be

```
from functools import partial
from operator import call

format_ = unformatted_string.format
string = "".join(map(partial(call, text="Spanish"),
  (partial(format_, color="blue"),
   partial(format_, color="red"), )))
```

However, note the following, more straight-forward code doesn't work:

```
string = "".join(map(partial(call, text="Spanish", color="red"),
  (partial(format_, color="blue"),
   format_, )))
```
)

Now, how about this?

```
format_ = '{a}{b}{c}'.format

string = ((format_(a=a0) + format_(b=b0)).format(c=c0)
   + (format_(a=a1) + format_(c=c1)).format(b=b1)
   + (format_(b=b2) + format_(c=c2)).format(a=a2)
   ).format(a=a3, b=b3, c=c3)
```

(For instance, the following code fails:

```
from itertools import chain

string = "".join(map(partial(call, a=a3, b=b3, c=c3),
  chain.from_iterable(
  map(map,
  (partial(partial, c=c0),
   partial(partial, b=b1),
   partial(partial, a=a2), ),
  ((partial(format_, a=a0),
partial(format_, b=b0), ),
   (partial(format_, a=a1),
partial(format_, c=c1), ),
   (partial(format_, b=b2),
partial(format_, c=c2), ), ))
  )))
```
)

What happens if you do '{open}...{close}'.partial_format(open='{close}'? 
You get '{close}...{close}', and you're going to have a problem using 
that as a format string and replacing only the second '{close}'.


Or how about '{open}...{close}'.partial_format(open='{')? You get 
'{...{close}'. Try using that as a format string!


That's why I think that the result of a partial format should be an 
instance of a new class and not a string.


___
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/TQOQ5CRLDTFXO2YS24UMLQB7ANXQNDWI/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Allowing `str.format` to format one or more parameters instead of all parameters

2023-04-28 Thread Matsuoka Takuo
What if it's done not by format method but by a separete method, say,
format_partially or something?  The method is different from format
also in that it should leave "{{" and "}}" unaltered.

On Fri, 28 Apr 2023 at 00:05, Matthias Görgens
 wrote:
>
> Does it have any use case that's not already served by functools.partial?

I guess you mean given

  partially_formatted_string = unformatted_string.format(color="blue")

that

  partially_formatted_string.format

would be equivalent to

  partial(unformatted_string.format, color="blue")

However, I think a partially formatted string can help since it will
have other methods than format as well.  For instance, given

  unformatted_string = '{color}{text}'

doing the following thing only with functools.partial could require
more care than you would be willing to give.

  string = (unformatted_string.format(color="blue")
+ unformatted_string
).format(text="Spanish", color="red")

(One of the easiest ways might be

```
from functools import partial
from operator import call

format_ = unformatted_string.format
string = "".join(map(partial(call, text="Spanish"),
 (partial(format_, color="blue"),
  partial(format_, color="red"), )))
```

However, note the following, more straight-forward code doesn't work:

```
string = "".join(map(partial(call, text="Spanish", color="red"),
 (partial(format_, color="blue"),
  format_, )))
```
)

Now, how about this?

```
format_ = '{a}{b}{c}'.format

string = ((format_(a=a0) + format_(b=b0)).format(c=c0)
  + (format_(a=a1) + format_(c=c1)).format(b=b1)
  + (format_(b=b2) + format_(c=c2)).format(a=a2)
  ).format(a=a3, b=b3, c=c3)
```

(For instance, the following code fails:

```
from itertools import chain

string = "".join(map(partial(call, a=a3, b=b3, c=c3),
 chain.from_iterable(
 map(map,
 (partial(partial, c=c0),
  partial(partial, b=b1),
  partial(partial, a=a2), ),
 ((partial(format_, a=a0),
   partial(format_, b=b0), ),
  (partial(format_, a=a1),
   partial(format_, c=c1), ),
  (partial(format_, b=b2),
   partial(format_, c=c2), ), ))
 )))
```
)

Best regards,
Takuo Matsuoka
___
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/K5RPB4XOQROYTWQHI5A4DVTKB2RNY6OC/
Code of Conduct: http://python.org/psf/codeofconduct/