[Python-ideas] Re: Bringing the print statement back

2020-10-22 Thread Henk-Jaap Wagenaar
On Fri, 23 Oct 2020 at 06:35, Random832  wrote:

> Does anyone else remember when xkcd first mentioned python? The main
> selling point it had for it [and the one that was actually literally true,
> vs 'import antigravity' which was a semi-satirical bit about the
> batteries-included philosophy] was 'Hello world is just print "Hello,
> world!"'
>

For reference the XKCD is https://xkcd.com/353/. I think the point of the
XKCD is not the difference between print "Hello World" and print("Hello
World") but all the other clutter normally needed (importing stdio.h in C
and main function comes to mind) and the other batteries included
(anti-gravity as a joke, but more seriously, all the lovely modules the
users can use by default).


>
> Wouldn't it be nice if that were true again, even if the details of how it
> works [and other things like how you print to other files] aren't quite the
> same as they used to be?
>

I disagree as do many in this thread.
___
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/EHX4KCSETXSTTGIAGT5PDD26C6ZBXP5L/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: f-strings as assignment targets

2020-10-22 Thread Random832
On Tue, Oct 20, 2020, at 22:03, David Mertz wrote:
> My initial impression of your intent was:
> 
> foo, bar = 42, 99
> # ... a million lines ...
> line = "123/"
> # ... more lines ...
> f"{foo}/{bar}" = line
> # raises if bar wasn't previously set
> # binds to prior value if it was set
> 
> But I think what you want is for the binding line never to raise, but 
> also not to have any local means to know whether 'bar' is a name after 
> that line. Or whether 'foo' is, for that matter.

"whether 'bar' is a name"? It is definitely a name, what you have no means to 
know is whether it has been assigned a value. I suspect you're trying to do the 
thing some people do where they insist on 'name' to avoid using the term 
'variable', and I don't want to start a debate about that, but you've used it 
incorrectly here, and your language seems to suggest it would be reasonable to 
treat bar as *global* if unassigned here. In fact, all names assigned in the 
function are in scope for the entire function regardless of whether they have 
been assigned values, whether that assignment is in a conditional that wasn't 
taken or even simply later in the function than when it is used.

Do you have similar objections to assigning inside an if statement? Because the 
suggested semantics are essentially the same as
x = sscanf(line, "%d/%d")
if len(x) >= 1: foo = x[0]
if len(x) >= 2: bar = x[1]
___
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/JKEJYTG2TS3AS263GKNEXZYK4C7D3YRT/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Bringing the print statement back

2020-10-22 Thread Random832
On Mon, Oct 19, 2020, at 22:41, James T Moon wrote:
> tl;dr *boo* *hiss*
> 
> I can only imagine the new Python programmer's look of confusion, 
> turning to disgust, turning to giving up.

Ten years from now, hopefully, Python 2 will be a distant memory, and Python 
3.8 will be, at the very least, long out of support and unlikely to be the 
system new users are learning Python on, and none of the dialogue you've just 
written will have to take place at all.

Does anyone else remember when xkcd first mentioned python? The main selling 
point it had for it [and the one that was actually literally true, vs 'import 
antigravity' which was a semi-satirical bit about the batteries-included 
philosophy] was 'Hello world is just print "Hello, world!"'

Wouldn't it be nice if that were true again, even if the details of how it 
works [and other things like how you print to other files] aren't quite the 
same as they used to be?
___
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/AEWAFNPPYDGQC2VWKX3OHIFN6EVWLH7C/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Dict unpacking assignment

2020-10-22 Thread Guido van Rossum
Oh, that's quite different than mapping patterns in PEP 634. :-(

On Thu, Oct 22, 2020 at 8:28 PM Steven D'Aprano  wrote:

> I would like to propose dict (or mapping) unpacking assignment. This is
> inspired in part by the Python-Ideas thread "f-strings as assignment
> targets", dict unpacking in function calls, and iterable unpacking
> assignment.
>
> Comments welcome.
>
>
> Background
> --
>
> Iterable unpacking assignment:
>
> values = (1, 2, 3)
> a, b, c = *values
>
> is a very successful and powerful technique in Python. Likewise dict
> unpacking in function calls and dict displays:
>
> kwargs = {'a': 1, 'b': 2}
> func(**kwargs)
> d = {**kwargs, 'c': 3}
>
>
> There have been various requests for allowing dict unpacking on the
> right-hand side of an assignment [citation required] but in my opinion
> none of them have had a good justification.
>
> Motivated by the idea of scanning text strings with a scanf-style
> function, I propose the following behaviour for dict unpacking
> assignment:
>
> items = {'eggs': 2, 'cheese': 3, 'spam': 1}
> spam, eggs, cheese = **items
> assert spam == 1 and eggs == 2 and cheese == 3
>
>
> Syntax
> --
>
> target_list [, **target] = **expression
>
> `target_list` is a comma-separated list of targets. Targets may be:
>
>
> - simple names, e.g. `spam` and `eggs`
>
> - dotted names, e.g. `spam.eggs`
>
> - numbered subscripts, e.g. `spam[1]`
>
>
> but is not required to support arbitrary complex targets such as:
>
> spam(*args).eggs(2*x + y)[1].cheese  # not supported
>
> Likewise only int literals are supported for subscripts. (These
> restrictions may be lifted.)
>
> This is similar to the limited range of fields acceptabled by the string
> format mini-language. The same restrictions apply to `**target`.
>
> Each target must be unique.
>
> `expression` must evaluate to a dict or other mapping.
>
> Assignment proceeds by matching up targets from the left to keys on the
> right:
>
> 1. Every target must be matched exactly by a key. If there is a target
> without a corresponding key, that is an error.
>
> 2. Any key which does not match up to a target is an error, unless a
> `**target` is given.
>
> 3. If `**target` is given, it will collect any excess key:value pairs
> remaining into a dict.
>
> 4. If the targets and keys match up, then the bindings are applied from
> left to right, binding the target to the value associated with that key.
>
> Examples:
>
>
> # Targets are not unique
> a, b, a = **items
> => SyntaxError
>
> # Too many targets
> a, b, c = **{'a': 1, 'b': 2}
> => raises a runtime exception
>
> # Too few targets
> a = **{'a': 1, 'b': 2}
> => raises a runtime exception
>
> a, **extras = **{'a': 1, 'b': 2}
> assert a == 1
> assert extras == {'b': 2}
>
> # Equal targets and keys
> a, b, **extras = **{'a': 1, 'b': 2}
> assert a == 1
> assert b == 2
> assert extras == {}
>
> # Dotted names
> from types import SimpleNamespace
> obj = SimpleNamespace()
> obj.spam = **{'obj.spam': 1}
> assert obj.spam == 1
>
> # Subscripts
> arr = [None]*5
> arr[1], arr[3] = **{'arr[3]': 33, 'arr[1]': 11}
> assert arr == [None, 11, None, 33, None]
>
>
> Assignments to dotted names or subscripts may fail, in which case the
> assignment may only partially succeed:
>
>
> spam = 'something'
> eggs = None
> spam, eggs.attr = {'spam': 1, 'eggs.attr': 2}
> # raises AttributeError: 'NoneType' object has no attribute 'attr'
> # but `spam` may have already been bound to 1
>
>
> (I think that this is undesirable but unavoidable.)
>
>
> Motivating use-cases
> 
>
> The motivation comes from the discussion for scanf-like functionality.
> The addition of dict unpacking assignment would allow something like
> this:
>
>
> pattern = "I'll have {main} and {extra} with {colour} coffee."
> string = "I'll have spam and eggs with black coffee."
> main, extra, colour = **scanf(pattern, string)
>
> assert main == 'spam'
> assert extra == 'eggs'
> assert colour == 'black'
>
>
> But the possibilities are not restricted to string scanning. This will
> allow functions that return multiple values to choose between returning
> them by position or by name:
>
>
> height, width = get_dimensions(window)  # returns a tuple
> height, width = **get_dimensions(window)  # returns a mapping
>
> Developers can choose whichever model best suits their API.
>
> Another use-case is dealing with kwargs inside functions and methods:
>
>
> def method(self, **kwargs):
> spam, eggs, **kw = **kwargs
> process(spam, eggs)
> super().method(**kw)
>
>
> --
> Steve
> ___
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@python.org
> 

[Python-ideas] Re: Call a function at invocation

2020-10-22 Thread 2QdxY4RzWzUUiLuE
On 2020-10-22 at 20:04:14 -0400,
Michael Smith  wrote:

> 1. Being able to call two different functions from the same module. (AND)
> 2. Being able to call some functions that exist today without modification
> or rearrangement. (AND)
> 3. Being able to invoke these things from python without installing a
> module from pip.
> 
> There are solutions that do some of these, but nothing that does them all.
> I think it's surprising that the python makers have found worthwhile three
> different solutions for invoking modules, but this list so far has seen
> little value in invoking a function.

The following module meets your three criteria:

%% begin Python code
def f():
print("This is f.")

def g():
print("This is g.")

h = 'hello'

i = lambda x: print(f"Hello, {x}.")

if __name__ == '__main__':
import sys

try:
function_name, *arguments = sys.argv[1:]
except (IndexError, ValueError):
print('missing function name')
sys.exit(1)

function = sys.modules[__name__].__dict__.get(function_name)
if not function or not callable(function):
print('cannot find or cannot call', function_name)
sys.exit(1)

function(*arguments)
%% end Python code

It's not polished, and it only handles positional string parameters, but
it should be fairly self-explanatory.  The __name__ == '__main__' idiom
allows the module to be imported by other modules without incident.

IMO, at best, it might be the beginning of a recipe somewhere rather
than being included in the standard library.  I agree with David Mertz
that as soon as it gets more complex, every application is going to want
something a little different.

> It would definitely be more empowering to be able to describe the
> command line args to such an invocation using the args to the
> function.

Such enhancements are left as an exercise to the interested reader.

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


[Python-ideas] Dict unpacking assignment

2020-10-22 Thread Steven D'Aprano
I would like to propose dict (or mapping) unpacking assignment. This is 
inspired in part by the Python-Ideas thread "f-strings as assignment 
targets", dict unpacking in function calls, and iterable unpacking 
assignment.

Comments welcome.


Background
--

Iterable unpacking assignment:

values = (1, 2, 3)
a, b, c = *values

is a very successful and powerful technique in Python. Likewise dict 
unpacking in function calls and dict displays:

kwargs = {'a': 1, 'b': 2}
func(**kwargs)
d = {**kwargs, 'c': 3}


There have been various requests for allowing dict unpacking on the 
right-hand side of an assignment [citation required] but in my opinion 
none of them have had a good justification.

Motivated by the idea of scanning text strings with a scanf-style 
function, I propose the following behaviour for dict unpacking 
assignment:

items = {'eggs': 2, 'cheese': 3, 'spam': 1}
spam, eggs, cheese = **items
assert spam == 1 and eggs == 2 and cheese == 3


Syntax
--

target_list [, **target] = **expression

`target_list` is a comma-separated list of targets. Targets may be:


- simple names, e.g. `spam` and `eggs`

- dotted names, e.g. `spam.eggs`

- numbered subscripts, e.g. `spam[1]`


but is not required to support arbitrary complex targets such as:

spam(*args).eggs(2*x + y)[1].cheese  # not supported

Likewise only int literals are supported for subscripts. (These 
restrictions may be lifted.)

This is similar to the limited range of fields acceptabled by the string 
format mini-language. The same restrictions apply to `**target`.

Each target must be unique.

`expression` must evaluate to a dict or other mapping.

Assignment proceeds by matching up targets from the left to keys on the 
right:

1. Every target must be matched exactly by a key. If there is a target 
without a corresponding key, that is an error.

2. Any key which does not match up to a target is an error, unless a 
`**target` is given.

3. If `**target` is given, it will collect any excess key:value pairs 
remaining into a dict.

4. If the targets and keys match up, then the bindings are applied from 
left to right, binding the target to the value associated with that key.

Examples:


# Targets are not unique
a, b, a = **items
=> SyntaxError

# Too many targets
a, b, c = **{'a': 1, 'b': 2}
=> raises a runtime exception

# Too few targets
a = **{'a': 1, 'b': 2}
=> raises a runtime exception

a, **extras = **{'a': 1, 'b': 2}
assert a == 1
assert extras == {'b': 2}

# Equal targets and keys
a, b, **extras = **{'a': 1, 'b': 2}
assert a == 1
assert b == 2
assert extras == {}

# Dotted names
from types import SimpleNamespace
obj = SimpleNamespace()
obj.spam = **{'obj.spam': 1}
assert obj.spam == 1

# Subscripts
arr = [None]*5
arr[1], arr[3] = **{'arr[3]': 33, 'arr[1]': 11}
assert arr == [None, 11, None, 33, None]


Assignments to dotted names or subscripts may fail, in which case the 
assignment may only partially succeed:


spam = 'something'
eggs = None
spam, eggs.attr = {'spam': 1, 'eggs.attr': 2}
# raises AttributeError: 'NoneType' object has no attribute 'attr'
# but `spam` may have already been bound to 1


(I think that this is undesirable but unavoidable.)


Motivating use-cases


The motivation comes from the discussion for scanf-like functionality. 
The addition of dict unpacking assignment would allow something like 
this:


pattern = "I'll have {main} and {extra} with {colour} coffee."
string = "I'll have spam and eggs with black coffee."
main, extra, colour = **scanf(pattern, string)

assert main == 'spam'
assert extra == 'eggs'
assert colour == 'black'


But the possibilities are not restricted to string scanning. This will 
allow functions that return multiple values to choose between returning 
them by position or by name:


height, width = get_dimensions(window)  # returns a tuple
height, width = **get_dimensions(window)  # returns a mapping

Developers can choose whichever model best suits their API.

Another use-case is dealing with kwargs inside functions and methods:


def method(self, **kwargs):
spam, eggs, **kw = **kwargs
process(spam, eggs)
super().method(**kw)


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


[Python-ideas] Re: f-string: empty expression should be allowed

2020-10-22 Thread Steven D'Aprano
On Thu, Oct 22, 2020 at 09:09:07AM -0700, Guido van Rossum wrote:
> On Thu, Oct 22, 2020 at 3:37 AM Hans Ginzel  wrote:
> 
> > Thank you for (ugly) workaorund.
> >
> 
> Careful who you're calling ugly.

"Who"? Syntax is a person now?

For what it's worth, I don't think escaping special symbols is ugly. 
More like homely. It does the job, plainly and simply, but I don't think 
it's especially good looking. Every other character stands for itself, 
with this handful of exceptional cases.


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


[Python-ideas] Re: f-string: empty expression should be allowed

2020-10-22 Thread Steven D'Aprano
On Thu, Oct 22, 2020 at 12:29:22PM +0200, Hans Ginzel wrote:

> >We could do that, but this is more likely to just hide bugs in the
> >f-string than be useful.
> 
> Thank you, that would be great and useful.

Oh, sorry Hans, I think that you may have misunderstood me.

In English, "We could do that, but..." usually means we won't do it 
because of the given reason. In this case, that is what I meant. We 
could do it, but we shouldn't.



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


[Python-ideas] Re: Call a function at invocation

2020-10-22 Thread David Mertz
I really don't see this goal as general purpose  enough to merit Python
syntax or standard library inclusion.  Needing a PyPI package to do
something slightly uncommon really doesn't feel like a bad obstacle.

Click is perfectly great.  It's a nice package for creating a certain kind
of command line interface, especially handy with subcommands.  Argparse
also supports subcommands.

But the cases where there is a single mapping from every function in a
module to an available command line argument/subcommand, always using the
same name, feel limited to me.  If that is what you want, that's fine, it's
not hard to do.  It can be as simple as an `eval()` in the __main__ block.
That particular use pattern feels niche to me.

Figuring out arguments to pass into functions, along with their types, is
certainly something that a command-line language COULD handle.  But it
doesn't seem like something that every command-line program should want to
handle in the same way.

On Fri, Oct 23, 2020 at 2:07 AM Michael Smith  wrote:

> What a few responders have said is along the lines that my proposal
>
> 1. Can already be done.
> 2. Has gaps/is too simple.
>
> I will try to address those points here, but before I start, I'm getting
> the impression I don't have a great grasp of the communication style of
> this list. I assumed that a simple proposal with _some value_ would meet
> less resistance than a complex one with more value, so I left out features
> (like handling arguments). I will try to avoid MVP-ing my proposals in the
> future, as I think that led to a more "meh" initial response than my idea
> deserves.
>
> -
>
> Can calling a function from the command line already be done? Yes, I led
> with that. But my idea would lead to the following improvements:
>
> 1. Being able to call two different functions from the same module. (AND)
> 2. Being able to call some functions that exist today without modification
> or rearrangement. (AND)
> 3. Being able to invoke these things from python without installing a
> module from pip.
>
> There are solutions that do some of these, but nothing that does them all.
> I think it's surprising that the python makers have found worthwhile three
> different solutions for invoking modules, but this list so far has seen
> little value in invoking a function.
>
> -
>
> Is my proposal oversimplified? Maybe? I actually think it's pretty nice
> just to be able to call a couple of arbitrary functions by name that know
> how to access args via argparse or whatever.
>
> It would definitely be more empowering to be able to describe the command
> line args to such an invocation using the args to the function.
>
> But, I guess the real weakness of my proposal was that it required
> anything special about the function at all. It'd be easy to handle some
> functions with arguments, certainly if they're all strings. Other primitive
> scalar types may be doable if we map type hints to constructors. But I
> can't think of a reasonable way to handle a function that expects a complex
> object for an argument.
>
> So, how about if the proposal expands to include functions with any arity
> of string-only arguments? I think that makes it possible to use a wide
> variety of functions without any special work.
>
> We could also say that positional arguments are treated positionally, and
> kwargs need to be expressed on the command line as --kwarg=value
>
> What else is missing?
>
> On Wed, Oct 21, 2020 at 13:15 Christopher Barker 
> wrote:
>
>> FWIW, one of my intro students just yesterday asked about this:
>>
>> Is there a way to call a function in a python file directly from the
>> command line?
>>
>> I have no idea what their programming background is, or why they expected
>> that to be possible, but there you go -- at least one newbie expected it to
>> be possible :-)
>>
>> However: This was literally class number one -- I had not yet showed them
>> the "if __name__ == '__main__':" idiom yet.
>>
>> Also, I'm pretty sure this student's expectation was that there would not
>> have to be anything special about the function (except maybe taking only
>> string arguments?)  -- so it's probably not a good idea to try to solve
>> that use case anyway.
>>
>> But that was the first time I was ever asked that question -- and here it
>> is on python-ideas -- quite a coincidence!
>>
>> -CHB
>>
>>
>>
>>
>>
>> On Tue, Oct 20, 2020 at 11:16 PM Paul Sokolovsky 
>> wrote:
>>
>>> Hello,
>>>
>>> On Wed, 21 Oct 2020 00:24:47 -0400
>>> Michael Smith  wrote:
>>>
>>> > On Tue, Oct 20, 2020 at 23:43 Guido van Rossum 
>>> > wrote:
>>> >
>>> > > The ‘if __name__…’ idiom makes one function special. Hm... So if the
>>> > > module has that, will that main() still be called with your
>>> > > proposal? I.e., is __name__ still ‘__main__’?
>>> > >
>>> >
>>> > Perhaps not. If __name__ were still '__main__' and calling the
>>> > function implied importing the module, then anything in `if __name__
>>> > == '__main__'` would still 

[Python-ideas] Re: Call a function at invocation

2020-10-22 Thread Michael Smith
What a few responders have said is along the lines that my proposal

1. Can already be done.
2. Has gaps/is too simple.

I will try to address those points here, but before I start, I'm getting
the impression I don't have a great grasp of the communication style of
this list. I assumed that a simple proposal with _some value_ would meet
less resistance than a complex one with more value, so I left out features
(like handling arguments). I will try to avoid MVP-ing my proposals in the
future, as I think that led to a more "meh" initial response than my idea
deserves.

-

Can calling a function from the command line already be done? Yes, I led
with that. But my idea would lead to the following improvements:

1. Being able to call two different functions from the same module. (AND)
2. Being able to call some functions that exist today without modification
or rearrangement. (AND)
3. Being able to invoke these things from python without installing a
module from pip.

There are solutions that do some of these, but nothing that does them all.
I think it's surprising that the python makers have found worthwhile three
different solutions for invoking modules, but this list so far has seen
little value in invoking a function.

-

Is my proposal oversimplified? Maybe? I actually think it's pretty nice
just to be able to call a couple of arbitrary functions by name that know
how to access args via argparse or whatever.

It would definitely be more empowering to be able to describe the command
line args to such an invocation using the args to the function.

But, I guess the real weakness of my proposal was that it required anything
special about the function at all. It'd be easy to handle some functions
with arguments, certainly if they're all strings. Other primitive scalar
types may be doable if we map type hints to constructors. But I can't think
of a reasonable way to handle a function that expects a complex object for
an argument.

So, how about if the proposal expands to include functions with any arity
of string-only arguments? I think that makes it possible to use a wide
variety of functions without any special work.

We could also say that positional arguments are treated positionally, and
kwargs need to be expressed on the command line as --kwarg=value

What else is missing?

On Wed, Oct 21, 2020 at 13:15 Christopher Barker 
wrote:

> FWIW, one of my intro students just yesterday asked about this:
>
> Is there a way to call a function in a python file directly from the
> command line?
>
> I have no idea what their programming background is, or why they expected
> that to be possible, but there you go -- at least one newbie expected it to
> be possible :-)
>
> However: This was literally class number one -- I had not yet showed them
> the "if __name__ == '__main__':" idiom yet.
>
> Also, I'm pretty sure this student's expectation was that there would not
> have to be anything special about the function (except maybe taking only
> string arguments?)  -- so it's probably not a good idea to try to solve
> that use case anyway.
>
> But that was the first time I was ever asked that question -- and here it
> is on python-ideas -- quite a coincidence!
>
> -CHB
>
>
>
>
>
> On Tue, Oct 20, 2020 at 11:16 PM Paul Sokolovsky 
> wrote:
>
>> Hello,
>>
>> On Wed, 21 Oct 2020 00:24:47 -0400
>> Michael Smith  wrote:
>>
>> > On Tue, Oct 20, 2020 at 23:43 Guido van Rossum 
>> > wrote:
>> >
>> > > The ‘if __name__…’ idiom makes one function special. Hm... So if the
>> > > module has that, will that main() still be called with your
>> > > proposal? I.e., is __name__ still ‘__main__’?
>> > >
>> >
>> > Perhaps not. If __name__ were still '__main__' and calling the
>> > function implied importing the module, then anything in `if __name__
>> > == '__main__'` would still get run. I think that would be
>> > inconvenient for folks.
>>
>> Alternative valuation is that your proposal is inconvenient to folks,
>> as it leaves too many gaps. Which, as it seems, you're eager to
>> bravely patch, but that does/will lead to only more confusion.
>>
>> > I think __name__ should be the module name in the context of the
>> > module, and the function name in the context of the function, in this
>> > case.
>>
>> __name__ is the name of the module. Or, as a special exception, it's
>> "__main__" for a module directly invoked as a script or via "-m"
>> switch.
>>
>> There's no need to complicate it any further (it's already complicated
>> enough; my bet that half of Python users won't be able to formulate it
>> like above by heart).
>>
>>
>> Back to the original proposal, there's no general need to invoke
>> an arbitrary function in an arbitrary module. That just makes no sense,
>> as most functions depend on context.
>>
>> If *you* need that, then, besides other options you mentioned in
>> your original mail, it's trivial to write a module which will do it for
>> you, like:
>>
>> python -m my_super_invocator module:thunk
>>
>>
>> Actually, 

[Python-ideas] Re: f-string: empty expression should be allowed

2020-10-22 Thread Guido van Rossum
On Thu, Oct 22, 2020 at 3:37 AM Hans Ginzel  wrote:

> Thank you for (ugly) workaorund.
>

Careful who you're calling ugly.

-- 
--Guido van Rossum (python.org/~guido)
*Pronouns: he/him **(why is my pronoun here?)*

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


[Python-ideas] Re: f-strings as assignment targets

2020-10-22 Thread Eric V. Smith

On 10/22/2020 11:04 AM, Guido van Rossum wrote:
 Another way this could go: If PEP 634 (pattern matching, reborn) gets 
accepted, a future Python version could add f-string patterns (which 
the PEP currently forbids). E.g.

```
x = "123 456 789"
match x:
  case f"{a} {b}": print("A pair:", a, b)
  case f"{a} {b} {c}": print("Triple", a, b, c)
```
Everything else (e.g. how to design the formatting language) would be 
open. We could even designate "raw" f-strings (rf"...") as regular 
expressions ().


I think it makes sense to move this into pattern matching, since it 
already has the variable binding baked in and well specified.


As you say, it still leaves all of the issues about specifying the 
format language. But as I've said, I think that should be done outside 
of any syntax proposal, and could be done now. In particular it should 
address returning types other than str. As MRAB points out (and assuming 
the proposal allows type conversion), how would it specify datetimes, 
decimals, etc., and how would it be extensible? And if it does specify 
type conversions, I think it would need to be something that could be 
understood by mypy.


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


[Python-ideas] Re: f-strings as assignment targets

2020-10-22 Thread Guido van Rossum
 Another way this could go: If PEP 634 (pattern matching, reborn) gets
accepted, a future Python version could add f-string patterns (which the
PEP currently forbids). E.g.
```
x = "123 456 789"
match x:
  case f"{a} {b}": print("A pair:", a, b)
  case f"{a} {b} {c}": print("Triple", a, b, c)
```
Everything else (e.g. how to design the formatting language) would be open.
We could even designate "raw" f-strings (rf"...") as regular expressions
().

-- 
--Guido van Rossum (python.org/~guido)
*Pronouns: he/him **(why is my pronoun here?)*

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


[Python-ideas] Re: f-strings as assignment targets

2020-10-22 Thread Eric V. Smith

On 10/22/2020 10:15 AM, Chris Angelico wrote:

On Fri, Oct 23, 2020 at 1:11 AM Eric V. Smith  wrote:

And if all f-strings brought to the table was the ability to use simple
variables as the value to be formatted, I'd have been opposed to that as
well. What's the point of:

f"{a} {b} {c}"

when:

"{} {} {}".format(a, b, c)

does the same thing? This was literally one of the proposals considered
when f-strings were being designed, and I was opposed.


The rationale in PEP 498 advocates the benefits even with just simple
names. You don't have to be embedding complex expressions in order to
benefit from f-strings.

(Also, assignment targets don't have to be simple names; targets like
"x[1]" or "x.y" would be perfectly valid. Although I doubt anyone
would want to assign to "a,b,c" inside an expression like this.)


None of which changes my opinion that it's not worth making this into 
syntax. As I said, reasonable people can disagree. But I think I'll wait 
until I see a PEP before commenting more broadly.


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


[Python-ideas] Re: f-strings as assignment targets

2020-10-22 Thread Chris Angelico
On Fri, Oct 23, 2020 at 1:11 AM Eric V. Smith  wrote:
> And if all f-strings brought to the table was the ability to use simple
> variables as the value to be formatted, I'd have been opposed to that as
> well. What's the point of:
>
> f"{a} {b} {c}"
>
> when:
>
> "{} {} {}".format(a, b, c)
>
> does the same thing? This was literally one of the proposals considered
> when f-strings were being designed, and I was opposed.
>

The rationale in PEP 498 advocates the benefits even with just simple
names. You don't have to be embedding complex expressions in order to
benefit from f-strings.

(Also, assignment targets don't have to be simple names; targets like
"x[1]" or "x.y" would be perfectly valid. Although I doubt anyone
would want to assign to "a,b,c" inside an expression like this.)

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


[Python-ideas] Re: f-strings as assignment targets

2020-10-22 Thread Eric V. Smith



On 10/22/2020 5:21 AM, Steven D'Aprano wrote:

On Wed, Oct 21, 2020 at 07:17:21PM -0700, Guido van Rossum wrote:


Hmm, if the above is acceptable, maybe f-strings are still the logical next
step, since they bring the format and the target name together again.

That's not the only way to bring the format and target name together.
Both brace-style and percent-style can do that:

 '{number:d}'
 '%(number)d'

I'm not sure if you've caught up on the entire thread, but Eric Smith is
opposed to this:

https://mail.python.org/archives/list/python-ideas@python.org/message/KTGQLT4TY672GRF6JFV6MZHUE4J4S3NS/

(For the benefit of those who aren't aware of the f-string history, Eric
wrote the PEP and at least part of the implementation.)
Steven sums up my objects very well here. Thanks, Steven. I think we 
definitely should not use the "f" prefix, and using no prefix at all is 
probably better than using a new prefix.


The only thing this proposal brings that couldn't be done with either a 
str method or with a 3rd party library is automatic variable 
creation/binding when the LHS is a literal. If we're seriously thinking 
of doing that, I'd rather it be regex based that some newly invented 
scanf-like (or even __format__format spec-like) "language", for lack of 
a better term. But again, I don't think this rises to the level of 
usefulness that would elevate it to needing syntax.


Is:

"{a:%d} {b:%d} {c:%d}" ="123 432 567"

such a big improvement over:

a, b, c = sscanf("%d %d %d", "123 432 567")

?

Reasonable people will disagree, but I think the answer is "no", 
especially when you factor in the inability to use a computed value for 
the LHS in the first example.


And if all f-strings brought to the table was the ability to use simple 
variables as the value to be formatted, I'd have been opposed to that as 
well. What's the point of:


f"{a} {b} {c}"

when:

"{} {} {}".format(a, b, c)

does the same thing? This was literally one of the proposals considered 
when f-strings were being designed, and I was opposed.


It's the ability of f-strings to handle arbitrary expressions that gives 
them the usefulness (and love!) that they have. Since that's by 
necessity missing from the "f-strings as assignment targets" proposal 
(as I understand it), then I again think we could just live with a str 
method or library that implements this.


Eric



f-strings also bring so much more to the table than is needed. For this
syntax to be sensible, we would have to prohibit so many legal f-strings
that it seems perverse to continue calling the subset of what's left
over f-strings.

1. They don't behave like f-strings: text scanning, not evaluation of
code. What meaning could we give an f-string target like this?

 f'{len(x)+1}' = string


2. They don't support the same formatting options as f-strings.

Chris has suggested a superset of formatting options, similar to
regexes; other f-string codes would be meaningless:

 f'a {spam:^5_d} b' = 'a 1234 b'
 # centre align; group digits using underscore

3. As Eric explains, they don't share the same mechanism as f-strings.

4. Actual f-strings need the prefix to distinguish them from regular
strings. But as an assignment target, there is no existing meaning to

 'email: {name}@{domain}' = string

so the f prefix has no purpose.

When they have so little in common with f-strings, apart from a spurious
and unnecessary f-prefix, why are we calling them f-strings?

Another problem is that using only a literal/display form as a target
means you can't pre-assemble a pattern and apply it later:

 # Match only the given domain.
 domain = get_wanted_domain()
 pattern = 'email: {name}@%s' % domain
 # ... now what?

I guess you could fall back to eval:

 eval('f{!r} = {!r}'.format(pattern, string))

but given that both the pattern and the string to be scanned are likely
to contain untrusted strings, that's probably not a good idea.




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


[Python-ideas] Re: f-strings as assignment targets

2020-10-22 Thread Chris Angelico
On Fri, Oct 23, 2020 at 12:56 AM Paul Moore  wrote:
>
> On Thu, 22 Oct 2020 at 14:44, Chris Angelico  wrote:
> > Returning a dict
> > would be FAR less convenient for the most common cases, but as you
> > say, it'd be the fallback for when you need dynamic parsing.
>
> If you're that sure that direct assignment to locals would be a killer
> feature (I'm not, but you seem to be unimpressed by any scanning
> proposal that *doesn't* include it) maybe a better syntax proposal
> would be something that takes a dict (or more generally maybe a
> "namespace") and injects it into locals? That could be used by a
> scanner function, as well as any other library that wanted a "directly
> assign variables" interface. So rather than
>
> f"{var1} {var2} {var3}" = target
>
> we'd have
>
> inject_vars parser("{var1} {var2} {var3}", target)
>
> and people who don't like/want variable assignment can just use
> parser() as a normal function returning a dict.
>

The trouble with this is that there's no way to know, at compilation
time, what names are being assigned to. I think that basically makes
it a non-starter. It'd have to be something like JavaScript's
destructuring syntax, where you explicitly name the variables you want
to grab:

const {var1, var2, var3} = target;

but that would mean the same duplication of names that was the reason
for f-strings on the RHS. I think this kind of thing might be useful,
but it wouldn't be enough to make this feature work.

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


[Python-ideas] Re: f-strings as assignment targets

2020-10-22 Thread Paul Moore
On Thu, 22 Oct 2020 at 14:44, Chris Angelico  wrote:
> Returning a dict
> would be FAR less convenient for the most common cases, but as you
> say, it'd be the fallback for when you need dynamic parsing.

If you're that sure that direct assignment to locals would be a killer
feature (I'm not, but you seem to be unimpressed by any scanning
proposal that *doesn't* include it) maybe a better syntax proposal
would be something that takes a dict (or more generally maybe a
"namespace") and injects it into locals? That could be used by a
scanner function, as well as any other library that wanted a "directly
assign variables" interface. So rather than

f"{var1} {var2} {var3}" = target

we'd have

inject_vars parser("{var1} {var2} {var3}", target)

and people who don't like/want variable assignment can just use
parser() as a normal function returning a dict.

If you're interested in something like that (I'm not) make it a new
thread, though, as it's way off topic for this thread.
Paul
___
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/N7ZPPYF6GQC6HHVRKZSSRS6CKS4HO5UC/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: f-strings as assignment targets

2020-10-22 Thread Chris Angelico
On Fri, Oct 23, 2020 at 12:31 AM Eric V. Smith  wrote:
>
> On 10/22/2020 8:29 AM, Chris Angelico wrote:
> > On Thu, Oct 22, 2020 at 8:22 PM Steven D'Aprano  wrote:
> >> Another problem is that using only a literal/display form as a target
> >> means you can't pre-assemble a pattern and apply it later:
> >>
> >>  # Match only the given domain.
> >>  domain = get_wanted_domain()
> >>  pattern = 'email: {name}@%s' % domain
> >>  # ... now what?
> > Right, and you can't do that with f-strings on the RHS either. The
> > specific thing you're asking about could easily be implemented as a
> > feature of the minilanguage itself, but I'm not sure it'd actually be
> > needed. Building patterns for future parsing is simply not the job of
> > this feature - use a regex if you need that.
>
> In the case of f-strings, the fallback is str.format(), which uses the
> exact same format specifiers. What's the equivalent when you need
> dynamic 'f-string assignment targets'?
>

Good question, but whatever it is, it can be part of the same
proposal. A standard library function that does the same kind of thing
but returns a dictionary would be useful, even if it isn't as
important. Pike has sscanf (compiler feature that assigns directly to
things) and array_sscanf (returns a sequential collection of matched
items), and Python could do the same kind of thing. Returning a dict
would be FAR less convenient for the most common cases, but as you
say, it'd be the fallback for when you need dynamic parsing.

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


[Python-ideas] Re: f-strings as assignment targets

2020-10-22 Thread Eric V. Smith

On 10/22/2020 8:29 AM, Chris Angelico wrote:

On Thu, Oct 22, 2020 at 8:22 PM Steven D'Aprano  wrote:

Another problem is that using only a literal/display form as a target
means you can't pre-assemble a pattern and apply it later:

 # Match only the given domain.
 domain = get_wanted_domain()
 pattern = 'email: {name}@%s' % domain
 # ... now what?

Right, and you can't do that with f-strings on the RHS either. The
specific thing you're asking about could easily be implemented as a
feature of the minilanguage itself, but I'm not sure it'd actually be
needed. Building patterns for future parsing is simply not the job of
this feature - use a regex if you need that.


In the case of f-strings, the fallback is str.format(), which uses the 
exact same format specifiers. What's the equivalent when you need 
dynamic 'f-string assignment targets'?


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


[Python-ideas] Re: f-strings as assignment targets

2020-10-22 Thread Paul Moore
On Thu, 22 Oct 2020 at 13:36, Chris Angelico  wrote:
>
> On Thu, Oct 22, 2020 at 8:22 PM Steven D'Aprano  wrote:
> >
> > On Wed, Oct 21, 2020 at 07:17:21PM -0700, Guido van Rossum wrote:
> >
> > > Hmm, if the above is acceptable, maybe f-strings are still the logical 
> > > next
> > > step, since they bring the format and the target name together again.
> >
> > That's not the only way to bring the format and target name together.
> > Both brace-style and percent-style can do that:
> >
> > '{number:d}'
> > '%(number)d'
>
> Maybe, but if it isn't an actual syntactic construct, there's no value
> - at best, all you can do is return a dictionary, and there's no
> convenient way to assign those to locals.

I think that there's *plenty* of value. Returning a dictionary (or
maybe a dataclass) is far from merely being "at best", it's a common,
well-known, and easy to use pattern. Libraries like argparse use it
very successfully.

Direct assignment to locals would require syntax, but I think a lot of
people in this thread consider that to be at best a minor additional
convenience - and many people have argued that the pitfalls are a lot
worse than the benefits, and consider direct assignment to locals to
be a disadvantage, rather than a benefit.

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


[Python-ideas] Re: f-string: empty expression should be allowed

2020-10-22 Thread Hans Ginzel

On Thu, Oct 22, 2020 at 11:32:36PM +1100, Chris Angelico wrote:

My recommendation here would be to separate the part where you insert
a table name from the rest of the statement:
cursor.execute(f"INSERT INTO {table} "
   "VALUES (1, '{}')")
That way, you aren't at risk of SQL injection in the rest of the
statement, and you have a very clear separation saying "hey this bit
is doing something really unusual and using interpolation in SQL".


Thank you, that is the best suggestion.

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


[Python-ideas] Re: f-strings as assignment targets

2020-10-22 Thread Chris Angelico
On Thu, Oct 22, 2020 at 8:22 PM Steven D'Aprano  wrote:
>
> On Wed, Oct 21, 2020 at 07:17:21PM -0700, Guido van Rossum wrote:
>
> > Hmm, if the above is acceptable, maybe f-strings are still the logical next
> > step, since they bring the format and the target name together again.
>
> That's not the only way to bring the format and target name together.
> Both brace-style and percent-style can do that:
>
> '{number:d}'
> '%(number)d'

Maybe, but if it isn't an actual syntactic construct, there's no value
- at best, all you can do is return a dictionary, and there's no
convenient way to assign those to locals.

> f-strings also bring so much more to the table than is needed. For this
> syntax to be sensible, we would have to prohibit so many legal f-strings
> that it seems perverse to continue calling the subset of what's left
> over f-strings.
>
> 1. They don't behave like f-strings: text scanning, not evaluation of
> code. What meaning could we give an f-string target like this?
>
> f'{len(x)+1}' = string

.. mini-language inspired by format language. I'm really not sure
how many times this has to be said. You don't see C programmers
complaining that sscanf and sprintf don't support the exact same set
of things. They're sufficiently similar that it is incredibly
practical and useful; I think there might be something in the zen of
Python about that...

> 4. Actual f-strings need the prefix to distinguish them from regular
> strings. But as an assignment target, there is no existing meaning to
>
> 'email: {name}@{domain}' = string
>
> so the f prefix has no purpose.
>
> When they have so little in common with f-strings, apart from a spurious
> and unnecessary f-prefix, why are we calling them f-strings?

If you're saying that this would be best done with an "assign to
string literal" syntax, then maybe, but I think the similarity with
RHS f-strings is useful enough to keep the prefix. Additionally, the
fact that both of them have to be syntactic constructs rather than
reusable objects is a useful parallel and a useful reminder.

> Another problem is that using only a literal/display form as a target
> means you can't pre-assemble a pattern and apply it later:
>
> # Match only the given domain.
> domain = get_wanted_domain()
> pattern = 'email: {name}@%s' % domain
> # ... now what?

Right, and you can't do that with f-strings on the RHS either. The
specific thing you're asking about could easily be implemented as a
feature of the minilanguage itself, but I'm not sure it'd actually be
needed. Building patterns for future parsing is simply not the job of
this feature - use a regex if you need that.

> I guess you could fall back to eval:
>
> eval('f{!r} = {!r}'.format(pattern, string))
>
> but given that both the pattern and the string to be scanned are likely
> to contain untrusted strings, that's probably not a good idea.
>

Agreed. Don't do that. There are PLENTY of better options than eval.

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


[Python-ideas] Re: f-string: empty expression should be allowed

2020-10-22 Thread Chris Angelico
On Thu, Oct 22, 2020 at 8:12 PM Hans Ginzel  wrote:
>
> Hello,
>
> consider this snippet please
>
> cursor.execute(f"INSERT INTO {table} VALUES (1, '{}');")
> SyntaxError: f-string: empty expression not allowed
>
> It is (absolutely) correct to insert empty json into database table field.
> Empty expression in f-string should
> * (silently) expand as '{}' (opening and closing braces),
> * generate a (compile time) warning if requested, e.g. with -W.

My recommendation here would be to separate the part where you insert
a table name from the rest of the statement:

cursor.execute(f"INSERT INTO {table} "
"VALUES (1, '{}')")

That way, you aren't at risk of SQL injection in the rest of the
statement, and you have a very clear separation saying "hey this bit
is doing something really unusual and using interpolation in SQL".

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


[Python-ideas] Re: f-string: empty expression should be allowed

2020-10-22 Thread Marco Sulla
On Thu, 22 Oct 2020 at 12:36, Hans Ginzel  wrote:

> On Thu, Oct 22, 2020 at 08:31:34PM +1100, Steven D'Aprano wrote:
> >> cursor.execute(f"INSERT INTO {table} VALUES (1, '{}');")
> >> SyntaxError: f-string: empty expression not allowed
> >
> >Escape the braces by doubling them:
> >f"INSERT INTO {table} VALUES (1, '{{}}');"
>
> Thank you for (ugly) workaorund.
>

It's not ugly for me too, but if you want another workaround:

d = {}
f"INSERT INTO {table} VALUES (1, '{d}');"
___
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/F63STJCC3MFLMYSS7KTKSRO3VGZOP27V/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: f-string: empty expression should be allowed

2020-10-22 Thread Eric V. Smith

On 10/22/2020 4:58 AM, Hans Ginzel wrote:

Hello,

consider this snippet please

cursor.execute(f"INSERT INTO {table} VALUES (1, '{}');")
SyntaxError: f-string: empty expression not allowed

It is (absolutely) correct to insert empty json into database table 
field.

Empty expression in f-string should
* (silently) expand as '{}' (opening and closing braces),
* generate a (compile time) warning if requested, e.g. with -W.


You can use f"INSERT INTO {table} VALUES (1, '{{}}');".

The doubled braces become single braces inside an f-string.

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


[Python-ideas] Re: f-strings as assignment targets

2020-10-22 Thread MRAB

On 2020-10-22 08:50, M.-A. Lemburg wrote:

On 22.10.2020 04:12, David Mertz wrote:

To bring it back to a concrete idea, here's how I see things:

 1. The idea of f-string-like assignment targets has little support.  Only
Chris, and maybe the OP who seems to have gone away.
 2. The idea of a "scanning language" seems to garner a fair amount of
enthusiasm from everyone who has commented.
 3. Having the scanning language be "inspired by" f-strings seems to fit nicely
with Python
 4. Lots of folks like C scanf() as another inspiration for the need.  I was not
being sarcastic in saying that I thought COBOL PICTURE clauses are another
similar useful case.  I think Perl 6 "rules" were trying to do something
along those lines... but, well, Perl.
 5. In my opinion, this is naturally a function, or several related functions,
not new syntax (I think Steven agrees)

So the question is, what should the scanning language look like?  Another
question is: "Does this already exist?"

I'm looking around PyPI, and I see this that looks vaguely along the same lines.
But most likely I am missing things: https://pypi.org/project/rebulk/

In terms of API, assuming functions, I think there are two basic models.  We
could have two (or more) functions that were related though:

# E.g. pat_with_names = "{foo:f}/{bar:4s}/{baz:3d}"
matches = scan_to_obj(pat_with_names, haystack)
# something like (different match objects are possible choices, dict, dataclass,
etc)
print(matches.foo)
print(maches['bar'])

Alternately:

# pat_only = "{:f}/{:4s}/{:3d}"
foo, bar, baz = scan_to_tuple(pat_only, haystack)
# names, if bound, have the types indicated by scanning language

There are questions open about partial matching, defaults, exceptions to raise,
etc.  But the general utility of something along those lines seems roughly
consensus.


I like this idea :-)

There are lots of use cases where regular expressions + subsequent
type conversion are just overkill for a small parsing task.

The above would fit this space quite nicely, esp. since it already
comes with a set of typical format you have to parse, without having
to worry about the nitty details (as you have to do with REs) or
the type conversion from string to e.g. float.

One limitation is that only a few types would supported: 's' for str, 
'd' or 'x' for int, 'f' for float.


But what if you wanted to scan to a Decimal instead of a float, or scan 
a date? A date could be formatted any number of ways!


So perhaps the scanning format should also let you specify the target 
type. For example, given "{?datetime:%H:%M}", it would look up the 
pre-registered name "datetime" to get a scanner; the scanner would be 
given the format, the string and the position and would return the value 
and the new position. I used '?' in the scan format to distinguish it 
from a format string.


It might even be possible to use the same format for both formatting and 
scanning. For example, given "{?datetime:%H:%M}", string formatting 
would just ignore the "?datetime" part.

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


[Python-ideas] Re: f-string: empty expression should be allowed

2020-10-22 Thread André Roberge
On Thu, Oct 22, 2020 at 7:39 AM Hans Ginzel  wrote:

> On Thu, Oct 22, 2020 at 08:31:34PM +1100, Steven D'Aprano wrote:
> >> cursor.execute(f"INSERT INTO {table} VALUES (1, '{}');")
> >> SyntaxError: f-string: empty expression not allowed
> >
> >Escape the braces by doubling them:
> >f"INSERT INTO {table} VALUES (1, '{{}}');"
>
> Thank you for (ugly) workaorund.
>
It is no different than having to write \\ in a string to get a single
backslash : it is part of the syntax of f-strings, and not a "workaround".

André Roberge

>
>
>
>
> --
> BR, H.
> ___
> 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/2B5KEM34SUO3TXDMMZE6A332L3SKVLEF/
> 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/67JTOL2MGRQB2CAAFG4HJXV7XDJXNT4Y/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: f-string: empty expression should be allowed

2020-10-22 Thread Paul Moore
On Thu, 22 Oct 2020 at 11:39, Hans Ginzel  wrote:
>
> On Thu, Oct 22, 2020 at 08:31:34PM +1100, Steven D'Aprano wrote:
> >> cursor.execute(f"INSERT INTO {table} VALUES (1, '{}');")
> >> SyntaxError: f-string: empty expression not allowed
> >
> >Escape the braces by doubling them:
> >f"INSERT INTO {table} VALUES (1, '{{}}');"
>
> Thank you for (ugly) workaorund.

Given that using an f-string is not advised in this context (it's a
vector for SQL injection attacks) I don't see this as a compelling
example, and I think the workaround is perfectly fine - ugliness (if
you choose to think of it as ugly) is arguably a benefit, because it
forces you to think about whether you want to do this.

> >The problem here is with the f-string, not the call to cursor.execute.
> >We can simplify the example to this:
> >f'{}'
> >and avoid the distraction of JSON, SQL, databases, etc.
>
> Technically we can, but the context give us a useful example.
> Strings like f"Use braces ({}) for {something}."
> are also a useful example.

It does, and as I say above, it shows that having to double the
brackets is fine (in my view).

> >> Empty expression in f-string should
> >> * (silently) expand as '{}' (opening and closing braces),
> >> * generate a (compile time) warning if requested, e.g. with -W.
> >
> >We could do that, but this is more likely to just hide bugs in the
> >f-string than be useful.
>
> Thank you, that would be great and useful.
> Users will be warned before potentially bug two times:
> 1) They will see the {} in output (which should be tested).
> 2) By the compiler when they ask for (-W), which is a better behaviour than 
> forced carefulness.

"We could do that" doesn't mean we will. And I'm definitely -1 on it,
for the reason Steven stated (it is more likely to hide bugs than to
be useful). It's also an odd special case that users will have to
understand ("to get a literal { or } character, double it, unless you
want using precisely {}, when you don't have to double the characters
but you can use {}. You can't use {{} or {}} though, these are right
out")

So no, I don't think this is a good idea, sorry.

>From the Zen, "Special cases aren't special enough to break the rules"
is probably relevant here, and I don't think you have demonstrated
that "Practicality beats purity" applies.

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


[Python-ideas] Re: f-string: empty expression should be allowed

2020-10-22 Thread Hans Ginzel

On Thu, Oct 22, 2020 at 08:31:34PM +1100, Steven D'Aprano wrote:

cursor.execute(f"INSERT INTO {table} VALUES (1, '{}');")
SyntaxError: f-string: empty expression not allowed


Escape the braces by doubling them:
   f"INSERT INTO {table} VALUES (1, '{{}}');"


Thank you for (ugly) workaorund.


The problem here is with the f-string, not the call to cursor.execute.
We can simplify the example to this:
   f'{}'
and avoid the distraction of JSON, SQL, databases, etc.


Technically we can, but the context give us a useful example.
Strings like f"Use braces ({}) for {something}."
are also a useful example.


Empty expression in f-string should
* (silently) expand as '{}' (opening and closing braces),
* generate a (compile time) warning if requested, e.g. with -W.


We could do that, but this is more likely to just hide bugs in the
f-string than be useful.


Thank you, that would be great and useful.
Users will be warned before potentially bug two times:
1) They will see the {} in output (which should be tested).
2) By the compiler when they ask for (-W), which is a better behaviour than 
forced carefulness.

--
BR, H.
___
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/2B5KEM34SUO3TXDMMZE6A332L3SKVLEF/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: f-string: empty expression should be allowed

2020-10-22 Thread Steven D'Aprano
On Thu, Oct 22, 2020 at 10:58:00AM +0200, Hans Ginzel wrote:
> Hello,
> 
> consider this snippet please
> 
> cursor.execute(f"INSERT INTO {table} VALUES (1, '{}');")
> SyntaxError: f-string: empty expression not allowed


Escape the braces by doubling them:

f"INSERT INTO {table} VALUES (1, '{{}}');"


> It is (absolutely) correct to insert empty json into database table field.

Sure, but the syntax error has nothing to do with the database. The 
syntax error occurs long before the SQL gets executed. The problem here 
is with the f-string, not the call to cursor.execute.

We can simplify the example to this:

f'{}'

and avoid the distraction of JSON, SQL, databases, etc.


> Empty expression in f-string should
> * (silently) expand as '{}' (opening and closing braces),
> * generate a (compile time) warning if requested, e.g. with -W.

We could do that, but this is more likely to just hide bugs in the 
f-string than be useful.


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


[Python-ideas] Re: f-strings as assignment targets

2020-10-22 Thread Steven D'Aprano
On Wed, Oct 21, 2020 at 07:17:21PM -0700, Guido van Rossum wrote:

> Hmm, if the above is acceptable, maybe f-strings are still the logical next
> step, since they bring the format and the target name together again.

That's not the only way to bring the format and target name together. 
Both brace-style and percent-style can do that:

'{number:d}'
'%(number)d'

I'm not sure if you've caught up on the entire thread, but Eric Smith is 
opposed to this:

https://mail.python.org/archives/list/python-ideas@python.org/message/KTGQLT4TY672GRF6JFV6MZHUE4J4S3NS/

(For the benefit of those who aren't aware of the f-string history, Eric 
wrote the PEP and at least part of the implementation.)

f-strings also bring so much more to the table than is needed. For this 
syntax to be sensible, we would have to prohibit so many legal f-strings 
that it seems perverse to continue calling the subset of what's left 
over f-strings.

1. They don't behave like f-strings: text scanning, not evaluation of 
code. What meaning could we give an f-string target like this?

f'{len(x)+1}' = string


2. They don't support the same formatting options as f-strings.

Chris has suggested a superset of formatting options, similar to 
regexes; other f-string codes would be meaningless:

f'a {spam:^5_d} b' = 'a 1234 b'
# centre align; group digits using underscore

3. As Eric explains, they don't share the same mechanism as f-strings.

4. Actual f-strings need the prefix to distinguish them from regular 
strings. But as an assignment target, there is no existing meaning to

'email: {name}@{domain}' = string

so the f prefix has no purpose.

When they have so little in common with f-strings, apart from a spurious 
and unnecessary f-prefix, why are we calling them f-strings?

Another problem is that using only a literal/display form as a target 
means you can't pre-assemble a pattern and apply it later:

# Match only the given domain.
domain = get_wanted_domain()
pattern = 'email: {name}@%s' % domain
# ... now what?

I guess you could fall back to eval:

eval('f{!r} = {!r}'.format(pattern, string))

but given that both the pattern and the string to be scanned are likely 
to contain untrusted strings, that's probably not a good idea.



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


[Python-ideas] f-string: empty expression should be allowed

2020-10-22 Thread Hans Ginzel

Hello,

consider this snippet please

cursor.execute(f"INSERT INTO {table} VALUES (1, '{}');")
SyntaxError: f-string: empty expression not allowed

It is (absolutely) correct to insert empty json into database table field.
Empty expression in f-string should
* (silently) expand as '{}' (opening and closing braces),
* generate a (compile time) warning if requested, e.g. with -W.

Thank you in advance
Hans
___
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/P2JVICNTXT5WEHGVLBGZASKBOC2CNSVF/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: f-strings as assignment targets

2020-10-22 Thread M.-A. Lemburg
On 22.10.2020 04:12, David Mertz wrote:
> To bring it back to a concrete idea, here's how I see things:
> 
>  1. The idea of f-string-like assignment targets has little support.  Only
> Chris, and maybe the OP who seems to have gone away.
>  2. The idea of a "scanning language" seems to garner a fair amount of
> enthusiasm from everyone who has commented.
>  3. Having the scanning language be "inspired by" f-strings seems to fit 
> nicely
> with Python
>  4. Lots of folks like C scanf() as another inspiration for the need.  I was 
> not
> being sarcastic in saying that I thought COBOL PICTURE clauses are another
> similar useful case.  I think Perl 6 "rules" were trying to do something
> along those lines... but, well, Perl.
>  5. In my opinion, this is naturally a function, or several related functions,
> not new syntax (I think Steven agrees)
> 
> So the question is, what should the scanning language look like?  Another
> question is: "Does this already exist?"
> 
> I'm looking around PyPI, and I see this that looks vaguely along the same 
> lines.
> But most likely I am missing things: https://pypi.org/project/rebulk/
> 
> In terms of API, assuming functions, I think there are two basic models.  We
> could have two (or more) functions that were related though:
> 
> # E.g. pat_with_names = "{foo:f}/{bar:4s}/{baz:3d}"
> matches = scan_to_obj(pat_with_names, haystack)
> # something like (different match objects are possible choices, dict, 
> dataclass,
> etc)
> print(matches.foo)
> print(maches['bar'])
> 
> Alternately:
> 
> # pat_only = "{:f}/{:4s}/{:3d}"
> foo, bar, baz = scan_to_tuple(pat_only, haystack)
> # names, if bound, have the types indicated by scanning language
> 
> There are questions open about partial matching, defaults, exceptions to 
> raise,
> etc.  But the general utility of something along those lines seems roughly
> consensus.

I like this idea :-)

There are lots of use cases where regular expressions + subsequent
type conversion are just overkill for a small parsing task.

The above would fit this space quite nicely, esp. since it already
comes with a set of typical format you have to parse, without having
to worry about the nitty details (as you have to do with REs) or
the type conversion from string to e.g. float.

-- 
Marc-Andre Lemburg
eGenix.com

Professional Python Services directly from the Experts (#1, Oct 22 2020)
>>> Python Projects, Coaching and Support ...https://www.egenix.com/
>>> Python Product Development ...https://consulting.egenix.com/


::: We implement business ideas - efficiently in both time and costs :::

   eGenix.com Software, Skills and Services GmbH  Pastor-Loeh-Str.48
D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg
   Registered at Amtsgericht Duesseldorf: HRB 46611
   https://www.egenix.com/company/contact/
 https://www.malemburg.com/
___
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/YD6B2JR7QKVD3MBPQMQQUUROFR7B4AQ2/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: f-strings as assignment targets

2020-10-22 Thread Paul Moore
On Thu, 22 Oct 2020 at 03:16, David Mertz  wrote:
>
> To bring it back to a concrete idea, here's how I see things:
>
> The idea of f-string-like assignment targets has little support.  Only Chris, 
> and maybe the OP who seems to have gone away.
> The idea of a "scanning language" seems to garner a fair amount of enthusiasm 
> from everyone who has commented.
> Having the scanning language be "inspired by" f-strings seems to fit nicely 
> with Python
> Lots of folks like C scanf() as another inspiration for the need.  I was not 
> being sarcastic in saying that I thought COBOL PICTURE clauses are another 
> similar useful case.  I think Perl 6 "rules" were trying to do something 
> along those lines... but, well, Perl.

There's also SNOBOL (and Icon) matching functions, although they are
less of a pattern "language" and more of a set of building blocks for
making matchers.

> In my opinion, this is naturally a function, or several related functions, 
> not new syntax (I think Steven agrees)
>
> So the question is, what should the scanning language look like?  Another 
> question is: "Does this already exist?"
>
> I'm looking around PyPI, and I see this that looks vaguely along the same 
> lines. But most likely I am missing things: https://pypi.org/project/rebulk/

The other one I know of (mentioned previously somewhere in all of
this) is https://pypi.org/project/parse/

>
> In terms of API, assuming functions, I think there are two basic models.  We 
> could have two (or more) functions that were related though:
>
> # E.g. pat_with_names = "{foo:f}/{bar:4s}/{baz:3d}"
> matches = scan_to_obj(pat_with_names, haystack)
> # something like (different match objects are possible choices, dict, 
> dataclass, etc)
> print(matches.foo)
> print(maches['bar'])
>
> Alternately:
>
> # pat_only = "{:f}/{:4s}/{:3d}"
> foo, bar, baz = scan_to_tuple(pat_only, haystack)
> # names, if bound, have the types indicated by scanning language
>
> There are questions open about partial matching, defaults, exceptions to 
> raise, etc.  But the general utility of something along those lines seems 
> roughly consensus.

Agreed

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