[Python-ideas] Re: re.match(pattern, string, require=True)

2023-10-21 Thread MRAB

On 2023-10-21 21:15, Chris Angelico wrote:

On Sun, 22 Oct 2023 at 06:37, Ram Rachum  wrote:


On Sat, Oct 21, 2023 at 10:30 PM Chris Angelico  wrote:



> I love that, but it mostly makes sense for "if there's a match do this, otherwise do that" where 
most cases fall into "I'm absolutely sure there's a match here and here's what we should do with that 
match", and when that "absolutely sure" fails, the proper way to deal with that is by raising an 
exception.
>

Oh, you mean like AttributeError?



What I propose is like AttributeError in that they are both exceptions, but 
unlike AttributeError in that it'll communicate the problem effectively in a 
way that's easy to understand, especially by people who aren't Python experts.

When you and I see this:

AttributeError: 'NoneType' object has no attribute 'strip'



Which is strong evidence of a bug in your code. You're trying to tell
me that you want a way to enforce that, if the regex doesn't match,
it's a bug in your code. This seems to do that perfectly well.

If it's NOT a bug when the regex doesn't match, you have the standard
conditional form available. I'm not seeing a problem here.

I think what the OP wants is to have re.match either return a match or 
raise an exception.

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


[Python-ideas] Re: SyntaxError: cannot use assignment expressions with attribute

2023-10-08 Thread MRAB

On 2023-10-09 02:17, Dom Grigonis wrote:

Is there a reason why this is not allowed?


return  (self.mode :=  self.mode_valid(mode))


The principal use-case for the operator is in conditions, for example:
if m := re.match(pattern_1, string):
...
elif m := re.match(pattern_2, string):
...
else:
...

or:

while line := file.readline():
...

Do you have a convincing argument that it should be expanded from a 
simple name?


Having:

self.mode = self.mode_valid(mode)
return self.mode

isn't too bad.
___
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/OIZ3W7XOIAFU345FKXN63YOC2J7E4R5I/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Extract variable name from itself

2023-09-13 Thread MRAB

On 2023-09-12 16:54, Rob Cliffe via Python-ideas wrote:



On 12/09/2023 11:54, Dom Grigonis wrote:

Yes, Thank you!

So 2 solutions now. They both solve what I have encountered. Beyond that, they 
differ by:

a) f-string print(f’{=a.method}’)   # ‘a.method’
No new builtin needed.
Simply reprints expression representation.


I don't understand your semantics either.  What would be the difference 
between your proposed

     print(f’{=a.method}’)
and simply writing
     print('a.method')
?

Would it be just that the syntax inside the curly braces is checked for 
legality,

so that
     print(f'{=!?}')
would not be allowed (presumably it would cause a SyntaxError)
?

Or do you want to check that the expression can be evaluated at run time?
You could achieve that by simply writing
     a.method

As for the example in your first post:
var = 710
variable_name = [k fork, v inlocals().items()ifv == 710][0]
print("Your variable name is "+ variable_name)

it does "work", but it doesn't make much sense with Python's semantics.  
You could have two identifiers bound to the same object; which one you 
got hold of would be essentially random.



I think the point is to have an equivalent to C#'s 'nameof'.

It would be evaluated at compile time to a string, but with the 
advantage that it's clear that it's a name and not some random string 
that just happens to look like a name.


For example, if you had, say:

print('The value of count is', count)

then an IDE wouldn't know that the "count" in the string literal is the 
name of the variable 'count', whereas in:


print('The value of', nameof(count), 'is', count)

it's clear that you're giving the name.

An IDE would be able to rename it correctly.

This:

print('The value of', nameof(count), 'is', count)

would be compiled as:

print('The value of', 'count', 'is', count)

Tell the IDE to rename 'count' to 'my_count' and you get:

print('The value of', nameof(my_count), 'is', my_count)

which would be compiled as:

print('The value of', 'my_count', 'is', my_count)

Telling an IDE to rename when you have:

print('The value of', 'count', 'is', count)

would give you:

print('The value of', 'count', 'is', my_count)

It would miss the string literal 'count', and you'd have to fix that by 
hand.

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


[Python-ideas] Re: Proposal for get_or function in Python dictionaries

2023-07-17 Thread MRAB

On 2023-07-17 18:10, Dom Grigonis wrote:


It does exactly the same as the C version and is more readable.  Or am 
I missing something?


My point is exactly that it is not easily readable compared to C 
version. Also, unnecessarily verbose. The order of components is rather 
awkward.


I came to this, because people seem to want one-liners for certain 
things and what I came up with is that maybe more concise if-else 
expression could help.



# Fairly reasonable case.

def  foo(a:bool, c:float, d:float)
 val=  a?  (c?  c : d) : (d?  d : c)
 return  val

# Comapred to
def  bar(a:bool, c:float, d:float)
 val=  (cif  celse  d)if  aelse  (dif  delse  c)
 return  val


Maybe for someone who majored in languages python’s if-else is more 
easily understood. To me, personally, 2nd one is unbearable, while 1st 
one is fairly pleasant and satisfying.


This whole thing started from dict’s `get` extension:


def  get_substitute(self, key, default=None, subs=()):
 return  keyin  self  ?  (self[key] :=  valin  subs?  subs[val] : val) : 
default

I dare you to do a 1-liner with current if-else.


def get_substitute(self, key, default=None, subs=()):
return (self[key] := subs[val] if val in subs else val) if key in 
self else default


Where does 'val' come from?

[snip]

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


[Python-ideas] Re: dict method to retrieve a key from a value

2023-07-02 Thread MRAB

On 2023-07-02 17:14, Stephen J. Turnbull wrote:

MRAB writes:

  > I would hope that if the maintainer knew that the package was on
  > the curated list, they would let the list know if they were going
  > to stop maintaining it. That would be part of being on the list -
  > informing the list's maintainers of any significant change of
  > status.

How do you enforce that that?  Yup, it's the responsibility of the
list curators because the package maintainers aren't always going to
do it.  Really, curating has to include removing packages that no
longer deserve listing as well as adding ones that do.

Well, you wouldn't be able to enforce it, but whether the maintainer 
shows a willingness to inform the list would be a factor in whether to 
include it.

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


[Python-ideas] Re: dict method to retrieve a key from a value

2023-07-02 Thread MRAB

On 2023-07-02 06:59, Chris Angelico wrote:

On Sun, 2 Jul 2023 at 15:48, Christopher Barker  wrote:

Only re (the one in the stdlib)? What if you want PCREs -
there's no package called "pcre" but there's "pcre2", "python-pcre",
and probably others.



And are those three (and others?) actually useful maintained packages? Or 
someone's abandoned experiment?  Who the heck knows without digging into each 
one?

I would hope that if the maintainer knew that the package was on the 
curated list, they would let the list know if they were going to stop 
maintaining it. That would be part of being on the list - informing the 
list's maintainers of any significant change of status.


Would you know that even if they were on some official curated list?
Projects get abandoned at any time, and unless the curators are
constantly checking every package for currency, it's no different -
except that people will expect it to be different.


NOTE: I did a (very) quick google to see if someone had written a blog about 
PCREs in Python that might provide some guidance -- no luck. I like your 
decentralized blog idea, but I'm not sure how to get people to write them :-)



Indeed. But I expect it'd be easier to get one person to write one
blog post about their favourite packages than to create some sort of
comprehensive list of everything that's good :)



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


[Python-ideas] Re: dict method to retrieve a key from a value

2023-07-01 Thread MRAB

On 2023-07-01 11:22, Paul Moore wrote:
On Sat, 1 Jul 2023 at 07:09, Christopher Barker > wrote:


So I think light curation would help a lot. [*]

I'd be completely in favour of someone setting up a curated package 
index. You could probably use the Warehouse codebase if you didn't want 
to write your own. There would probably be a small amount of work to do 
re-branding. You might also need to write something to put a moderation 
layer on the upload interface. I'm not familiar with the Warehouse 
codebase, so I don't know what that would involve.


Assuming it gets sufficient popularity, it could apply for PyPA 
membership if it wanted to be "official" (whatever that means ;-))


The problem isn't so much with the idea, it's with the fact that 
everyone likes talking about it, but no-one will actually *do* it. And 
everyone underestimates the amount of work involved - running PyPI, with 
its bare minimum curation (blocking malware and typosquatting) is a huge 
effort. Why do people think a new index with ambitions of more curation 
would take *less* effort? Or do people have the sort of resources that 
PyPI consumes lying around looking for something to do? Because if so, 
there's plenty of other projects looking for resources (a PyPI build 
farm, anyone?)


  Who said anything about the PSF?


Nobody, I guess, but it's symptomatic of what I said above - everyone 
assumes *someone else* will do the work, and the convenient "someone 
else" is usually the PyPA or the PSF.



How about adding ticks to some PyPI packages? :-)

(There's still the problem of who gets to decide which ones get a tick...)
___
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/J6JDGX4ZRH36BC63DH6USTDS5LSJR3PW/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: else without except

2023-06-30 Thread MRAB

On 2023-06-30 14:55, Daniel Walker wrote:

As most of you probably know, you can use else with try blocks:

try:
     do_stuff()
except SomeExceptionClass:
    handle_error()
else:
    no_error_occurred()

Here, no_error_occurred will only be called if do_stuff() didn't raise 
an exception.


However, the following is invalid syntax:

try:
    do_stuff()
else:
    no_error_occurred()

Now you might say that this isn't needed as you can achieve the same 
result with


do_stuff()
no_error_occurred()

However, what if I want to use finally as well:

try:
    do_stuff()
else:
    no_error_occurred()
finally:
    cleanup()

and I need no_error_occurred to be called before cleanup?  For my actual 
use case, I've done


try:
    do_stuff()
except Exception:
     raise
else:
    no_error_occurred()
finally:
    cleanup()

This seems very non-Pythonic.  Is there a reason why else without except 
has to be invalid syntax?



What would be the difference between

try:
   do_stuff()
else:
   no_error_occurred()
finally:
   cleanup()

and

try:
   do_stuff()
   no_error_occurred()
finally:
   cleanup()

?

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


[Python-ideas] Re: Warn when iterating over an already exhausted generator

2023-06-13 Thread MRAB

On 2023-06-13 16:42, Chris Angelico wrote:

On Wed, 14 Jun 2023 at 01:07, BoppreH via Python-ideas
 wrote:

And I have to say I'm surprised by the responses. Does nobody else hit bugs 
like this and wish they were automatically detected?



Nope, I've never had that happen to me, and I *have* made use of
calling iter() on potentially-exhausted iterators (usually
implicitly).


I think I might've done it once, but I can't be sure...
___
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/XM5PGLOBDNUKLTYG3EVO3D4YU6MY5AKF/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: @lazy decorator an alternative to functools.partial ?

2023-05-18 Thread MRAB

On 2023-05-19 00:54, Greg Ewing wrote:

On 19/05/23 4:16 am, Christopher Barker wrote:
The problem with "batteries included" is that what exactly is a 
battery is hard to define, and everyone has a different opinion about it.


To my mind, "batteries included" means you can do *something*
useful with it out of the box. It doesn't mean you can do
*everything* you might want to do.


As Tim Peters has said: "Batteries included - but not nuclear reactors".
___
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/7WOG5TOKGSCHP5SRUQU23J6MOF5VUADZ/
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-29 Thread MRAB

On 2023-04-29 08:31, Matsuoka Takuo wrote:

On Sat, 29 Apr 2023 at 00:52, 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}'.

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.


That's a quite subtle point.  I think
'{open}...{close}'.partial_format(open='{close}') could be the string

   '{open}...{close}'.format(open='{{close}}', close='{close}')

and '{open}...{close}'.partial_format(open='{') could be
'{open}...{close}'.format(open='{{', close='{close}')


You might not know what the replacements are until runtime, so:

'{open}...{close}'.partial_format(open=opening_item)

___
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/ZBYAULU76TLRZZOH4OMQB5VE74WPCVZE/
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-26 Thread MRAB

On 2023-04-26 17:41, Alexandre Brault wrote:

On 2023-04-26 11:03 a.m., MRAB wrote:

On 2023-04-26 02:16, Joao S. O. Bueno wrote:
On Sat, Apr 22, 2023 at 10:06 AM Damian Cross <mailto:damnedbo...@gmail.com>> wrote:


    That would have the effect that every use of str.format for everyone
    would start producing partially-formatted strings if an argument is
    accidentally omitted instead of raising an error. Some people might
    not like that.
    ___

If that is all there is for a downside, this is actually quite weak. 
You just changed my mind to +1  on the proposal.


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.


We can't stal all augmenting to language functionalities because  
"some is used with the fact writing incorrect code in this way used 
to produce an error before".  Ultimately, by this logic, it would be 
impossible to add even any new keyword only parameters to any stdlib 
call, because  "there might be some code out there using this 
parameter, and that used to raise an error"


The problem is that the resulting string might or might not be fully 
formatted, but you wouldn't be sure.


The original post itself almost demonstrates the issue. I say "almost" 
because it has:


>>> r"\mathjax{{color}}{{text}}".format(color="blue", text="Spanish")

which is '\\mathjax{color}{text}', not "\\mathjax{blue}{Spanish}", 
because "{{" and "}}" are literals.


After correction:

>>> pfr = r"\mathjax{{{color}}}{{{text}}}".format(color="blue")

So, pfr == r"\mathjax{blue}{{{text}}}".

That looks like a format string with 2 placeholders, "{blue}" and 
"{text}".



It's probably worse than that. I would suspect/expect pfr to be
r"\mathjax{blue}{text}"; I see no reason why the brace literals
surrounding {text}  would be left unescaped and the other ones escaped.



You'd be better off creating a new Format class that parses a format 
string and lets you insert values:


>>> fmt = Format(r"\mathjax{{{color}}}{{{text}}}")
>>> fmt
Format('\\mathjax{{{color}}}{{{text}}}')

(Calling it "Format" has the disadvantage that it's too close to the 
build-in function "format".)


Placeholders can be positional or named, which is like the arguments 
of function calls, so maybe it's a callable:


>>> fmt = fmt(color="blue")
>>> fmt
Format('\\mathjax{{{color}}}{{{text}}}', color='blue')
>>> fmt = fmt(text="Spanish")
>>> fmt
Format('\\mathjax{{{color}}}{{{text}}}', color='blue', text='Spanish')
>>> str(fmt)
'\\mathjax{blue}{Spanish}'
>>> print(fmt)
\mathjax{blue}{Spanish}

The advantages of leaving it as a format each time are 1) it can 
ignore unneeded values and 2) it consistently returns an instance of 
the same type.



Doesn't that essentially already exist as `string.Template` (albeit with
a different though configurable identifier substitution language).

  >>> import string
  >>>
string.Template(r'\mathjax{$color}{$text}').safe_substitute(color='blue')
r'\mathjax{blue}{$text}'

It allows partial substitution, but the result is a string, so it 
suffers from the same problem.


___
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/S4A4XF2J77KXVXSSV4RR3V3WJZF33CCK/
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-26 Thread MRAB

On 2023-04-26 02:16, Joao S. O. Bueno wrote:
On Sat, Apr 22, 2023 at 10:06 AM Damian Cross > wrote:


That would have the effect that every use of str.format for everyone
would start producing partially-formatted strings if an argument is
accidentally omitted instead of raising an error. Some people might
not like that.
___

If that is all there is for a downside, this is actually quite weak. You 
just changed my mind to +1  on the proposal.


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.


We can't stal all augmenting to language functionalities because  "some 
is used with the fact writing incorrect code in this way used to produce 
an error before".  Ultimately, by this logic, it would be impossible to 
add even any new keyword only parameters to any stdlib call, because  
"there might be some code out there using this parameter, and that used 
to raise an error"


The problem is that the resulting string might or might not be fully 
formatted, but you wouldn't be sure.


The original post itself almost demonstrates the issue. I say "almost" 
because it has:


>>> r"\mathjax{{color}}{{text}}".format(color="blue", text="Spanish")

which is '\\mathjax{color}{text}', not "\\mathjax{blue}{Spanish}", 
because "{{" and "}}" are literals.


After correction:

>>> pfr = r"\mathjax{{{color}}}{{{text}}}".format(color="blue")

So, pfr == r"\mathjax{blue}{{{text}}}".

That looks like a format string with 2 placeholders, "{blue}" and "{text}".

And what happens if the partially-formatted string isn't a valid format 
string?


So I'm -1 on the idea.

You'd be better off creating a new Format class that parses a format 
string and lets you insert values:


>>> fmt = Format(r"\mathjax{{{color}}}{{{text}}}")
>>> fmt
Format('\\mathjax{{{color}}}{{{text}}}')

(Calling it "Format" has the disadvantage that it's too close to the 
build-in function "format".)


Placeholders can be positional or named, which is like the arguments of 
function calls, so maybe it's a callable:


>>> fmt = fmt(color="blue")
>>> fmt
Format('\\mathjax{{{color}}}{{{text}}}', color='blue')
>>> fmt = fmt(text="Spanish")
>>> fmt
Format('\\mathjax{{{color}}}{{{text}}}', color='blue', text='Spanish')
>>> str(fmt)
'\\mathjax{blue}{Spanish}'
>>> print(fmt)
\mathjax{blue}{Spanish}

The advantages of leaving it as a format each time are 1) it can ignore 
unneeded values and 2) it consistently returns an instance of the same type.


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


[Python-ideas] Re: Combinations of keywords

2023-02-21 Thread MRAB

On 2023-02-21 11:26, Steven D'Aprano wrote:
[snip]

If your code blocks are a single statement, you can write:

 try: import windows_module
 except ImportError: import unix_module

but most people will say that is ugly and be spread out:

 try:
 import windows_module
 except ImportError:
 import unix_module


I can think of one use-case.

Suppose this:

try:
import windows_module as module
except ImportError:
import unix_module as module

could be shortened to this:

import windows_module else unix_module as module

Not that I'm in favour of it, because it occurs too rarely to be worth a 
special syntax.


[snip]

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


[Python-ideas] Re: Add a line_offsets() method to str

2022-06-20 Thread MRAB

On 2022-06-20 16:12, Christopher Barker wrote:
Hmm - I’m a bit confused about how you handle mixed / multiple line 
endings. If you use splitlines(), then it will remove the line endings, 
so if there are two-char line endings, then you’ll get off by one 
errors, yes?


I would think you could look for “\n”, and get the correct answer ( with 
extraneous “\r”s in the substrings…


-CHB

How about something like .split, but returning the spans instead of the 
strings?


On Mon, Jun 20, 2022 at 5:04 PM Christopher Barker > wrote:


If you are working with bytes, then numpy could be perfect— not a
small dependency of course, but it should work, and work fast.

And a cython method would be quite easy to write, but of course
substantially harder to distribute :-(

-CHB

On Sun, Jun 19, 2022 at 5:30 PM Jonathan Slenders
mailto:jonat...@slenders.be>> wrote:

Thanks all for all the responses! That's quite a bit to think about.

A couple of thoughts:

1. First, I do support a transition to UTF-8, so I understand we
don't want to add more methods that deal with character offsets.
(I'm familiar with how strings work in Rust.) However, does that
mean we won't be using/exposing any offset at all, or will it
become possible to slice using byte offsets?

2. The commercial application I mentioned where this is critical
is actually using bytes instead of str. Sorry for not mentioning
earlier. We were doing the following:
     list(accumulate(chain([0], map(len, text.splitlines(True)
where text is a bytes object. This is significantly faster than
a binary regex for finding all universal line endings. This
application is an asyncio web app that streams Cisco show-tech
files (often several gigabytes) from a file server over HTTP;
stores them chunk by chunk into a local cache file on disk; and
builds a index of byte offsets in the meantime by running the
above expression over every chunk. That way the client web app
can quickly load the lines from disk as the user scrolls through
the file. A very niche application indeed, so use of Cython
would be acceptable in this particular case. I published the
relevant snippet here to be studied:

https://gist.github.com/jonathanslenders/59ddf8fe2a0954c7f1865fba3b151868


It does handle an interesting edge case regarding UTF-16.

3. The code in prompt_toolkit can be found here:

https://github.com/prompt-toolkit/python-prompt-toolkit/blob/master/src/prompt_toolkit/document.py#L209


(It's not yet using 'accumulate' there, but for the rest it's
the same.) Also here, universal line endings support is
important, because the editing buffer can in theory contain a
mix of line endings. It has to be performant, because it
executes on every key stroke. In this case, a more complex data
structure could probably solve performance issues here, but it's
really not worth the complexity that it introduces in every text
manipulation (like every key binding). Also try using the "re"
library to search over a list of lines or anything that's not a
simple string.

4. I tested on 3.11.0b3. Using the splitlines() approach is
still 2.5 times faster than re. Imagine if splitlines() doesn't
have to do the work to actually create the substrings, but only
has to return the offsets, that should be even much faster and
not require so much memory. (I have an benchmark that does it
one chunk at a time, to prevent using too much memory:

https://gist.github.com/jonathanslenders/bfca8e4f318ca64e718b4085a737accf


)

So talking about bytes. Would it be acceptable to have a
`bytes.line_offsets()` method instead? Or
`bytes.splitlines(return_offsets=True)`? Because byte offsets
are okay, or not? `str.splitlines(return_offsets=True)` would be
very nice, but I understand the concerns.

It's somewhat frustrating here knowing that for `splitlines()`,
the information is there, already computed, just not immediately
accessible. (without having Python do lots of unnecessary work.)

Jonathan


Le dim. 19 juin 2022 à 15:34, Jonathan Fine mailto:jfine2...@gmail.com>> a écrit :

Hi

This is a nice problem, well presented. Here's four comments
/ questions.

1. How does the introduction of faster CPython in Python
3.11 af

[Python-ideas] Re: Bare wildcard in de-structuring to ignore remainder and stop iterating (restart)

2022-06-20 Thread MRAB

On 2022-06-20 15:05, Chris Angelico wrote:

On Mon, 20 Jun 2022 at 21:11, Jonathan Fine  wrote:


Hi

Some have liked adding a new syntax
a, b, ... = iterable
to mean consume two items from the iterable. However,
   a, b, Ellipsis = iterable
has a different meaning (at least in Python 3.8). It redefines Ellipsis. (As an 
explicit constant, '...' can be redefined.)


To clarify: The syntactic token '...' will always refer to the special
object Ellipsis (at least back as far as Python 3.4 - can't remember
when it became available in all contexts), but the name Ellipsis can
be rebound. So even though, in many contexts, "x = Ellipsis" and "x =
..." will have the same net effect, they are distinct (one is a name
lookup and the other is a constant), and they're definitely different
in assignment.

(Though it wouldn't surprise me if a future Python release adds
Ellipsis to the set of non-assignable names, with None/True/False.)


The syntax
  a, b, ... = iterable
so to speak fills a gap in existing syntax, as the construct is at present 
invalid. I actually like gaps in syntax, for the same reason that I like a 
central reservation in a highway. The same goes for the hard shoulder / 
breakdown lane.

The title of this thread includes the phrase 'Stop Iterating' (capitals added). 
This suggests the syntax
  a, b, StopIterating = iterable
where StopIterating is a new keyword that can be used only in this context.

I'd like to know what others think about this suggestion.



Hard no. That is currently-legal syntax, and it's also clunky. I'd
much rather the "assign to ..." notation than a weird new soft keyword
that people are going to think is a typo for StopIteration.

It's worth noting that the proposed syntax has a slight distinction
from the normal asterisk notation, in that it makes perfect sense to
write this:

a, *_, b = thing

but does not make sense to write this:

a, ..., b = thing

as the "don't iterate over this thing" concept doesn't work here.
(Supporting this would require some way to reverse the iterator, and
that's not a language guarantee.)

It could be taken to mean "consume but discard", leaving 'a' bound to 
the first item and 'b' bound to the last item, but then:


a, ... = thing

would have to leave 'a' bound to the first item and the iterator exhausted.

In fact, use of ... would always have to exhaust the iterator, which, I 
think, would not be very useful.


Best not to go that way.
___
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/5NXRQSQVZWLIOU64E3CHH4H57VATAOLU/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Add a line_offsets() method to str

2022-06-18 Thread MRAB

On 2022-06-18 21:55, Jonathan Slenders wrote:
Good catch! One correction here, I somewhat mixed up the benchmarks. I 
forgot both projects of mine required support for universal line endings 
exactly like splitlines() does this out of the box. That requires a more 
complex regex pattern. I was actually using:

re.compile(r"\n|\r(?!\n)")
And then the regex becomes significantly slower than the splitlines() 
solution, which is still much slower than it has to be.


If you're opening a file as text, it'll default to universal line 
endings, so the strings you'll get will have only '\n' as the line ending.


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


[Python-ideas] Re: Bare wildcard in de-structuring to ignore remainder and stop iterating (restart)

2022-06-17 Thread MRAB

On 2022-06-17 14:10, Jonathan Fine wrote:

Hi

Consider
     >>> a, b, *_ = iter('abdef')
     >>> a, b, None = iter('abdef')
       File "", line 1
     SyntaxError: can't assign to keyword

If providing this feature is found to be a good idea, it might be better 
to use 'None' or even a new keyword rather than '*'. Obvious benefits is 
it avoids further overloading '*', reduces the opportunity for a 
fat-fingers error, and a lazy eyes code review error. It's also easier 
to check a source file for use of this new feature.


If you can't find a good keyword for this feature, then that would 
suggest that it's not a good idea.



How about "..."?

>>> a, b, *_ = iter('abdef')
>>> a, b, ... = iter('abdef')
  File "", line 1
a, b, ... = iter('abdef')
  ^^^
SyntaxError: cannot assign to ellipsis here. Maybe you meant '==' 
instead of '='?

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


[Python-ideas] Re: Addition to fnmatch.py

2022-06-07 Thread MRAB

On 2022-06-07 11:03, Chris Angelico wrote:

On Tue, 7 Jun 2022 at 19:09, Ben Rudiak-Gould  wrote:


This calls the predicate once per element:

def partition(pred, iterable):
t1, t2 = tee((pred(x), x) for x in iterable)
return (x for b, x in t1 if not b), (x for b, x in t2 if b)

It's kind of inefficient though.


Honestly, if it weren't that there's currently a recipe in itertools,
I think the list-based version would be the best recipe to offer. The
cost of doing the job lazily AND maintaining all the other
expectations is too high; if you really need it to be lazy, it's
probably worth seeing if one of the other demands can be relaxed (eg
if it's fine to call the predicate twice).

For the OP's task, doing the partitioning eagerly wouldn't be an issue.

The problem with a lazy solution is that if you're producing 2 streams 
of output, as it were, and if you're consuming from only one of them, 
what are you going to do about the other one? You still need to store 
the items for it in case you want to consume them later, and if the 
original iterable is infinite, you have a problem...

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


[Python-ideas] Re: Addition to fnmatch.py

2022-06-05 Thread MRAB

On 2022-06-05 16:12, David Mertz, Ph.D. wrote:
This is exactly the problem solved by set difference. E.g. `{a, b, c} - 
{a, c}`.


This operation is linear on the size of the removed set.

You don't have to use a set difference, which might matter if the order 
was important, but just make a set of the ones found:


s = set(b)

And then the list comprehension:

[x for x in a if x not in s]

On Sun, Jun 5, 2022, 11:01 AM John Carter > wrote:


I’d like to propose a simple addition to the 'fnmatch' module.
Specificity a function that returns a list of names that match a
pattern AND a list of those that don't.

In a recent project I found that I wished to split  a list of files
and move those that matched a pattern to one folder and those that
didn't to another folder. I was using fnmatch.filter to select the
first set of files and then a list comprehension to generate the
second set.

For a small number of files (~ 10) this was perfectly adequate.
However as I needed to process many files (>>1) the execution
time was very significant. Profiling the code showed that the time
was spent in generating the second set. I tried a number of
solutions including designing a negative filter, walking the file
system to find those files that had not been moved and using more
and more convoluted ways to improve the second selection. Eventually
I gave in and hacked a local copy of fnmatch.py as below:

def split(names, pat):
     """Return the subset of the list NAMES that match PAT."""
     """Also returns those names not in NAMES"""
     result = []
     notresult = []
     pat = os.path.normcase(pat)
     pattern_match = _compile_pattern(pat)
     if os.path is posixpath:
         # normcase on posix is NOP. Optimize it away from the loop.
         for name in names:
             if not pattern_match(name):
                 result.append(name)
             else:
                 notresult.append(name)
     else:
         for name in names:
             if not pattern_match(os.path.normcase(name)):
                 result.append(name)
             else:
                 notresult.append(name)
     return result, notresult

The change is the addition of else clauses to the if not pattermath
statements. This solved the problem and benchmarking showed that it
only took a very small additional time (20ms for a million strings)
to generate both lists

Number of tests cases 100
Example data ['Ba1txmKkiC', 'KlJx.f_AGj', 'Umwbw._Wa9', '4YlgA5LVpI’]
Search for '*A*'
Test                            Time(sec)       Positive        Negative
WCmatch.filter          1.953125           26211          0
filter                         0.328125    14259          0
split                  0.343750    14259      85741
List Comp.           270.468751     14259      85741

The list comprehension [x for x in a if x not in b]*, was nearly 900
times slower.

‘fnmatch’ was an appropriate solution to this problem as typing
‘glob’ style search patterns was easier than having to enter regular
expressions when prompted by my code.

I would like to propose that split, even though it is very simple,
be included in the 'fnmatch' module.

John

*a is the original and b is those that match.


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


[Python-ideas] Re: Awaiting until a condition is met

2022-05-15 Thread MRAB

On 2022-05-16 00:47, Steven D'Aprano wrote:

On Sun, May 15, 2022 at 03:34:15PM +0100, MRAB wrote:

On 2022-05-15 03:10, Aaron Fink wrote:
>Hello.
>
>I've been thinking it would be nice to be able to use await to suspend 
>execution until a condition is met (as represented by a function or 
>lambda which returns a boolean.

[...]
It's still just polling, so it could be expensive to check very often. 
All the callback is returning is True/False, which isn't very helpful 
for deciding how often it should check.


https://www.youtube.com/watch?v=18AzodTPG5U


Exactly. Now imagine that happening 60 times a second!
___
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/AOKD57X3FKOGPIBSIGKOSXYKB25STXEE/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Awaiting until a condition is met

2022-05-15 Thread MRAB

On 2022-05-15 03:10, Aaron Fink wrote:

Hello.

I've been thinking it would be nice to be able to use await to suspend 
execution until a condition is met (as represented by a function or 
lambda which returns a boolean.


Currently, as far as I can tell, the way to accomplish this is with a 
while loop which frequently checks the condition, suspending execution 
in between checks. My use case is in robotics, so I'll use that. Here's 
a minimal version of my current approach.


start_moving_to(dest)
while distance_to(dest) > tolerance:
     await asyncio.sleep(1 / 60)

This requires choosing a somewhat arbitrary frequency with which to 
check the condition. But if the frequency is too high, the function may 
not be suspended often enough for other tasks to run and if it's too 
low, there's a significant delay before the condition's satisfaction can 
be noticed.


So here's my proposal for syntax that I think is quite a bit cleaner:

start_moving_to(dest)
await lambda: distance_to(dest) <= tolerance

This eliminates the need to choose a frequency and makes the code even 
more readable. Of course, a previously-defined function could be used in 
place of a lambda, which would allow for the even cleaner expression


await has_arrived

if has_arrived is already defined.

While I only have a basic understanding of how the event loop works, it 
seems to me it should be fairly straightforward to add a list of that 
pairs conditions with callbacks and check those conditions on each pass 
through the list of registered callbacks, fairly similarly to how 
scheduled callbacks created with asyncio.sleep wait until enough time 
has passed.


Looking forward to hearing people's thoughts.


I don't see how that could work.

It's still just polling, so it could be expensive to check very often. 
All the callback is returning is True/False, which isn't very helpful 
for deciding how often it should check.


As for your robotics example, you could adjust the frequency of checking 
according to how far it still has to go and how fast it's getting there 
- if it won't get anywhere close to the destination in, say, the next 
second, there's not much point in checking every 1/60 seconds. There can 
be a minimum frequency of checking, and you can increase the frequency 
as it gets very close to the destination.

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


[Python-ideas] Re: Time to relax some restrictions on the walrus operator?

2022-05-08 Thread MRAB

On 2022-05-08 13:44, Chris Angelico wrote:

On Sun, 8 May 2022 at 22:09, Valentin Berlier  wrote:


A while ago there was a discussion about allowing "match" patterns for the 
walrus operator. This would cover iterable unpacking as you suggested along with all the 
patterns allowed in match statements.

if [x, y, z] := re.match(r"...").groups():
print(x, y, z)

The walrus expression would evaluate to None if the pattern on the left can't 
be matched.



What if it does match, though? That's a little less clear. I like the
idea, but I'm not entirely sure what this should do, for instance:

print( {"x": x} := some_dict )

Clearly it should assign x to some_dict["x"] if possible, but then
what should get printed out? A small dict with one key/value pair? The
original dict? There would need to be a guarantee that the return
value is truthy, otherwise it'll create bizarre situations where you
try to match and it looks as if the match failed.

Perhaps the solution would be to add another operator, "?=", that would 
return True if the binding succeeded and False if it failed.



By the way: With any proposal to further generalize assignment
expressions, it'd be good to keep in mind the "implicit nonlocal"
effect that they currently have with comprehensions:


def f():

... x, y = "old x", "old y"
... print([(x := "new x") for y in ["new y"]])
... return x, y
...

f()

['new x']
('new x', 'old y')




My best guess is that this effect should be extended to any simple
names that could _potentially_ be assigned to, even if (as in the case
of some match expressions) they might not all actually be assigned to.


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


[Python-ideas] Re: Time to relax some restrictions on the walrus operator?

2022-05-08 Thread MRAB

On 2022-05-08 11:50, Steven D'Aprano wrote:

I don't have an opinion one way or the other, but there is a discussion
on Discourse about the walrus operator:

https://discuss.python.org/t/walrus-fails-with/15606/1


Just a quick straw poll, how would people feel about relaxing the
restriction on the walrus operator so that iterable unpacking is
allowed?

 # Currently a syntax error.
 results = (1, 2, (a, b) := (3, 4), 5)

Doesn't ':=' have a lower precedence than ',', so you're effectively 
asking it to bind:


(1, 2, (a, b))

to:

((3, 4), 5)

?


which would create the following bindings:

 results = (1, 2, (3, 4), 5)
 a = 3
 b = 4

A more complex example:

 expression = "uvwxyz"
 results = (1, 2, ([a, *b, c] := expression), 5)

giving:

 results = (1, 2, "uvwxyz", 5)
 a = "u"
 b = ("v", "w", "x", "y")
 c = "z"


Thoughts?


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


[Python-ideas] Re: Custom literals, a la C++

2022-04-11 Thread MRAB

On 2022-04-11 20:01, Chris Angelico wrote:
[snip]


Which raises the question: what if the current directory no longer has
a path name? Or is that simply not possible on Windows? I know that on
Linux, I can unlink a directory while being in it (which creates
interesting problems for bash, git, and other tools, but not
fundamental ones for the process model itself), and many references
WILL be resolved correctly. Or I can move the directory to another
parent, and "pwd" says the original name (because that's a shell
feature), but "ls .." will list the contents of the new directory.


Windows won't let you delete a directory that's currently being used.

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


[Python-ideas] Re: A modulo operator consistent with euclidean division.

2022-03-18 Thread MRAB

On 2022-03-19 02:38, Steven D'Aprano wrote:

Hi Nathan, and welcome!


On Fri, Mar 18, 2022 at 05:13:16AM -, Nathan Levett wrote:

First time posting here ~ I've recently encountered that python does 
not have an OOTB operator for modulo that is consistent with Euclidean 
division. Although it should be easy for anyone who wants this to 
create it themselves, it struck me as odd that it was not an already 
included feature. I was even more shocked to see a list indicating 
that most languages don't include one consister with Euclidean 
division (disheartening to realise that the number theory way of doing 
things is not the default).


Your post would be more persuasive if you:

* explained how Python's modulo is not consistent with Euclidean division;

* defined what definition of modulo is "the number theory way of doing things";

* told us what languages you have found that do include this version of modulo.


Wikipedia describes Euclidean division.

Basically, the modulo is non-negative:

a == b * q + r where 0 <= r < abs(b)


I'm not sure what part of number theory you are referring to. You should
explain, since its not obvious. I've just grabbed one of my text books,
and it doesn't even define a modulo operator. It only defines modulo
arithmetic, as in:

 a is congruent to b mod m if m∣(a-b)

with a, b, m ∈ ℤ and m non-negative.

where ∣ is "divides". Although both a and b may be negative, not one of
the examples or exercises include examples where they are negative.

Wolfram language (Mathematica) define their Mod[a, b] function:

 a mod b = a - b*floor(a/b)

which for real-valued a, b gives the result with the same sign as b.

https://functions.wolfram.com/IntegerFunctions/Mod/

That, I believe, makes it the same as Python's % operator.

Ada has two functions, mod() and rem(). I believe that mod(a, b) is the
same as Python's a%b, while rem(a, b) takes the sign of a rather than
the sign of b.

http://archive.adaic.com/standards/83lrm/html/lrm-04-05.html#4.5.5

Julia has the same:

https://docs.julialang.org/en/v1/manual/mathematical-operations/#Division-functions


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


[Python-ideas] Re: Add a replace method to tuples

2022-03-15 Thread MRAB

On 2022-03-15 23:13, Steven D'Aprano wrote:

On Tue, Mar 15, 2022 at 11:16:04AM +1100, Chris Angelico wrote:


> How do we make a new list with a change other than the same slice and
> concatenation we use with tuples?
>
> alist[:i] + [value] + alist[i+1:]
>
> I mean as an expression, of course we can split it over two statements:
>
> newlist = alist[:]
> newlist[i] = value
>
> which is fine, but it does lose the expressiveness of an expression :-)
>

The functional programming style would be mapping most elements to
themselves, and the one you're replacing to the replacement.


No, that doesn't work, because that is replacing by value, not by
position. You're answering the wrong problem.



(Or, if you need to do it with indices, map the range of integers to
either the original element at that index or the replacement.)


You mean this?

 [value if index == i else alist[i] for index in range(len(alist))]

This would be *slightly* less unpythonic:

 [value if index == i else x for (index, x) in enumerate(alist)]


but I would reject both of those in a code review unless you had clear
proof that they were significantly faster or more optimal than the
standard idioms. Which I am confident you won't have.

I'm so confident that they're slower I'm not even going to time it
myself before saying I'm confident they're slower! *wink*

Famous-last-words-ly y'rs,

I'm wondering whether an alterative could be a function for splicing 
sequences such as lists and tuples which would avoid the need to create 
and then destroy intermediate sequences:


splice(alist, i, 1 + 1, [value])

In Python terms it would be:

def splice(sequence, start, end, insertion):
return sequence[ : start] + insertion + sequence[end : ]

but, as I said, without the intermediate sequences, just allocate to the 
final length and then shallow copy.

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


[Python-ideas] Re: Using "Get Satisfaction" for Python Suggestions

2022-02-22 Thread MRAB

On 2022-02-20 17:56, Stephen J. Turnbull wrote:

Gerrit Holl writes:

  > If voting is limited to a select group (which could be as small as
  > Python core developers, or as large as anyone who has ever had a pull
  > request merged into cpython, or something in-between), then a vote
  > could be a way to measure opinions after a lengthy discussion fails to
  > reach a consensus.

I'm not sure what the benefit of "measuring opinions" is supposed to
be, when those opinions don't bring real resources with them, and few
of them are informed beyond "sounds cool" and "YAGNI".  If a
discussion fails to reach consensus, human brains do OK at holding a
fairly detailed summary of it, including who held what opinion when
discussion ended -- far more informative than the result of a vote.

What a vote can do for you is make an up or down decision, or choose
among alternatives.  But from the project's point of view, these
decisions are rarely pressing (except maybe security fixes, and those
are not going to be discussed publicly, let alone put to a general
vote!)  If an issue is still controversial after a long discussion,
it's usually because there are competing interests in play, and
somebody has to lose something they want.  In those cases, it's almost
always best to table it, and see if any technical progress is made on
reconciling differences about the issue over the next release cycle.

Sure, tabling issues frustrates non-committer proponents (who are also
usually the proponents of voting schemes, what a coincidence!), but
that's normally better than frustrating committers who are against it.

FYI, the verb "to table" has different meanings in US and UK English. In 
US English it means to remove from discussion, whereas in UK English it 
means to propose for discussion, which is the opposite. On a list that 
has an international reach, it's probably best to avoid the verb altogether.

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


[Python-ideas] Re: Regex timeouts

2022-02-16 Thread MRAB

On 2022-02-16 22:13, Tim Peters wrote:

[J.B. Langston ]

Well, I certainly sparked a lot of interesting discussion, which I have
quite enjoyed reading. But to bring this thread back around to its
original topic, is there support among the Python maintainers for
adding a timeout feature to the Python re library?


Buried in the fun discussion was my guess: no way. Python's re is
effectively dead legacy code, with no current "owner". Its commit
history shows very little activity for some years already. Mos\
commits are due to generic "cod\e cleanup" crusades that have nothing
specific to do with the algorithms. None required non-triv\ial
knowledge of the implementation.

Here's the most recent I found that actually changed behavior:

"""
commit 6cc8ac949907b9a1c0f73709c6978b7a43e634e3
Author: Zackery Spytz 
Date:   Fri May 21 14:02:42 2021 -0700

 bpo-40736: Improve the error message for re.search() TypeError (GH-23312)

 Include the invalid type in the error message.
""""

A trivial change.


I will look at the third-party regex library that Jonathan suggested but
I still believe a timeout option would be a valuable feature to have
in the standard library.


Which is the problem:  regex has _dozens_ of features that would be
valuable to have in the standard library. reg\ex is in fact one of the
best regexp libraries on the planet. It already has timeouts, and
other features (like possessive quantifiers) that are actually (unlike
timeouts) frequently asked about by many programmers.

In fact regex started life intending to go into core Python, in 2008:

https://bugs.python.org/issue3825

That stretched on and on, and the endless bikeshedding eventually
appeared to fizzle out in 2014:

https://bugs.python.org/issue2636

In 2021 a core dev eventually rejected it, as by then MRAB had long
since released it as a successful extension module. I assume - but
don't know - he got burned out by "the endless bikeshedding" on those
issue reports.

I eventually decided against having it added to the standard library 
because that would tie fixes and additions to Python's release cycle, 
and there's that adage that Python has "batteries included", but not 
nuclear reactors. PyPI is a better place for it, for those who need more 
than what the standard re module provides.



In any cose, no, no core dev I know of is going to devote their
limited time to reproducing a tiny subset of regex's many improvements
in Python's legacy engine. In fact, "install regex!" is such an
obvious choice at this point that I wouldn't even give time to just
reviewing a patch that added timeouts.

BTW, I didn't mention regex in your BPO report because I didn't know
at the time it already implemented timeouts. I learned that 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/5K3XWIY7YK4RUMIZGYWNETB3N74PTLPZ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Regex timeouts

2022-02-15 Thread MRAB

On 2022-02-16 02:11, Chris Angelico wrote:

On Wed, 16 Feb 2022 at 12:56, Tim Peters  wrote:

Regexps keep "evolving"...


Once upon a time, a "regular expression" was a regular grammar. That
is no longer the case.

Once upon a time, a regular expression could be broadly compatible
with multiple different parser engines. That is being constantly
eroded.

So far, I think they still count as expressions. That's about all we
can depend on.

Is there any sort of standardization of regexp syntax and semantics,
or does everyone just extend it in their own directions, borrowing
ideas from each other to give some not-always-false assurance of
compatibility?

The only regex standard I know of is the POSIX standard, but I don't 
know of a common implementation that follows it. Most tend to follow 
Perl, although Perl borrowed named groups from Python, though with a 
slightly different syntax ("(?...)" instead of "(?P...)").

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


[Python-ideas] Re: Regex timeouts

2022-02-15 Thread MRAB

On 2022-02-15 06:05, Tim Peters wrote:

[Steven D'Aprano ]

I've been interested in the existence of SNOBOL string scanning for
a long time, but I know very little about it.

How does it differ from regexes, and why have programming languages
pretty much standardised on regexes rather than other forms of string
matching?


What we call "regexps" today contain all sorts of things that aren't
in the original formal definition of "regular expressions". For
example, even the ubiquitous "^" and "$" (start- and end-of-line
assertions) go beyond what the phrase formally means.

So the question is ill-defined. When Perl added recursive regular
expressions, I'm not sure there's any real difference in theoretical
capability remaining. Without that, though, and for example, you can't
write a regular expression that matches strings with balanced
parentheses ("regexps can't count"), while I earlier posted a simple
2-liner in SNOBOL that implements such a thing (patterns in SNOBOL can
freely invoke other patterns, including themselves).

As to why regexps prevailed, traction! They are useful tools, and
_started_ life as pretty simple things, with small, elegant, and
efficient implementations Feature creep and "faster! faster! faster!"
turned the implementations more into bottomless pits now ;-)

Adoption breeds more adoption in the computer world. They have no real
competition anymore. The same sociological illness has also cursed us,
e.g., with an eternity of floating point signed zeroes ;--)

Chris didn't say this, but I will: I'm amazed that things much
_simpler_ than regexps, like his scanf and REXX PARSE
examples,,haven't spread more. Simple solutions to simple problems are
very appealing to me. Although, to be fair, I get a kick too out of
massive overkill ;l-)

Regexes were simple to start with, so only a few metacharacters were 
needed, the remaining characters being treated as literals.


As new features were added, the existing metacharacters were used in new 
ways that had been illegal until then in order to remain 
backwards-compatible.


Add to that that there are multiple implementations with differing (and 
sometimes only slightly differing) features and behaviours.


It's a good example of evolution: often messy, and resulting in clunky 
designs.

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


[Python-ideas] Re: Missing expandvars equivalent in pathlib

2022-02-11 Thread MRAB

On 2022-02-11 20:05, Ricky Teachey wrote:
Just had a thought kernel: what if there were an f-string mini-language 
directive to grab environment variables and expand user paths? That 
seems to me like it could be even more useful beyond just working with 
paths.


Maybe something like:

f"{my_var:$}"

This would return the same as os.path.expandvars("$my_var")

No, that would be the value of the Python variable 'my_var' with the 
format string "$".



I am not sure about user name expansion though. Maybe something like:

f"{user:~}"

...would return the user directory, and this:

f"{:~}"

...would give the same result as os.path.expanduser("~")

---
Ricky.

"I've never met a Kentucky man who wasn't either thinking about going 
home or actually going home." - Happy Chandler



On Fri, Feb 11, 2022 at 2:04 PM Paul Moore > wrote:


On Fri, 11 Feb 2022 at 16:37, Christopher Barker
mailto:python...@gmail.com>> wrote:
 >
 > On Fri, Feb 11, 2022 at 12:28 AM Serhiy Storchaka
mailto:storch...@gmail.com>> wrote:
 >>
 >> expandvars() does not operate on paths, it operates on strings and
 >> bytestrings. There is nothing path-specific here. Expanding
environment
 >> variables consists of three distinct steps:
 >
 > sure -- but it does live in os.paths now, the docs talk about
paths, and it is useful for paths -- so it seems a fine idea to have
that functionality in pathlib.

One way that tying it to paths is bad is that it ignores the path
structure. If environment variable a is "d1/f1" and b is "d2/f2" then
"${a}x${b}" is "d1/f1xd2/f2", which could be very confusing to someone
who sees the value of b and expects the result to be a file in a
directory called d2. Yes, I know that the documentation could make
this clear (the docs in os.path don't, BTW) and I know that it's no
different than the os.path version, but adding an expandvars method to
pathlib feels like throwing good money after bad...

Let's leave it where it is and keep the status quo, or fix it
*properly* and put it somewhere more logical like shlex. Personally I
don't use it that often, so I'm fine with just leaving it alone.


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


[Python-ideas] Re: "frozen" operator Re: Revisiting a frozenset display literal

2022-01-20 Thread MRAB

On 2022-01-21 00:18, Cameron Simpson wrote:

Well, I've just waded through this discussion.

This all feels to me like a special case of "wanting a constant for
bytecode".  What is we had a "freeze" operator, eg:

 |foo|

which would produce a frozen version of foo. I'm liking the vertical
bars myself, I think because it feels vaguely slightly analogous to
"absolute value". So (assuming we can squeeze it into the expression
syntax):

 |{1,2,3}|

always makes a direct frozen set on the same basis that:

 x in {1,2,3}

directly makes a frozenset by expression inspection. Then

Paired with a __freeze__ dunder method, this applies to any type, not
just sets. (Where appropriate of course.)

So:

 |{1,2,3}|   frozen set
 |[1,2,3]|   tuple!
 |any-iterable|  tuple!
 |{1:2, 3:4}|frozen dict

Ths saves us (a) inventing a special syntax for frozen sets and (b)
gateways to freezing many things, starting with the obvious above, via
the __freeze__ dunder method.

This feels more general and less bikeshedable.

My main question is: is the syntax unambiguous?


I don't know whether it's unambiguous, but it could be confusing.

For example, what does this mean:

| a | b |

?

It's:

| (a | b) |

I think.

The problem is that '|' could be an opening '|', a closing '|', or an 
infix '|'.


You don't get this problem with differing open and closing pairs such as 
'(' and ')'.

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


[Python-ideas] Re: Allowing non-ASCII bracket and quote characters in source code

2022-01-18 Thread MRAB

On 2022-01-19 00:02, Steven D'Aprano wrote:

On Wed, Jan 19, 2022 at 10:12:23AM +1100, Chris Angelico wrote:


Not sure about Python, but C and C++ have digraphs and trigraphs as
alternatives for certain symbols, specifically because some
OS/keyboard/language combinations may not be able to easily type the
originals.


I believe that those C digraphs date back to days when ASCII was not a
guaranteed lowest common denominator, and there were computers that did
not support characters such as braces {}. And then C++ just inherited
them from C.

Pascal had the same thing: comments were either {comment} or (*comment*)
specifically because in the 1970s there were lots of computers and OSes
that did not support braces. It wasn't until the early 80s that the
ASCII character set became more or less universally supported in the
English-speaking world.



> Okay. Without looking it up, how would *you* type ⟮ U+27EE "Mathematical
> Left Flattened Parentheses"? On your honour now, don't look it up.

Be careful: don't give people the codepoint number in these
challenges, because a lot of input systems let you enter any character
by keying in the codepoint.


So David has made it clear.



Here's a better challenge: Type five unique open parenthesis signs,
without looking up their key sequences or codepoints.


Yes :-)

"Icon" is/was an interesting language. It did automatic conversions such 
as between numbers and strings.


The problem with that was that it needed more operators.

For example:

"+" for addition and "++" for union.

"|" for alternation, "|" for string concatenation and "|||" for 
list concatenation.


"=" for numerical equals, "==" for string equals and "===" for 
value equals.


It can be difficult to remember what each of a set of similar operators 
is used for.


Python already has 3 pairs with (), [] and {}, and 2 of them have more 
than one use.

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


[Python-ideas] Re: Revisiting a frozenset display literal

2022-01-18 Thread MRAB

On 2022-01-18 23:50, Steven D'Aprano wrote:

On Wed, Jan 19, 2022 at 11:30:36AM +1300, Greg Ewing wrote:


I'd also be happy with making frozenset a keyword.


- int, float, str, tuple, dict, set, exceptions, len, etc
   are not keywords, so they can be shadowed (for good or bad);

- alone out of all the builtin types and functions, frozenset is a
   keyword.

Shadowing of builtin functions is a double-edged feature. But I think
that, having made the decision to make them *not* keywords, they
should either *all* be keywords, or *none*. It is weird to have some of
them shadowable and some of them not.

None, True and False are special values, in a category of their own, so
I don't think the inconsistency there is important. But having frozenset
_alone_ out of the builtin functions and types a keyword would be a real
Wat? moment.

I know about "foolish consistency", but then there is also foolish
inconsistency. If we could just make one builtin function/type a
keyword, with all the optimization advantages that allows for, would we
*really* choose frozenset as the most important?

I don't know, the answer isn't clear to me. But it certainly wouldn't
be my first choice.

A suggestion (that you're probably not going to like!) would be to have 
a way of indicating explicitly that you're referring a builtin, e.g. 
`frozenset` (using backticks).


You could redefine "frozenset", but `frozenset` still refers to the 
builtin "frozenset".

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


[Python-ideas] Re: Revisiting a frozenset display literal

2022-01-18 Thread MRAB

On 2022-01-18 18:54, Neil Girdhar wrote:
Even if f{1} creates a frozenset, I don't think f{} should create a 
frozenset.  I think it makes more sense to keep f{1: 2} open for 
frozendict if it ever makes it in.  Also, {} should be consisten with 
f{} (both should create dicts).  If you want an empty frozenset, you 
would have to do it the same way you do it for sets: either frozenset() 
or f{*()}.



[snip]
An alternative might be to allow {,} for an empty set, which would then 
let you have f{,} for an empty frozenset.


On Tuesday, January 18, 2022 at 1:19:30 PM UTC-5 João Bernardo wrote:


One thing to consider is if we're going to have a syntax capable of
creating an empty frozenset, we need one that creates an empty set.

if f{...} exists, then s{...} should also exist?

Regards
João Bernardo


On Tue, Jan 18, 2022 at 2:59 PM Rob Cliffe via Python-ideas
 wrote:

I'm +1 on the idea.
I'm happy with the
     f{ ... }
syntax (although I did suggest something else).
We already have letter-prefixes, let's stick to them rather than
adding something new (which conceivably might one day find
another use).
Best wishes
Rob Cliffe

On 18/01/2022 15:53, Ricky Teachey wrote:

On Tue, Jan 18, 2022 at 10:02 AM Joao S. O. Bueno
 wrote:

>  but I don't think we should underestimate the cost of
even this small complexity increase in the language.

Actually, I think _maybe_ in this case the "complexity
increase" cost is _negative_. People might waste
more time looking for a way of spelling a frozenset
literal than just filling in "frozenset()".
I for one, even knowing that the cost of
writing "frozenset({1,2,3})" is negligible, would
"feel" better there was a way to spell that without the
needless conversions.

That said, an appropriate prefix for the {} just as we do
for strigns would be nice, and
I disagree that it would be a significant source for
"bugs". The "@{" is a nice
way out if people think "f{}" would be too close to "f()".
And "<1,2,3>" just for frozensets
are indeed overkill. We already do "literal prefixing"
with `"` after all. and formally extending this
prefix usage as needed for other literals seems like a
nice path.
But, as far as bikeshedding go, we also have "literal
sufixing" (2.0j anyone?)- maybe
"{1,2,3}f" ?


I have been following along with not much to comment but this
response sparked something in me.

After reading all the viewpoints I think I would be +1 on the
basic idea, and a +1 on the postfix/suffix syntax just
suggested... the other syntaxes I'm more of +0.5

I like the way the suffix FLOWS with the act of writing the
program. When I write a set, I am primarily focused on /what I
am going to put in it/, and whether or not it should be
mutable is kind of a later thought/debate in my head after I
have established what it contains.

As a dumb example, if my task at hand is "I need to create a
bag of sports balls", I am mostly thinking about what goes
into that bag at first, so I will write that first:

   >>> {Ball("basketball"), Ball("soccer"), Ball("football"),
Ball("golf")}

Now I get to the end of that line, and I then sort of
naturally think "ok does it make sense to freeze this" after i
know what is in it.  With the postfix syntax, I then either
type the f:

   >>> {Ball("basketball"), Ball("soccer"), Ball("football"),
Ball("golf")}f

...or not. With a prefix type syntax, or a smooth bracket
syntax, either:

A. it takes slightly more "work' at this point to "convert"
the set to a frozenset, OR
B. i have to think about ahead of time-- before i have
actually written what is in the set- whether it will be
frozen, or not.

In contrast, when you are deciding whether to write a list vs
a tuple, you are deciding between two things that are
fundamentally far more different IDEAS than a "bag of things,
frozen or unfrozen". A list is very often more of an open
ended stack than it is "an unfrozen tuple". A tuple is very
often much more of an object that can be used as a dictionary
key, or a member of a set, than it is a container of things
(of course, it is a container of things, too). These
differences make is a lot easier to choose, ahead of time,
which one makes sense before you have even written the line of
code.

Maybe I'm making too much of this, but I really like the idea
  

[Python-ideas] Re: Revisiting a frozenset display literal

2022-01-17 Thread MRAB

On 2022-01-17 06:07, Greg Ewing wrote:

U+2744 Snowflake, anyone?

my_frozenset = ❄{1, 2, 3}


That makes me think about using '@':

my_frozenset = @{1, 2, 3}

It's currently used as a prefix for decorators, but that's at the start 
of a line.


It could be a problem for the REPL, though:

>>> @{1, 2, 3}

Looks like a decorator there, but you could parenthesise it in that case:

>>> (@{1, 2, 3})
___
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/AVVD6YWOEKOOJWB53UAQJZCQSMXAM3AG/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Shouldn't 'input' prompt be going to stderr?

2022-01-16 Thread MRAB

On 2022-01-17 03:11, Cameron Simpson wrote:

On 16Jan2022 20:57, MRAB  wrote:
There was a discussion on another forum that mentioned the 'input' 
function, and it made me wonder whether 'input' should be printing the 
prompt to stderr instead of stdout.


The convention is for normal output to go to stdout and error messages 
to go to stderr, so if a program needs to ask the user, shouldn't it be 
using stderr for prompts in order not to mess up the normal output?


This is a good reason to avoid sending prompts to stdout. But stderr
isn't necessarily right either. If stderr's attached to a tty (UNIX,
different techiness for Windows) you could reasonably send to stderr,
otherwise you might be better opening /dev/tty (if you're allowed to,
and if you have one). Etc etc.

There was a long thread in the "Core Development" forum just the other
day about this, here:
https://discuss.python.org/t/builtin-function-input-writes-its-prompt-to-sys-stderr-and-not-to-sys-stdout/12955

Have a read.


Thanks for that.

I did think that it's way too late to change it now, but perhaps an 
argument to redirect the prompt is a possibility.

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


[Python-ideas] Re: Revisiting a frozenset display literal

2022-01-16 Thread MRAB

On 2022-01-17 01:36, Steven D'Aprano wrote:

On Sun, Jan 16, 2022 at 04:23:47PM -0800, Brendan Barnwell wrote:

On 2022-01-16 16:11, Steven D'Aprano wrote:
>Do they? How are they different? You have a start delimiter and an end
>delimiter.
>

[snip]


Hell, even if your argument is just "Nope, I just don't like the look of
it!", I would respect that even if I disagree. Aesthetics are important,
even when they are totally subjective.

If it helps, Julia supports this syntax for typed dicts:

 Dict{keytype, valuetype}(key => value)

where the braces {keytype, valuetype} are optional. That's not a display
syntax as such, or a prefix, but it is visually kinda similar.

Here are some similar syntax forms with prefixes:

* Dylan list displays: #(a, b, c)
* Smalltalk drops the comma separators: #(a b c)
* Scheme and Common Lisp: '(a b c)

and double delimiters:

* Pike: ({ a, b, c })
* Pike dicts: ([ a:b, c:d ])

Not that we could use any of those as-given.


How about doubling-up the braces:

{{1, 2, 3}}

and for frozen dicts:

{{1: 'one', 2: 'two', 3: 'three'}}

if needed?

Those currently raise exception because sets and dics are unhashable.

It might be confusing, though, if you try to nest them, putting a 
frozenset in a frozenset:


{{ {{1, 2, 3}} }}

or, without the extra spaces:

1, 2, 3

but how often would you do that?
___
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/JJICU47NVIU5MJYRASI6SM4J7UFWBGFQ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Shouldn't 'input' prompt be going to stderr?

2022-01-16 Thread MRAB
There was a discussion on another forum that mentioned the 'input' 
function, and it made me wonder whether 'input' should be printing the 
prompt to stderr instead of stdout.


The convention is for normal output to go to stdout and error messages 
to go to stderr, so if a program needs to ask the user, shouldn't it be 
using stderr for prompts in order not to mess up the normal output?

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


[Python-ideas] Re: Revisiting a frozenset display literal

2022-01-16 Thread MRAB

On 2022-01-16 08:27, Steven D'Aprano wrote:
[snip]

dis.dis("frozenset({1, 2, 3})")

   1   0 LOAD_NAME0 (frozenset)
   2 BUILD_SET0
   4 LOAD_CONST   0 (frozenset({1, 2, 3}))
   6 SET_UPDATE   1
   8 CALL_FUNCTION1
  10 RETURN_VALUE

Got that? To create a frozenset of literals, first the compiler creates
a frozenset constant containing what you wanted. Then at runtime, it:

- looks up frozenset in globals and builtins;
- loads the pre-prepared frozenset (which is exactly what we want);
- creates a new set from that frozenset;
- calls the frozenset() function on that set to create a new frozenset
   that duplicates the pre-prepared one;
- and finally garbage-collects the temporary set.


[snip]

Not quite as bad as that:

>>> f = frozenset({1, 2, 3})
>>> f is frozenset(f)
True
___
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/M2N3GNQRCPDYUQK7KGS3T5RI5NE3BBYJ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Add a `count` argument to `list.remove`

2021-12-25 Thread MRAB

On 2021-12-25 23:52, Steven D'Aprano wrote:

On Thu, Dec 23, 2021 at 05:53:46PM -, Stefan Pochmann wrote:

Chris Angelico wrote:
> If you're removing multiple, it's usually best to filter. This is a
> great opportunity to learn about list comprehensions and the
> difference between O(n) and O(n²) :)
> ChrisA

It would be O(n) if done right.


Can you sketch an O(n) algorithm for removing multiple items from an
array, which *doesn't* involving building a temporary new list?

I thought of this:

- walk forward along the list, identifying the indices where the item
   equals the target;

- stop when you reach maxcount, or the end of the list;

- delete the indices in reverse order

which I am pretty sure minimises movement of the items, but that's still
O(N**2). (To be precise, O(N*M) where M is the number of items to be
removed.)

Anyway, it doesn't matter how efficient the code is if nobody uses it.
Some use-cases would be nice.


It can be done with a pass to remove the matches and pack the list:

Where there's a match, move it if you've exceeded maxcount, else 
skip it.


Where there isn't a match, move it.

followed by truncation of the list if necessary.
___
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/3XWXHM5KXBISDOHOKXDYDMAW7KQW6F76/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Add a `count` argument to `list.remove`

2021-12-21 Thread MRAB

On 2021-12-22 01:53, Rob Cliffe via Python-ideas wrote:

Currently list.remove raises ValueError if the element is not in the list.
When called with the count argument, should it raise ValueError if there
are fewer than `count` occurrences of the element in the list?

There's str.replace and str.split that accept a maximum count, and 
functions and methods in the re module that accept a maximum count. Is 
there any place where such a count isn't treated as a maximum?


On 22/12/2021 00:09, Jeremiah Vivian wrote:

I expect some sort of "there's no benefit in this, just write the current 
implementation", indirectly or directly.
Currently, this is the way to remove `num` occurrences of an element from a 
list:

idx = 0
while idx < len(the_list) and num:
 if the_list[idx] == element_to_remove:
 del the_list[idx]
 num -= 1
 else:
 idx += 1

With a `count` argument to `list.remove`, this is how it would be done:

the_list.remove(element_to_remove, count=num)

(Doesn't necessarily have to be a keyword argument)
Is this a good idea?

Speaking of which, is there a use case for a 'key' argument? Just 
wondering...

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


[Python-ideas] Re: PEP 671 (late-bound arg defaults), next round of discussion!

2021-12-12 Thread MRAB

On 2021-12-12 23:49, Steven D'Aprano wrote:

On Sun, Dec 12, 2021 at 12:07:30PM -0700, Carl Meyer wrote:


I don't think this is a fair dismissal of the concern. Taken broadly,
function "wrapping" is extremely common, in the sense that what many
(most?) functions do is call other functions, and there is a wide
spectrum of "wrapping" from "pure wrapper that does not change the
signature at all" through "non-trivial wrapper that has a different
signature but requires some of the same arguments with the same
semantics" all the way to "not a wrapper at all because it uses the
called function for a very small portion of what it does and shares no
signature with it."

In any case where the same argument with the same semantics needs to
be passed through multiple layers of a function call chain (and again,
my experience is this is quite common in real world code; I can
collect some data on this if anyone finds this assertion
unconvincing), non-trivial argument defaults are painful. One is faced
with two unappealing options: either duplicate the non-trivial default
(in which case you have code duplication and more places to update on
any change), or give up entirely on introspectable/legible signatures
and use `*args, **kwargs`.


I think you have identified a real pain point, function wrapping, but it
is a much bigger pain point that just function defaults, and it won't be
made appreciably worse by late-bound defaults.

Over the years, I have written about this pain point a number of times.
It is much more significant than just defaults: it is hits parameter
naming, and order, and annotations.

The problem is that we have no good notation to say that one function
inherits its signature (possibly with changes) from another function.

This is especially noticable during rapid experimental development,
where the signature of functions might be changing rapidly, but it
occurs in stable code too. Even if the signature is changing, the
wrapper nevertheless has to be aware of the signature, and duplicate it.

The idea that this problem is unique, or especially acute, for function
defaults is false. It is a problem across the board:

- if the *order of parameters* changes, the wrapping function must
   also change, unless it exclusively uses keyword arguments;

- if the *parameter names* change, the wrapping function likewise
   must also change, unless it exclusively uses positional arguments;

- if the *parameter type declarations* change, the wrapping function
   should also change, lest the reader get confused, and static or
   runtime type checkers flag the code as wrong.

Or to put it more succinctly:

The wrapper must be aware of the wrapped signature in order to duplicate
it. Function signatures are code, and this is a violation of DRY.

If anything, the "default argument" problem is the *least* issue here,
not the most, because the wrapper can, at least sometimes, just omit the
parameter with a default.

The only solution to this right now is to use `*args, **kwargs`.

If that hurts introspection, then that demonstrates a weakness in our
introspection tools that needs to be fixed.

If you try to reduce the problem by removing defaults, or annotations,
or only using keyword arguments, or only using positional arguments, not
only does it not solve the problem, but the solution is worse than the
problem being solved.

But if we focus only on one tiny little corner of the problem space,
complex defaults (whether early or late), there is one other possible
mitigation that is out of scope for this PEP but perhaps we could
consider it. Namely a Javascript-like undefined value that the
interpreter can use as an explicit signal to "treat this as a missing
argument and use the default".

But undefined has its own problems to, and its not clear to me that this
would be any more of a solution to the tight coupling between wrapper
and wrapped functions problem than any of the other non-solutions are.


[snip]

Hmm.

What about something like this as a bit of syntax:

def my_decorator(f):
@wraps
def wrapper(from my_decorator):
return f(from my_decorator)
return wrapper

The idea is that in a function's parameter list it would pick up the 
signature and in a function call it would pick up the arguments.

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


[Python-ideas] Re: PEP 671 (late-bound arg defaults), next round of discussion!

2021-12-08 Thread MRAB

On 2021-12-08 23:39, Chris Angelico wrote:

On Thu, Dec 9, 2021 at 10:35 AM Paul Moore  wrote:


On Wed, 8 Dec 2021 at 23:18, Chris Angelico  wrote:
> Part of the problem is that it is really REALLY hard to figure out
> what the actual objections are. I asked, and the one clear answer I
> got was one subjective opinion that the cognitive load exceeded the
> benefit. Great! That's one person's concern. I've responded to that by
> clarifying parts of the cognitive load problem, and that's about as
> far as that can go.

Um, what parts of my response were unclear? I gave 4 specific points,
Brendan gave 4 more (there wasn't much overlap with mine, either).

Multiple people have mentioned that the proposed syntax is confusing.
You don't have to respond to everyone individually, and indeed you
shouldn't - it's the cumulative effect that matters. Telling 10 people
that their concern "is one person's concern" doesn't address the fact
that 10 people felt similarly. And honestly, there's only about 10
active participants in this thread, so even 5 people with reservations
about the syntax is still "half the people who expressed an opinion".


I have attempted to explain the syntax. What is confusing?

def f(x=spam): ...

def f(x=>spam): ...

I'm not sure what concerns need to be addressed, because I don't
understand the concerns. Maybe I'm just getting caught up on all the
side threads about "deferreds are better" and "it should be a magical
function instead" and I've lost some of the basics? Feel free to
repost a simple concern and I will attempt to respond.


[snip]

I haven't been following the thread for some time, but my expectation 
would be that:


def f(x=>spam):
...

would behave like:

_Missing_ = object()

def f(x=_Missing_):
if x is _Missing_:
x = spam
...
___
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/ZNUY6667KQ5HTH6ZA52OVHPL5U62JWSR/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: PEP 671: Syntax for late-bound function argument defaults -- choice of -> vs @

2021-11-03 Thread MRAB

On 2021-11-03 18:14, Ethan Furman wrote:

On 11/3/21 10:35 AM, Steven D'Aprano wrote:

  > I suppose that we could even add yet another overloaded meaning on the
  > asterix:
  >
  >  # with no default, * keeps the old meaning of collecting
  >  # extra positional values
  >
  >  *parameter
  >
  >  # with a default, * triggers late-binding
  >
  >  *parameter=expression
  >
  > I should hate that, I know I should... but I kinda don't.

Don't worry, I do.  ;-)


How about:

parameter=*expression

so, for example:

parameter=*[]

indicates that you get a new list for each default, so multiple lists, 
not a single shared list?

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


[Python-ideas] Re: Real Positional Arguments or OO Currying

2021-10-18 Thread MRAB

On 2021-10-18 15:58, Steven D'Aprano wrote:

On Mon, Oct 18, 2021 at 10:20:17AM -, Mathew Elman wrote:

despite a driving idea of python syntax being readability in 
english, the function signature is distinctly not english.


Python's syntax was not really modelled on English, as far as I can
tell. It was (I think) modelled more on Pascal, Modula-2/3, C and most
of all, ABC:

https://www.artima.com/articles/the-making-of-python

All of those languages (like most programming languages) use English
keywords, but not English grammar. In Python's case, I think it is
better to say that the language aims to read like executable
pseudo-code, not English.

If Guido is reading, he might like to step in and correct me, but as far
as I know, the intent was never to make Python code read as English.

There are languages that do that. The ultimate example of that is quite
probably Inform7, a specialised game language that reads like this:

 Afterlife is a room. "Fluffy white clouds gather round you here in
 the afterlife." The Pearly Gates are a door in Afterlife. "The
 Pearly Gates - large, white, wrought-iron and splendidly monumental
 - stand above you." Heaven is a room. The Gates are above the
 Afterlife and below Heaven.

Yes, that is actual source code, not documentation, taken from the
Inform website.

http://inform7.com/

Inform 7 is specialised for making text games, but a more general
purpose English-like languague comes from the XTalk family of languages,
starting with Apple's Hypertalk in the 1990s. In XTalk languages, we can
write English-like statements like these:

 put the date into field "Today"
 get the second line of todo_list
 put prefix before the third word of it
 get the number of words of password
 if it < 10 then answer "Your password is too weak"
 add seven to the name of button id 21
 put any word of field 1 after the middle word of field 2

Aside from mentioning that "field" here refers to editable text entry
fields in the GUI, I probably don't have to explain what any of those
lines do.

I have a soft spot in my heart for Hypertalk and its GUI builder,
Hypercard, so I completely understand your desire to write code with a
more English-like syntax.

If my memory is correct, in Hypertalk you could take any function of one
argument and write it as either of these forms:

 function(argument)
 the function of argument

So it is not a huge step to imagine a new syntax that looks like your
example:

  insert 1 into container

That's practically the same as Hypertalk's "put ... into ...".
(Hypertalk also supported put...after and put...before.) So what you are
asking for is certainly *possible*.

But I do not think it is a good fit for Python's syntax. I love
Hypertalk's syntax, but it does not fit well with Python's existing
syntax.

English-like code and Python code are both great, but a mix of the two
in the same file would be like some sort of horrible surgical experiment
gone wrong.

I once had to do something in Appletalk. If you wanted to refer to the 
title of a window you would say "title of window" or "window's title".


So, how would you refer to the program's title?

If it borrowed from Smalltalk it would be "title of windows of self". 
That didn't work.


If it borrowed from C++ it would be "title of windows of this". No luck.

After a bit more guesswork I tried "title of window of me". That worked.

Alternatively, you could have "me's window's title". Not "my", but "me's".

I felt that it was trying too much to be like English whist not being 
English, so it wasn't as clear what was actually legal.


I think that a programming language needs to be different enough from a 
natural language to remind you that it's a programming language and that 
the computer isn't that smart. The computer will do as you say, not as 
you mean.

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


[Python-ideas] Re: Real Positional Arguments or OO Currying

2021-10-18 Thread MRAB

On 2021-10-18 11:20, Mathew Elman wrote:

I don't know if this has been suggested before, or if this is outlandishly 
impossible (though I would be surprised if it was), so apologies in advance if 
so.

I have on occasion come across a situation where I use/write a signature like 
this:

 def insert_x_into_y(x, y):
 ...

or worse
 
 def insert_into(item, container):

 ...

where, despite a driving idea of python syntax being readability in english, 
the function signature is distinctly not english.
"I'll just go and insert into this item that container", is not only never said 
but is actually ambiguous in english.

What would be really cool, is if python let you write function signatures like 
this:

 def insert_(item)_into_(container):
 ...

where the arguments dispersed between the function name are positional only 
argument, and any key word arguments would have to go at the end.
It would create a function that could be called as:

 insert_(1)_into_(my_list)
 
or


 insert__into_(1, my_list)
 

[snip]
It looks like what you want is the Smalltalk language.
___
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/BZHMDPWR63FHY6YG6ZOXXZ55CWMHH2YF/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Unpacking in tuple/list/set/dict comprehensions

2021-10-16 Thread MRAB

On 2021-10-16 20:31, Erik Demaine wrote:

On Sun, 17 Oct 2021, Steven D'Aprano wrote:


On Sat, Oct 16, 2021 at 11:42:49AM -0400, Erik Demaine wrote:


I guess the question is whether to define `(*it for it in its)` to mean
tuple or generator comprehension or nothing at all.


I don't see why that is even a question. We don't have tuple
comprehensions and `(expr for x in items)` is always a generator, never
a tuple. There's no ambiguity there. Why would allowing unpacking turn
it into a tuple?


Agreed.  I got confused by the symmetry.


The only tricky corner case is that generator comprehensions can forgo
the surrounding brackets in the case of a function call:

   func( (expr for x in items) )
   func( expr for x in items )  # we can leave out the brackets

But with the unpacking operator, it is unclear whether the unpacking
star applies to the entire generator or the inner expression:

   func(*expr for x in items)

That could be read as either:

   it = (expr for x in items)
   func(*it)

or this:

   it = (*expr for x in items)
   func(it)

Of course we can disambiguate it with precedence rules, [...]


I'd be inclined to go that way, as the latter seems like the only reasonable
(to me) parse for that syntax.  Indeed, that's how the current parser
interprets this:

```
  func(*expr for x in items)
   ^
SyntaxError: iterable unpacking cannot be used in comprehension
```

To get the former meaning, which is possible today, you already need
parentheses, as in


   func(*(expr for x in items))




But it would be quite surprising for this minor issue to lead to the
major inconsistency of prohibiting unpacking inside generator comps when
it is allowed in list, dict and set comps.


Good point.  Now I'm much more inclined to define the generator expression
`(*expr for x in items)`.  Thanks for your input!


As we can already have:

func(*a, *b)

it's clear that * has a high precedence, so having:

func(*expr for x in items)

be equivalent to:

func((*expr for x in items))

does makes sense. It would be passing a generator.

On the other hand, wouldn't that make:

[*s for s in ["abc", "def", "ghi"]]

be equivalent to:

[(*s for s in ["abc", "def", "ghi"])]

? It would be making a list that contains a generator.

If:

[*s for s in ["abc", "def", "ghi"]]

should unpack, then shouldn't:

func(*expr for x in items)

also unpack?


On Sat, 16 Oct 2021, Serhiy Storchaka wrote:


It was considered and rejected in PEP 448. What was changed since? What
new facts or arguments have emerged?


I need to read the original discussion more (e.g.
https://mail.python.org/pipermail/python-dev/2015-February/138564.html), but
you can see the summary of why it was removed here:
https://www.python.org/dev/peps/pep-0448/#variations

In particular, there was "limited support" before (and the generator ambiguity
issue discussed above).  I expect now that we've gotten to enjoy PEP 448 for 5
years, it's more "obvious" that this functionality is missing and useful.  So
far that seems true (all responses have been at least +0), but if anyone
disagree, please say so.

Erik



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


[Python-ideas] Re: Implementing additional string operators

2021-10-13 Thread MRAB

On 2021-10-13 16:26, Marc-Andre Lemburg wrote:

On 13.10.2021 17:11, Guido van Rossum wrote:

Maybe we should only accept operators as aliases for existing methods.

x-y could mean x.removesuffix(y)


That was the idea, yes, in particular to make it similar to "+",
which adds to the end of the string, so that:

s = x - oldend + newend

works as expected.


I don't think x~y is intuitive enough to use.


True.

I tried to find an operator that looked similar to "-", but
"~" would only work as unary operator, a Chris correctly pointed
out, and even if it were a binary one, it would look too
similar to "-" and also doesn't play well when used on a single
line.

s = newstart + (x ~ oldstart)

So I withdraw that proposal.


From a mathematical point of view, x-y is equivalent to x+(-y).

That leads me to me "negative" strings that, when added to a string, 
remove characters instead of adding them.


For example:

"abcdef" - "ef" == "abcdef" + (-"ef") == "abcd"

and also:

(-"ab") + "abcdef" == "cdef"

Voilà! An alternative to .removeprefix. :-)


On Wed, Oct 13, 2021 at 8:03 AM Stephen J. Turnbull mailto:stephenjturnb...@gmail.com>> wrote:

Chris Angelico writes:

 > +1, although it's debatable whether it should be remove suffix or
 > remove all. I'd be happy with either.

If by "remove all" you mean "efefef" - "ef" == "", I think that's a
footgun.  Similarly for "efabcd" - "ef" == "abcdef" - "ef".

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


[Python-ideas] Re: Overloading unary plus in strings with "ord"

2021-10-12 Thread MRAB

On 2021-10-12 23:57, Steven D'Aprano wrote:

On Wed, Oct 13, 2021 at 09:22:09AM +1100, Chris Angelico wrote:


Mathematicians and programmers both extend
operators to new meanings, but only where it makes sense.


In fairness, mathematicians typically just invent new symbols, when
they're not repurposing existing symbols for totally unrelated ideas :-(

I count over 400 maths symbols in Unicode, including over 100 variations
on < and > and over 30 variations of the plus sign.

So we want to be *really* cautious about following the lead of
mathematicians.


If you want compact code, try APL.
___
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/PTIZ5OWVN3DJZLLJOGXA7RGT3SPFKH4X/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Overloading unary plus in strings with "ord"

2021-10-12 Thread MRAB

On 2021-10-12 13:49, Steven D'Aprano wrote:

On Tue, Oct 12, 2021 at 11:36:42PM +1100, Chris Angelico wrote:


You haven't given any reason why unary plus should imply ord().


I think the question Chris is really asking is why should unary plus
return ord() rather than any other function or method.

We could make unary plus of a string equal to the upper() method:

 +"Hello world"  # returns "HELLO WORLD"

You could then strengthen that suggestion by saying the unary minus 
would be equivalent to the lower() method.



or the strip() method:

 +"  Hello world  "  # returns "Hello world"

or len():

 +"Hello world"  # returns 11

or any other function or method we want. What is so special about ord(),
and what is the connection between ord() and `+` that makes it obvious
that +"a" should return 97 rather than "A" or 1 or 10 or something else?

It's not enough to just say that unary plus is unused for strings, you
have to justify why the average programmer will look at unary plus and
immediately think "ord".


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


[Python-ideas] Re: Overloading unary plus in strings with "ord"

2021-10-12 Thread MRAB

On 2021-10-12 13:36, Chris Angelico wrote:

On Tue, Oct 12, 2021 at 11:27 PM Jeremiah Vivian
 wrote:


> -1. It's unnecessary optimization for an uncommon case, abuse of syntax
Good point. But what else can the unary positive do? I'm just trying to add a 
use for it.
> illogical - why should +"a" be the integer 97?
Because `ord("a")` is `97`. Have you read the last question at the end of the 
post?


And eval("0xa") is 10. Why shouldn't +"a" be 10 instead?


Why are you using eval? int is safer: int("0xa", 0)


You haven't given any reason why unary plus should imply ord().


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


[Python-ideas] Re: Overloading unary plus in strings with "ord"

2021-10-12 Thread MRAB

On 2021-10-12 13:25, Jeremiah Vivian wrote:

-1. It's unnecessary optimization for an uncommon case, abuse of syntax

Good point. But what else can the unary positive do? I'm just trying to add a 
use for it.

illogical - why should +"a" be the integer 97?

Because `ord("a")` is `97`. Have you read the last question at the end of the 
post?

It would be very surprising for unary plus to return something of a 
different type to its argument.


And, anyway, why should it be equivalent to 'ord' and not 'int'?
___
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/PPMURQR3DF2ZODWRPO5ORVOUY4QFH5GG/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Allow regex group name redefinitions

2021-10-02 Thread MRAB

On 2021-10-02 10:27, ven...@razdva.cz wrote:

Hello everybody,

I've got a suggestion for the std. re module developers: to consider allowing 
match group name redefinitions, especially in alternatives.

[snip]
FYI, the regex module on PyPI supports that.
___
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/2TQ46HDKSLINSGF7AEKCB5UNWJKZUPA4/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Shorthand syntax for lambda functions that have a single parameter

2021-10-02 Thread MRAB

On 2021-10-02 08:59, Abdulla Al Kathiri wrote:

Let’s say I want to write a lambda function with no arguments that’s connected to a 
button in GUI coding, will blabla.connect(()=>print(“clicked”)) be used or will 
blabla.connect(=>print(“clicked”)) be used?

In the case of C#, the parentheses are optional if there's only one 
parameter, so:


    () => ...

    (x) => ... or x => ...

    (x, y) => ...

    (x, y, z) => ...

etc.


> On 30 Sep 2021, at 7:53 PM, MRAB  wrote:
> 
> On 2021-09-30 07:21, Chris Angelico wrote:

>>> On Thu, Sep 30, 2021 at 4:19 PM Steven D'Aprano  wrote:
>>> 
>>>> On Wed, Sep 29, 2021 at 02:09:03PM -0700, Guido van Rossum wrote:

>>> > Over in typing-sig we're considering a new syntax for callable *types*,
>>> > which would look like (int, int, str) -> float. A matching syntax for
>>> > lambda would use a different arrow, e.g. (x, y, z) => x+y+z.
>>> 
>>> I like arrow operators :-)
>>> 
>>> But I fear that it will be too easy to misread `=>` as greater than or

>>> equal to, especially when skimming code.
>>> 
>>> Assuming that they need to be different arrows, how do you feel about

>>> `->` for types and annotations, and `-->` for lambdas? Or `->>`?
>>> 
>> JavaScript uses => for functions, and the confusion with ">=" doesn't

>> seem to be a major problem with it.
> C# also uses "=>".
> 

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


[Python-ideas] Re: Shorthand syntax for lambda functions that have a single parameter

2021-09-30 Thread MRAB

On 2021-09-30 07:21, Chris Angelico wrote:

On Thu, Sep 30, 2021 at 4:19 PM Steven D'Aprano  wrote:


On Wed, Sep 29, 2021 at 02:09:03PM -0700, Guido van Rossum wrote:
> Over in typing-sig we're considering a new syntax for callable *types*,
> which would look like (int, int, str) -> float. A matching syntax for
> lambda would use a different arrow, e.g. (x, y, z) => x+y+z.

I like arrow operators :-)

But I fear that it will be too easy to misread `=>` as greater than or
equal to, especially when skimming code.

Assuming that they need to be different arrows, how do you feel about
`->` for types and annotations, and `-->` for lambdas? Or `->>`?



JavaScript uses => for functions, and the confusion with ">=" doesn't
seem to be a major problem with it.


C# also uses "=>".
___
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/CDYWUHFCMKR6A7J5C7K6KWITUJAUZWMI/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Shorthand syntax for lambda functions that have a single parameter

2021-09-29 Thread MRAB

On 2021-09-29 10:11, Dominik Vilsmeier wrote:

Lambda functions that have a single parameter are a common thing, e.g. for "key" functions: 
`sorted(items, key=lambda x: x['key'])`. For these cases however, the rather long word 
"lambda" together with the repetition of the parameter name, results in more overhead than 
actual content (the `x['key']`) and thus makes it more difficult to read. This is also a difficulty 
for `map` and `filter` for example where there's lots of visual overhead when using a lambda function 
and hence it's difficult to read: `filter(lambda x: x > 0, items)` or `map(lambda x: f'{x:.3f}', 
items)`.

Hence the proposal is to add a new syntax via the new token `?`. For the 
examples above:

* `sorted(items, key=?['key'])`
* `filter(? > 0, items)`
* `map(f'{?:.3f}', items)`

The rules are simple: whenever the token `?` is encountered as part of an 
expression (at a position where a name/identifier would be legal), the 
expression is replaced by a lambda function with a single parameter which has 
that expression as a return value, where any instances of `?` are replaced by 
the name of that single parameter. For example:

* `?['key']` translates to `lambda x: x['key']`
* `? > 0` translates to `lambda x: x > 0`
* `f'{?:.3f}'` translates to `lambda x: f'{x:.3f}'`
* `?*?` translates to `lambda x: x*x`


[snip]

I'd prefer something like "x -> x" "x => x" as an equivalent to "lambda 
x: x":


sorted(items, key=i -> i['key'])

The advantage of using '->' is that it already exists.

This has all been suggested before.

There have also the suggestions of adding a None-coalesce operator '??', 
plus None-coalesce subscripting with '?[...]', etc, which would be 
Python's equivalent of the null-coalesce operator of some other languages.

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


[Python-ideas] Re: Different exceptions for assert

2021-09-09 Thread MRAB

On 2021-09-09 22:31, Juancarlo Añez wrote:
Well, if the idea makes sense, then I'm certain that we'll have a very 
long and productive discussion about the best syntax here (re: *:=*).


;-)

For backwards compatibility and no surprises:


*assert: *ExType, cond, args


It doesn't break anything, ExtType defaults to AssertionError, and 
linters can check that /args/ match ExType.


A more readable and pythonic syntax would be:

*assert *cond: ExtType(args)



Or, perhaps:

assert cond: raise ExtType(args)

That would make it more like an if and would leave open the possibility 
of extending it to accept multiple lines:


assert cond:
# Write some debugging info to a log.
...
raise ExtType(args)

Just a thought.

Forgoing the comma doesn't break anything, linters can check the 
ExType() typing, and the semantics would be those of:


*if* __debug__ *and* *not *cond:

*raise* ExType(args)


Although I would drop the check for /__debug__/ if an explicit ExtType 
is given.


It's similar to the changes introduced for:


*except* (OneEx, TwoEx):


On Thu, Sep 9, 2021 at 12:16 PM Guido van Rossum > wrote:


Ooh, that’s a nice idea. If the message is an exception instance,
raise it instead of AssertionError. Unfortunately it’s not 100%
backwards compatible. We could address that with the syntax

   assert cond, raise=ExcType(args)

Maybe we could deprecate the case

   assert cond, ExcType(args)

So that eventually the raise= keyword can become optional.

—Guido

On Thu, Sep 9, 2021 at 09:04 Juancarlo Añez mailto:apal...@gmail.com>> wrote:

Steven,

The purpose is to make it easier to make software more resilient.

The inspiration was this article that reminded me that software
/_will always fail_/, and also reminded me about all the
discussions around DBC and Eiffel:

https://www.youtube.com/watch?v=AaZ_RSt0KP8



IOW, my premise is that we should be using /_lots_/ of
assertions, /_always_/, and that for that we need to make them
easier to write, and easier to handle in the event of the
unavoidable failures. Seeking unit-test coverage is not enough
because unit tests don't run in production.

I will concede that code written under the /"Python culture"/
tends to be resilient because the semantics of defaults and
border conditions are explicit in the documentation, and
implemented thus.

Perhaps it's enough to allow for:

*assert */cond/*, *ExType(args)



On Tue, Sep 7, 2021 at 9:28 PM Steven D'Aprano
mailto:st...@pearwood.info>> wrote:

On Tue, Sep 07, 2021 at 11:12:37AM -0400, Juancarlo Añez wrote:
 > I won't propose a syntax, but I think it would be useful
if *assert* could
 > raise an exception different from *AssertionError*.
 >
 > This is in the context of "Design by contrast" (DBC) as a
useful companion
 > to "Test-driven development" and other forms of external
tests.

I don't see why that would be useful. DBC assertions are
assertions. You
are *asserting* that a condition is always true. Since it is
always
true, it should be safe to disable those DBC assertion
checks once your
software is in production.

I could *maybe* see that having fine distinction between
pre-condition,
post-condition and invariant failures would be useful, but
without a
system in place to allow those to be globally enabled/disabled
separately, what's the point?

In any case, in the event of a contract failure, there's
really nothing
you can do except log the error and exit. Raising errors
like TypeError
etc will encourage people to abuse assertions and contracts
by catching
those exceptions, for checking caller-supplied parameters
and user data,
or for flow control.


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


[Python-ideas] Re: Allow starred expressions to be used as subscripts for nested lookups for getitem and setitem

2021-09-01 Thread MRAB

On 2021-09-01 17:41, Kevin Mills wrote:

Given code like this:

```
d = {1: {2: {3: 4}}}
print(d[1][2][3])
d[1][2][3] = None
print(d)
```

It should be possible to rewrite it using a starred expression, like this:

```
d = {1: {2: {3: 4}}}
keys= 1,2,3
print(d[*keys])
d[*keys] = None
print(d)
```

Hopefully it's clear from that example what I'm suggesting.


Would that be equivalent to d[keys[0], keys[1], keys[2]]?

If so, it would be equivalent to something that's already legal, namely, 
a subscript that's a tuple.

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


[Python-ideas] Re: NAN handling in statistics functions

2021-08-29 Thread MRAB

On 2021-08-30 04:31, Steven D'Aprano wrote:

On Sun, Aug 29, 2021 at 08:20:07PM -0400, tritium-l...@sdamon.com wrote:


Not to go off on too much of a tangent, but isn't NaN unorderable?  Its
greater than nothing, and less than nothing, so you can't even really sort a
list with a NaN value in it (..though I'm sure python does sort it by some
metric for practical reasons) - it would be impossible to find a NaN with a
binary search... it would be impossible to have a NaN in an ordered sequence
 wouldn't it?


Sorting NANs will end up arranging them in arbitrary positions, and
spoil the order of other values:

 >>> from math import nan
 >>> sorted([4, nan, 2, 5, 1, nan, 3, 0])
 [4, nan, 0, 1, 2, 5, nan, 3]

I *think* Timsort will end up leaving each NAN in its original position,
but other implementations may do something different. However you sort,
they end up messing the order up.

However we could add a function, totalorder, which can be used as a key
function to force an order on NANs. The 2008 version of the IEEE-754
standard recommends such a function:

 from some_module import totalorder
 sorted([4, nan, 2, 5, 1, nan, 3, 0], key=totalorder)
 # --> [nan, nan, 0, 1, 2, 3, 4, 5]

It would be nice if such a totalorder function worked correctly on both
floats and Decimals. Anyone feel up to writing one?


How about:

def totalorder(x):
return (0,) if math.isnan(x) else (1, x)


Decimal already has a `compare_total` method, but I'm unsure if it
behaves the expected way. But we have no equivalent key function for
floats.


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


[Python-ideas] Re: We should have an explicit concept of emptiness for collections

2021-08-24 Thread MRAB

On 2021-08-25 00:48, Guido van Rossum wrote:

Hi Tim,

I'm sorry if this has been brought up before, but *aside from PEP 8* is 
there anything wrong with using "if len(a)" for nonempty, or "if not 
len(a)" for empty?


What is the cost of 'len'? If it's always O(1), then it's not a problem, 
but if it's not O(1) (counting the items in a tree, for example) and 
you're not interested in how many items there are but only whether 
there's at least one, then...


It would seem to work for numpy and pandas arrays, and it works for 
builtin sequences. Also, it has the advantage of being 100% backwards 
compatible. :-)


Surely conforming to PEP 8 shouldn't need an addition to the language or 
stdlib? Or does it not work?


On Tue, Aug 24, 2021 at 3:42 PM Tim Hoffmann via Python-ideas 
mailto:python-ideas@python.org>> wrote:


Ethan Furman wrote:
 > On 8/24/21 3:03 PM, Tim Hoffmann via Python-ideas wrote:
 > > **How do you check if a container is empty?**
 > > IMHO the answer should not depend on the container.
 > I think this is the fly in the ointment -- just about everything,
from len() to bool(), to add, to iter() /all/ depend
 > on the container -- even equality depends on the container. 
`and`, `or`, and `not` partially depend on the container

 > (via bool()).  Only `is` is truly independent.

Sorry, I think you got me wrong: The meaning and thus implementation
depends on the type (e.g. each container defines its own __len__()).
However the syntax for querying length that is still uniformly
`len(container)`. Likewise I'd like to have a uniform syntax for
emptiness, and not different syntax for different types (`if not
container` / `if len(array) == 0` / `if dataframe.empty`).


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


[Python-ideas] Re: We should have an explicit concept of emptiness for collections

2021-08-22 Thread MRAB

On 2021-08-23 01:28, Steven D'Aprano wrote:

On Sun, Aug 22, 2021 at 07:01:28PM +0300, Serhiy Storchaka wrote:


(len(collection) == 0) is True


Ha ha, yes, very good, you got me. But the trouble is, if you don't
trust the truth value of the predicate, it is hard to know when to
stop:

 len(collection) == 0
 (len(collection) == 0) is True
 ((len(collection) == 0) is True) is True
 (((len(collection) == 0) is True) is True) is True
 len(collection) == 0) is True) is True)) is True
 # ...

*wink*

MRAB and Ricky:

`__builtins__` is a CPython implementation detail and is reserved for
the interpreter's private use. Other implementations may not even have
it. The right way to write your code should be

 import builtins
 builtins.bool((builtins.len(collection) == 0) is True) is True

I considered that but thought it could be shadowed. After testing, it 
appears that it can't.

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


[Python-ideas] Re: We should have an explicit concept of emptiness for collections

2021-08-22 Thread MRAB

On 2021-08-22 17:36, Thomas Grainger wrote:

bool((len(collection) == 0) is True) == True and issubclass(True, bool)


'True' is a reserved word, so you don't need to check it.

However, 'bool' might have been overridden, so:

__builtins__.bool((len(collection) == 0) is True) == True

Come to think of it, 'len' might have been overridden too, so:

__builtins__.bool((__builtins__.len(collection) == 0) is True) == True

On Sun, 22 Aug 2021, 17:09 Valentin Berlier, > wrote:


 > (len(collection) == 0) is True

bool((len(collection) == 0) is True) == True


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


[Python-ideas] Re: Definition of a starred expression in the Language Reference

2021-08-22 Thread MRAB

On 2021-08-22 11:51, Matsuoka Takuo wrote:

Dear developers,

According to the Language Reference, a starred expression is defined
by

   starred_expression ::=  expression | (starred_item ",")* [starred_item]

https://docs.python.org/3/reference/expressions.html#expression-lists

However, in view of the definition of an assignment statement

   assignment_stmt ::=  (target_list "=")+ (starred_expression |
yield_expression)

https://docs.python.org/3/reference/simple_stmts.html#assignment-statements

I believe the correct definition actually used is

   starred_expression ::=  expression | (starred_item ",")+ [starred_item]

(that is, use "+" instead of "*").

Should it be fixed?

The existing definition states that 'starred_expression' could be empty, 
so it does look suspicious.

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


[Python-ideas] Re: builtins for running context managers

2021-07-16 Thread MRAB

On 2021-07-16 12:44, Stephen J. Turnbull wrote:

Thomas Grainger writes:

  > Another example, is a cash point (ATM) won't give you your money
  > until you take your card

That ATM is effective in enforcing the desired behavior.  In Python
you would usually use an exception to force handling.  Returning
status codes, or couples of status codes and values, isn't nearly as
effective.

And a (status, value) couple does nothing to encourage checking the
code over (value, status).

To me, it makes more sense to return (status, value) than (value, 
status) because it's clearer to say "that didn't work, so you can just 
ignore the value" than "here's a value, but it didn't work, so just 
ignore the value even though I mentioned it first".

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


[Python-ideas] Re: writelines2?

2021-07-13 Thread MRAB

On 2021-07-13 15:18, Eric V. Smith wrote:

On 7/13/2021 9:52 AM, Thomas Güttler wrote:



Am Di., 13. Juli 2021 um 15:02 Uhr schrieb >:


Right now, writelines is a very big misnomer to many python
developers, especially beginners who would expect writelines to
put new lines at the end of every element in the list

My suggestion is to have either a writelines2 or a newline kwarg
which does put new lines automatically at the end of every line
written


I like the idea of having a kwarg for writelines 
.


Do you want a boolean like "append_newlines=True" or a string like 
"append_string='\n'"


But it only applies if the argument is iterable, right?

That is, it would have no effect on something like:

fl.writelines(3, append_newlines=True)


That raises an exception, and I wouldn't expect that to change.

Assuming so, the parameter would need to have some more appropriate 
name, like append_newlines_if_iterable.


Personally, I don't think this has any chance of being accepted, but 
that's me. There are numerous ways to achieve this already, and we don't 
need another one.



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


[Python-ideas] Re: writelines2?

2021-07-13 Thread MRAB

On 2021-07-13 15:11, sandhoners...@gmail.com wrote:

Maybe (to be consistent with other functions like print), end= since that would 
allow even custom line endings

I'm not sure about the name 'end'. The 'print' function has 'end', but 
it's printed only at the end(!); .writelines would write it after every 
line.

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


[Python-ideas] Re: Default List .get Method

2021-07-06 Thread MRAB

On 2021-07-07 01:36, Steven D'Aprano wrote:

On Tue, Jul 06, 2021 at 02:54:32PM +0100, MRAB wrote:

This has been discussed before, most recently on 2021-06-05, but also in 
August 2020, and in 2017.


Hi MRAB,

Thanks for looking those up, but you don't happen to have URLs do you?
Or at least tell us whether they are on the Python-Ideas mailing list,
or Python-Dev, Python-List, or the Python Discuss forum?


In 2021:

Re: What about having a .get(index, default) method for arrays like 
we have for dicts?


https://mail.python.org/archives/list/python-ideas@python.org/thread/LLK3EQ3QWNDB54SEBKJ4XEV4LXP5HVJS/#YDSC5T7MLM2VBJCLCFP2V5OPS34LD73B

In 2020:

Add `get`as a method to list and tuple

https://mail.python.org/archives/list/python-ideas@python.org/thread/Q4ST3IF2YXR4FTB73V545NQBKHRB6RHX/

In 2017:

get() method for list and tuples

https://mail.python.org/archives/list/python-ideas@python.org/thread/OSPMJMVLU3DLLP6D532ZAS26ZCQLFFJ4/#WR4GMZE4GME6C2XFYAF5EZJ5GAVSNXVR

And those are just the ones I've found in a few minutes.
___
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/H2IXAPAX3C47JBKE3L5SFODAXAEOZDOU/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Default List .get Method

2021-07-06 Thread MRAB

On 2021-07-06 02:52, Austin Graham wrote:
I'm a lurker on this list and wanted to submit my own idea. It's a 
feature I've been wanting in Python for a while, and I have a simple 
implementation for it for personal use at the moment. Wanted to get 
feedback before I move forward.


Essentially, I want to be able to perform a simple default get on a list 
if an index does not exist, similar to a dictionary. For example:


*my_dict = {"test1": "value1"}*
*my_dict.get("test2", None)*
*
*
results in a "None" value, since the key doesn't exist.

Similarly with a list:

*my_list = [1, 2, 3]*
*my_list.get(10, 0)*
*
*
says that since index 10 does not exist, I expect a 0 to be returned. 
Currently, you have to check the length of the list of use a try/except, 
which takes more lines than I'd like to use.


I'm welcoming feedback on this feature, or if it's already been 
discussed then I'm expecting to be shut down.


Thank you for your time!

This has been discussed before, most recently on 2021-06-05, but also in 
August 2020, and in 2017.

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


[Python-ideas] Re: Deprecate sum of lists

2021-06-16 Thread MRAB

On 2021-06-17 00:57, Chris Angelico wrote:

On Thu, Jun 17, 2021 at 9:46 AM Oliver Margetts
 wrote:


> I'm not sure why it doesn't special-case it to "".join()
One reason might be because you'd have to read the entire iterator to know if 
it really was only strings. So there are concerns with generators which 
complicate things a fair bit



Perhaps, but I'm not sure what's actually being verified here. The
check is applied to the start parameter. (If you don't set start,
you'll get a TypeError for trying to add an int and a str.) In fact,
if you disrupt that check, sum() is quite happy to add strings
together - with potentially quadratic runtime:


class AdditiveIdentity:

... def __add__(self, other): return other
...

sum(["Hello ", "world!"], start=AdditiveIdentity())

'Hello world!'

Either way, if there's a non-str part way through, it'll bomb when it
reaches that. I've no idea what the reason is for not bouncing it
straight into join(), but I'm sure there must be one.

I wonder whether we could introduce a new dunder __sum__ for summing 
sequences. It would call type(start).__sum__ with the start value and 
the sequence.


str.__sum__ would use str.join and list.__sum__ would use list.extend.

The fallback would be to do what it does currently.
___
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/KANNLLDGJ2ASZVVZEPL5XUZKJJEBVAGG/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: The name Ellipsis should be a constant

2021-05-31 Thread MRAB

On 2021-05-31 21:19, Serhiy Storchaka wrote:

31.05.21 22:46, Chris Angelico пише:

Originally, the notation "..." could only be used inside a subscript,
and anywhere else, you'd have to spell it "Ellipsis". Now that you can
use "..." anywhere, would it be worth switching the repr to just be
that?


How would you then distinguish a recursive list from a list containing
Ellipsis?

>>> a = []; a.append(a); a
[[...]]
>>> [[...]]
[[Ellipsis]]

Why is it 3 dots anyway? As we've already ascribed a meaning to 3 dots, 
why not use 4 dots in this use?

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


[Python-ideas] Re: The name Ellipsis should be a constant

2021-05-31 Thread MRAB

On 2021-05-31 15:55, Paul Bryan wrote:
If you're proposing prevention of monkey patching Ellipsis, I think 
you'll have to go all-in on all builtins.


For example:


str = int



str





str == int


True


If you rebind str to int, the repr of str will say , so you 
can tell that something's happened, but the repr of ... is always 
'Ellipsis', even though you've rebound Ellipsis.




On Mon, 2021-05-31 at 11:37 -0300, André Roberge wrote:

In Python `...` is referred to as `Ellipsis` and cannot be assigned to.
Yet, one can assign any value to the name `Ellipsis`.

Consider the following:

```
>>> ...
Ellipsis
>>> ... == Ellipsis
True
>>> Ellipsis
Ellipsis
>>> Ellipsis = 3
>>> Ellipsis
3
>>> ... = 4
  File "", line 1
    ... = 4
    ^
SyntaxError: cannot assign to Ellipsis
>>>  # But I just did assign a new value to the name Ellipsis above.
>>> Ellipsis
3
>>> ...
Ellipsis
>>> ... == Ellipsis
False
```

For consistency, `Ellipsis` (the name) should **always** refer to the 
same object that `...` refers to, so that both could not be assigned a 
new value.



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


[Python-ideas] Re: Add static variable storage in functions

2021-05-27 Thread MRAB

On 2021-05-27 21:02, Brendan Barnwell wrote:

On 2021-05-27 12:33, Chris Angelico wrote:

With statics, you could write it like this:

def merge_shortest(things):
 static len=len
 ...

Simple. Easy. Reliable. (And this usage would work with pretty much
any of the defined semantics.) There's no more confusion.


You can already do that:

def merge_shortest(things):
   len=len
   ...


No, that raises an UnboundLocalError exception.
___
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/CRVOQZMZJFLLCGUHRJ3LXIJIIV4UIYCM/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Add static variable storage in functions

2021-05-27 Thread MRAB

On 2021-05-27 17:44, Shreyan Avigyan wrote:

My proposal is somewhat the sum of all of your ideas. Well I propose there 
should a STORE_STATIC_FAST opcode that stores a static variable. Static 
variable will be declared only once and will be initialized to None (statement 
syntax will be similar to that of global). It will be initialized in 
MAKE_FUNCTION. Now it will be set by STORE_STATIC_FAST. Where will the 
variables be stored? It will have references in locals and __statics__. 
Therefore LOAD_FAST can find it. So I don't hope there will be performance 
decrease but performance increase is also not guaranteed. :-)

And if these are thread unsafe then is __defaults__ also thread unsafe?


Why initialise them to None? Other variables don't behave like that.

My preference would be to have something like this:

def foo():
static x = 0

that would bind 'x' the first time it met that statement, and if it 
tried to use 'x' before that has met that statement for the same time it 
would raise something like UnboundLocalError (perhaps UnboundStaticError 
in this case?) like happens currently for local variables.

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


[Python-ideas] Re: Add static variable storage in functions

2021-05-27 Thread MRAB

On 2021-05-27 10:39, Shreyan Avigyan wrote:

Well sometimes we don't want to pollute the module namespace. Two functions can 
have two variables with the same name but with different values that we want to 
be static. And this functionality already exists in Python but as a *hack*. 
This idea proposes to add a new dunder member and a keyword that allows us to 
use global variables but are limited to local scope. But since it's Python 
anyone can access it using the dunder member.

This was discussed some years ago. IIRC, one of the questions was about 
how and when such variables would be initialised.

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


[Python-ideas] Re: Introduce constants in Python (constant name binding)

2021-05-26 Thread MRAB

On 2021-05-26 13:53, Shreyan Avigyan wrote:

I've already given one. Since Python is dynamically typed changing a critical 
variable can cause huge instability. Want a demonstration? Here we go,

import sys
sys.stdout = None

Now what? Now how can we print anything? Isn't this a bug? There are lots of 
code out there where we need to protect things from being overwritten. Though 
I'm never telling to use constants in Python stdlib or else I could have never 
done this demonstration. :)


Actually, I've done something like that.

import codecs
import sys
sys.stdout = codecs.getwriter('utf-8')(sys.stdout.detach())

This was because I was running a script from an editor and it picked up 
the wrong output encoding, raising an error when I tried to print 
characters that were outside the ASCII range. Thankfully that problem is 
now solved, but it was a useful workaround.

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


[Python-ideas] Re: dict.get_deep()

2021-05-23 Thread MRAB

On 2021-05-23 13:37, Marco Sulla wrote:

I propose to add a get_deep(*args, default=_sentinel) method to dict.

It can accept a single argument, that must be an iterable, or multiple
arguments.

The first element must be a key of the dict. If there's not a second
element, the value is returned. If it's present, it tries to use it as
an argument for the eventual __getitem__() of the value object, and so
on.

In this process, if a KeyError, an IndexError or a TypeError is
raised, if default is set its value is returned, otherwise the
exception will be raised.

Example:

d = {1: [42]}
d.get_deep(1, 0)
# 42
d.get_deep(range(3), default=1981)
# 1981
d.get_deep((1, 1))
# IndexError: list index out of range


A slight problem here: a tuple (1, 1) can be a key of the dict.

Also, if the first lookup returns a list or a tuple, and an argument can 
be an index of that list, would be make sense to add a similar method to 
lists and tuples?

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


[Python-ideas] Re: Add a mechanism so that multiple exceptions can be caught using `except E1, E2, E3:`

2021-05-09 Thread MRAB

On 2021-05-09 21:11, Bruce Leban wrote:



On Sun, May 9, 2021 at 9:48 AM Thomas Grainger > wrote:


now that python2.7 is EOL, it might be worth resurrecting this
syntax as discussed in
https://www.python.org/dev/peps/pep-3100/#id13


eg, python 3.11 could support
```
try:
     ...
except (E1, E2, E3) as e:
     ...
```

as equivalent to

```
try:
     ...
except E1, E2, E3 as e:
     ...
```


-1

I think you really mean you want Python to accept the form without the 
parenthesis. I don't like it because it's easy to read that as


except E1, E2, (E3 as e):

and I don't think saving two characters is worth the disruption caused 
by people being able to write Python 3.11 code that won't work in Python 
3.10. Many people would not adopt the new syntax for that reason.



I'm not keen on it either.

On the other hand, binding to e for E3 but not for E1 or E2 would be 
kind of weird, and "e = E1, E2, E3" is valid.


On the third hand(!), 'as' is used in the 'import' and 'with' 
statements, where it binds to only one preceding item.

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


[Python-ideas] Re: Reverse polish notation

2021-04-02 Thread MRAB

On 2021-04-02 16:55, Richard Damon wrote:

I think python only has 3 unary operations, + - and ~ and only + and -
can also be binary operations.

unary + has less uses, since it normally just passes its argument, if
valid, unchanged, but can be used to validate that its argument has the
right type. I am not sure if a type could define its own unary+ to do
something special, but I thought it could.


The Counter class from the collections module has a special use for unary +.


On 4/2/21 11:19 AM, John wrote:

True.  It gets ambiguous when doing n*(-(x + y)) i.e. n x y + - *
(fail).  The simplest solution is n 0 x y + - *

I can't actually think of any other unary operators.

On Fri, Apr 2, 2021 at 10:54 AM Richard Damon  wrote:

One problem with trying to mix RPN with in-fix is that some operators,
like - can be either a unary or binary operation in the in-fix
notations, distinguished by context. In RPN you have lost that context.

is x y - - the same as -(x-y) or is it x-(-y) ? or is it waiting for
another operator and be x ?? (-(-y)) or is it expecting a previous
operand and is ?? - (x-y)

(same with +)

Typical RPN systems get around this by having unary - be a different
symbol/key that binary -


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


[Python-ideas] Re: Alternate lambda syntax

2021-02-17 Thread MRAB

On 2021-02-17 05:57, Steven D'Aprano wrote:

On Wed, Feb 17, 2021 at 11:13:08AM +1300, Greg Ewing wrote:

On 17/02/21 7:10 am, Steven D'Aprano wrote:
>"It's Greek letter, like pi that you may remember from maths
>class. In some technical computer science, the Greek L, lambda, is used
>as the symbol for functions."

The most accurate answer seems to be "Because somebody made
a mistake transcribing a mathematics paper many years ago." :-)


Not according to Alonzo Church, who at various times has stated that it
was either more or less chosen at random, or that it was derived from
Whitehead and Russell's x̂ (x-hat) via ∧x to λx to make it easier for the
printers.

Either way it wasn't a mistake, but a deliberate choice.

It is really remarkable how much attention lambda gets. As far as I
know, mathematicians don't ask why Hilbert chose epsilon for his epsilon
calculus, and nobody ever asks where "byte" comes from.

It is, apparently, a deliberate misspelling of bite, to avoid it being
accidently changed to bit. But why *bite*?

The first published use of "byte" apparently was in a 1956 IBM memo by
Werner Buchholz:

"[…] Most important, from the point of view of editing, will be the
ability to handle any characters or digits, from 1 to 6 bits long.
Figure 2 shows the Shift Matrix to be used to convert a 60-bit word,
coming from Memory in parallel, into characters, or 'bytes' as we have
called them, to be sent to the Adder serially."

The memo already shows that Buchholz and IBM were thinking of
multiple bits being a "word", so it's not clear why bytes. There's no
ordinary sense that a collection of bits (as in "a bit of stuff") is
considered "a bite".

It's like eating a sausage. You start at one end and take bites off it 
until you've eaten it all.


So a "byte" is part of a word (a word contains multiple characters).


Language is fun.


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


[Python-ideas] Re: Conditional with statements

2021-02-06 Thread MRAB

On 2021-02-07 00:57, Jonathan Crall wrote:



[snip]


To be clear, in the proposed syntax:

     if [condition] with [obj]:
         [code]

Would behave exactly as:

     if [condition]:
         with [obj]:
             [code]

Is there any chance that this conditional context manager syntax might be
considered? Does anyone but myself think this might be a good idea?


-1. It's not that much shorter. You wouldn't be saving much typing or space.
___
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/ASHN4HGPRJD2QEQJSCWSH7CKJKANNVX3/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Adding `open_text()` builtin function. (relating to PEP 597)

2021-01-24 Thread MRAB

On 2021-01-24 17:04, Chris Angelico wrote:

On Mon, Jan 25, 2021 at 3:55 AM Stephen J. Turnbull
 wrote:


Chris Angelico writes:
 > Right, but as long as there's only one system encoding, that's not
 > our problem. If you're on a Greek system and you want to decode
 > ISO-8859-9 text, you have to state that explicitly. For the
 > situations where you want heuristics based on byte distributions,
 > there's always chardet.

But that's the big question.  If you're just going to fall back to
chardet, you might as well start there.  No?  Consider: if 'open'
detects the encoding for you, *you can't find out what it is*.  'open'
has no facility to tell you!


Isn't that what file objects have attributes for? You can find out,
for instance, what newlines a file uses, even if it's being
autodetected.


 > In theory, UTF-16 without a BOM can consist entirely of byte values
 > below 128,

It's not just theory, it's my life.  62/80 of the Japanese "hiragana"
syllabary is composed of 2 printing ASCII characters (including SPC).
A large fraction of the Han ideographs satisfy that condition, and I
wouldn't be surprised if a majority of the 1000 most common ones do.
(Not a good bet because half of the ideographs have a low byte > 127,
but the order of characters isn't random, so if you get a couple of
popular radicals that have 50 or so characters in a group in that
range, you'd be much of the way there.)

 > But there's no solution to that,

Well, yes, but that's my line. ;-)



Do you get files that lack the BOM? If so, there's fundamentally no
way for the autodetection to recognize them. That's why, in my
quickly-whipped-up algorithm above, I basically had it assume that no
BOM means not UTF-16. After all, there's no way to know whether it's
UTF-16-BE or UTF-16-LE without a BOM anyway (which is kinda the point
of it), so IMO it's not unreasonable to assert that all files that
don't start either b"\xFF\xFE" or b"\xFE\xFF" should be decoded using
the ASCII-compatible detection method.

(Of course, this is *ONLY* if you don't specify an encoding. That part
won't be going away.)

Well, if you see patterns like b'\x00H\x00e\x00l\x00l\x00o' then it's 
probably UTF16-BE and if you see patterns like 
b'H\x00e\x00l\x00l\x00o\x00' then it's probably UTF16-LE.


You could also look for, say, sequences of Latin characters and 
sequences of Han characters.

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


[Python-ideas] Re: Adding `open_text()` builtin function. (relating to PEP 597)

2021-01-23 Thread MRAB

On 2021-01-24 01:14, Guido van Rossum wrote:

I have definitely seen BOMs written by Notepad on Windows 10.

Why can’t the future be that open() in text mode guesses the encoding?


"In the face of ambiguity, refuse the temptation to guess."
___
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/KVLLWSHHVZPLC3OLPAIT7BOXJJK2VPNU/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Adding `open_text()` builtin function. (relating to PEP 597)

2021-01-23 Thread MRAB

On 2021-01-23 10:11, Chris Angelico wrote:
[snip]


Okay. If the goal is to make UTF-8 the default, may I request that PEP
597 say so, please? With a heading of "deprecation", it's not really
clear what its actual goal is.

  From the sound of things - and it's still possible I'm misreading PEP
597, my apologies if so - this open_text function wouldn't really
solve anything much, and the original goal of "change the default
encoding to UTF-8" is better served by 597.

I use Windows and I switched to UTF-8 years ago. However, the standard 
on Windows is 'utf-8-sig', so I'd probably prefer it if the default when 
_reading_ was 'utf-8-sig'. (I'm not bothered about writing; I can still 
be explicit if I want 'utf-8-sig' for Windows-specific UTF-8 files.)

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


[Python-ideas] Re: Move semantics

2020-11-26 Thread MRAB

On 2020-11-27 02:30, Ned Batchelder wrote:

On 11/26/20 9:02 PM, MRAB wrote:

On 2020-11-27 01:12, Ned Batchelder wrote:

On 11/26/20 6:44 AM, 3mi...@gmail.com wrote:
Add something like Move type hint to typing module. It will tell the 
analyzer that the input parameter of the function is moved and can 
not be used after. For example:

```
def f(d: Move[dict]) -> dict:
 d['a'] = 2
 return d

d = {1: 2}
f(d)
print(d[1])  # mistake, using of moved value


Maybe I'm behind the times on the latest thinking in programming
languages.  I'm not familiar with "move semantics". Can someone explain
what is wrong with the code above?  What is the mistake? `print(d[1])`
will work perfectly fine.  The function changes the 'a' key, and then we
access the 1 key. Should the example have used the same key in both 
places?


d is moved into function f. f does return d when it exits, moving it 
out back again, but as the caller doesn't bind to it, it's discarded.



It's not discarded, it's still referenced by d in the outer scope.

No, it's not any more, and that's the point. It was _moved_ into the 
function, and although the function returned it, it was discarded 
because the caller didn't bind it to keep hold of it.

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


[Python-ideas] Re: Move semantics

2020-11-26 Thread MRAB

On 2020-11-27 01:12, Ned Batchelder wrote:

On 11/26/20 6:44 AM, 3mi...@gmail.com wrote:

Add something like Move type hint to typing module. It will tell the analyzer 
that the input parameter of the function is moved and can not be used after. 
For example:
```
def f(d: Move[dict]) -> dict:
 d['a'] = 2
 return d

d = {1: 2}
f(d)
print(d[1])  # mistake, using of moved value


Maybe I'm behind the times on the latest thinking in programming
languages.  I'm not familiar with "move semantics". Can someone explain
what is wrong with the code above?  What is the mistake? `print(d[1])`
will work perfectly fine.  The function changes the 'a' key, and then we
access the 1 key. Should the example have used the same key in both places?

d is moved into function f. f does return d when it exits, moving it out 
back again, but as the caller doesn't bind to it, it's discarded.


Move semantics is a way of ensuring that there's only one "owner", which 
makes garbage collection simpler; when an object is discarded 
(dereferenced) by its the owner, it can be garbage-collected.

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


[Python-ideas] Re: Adding PyInstaller to the standard library

2020-11-24 Thread MRAB

On 2020-11-25 00:42, Greg Ewing wrote:

On 25/11/20 12:14 pm, Chris Angelico wrote:

If you want a perfectly out-of-the-box app, you're probably
going to have to stick to Tkinter.


Which is only bundled with Python on Windows, as far
as I know.


It's also bundled with Python on Raspbian.
___
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/PJNWTQLVS3LC642JW4HFUSL6HRBAJRDK/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Dict unpacking assignment

2020-10-26 Thread MRAB

On 2020-10-26 04:56, Dennis Sweeney wrote:

What if the mapping assignment were more harmonious with the pattern matching 
PEP? Something like this:

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

The keys here could be arbitrary hashables and the "values" could be arbitrary assignment 
targets (assigned all-or-nothing). This wouldn't need the right-hand-side double-star, and I think 
it more closely resembles the sequence unpacking assignment syntax. You can assign to a (thing that 
looks like a) tuple or to a (thing that looks like a) list or to a sequence subscript or object 
attribute, why not be able to assign to a (thing that looks like a) dictionary? This also avoids 
polluting the local namespace in case one of your keys is the string "range" or 
something. It also feels less magical to me, albeit more verbose.

Calls to a hypothetical parse/sscanf function could closely mirror some 
str.format() calls:

 text = "{a}, {b}, {c}".format(**{'a': a0, 'b': b0, 'c': c0})
 {'a': a1, 'b': b1, 'c': c1} = "{a}, {b}, {c}".parse(text)
 assert (a1, b1, c1) == (a0, b0, c0)

Alternative positional parsing would be useful as well, as in:

 text = "{}, {}, {}".format(a0, b0, c0)
 a1, b1, c1 = "{}, {}, {}".parse(text)
 assert (a1, b1, c1) == (a0, b0, c0)

The assertions could still fail because there's nothing there to say 
that a0, b0 and c0 are strings, or, indeed, that there isn't a comma in 
one of them.


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


[Python-ideas] Re: Extrapolating PEP 634: The walrus was waiting for patmat all along

2020-10-23 Thread MRAB

On 2020-10-23 23:25, Valentin Berlier wrote:

Pattern-matching is great. I think PEP 634 is on the right track, but it
would be a waste to only use pattern-matching for choosing a branch in a
match statement.

Let’s look at Rust:

  if let [x, y] = my_array {
  ...
  }

Rust "if let" constructs are an alternative to full-blown match
statements that make it less verbose to match a single pattern.

We have a similar problem. The syntax proposed by PEP 634 is pretty
verbose for matching a single pattern:

  match my_list:
  case [x, y]:
  ...

Two keywords and two indentation levels. We can do better:

  if [x, y] := my_list:
  ...

Yes, your first intuition is right. This looks similar to the Rust
version but would work completely differently. But hear me out. Let's
look past my terrible example and focus on the idea.

1. The walrus operator was purposefully designed to create bindings and
not to perform assignments to arbitrary lvalues.
2. Matching a pattern only introduces bindings as well, no assignments.
3. The current behavior of the walrus operator is equivalent to matching
the right-side operand to an "irrefutable" capture pattern.

Allowing the walrus operator to do pattern-matching would simply make
the returned value conditional. If the pattern doesn't match, the walrus
operator returns None.

  print(x := 42)  # 42
  print(1 := 42)  # None

Why should a failed match return None? That's not helpful if it matches 
but the value itself is None.


[snip]
___
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/M53Q24WL3VA2W2FC2TDYJDD77NVURCXF/
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: New feature

2020-10-13 Thread MRAB

On 2020-10-14 00:46, Steven D'Aprano wrote:

On Tue, Oct 13, 2020 at 03:35:58PM -0700, Guido van Rossum wrote:


Can one of the educators on the list explain why this is such a commonly
required feature? I literally never feel the need to clear my screen -- but
I've seen this requested quite a few times in various forms, often as a bug
report "IDLE does not support CLS". I presume that this is a common thing
in other programming environments for beginners -- even C++ (given that it
was mentioned). Maybe it's a thing that command-line users on Windows are
told to do frequently? What am I missing that students want to do
frequently? Is it a holdover from the DOS age?


I think it's a personal preference to remove the visible clutter from
the screen without going so far as to exit the interpreter and start a
new session.

And I do it frequently, in both Python and bash. Because I never
remember the name of the bash command to do it (cls or clear?), and
Python doesn't have one, I just hold down the Enter key for a couple of
seconds until there's no clutter visible.

(I just tried it in bash now, and it is spelled "clear", and it clears
the scrollback buffer as well as just clearing the visible clutter on
the screen.)

Oh, apparently Ctrl-L works too. I don't know if that's a feature of my
terminal or of the Python interpreter.

Historically, Ctrl+L is the Form Feed control character. I remember the 
the BBC Micro supporting it.



There's supposed to be a magic escape sequence that will clear the
screen when printed, if your terminal supports it, but I never remember
that either. Let me look it up...

 print("\x1b[H\x1b[2J")

seems to work.



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


[Python-ideas] Re: Add _KB, _MB, _GB to numeric literals

2020-10-13 Thread MRAB

On 2020-10-13 06:06, malin...@163.com wrote:

PEP 515 added underscore to numeric literals, it brings better readability.

 PEP 515 -- Underscores in Numeric Literals
 https://www.python.org/dev/peps/pep-0515/

Is it possible to add _KB, _MB, _GB to numeric literals, for example:

  200_KB   (200*1024)
  150_MB   (150*1024*1024)
  2_GB (2*1024*1024*1024)
  
Do you think it's a good code style?



A couple of points:

1. 200_KB is really a size in bytes, not a number, if you see what I 
mean. In general, I'm -1.


2. The use of K/M/G as powers of 1024 is an old, though common, 
convention. These days it's recommended to keep those prefixes as powers 
of 1000 as in the metric system (SI) (although SI uses 'k' instead of 
'K') and use Ki/Mi/Gi instead as powers of 1024.

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


[Python-ideas] Re: PEP 637 and keyword only subscripts

2020-09-28 Thread MRAB

On 2020-09-28 06:51, Chris Angelico wrote:

On Mon, Sep 28, 2020 at 3:33 PM Christopher Barker  wrote:

As for using an empty tuple, thanks Guido for laying out the logic so succinctly, and it 
does make it pretty simple that only the one index case is special. Nevertheless, I think 
most folks expect the special case to be at the end of the "series", not in the 
middle -- i.e.

four is the same as three is the same as two, one is special, and zero is not 
allowed.

rather than

four is the same as three is the same as two, one is special, and zero is the 
same as two, three, four, ...

For that reason, I prefer a separate sentinel.



English treats 1 as special and 0 as the same as other numbers when it
comes to singulars and plurals. You talk about "an item", but "no
items" or "two items" or "three items". As you descend through the
numbers, four ("items") is the same as three ("items") is the same as
two ("items"), and one is special ("item"), and zero is back to the
normal case ("items").

I'm not saying that English should be the fundamental basis upon which
Python is designed, but at least there's some precedent :) What do
other languages do in this way? Are other human languages based around
the idea that zero matches others, or are there different ways to
write things?

Dutch is, of course, of particular interest here :)


Some languages have singular, dual, and plural.

Some languages use the singular if the number ends with 1, so "20 
items", "21 item", "22 items".


I believe I read somewhere that some languages are OK with "found 2 
files" and "found 1 file", but reject "found 0 files"; it has to be 
"didn't find any files".


And some languages don't inflect for number at all.
___
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/TDTNTMDYNCRUAVKQKQV4DZBUWGKGJDPI/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: PEP 637 and keyword only subscripts

2020-09-27 Thread MRAB

On 2020-09-27 21:47, David Mertz wrote:
On Sun, Sep 27, 2020 at 10:41 AM Stefano Borini 
mailto:stefano.bor...@gmail.com>> wrote:


I kept the tuple as the accepted option, but I am personally open to
NoIndex as well. I am not sure how the SC would take a non-hashable,
new constant to be
honest, for such a specific use case.


My "vote" is for NoIndex.  I suggested that new object and name, after 
all :-).


But I find empty tuple perfectly fine, and would have no objection if 
that is chosen.



I'd go for something that would have a wider use.

Consider, for example, the use-case of a function that has an optional 
parameter and you want a way to know whether an argument has been 
provided but None is a valid value that could be passed in.


Having a singleton such as Missing would be helpful there.

An index/subscript that has no positional component is just a special 
case of that.

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


[Python-ideas] Re: Suggestion: annotated exceptions

2020-09-25 Thread MRAB

On 2020-09-26 01:23, Greg Ewing wrote:

On 26/09/20 4:32 am, Oscar Benjamin wrote:

annotations could be used to document in a statically
analysable way what the "expected" exceptions are. A type checker
could use those to check whether a caller is handling the *expected*
exceptions


But that would be inappropriate. Even if an exception is
"expected" (assuming for a moment we agree on what that means),
the immediate caller is *not* obliged to handle it. Just as
with any other exception, it's perfectly fine to let it propagate
up to a level where something sensible can be done with it.

Treating this as an error would be more annoying than helpful in
most situations, I think.

There are a few cases where it *might* make sense, such as
StopIteration, which is pretty much part of the function's API
and letting it escape is probably a mistake. But such cases
are very rare and probably not worth adding a new language
mechanism for.

An "expected" exception would be one that could be regarded as part of 
the interface/API, e.g. json.load raising JSONDecodeError on malformed 
JSON. Other exceptions could also be raised, if you, for example, you 
didn't pass in a file, or there's an I/O error, or you run out of memory.

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


[Python-ideas] Re: PEP 637 - support for indexing with keyword arguments (Was: Re: PEP 9999 (provisional): ...)

2020-09-25 Thread MRAB

On 2020-09-25 20:36, Christopher Barker wrote:
On Fri, Sep 25, 2020 at 6:05 AM Ricky Teachey > wrote:


I'd like to hear more about why the empty tuple has been selected as
the default index. 



It makes sense to me: if more than one index is passed, they are passed 
as a tuple. so many classes need to handle tuples anyway.


What other options are there? I suppose None is a possibility, but None 
is a valid dict key, so probably not a great idea. Hmm, so is an empty 
tuple. Darn.


I think having no default is a better option, as someone pointed out 
already in this thread.


It currently doesn't support multiple indexes, so there's no distinction 
between one index that's a 2-tuple and 2 indexes: d[(1, 2)] == d[1, 2].


Using an empty tuple as the default index isn't that bad, assuming 
you're going to allow a default.

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


[Python-ideas] Re: What about having a .get(index, default) method for arrays like we have for dicts?

2020-08-25 Thread MRAB

On 2020-08-25 13:52, Daniel. wrote:

I just came across this again while implementing an parser

I would like to compare stack elements as

if stack[-3] == x and stack[-2] == y and stack[-1] == z


if stack[-3 : ] == [x, y, z]:


and somewere below

elif stack[-1] == t


elif stack[-1 : ] == [t]:


I had to spread `len(stack)` in a lot of places.


You can use slicing to reduce the number of `len(stack)`.

People said about the length of a list is usually known, but when you 
use it as a stack is the oposit.



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


[Python-ideas] Re: Package kwkey and PEP 472 -- Support for indexing with keyword arguments

2020-08-07 Thread MRAB

On 2020-08-07 13:13, Jonathan Fine wrote:

We are discussing a proposal to extend Python's syntax to allow
     d[1, 2, a=3, b=4]

We are also discussing the associated semantics. At present
     d[1, 2]
     d[(1, 2)]
are semantically equivalent.


Python behaves as though it's wrapping parentheses around the index:

d[1, 2] => d[(1, 2)]
d[(1, 2)] => d[((1, 2))] == d[(1, 2)]


There is a proposal, that
     d[1, 2, a=3, b=4]
     d[(1, 2), a=3, b=4]
be semantically equivalent.

Will adding keyword arguments break existing code? No, because they're 
currently not allowed.


Python doesn't even allow you to unpack with *, so that won't break 
existing code either.


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


  1   2   3   4   >