[Python-ideas] Re: Idea: Extend "for ... else ..." to allow "for ... if break ..." else

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



On 28/07/2020 15:33, Guido van Rossum wrote:
Rest assured this is not a problem. In any case it’s the compiler, not 
the parser, that generates the bytecode, from the AST. The compiler 
always has the full AST available before it is asked to generate any 
bytecode. The new parser just allows more flexible syntactic 
constructs, esp. “soft keywords”.


*If* you want tou propose clearer syntax for this, please extend the 
loop syntax, not the ‘if’ syntax. So, ‘case ... zero’ makes more sense 
than ‘if [not] break’.


—Guido

On Tue, Jul 28, 2020 at 03:26 Jonathan Fine > wrote:


Hi Rob

You wrote:

So: You're asking that the bytecode generated for the for-loop
depends
on something that happens (or not) after the end of the
for-loop body
(which could be arbitrarily long).

I speak from ignorance, but I suspect that even with the new
parser,
which I am reliably informed can make the tea and implement
world peace,
that would be asking a lot.


I'm also speaking from ignorance. However, here I'm the optimist.
Ignorance is bliss. You're the pessimist. The devil is in the details.

Until we have knowledge and wisdom on this, I think we need both
points of view. So I'm grateful for your
https://en.wikipedia.org/wiki/Grain_of_salt (American English,
pinch of salt in British English). I hope it makes my dish taste
better!
-- 
Jonathan


I stand corrected; my objection to detecting "zero iterations" has no 
foundation.

It's good to know the facts.

On labelled breaks:
My God, you want to bring back the GOTO statement!:-)  Seriously, 
though, I can see that labelled breaks might be useful.  Especially 
where the same label is used more than once, helping DRY.

One thought though:
A possible, unrelated, future language extension is to allow breaking 
out of more than one loop at a time.  (I know there have been times 
where I would have found this useful, though I can't recall them now.)
So the syntax to break out of 3 loops at a time might be "break break 
break" or "break 3" or "break 3 times" or .
A syntax to break out of *all* enclosing loops (although not great 
programming style, because it would be broken by adding a new outer 
loop) might be "break all" or "break *".

(BTW I have a job lot of bikesheds, in case you want any cheap ones.)
So maybe you could give half an eye to not clashing with some such 
possible future scheme?

Rob



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

--
--Guido (mobile)


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


[Python-ideas] Re: Thoughts about implementing object-compare in unittest package?

2020-07-28 Thread Stephen J. Turnbull
2qdxy4rzwzuui...@potatochowder.com writes:

 > in order to foil suck attacks.

Typo of the Year candidate!  (It was a typo, right?)
___
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/DIMKMR5EKYUJFFGBKVCZY7VGPID2FGPU/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Access (ordered) dict by index; insert slice

2020-07-28 Thread Stephen J. Turnbull
Christopher Barker writes:

 > from itertools import islice
 > 
 > smaller_dict = dict(islice(large_dict.items(), 0, 255))
 > 
 > which works, and isn't doing an unnecessary copying but it's pretty
 > darn ugly, as far as I'm concerned.

In your application, I think that's just pretty, myself.  The only thing
that's missing is slice notation.  But that's probably not hard to
implement in terms of the islice function, just completely redundant.
___
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/LPHMWNCI3VPPN7FEBEUJR4K2QDVNCPX3/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Idea: Extend "for ... else ..." to allow "for ... if break ..." else

2020-07-28 Thread Stephen J. Turnbull
Jonathan Fine writes:

 > Sometimes a loop has multiple break commands, which have different
 > purposes. So a further extension might be
 > for i in items:
 > LOOP_BODY
 > if break left:

An if here is already valid syntax.  I'm pretty sure that the parsers
can handle it.  But Python statement-introducing keywords are
intentionally quite distinct for human consumption.  The fact that
else and elif are similar in some ways is mitigated by the fact that
they have very similar semantics.

It's also true that the "in" and "is" operators would be somewhat
confusable, but I don't think that's as important as having quite
distinct statement keywords.

 > print('exit via break left')
 > elif break right:
 > print('exit via break right')
 > elif break:

'break' is of course already a "hard" keyword, globally reserved.  But
this looks very much like

elif flag:

to me.

 > print('exit via some other break')
 > else:
 > print('exit via StopIteration')

Finally, much of what this syntax allows is possible like this:

for i in items:
LOOP_BODY_ABOVE_BREAKS
if LEFT:
# NOTE: additional indentation here is hidden in LOOP_BODY
# in the OP.
print('exit via break left')
break;
LOOP_BODY_AMID_BREAKS
if RIGHT:
print('exit via break right')
break;
LOOP_BODY_AMID_BREAKS
if CENTER:
print('exit via some other break')
break;
LOOP_BODY_BELOW_BREAKS
else:
print('exit via StopIteration')

So the new feature is to distinguish some breaks from other breaks and
collect the action suites for breaks that have exactly the same
actions in a single place.  But how often is this going to be useful?

If it *is* useful, it occurs to me that (1) this looks a lot like the
try ... except ... pattern, and (2) breaks are generally perceived as
exceptional exits from a loop.  Instead of "if break [LABEL]", "except
[LABEL]" might work, although the semantic difference between labels
and exceptions might get a ton of pushback.

That said, I can't think of a time where I wanted more than one kind
of a break from a loop, let alone where some kinds existed in multiple
instances.  So I'm -1 unless we see plausible use cases for the extra
power, and a before-after comparison shows a perceptible readability
improvement.

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


[Python-ideas] Re: Fwd: Re: Experimenting with dict performance, and an immutable dict

2020-07-28 Thread Inada Naoki
On Sun, Jul 26, 2020 at 4:44 AM Marco Sulla
 wrote:
>
> I also remembered another possible use-case: kwargs in CPython. In C code, 
> kwargs are PyDictObjects. I suppose they are usually not modified; if so, 
> fdict could be used, since it seems to be faster at creation.
>

I have not confirmed why frozendict is faster than dict for creation.
But note that kwargs is not created by `dict(d)`.
It is created by PyDict_New() and PyDict_SetItem(). Please benchmark
these C APIs if you want to propose the idea.

https://github.com/python/cpython/blob/a74eea238f5baba15797e2e8b570d153bc8690a7/Python/ceval.c#L4155
https://github.com/python/cpython/blob/a74eea238f5baba15797e2e8b570d153bc8690a7/Python/ceval.c#L4245


FWIW, I optimized dict(d) in https://bugs.python.org/issue41431
(https://github.com/python/cpython/pull/21674 )

$ ./python -m pyperf timeit --compare-to ./python-master -s
'd=dict.fromkeys(range(1000))' -- 'dict(d)'
python-master: . 21.5 us +- 0.2 us
python: . 4.52 us +- 0.16 us
Mean +- std dev: [python-master] 21.5 us +- 0.2 us -> [python] 4.52 us
+- 0.16 us: 4.76x faster (-79%)

Regards,

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


[Python-ideas] Re: Thoughts about implementing object-compare in unittest package?

2020-07-28 Thread 2QdxY4RzWzUUiLuE
On 2020-07-28 at 15:58:58 -0700,
Christopher Barker  wrote:

> But a dict always has a LOT fewer buckets than possible hash values,
> so clashes within a bucket are not so rare, so equality needs to be
> checked always -- which is what I was missing.

> And while it wouldn't break anything, having a bunch of non-equal
> objects produce the same hash wouldn't break anything, it would break
> the O(1) performance of dicts.

> Have I got that right?

Yes.

Breaking O(1) performance was actually the root of possible Denial of
Service attacks:  if an attacker knows the algorithms, that attacker
could specifically create keys (e.g., user names) whose hash values are
the same, and then searching a dict degenerates to O(N), and then your
server falls to its knees.  At some point, Python added some
randomization to the way dictionaries work in order to foil suck
attacks.
___
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/TJCGVDGZWP4LXG44P4Z34BPMZRI3ODY3/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Access (ordered) dict by index; insert slice

2020-07-28 Thread Christopher Barker
re-awakening this thread, because I just happened on an actual real-world
use case:

I need the first 255 items in a dict, as a dict. Order is important, and I
can count on an order-preserving dict.

I ended up with:

from itertools import islice

smaller_dict = dict(islice(large_dict.items(), 0, 255))

which works, and isn't doing an unnecessary copying but it's pretty darn
ugly, as far as I'm concerned.

I could also do it the old fashioned way:

smaller_dict = {}
for k, v in dict.items():
if i > 255:
break
 smaller_dict[k] = v

which is worse.

I'd much rather:

dict(large_dict.items[:255])

I'd even more prefer:

dict[:255]

which would, in theory be possible, as slices are not hashable, so no one
is doing this in current code as an actual dict key, but yeah, that's too
much magic to ask for.

To be fair, this isn't that much data, and it's in memory already, so:

dict(tuple(large_dict.items())[:255])

would work just fine. but as Python has moved toward a lot more iterables,
and lazy evaluation, it seems like we shouldn't have to make a full copy,
just to pull a fraction of something out.

Note that this is related to an earlier thread I started about having a way
to lazy-slice a Sequence -- essentially islice, but with slice syntax.

This is also related a bit to another thread about keywords in indexing --
there were examples there where it would be nice to have slice syntax in
more places, like function calls. then this could be:

So: anyone have a cleaner way to accomplish this without any changes to
Python?

This is still an oddball use case, so may not be a reason to change Python
-- but it IS a real world, operational code, use case :-)

-CHB



On Sun, Jul 12, 2020 at 9:55 PM Christopher Barker 
wrote:

> On Sat, Jul 11, 2020 at 1:33 PM David Mertz  wrote:
>
>> On Sat, Jul 11, 2020 at 3:45 PM Christopher Barker 
>> wrote:
>>
>>> random.choice(the_dict.keys())
>>>
>>> is a little easier than:
>>>
>>> random.choice(list(the_dict.keys())
>>>
>>
>> Ummm... don't you mean:
>>
>> random.choice(list(the_dict))
>>
>
> well, sure, though I have to say that I think that that's an unfortunate
> confusing thing about python dicts. IN fact, I doubt there are many uses at
> all for dict.keys() -- most uses can jsut use the dict.
>
> I certainly see newbies write:
>
> if this in dict.keys():
>
> pretty often.
>
> maybe adding indexing to the dict views will give the dict_keys object
> more reason to exist :-)
>
> -CHB
>
>
>
>
>
>
>
>
>> If it's keys you care about I've saved you one character over your
>> proposed style, while also reading better to me.  It's only for .items()
>> where it doesn't work.  And honestly, just looking up the value from the
>> random key is not hard.
>>
>> In any case, if "reservoir sampling" is the goal here, we should just add
>> a function `random.reservoir_sample()` to accommodate using iterators
>> rather than sequences (https://en.wikipedia.org/wiki/Reservoir_sampling)
>>
>>
>> --
>> The dead increasingly dominate and strangle both the living and the
>> not-yet born.  Vampiric capital and undead corporate persons abuse
>> the lives and control the thoughts of homo faber. Ideas, once born,
>> become abortifacients against new conceptions.
>>
>
>
> --
> Christopher Barker, PhD
>
> Python Language Consulting
>   - Teaching
>   - Scientific Software Development
>   - Desktop GUI and Web Development
>   - wxPython, numpy, scipy, Cython
>


-- 
Christopher Barker, PhD

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
___
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/BXSOYCMJ2YN7NUKXFDVFBXOMAHZR45L5/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Thoughts about implementing object-compare in unittest package?

2020-07-28 Thread Christopher Barker
On Mon, Jul 27, 2020 at 5:42 PM Ethan Furman  wrote:
> Chris Barker wrote:

> >  Is this because it's possible, if very
> > unlikely, for ANY hash algorithm to create the same hash for two
> > different inputs? So equality always has to be checked anyway?
>
> snip

For example, if a hash algorithm decided to use short names, then a
> group of people might be sorted like this:
>
> Bob: Bob, Robert
> Chris: Christopher, Christine, Christian, Christina
> Ed: Edmund, Edward, Edwin, Edwina
>
> So if somebody draws a name from a hat:
>
>Christina
>
> You apply the hash to it:
>
>Chris
>
> Ignore the Bob and Ed buckets, then use equality checks on the Chris
> names to find the right one.
>

sure, but know (or assume anyway) that python dicts and sets don't use such
a simple, naive hash algorithm, so in fact, non-equal strings are very
unlikely to have the same hash:

In [42]: hash("Christina")

Out[42]: -8424898463413304204

In [43]: hash("Christopher")

Out[43]: 4404166401429815751

In [44]: hash("Christian")

Out[44]: 1032502133450913307

But a dict always has a LOT fewer buckets than possible hash values, so
clashes within a bucket are not so rare, so equality needs to be checked
always -- which is what I was missing.

And while it wouldn't break anything, having a bunch of non-equal objects
produce the same hash wouldn't break anything, it would break the O(1)
performance of dicts.

Have I got that right?

-CHB







> >> From a practical standpoint, think of dictionaries:
> >
> > (that's the trick here -- you can't "get" this without knowing something
> > about the implementation details of dicts.)
>
> Depends on the person -- I always do better with a concrete application.
>
> >> adding
> >> --
> >> - objects are sorted into buckets based on their hash
> >> - any one bucket can have several items with equal hashes
> >
> > is this mostly because there are many more possible hashes than buckets?
>
> Yes.
>
> >> - those several items (obviously) will not compare equal
> >
> > So the hash is a fast way to put stuff in buckets, so you only need to
> > compare with the others that end up in the same bucket?
>
> Yes.
>
> >> retrieving
> >> --
> >> - get the hash of the object
> >> - find the bucket that would hold that hash
> >> - find the already stored objects with the same hash
> >> - use __eq__ on each one to find the match
> >
> > So here's my question: if there is only one object in that bucket, is
> > __eq__ checked anyway?
>
> Yes -- just because it has the same hash does not mean it's equal.
>
> > So what happens when there is no __eq__?The object can still be hashable
> > -- I guess that's because there IS an __eq__ -- it defaults to an id
> > check, yes?
>
> Yes.
>
> The default hash, I believe, also defaults to the object id -- so, by
> default, objects are hashable and compare equal only to themselves.
>
> --
> ~Ethan~
> ___
> 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/XPUXOSK7WHXV7LRB7H3I4S42JQ2WXQU3/
> Code of Conduct: http://python.org/psf/codeofconduct/
>


-- 
Christopher Barker, PhD

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
___
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/YJNU4QPGWJUFYIL33PSI2NPYAC2BRLI5/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Function suggestion: itertools.one()

2020-07-28 Thread Sebastian Kreft
Check the thread
https://mail.python.org/archives/list/python-ideas@python.org/thread/REYDJFCXQNQG4SAWKELQMCGM77IZG47Q/#CGMWPLJME4ZZNGHDY4DGCSF347VBMAKZ

There are comments in favor of both first and one.

On Tue, Jul 28, 2020 at 3:59 PM Noam Yorav-Raphael 
wrote:

> Thanks! It's good to hear that you too find it useful.
>
> Since adding methods to built-in types is much heavier than adding one
> function to a module, l suggest keeping this discussion focused on adding
> just the one() function to itertools, and see if there is enough support
> for this.
>
> Cheers,
> Noam
>
> On Tue, Jul 28, 2020 at 10:47 PM Alex Hall  wrote:
>
>> In my personal toolbox of utility functions, this is by far the function
>> I use most often, although it's implemented slightly differently and I call
>> it `only`. I think it's very useful and it would be great to have in the
>> standard library to encourage people to write safer code.
>>
>> Often this is part of a larger expression, especially if I'm drilling
>> into some nested data structure. This can lead to having a prefix operation
>> (the function call) breaking a chain of postfix operations (attributes,
>> method calls, subscripting...) which is ugly and less readable. It would be
>> nice if this could also be available as a method on lists, tuples, and sets
>> to keep the data flowing left to right. Plus it would save an import.
>>
>> On Tue, Jul 28, 2020 at 9:29 PM Noam Yorav-Raphael 
>> wrote:
>>
>>> Hello,
>>>
>>> There's a simple function that I use many times, and I think may be a
>>> good fit to be added to itertools. A function that gets an iterator, and if
>>> it has exactly one element returns it, and otherwise raises an exception.
>>> This is very useful for cases where I do some sort of query that I expect
>>> to get exactly one result, and I want an exception to be raised if I'm
>>> wrong. For example:
>>>
>>> jack = one(p for p in people if p.id == '1234')
>>>
>>> sqlalchemy already has such a function for queries:
>>> https://docs.sqlalchemy.org/en/13/orm/query.html#sqlalchemy.orm.query.Query.one
>>>
>>> more-itertools has this exact function:
>>>
>>> https://more-itertools.readthedocs.io/en/latest/api.html#more_itertools.one
>>>
>>> Here is a simple implementation:
>>>
>>> def one(iterable):
>>> it = iter(iterable)
>>> try:
>>> first = next(it)
>>> except StopIteration:
>>> raise ValueError("Iterator is empty")
>>> try:
>>> second = next(it)
>>> except StopIteration:
>>> return first
>>> else:
>>> raise ValueError("Iterator has more than one item")
>>>
>>> I brought this up on python-dev, but it should be discussed here.
>>> Here is the discussion:
>>>
>>> https://mail.python.org/archives/list/python-...@python.org/thread/D52MPKLIN4VEXBOCKVMTWAK66MAOEINY/
>>>
>>> Brett Cannon said that this idea has been brought up at least twice
>>> before. I found:
>>>
>>> https://mail.python.org/archives/list/python-ideas@python.org/thread/FTJ6JRDTZ57HUVZ3PVIZV2NHU2NLAC4X/#RMWV3SNZ2N4KZLPKPIDE42H46QDEIVHE
>>>
>>>
>>> https://mail.python.org/archives/list/python-ideas@python.org/thread/REYDJFCXQNQG4SAWKELQMCGM77IZG47Q/#ITR2ILPVCKYR52U2D7RHGENASZTNVDHN
>>>
>>> The first thread hasn't reached any operative conclusion. The second
>>> thread was very long, and seemed to focus mostly on another function,
>>> first(), that doesn't check if there is more than one item. Joao S. O Bueno
>>> said that it passed "general approval". I think that perhaps a new
>>> discussion, focused just on one (no pun intended) function in the itertools
>>> module may reach a conclusion.
>>>
>>> It was suggested that instead of an additional function, one can use
>>> iterator unpacking:
>>>
>>> jack, = (p for p in people if p.id == '1234')
>>> or
>>> [jack] = (p for p in people if p.id == '1234')
>>>
>>> I still think that having a one() function would be useful, since:
>>> 1. I think it spells the intention more clearly. It is not symbols that
>>> you need to understand their meaning in order to understand that I expect
>>> the iterable to have exactly one item, it's spelled in code.
>>> 2. The exception would be easier to understand, since errors in tuple
>>> unpacking usually mean something else.
>>> 3. The one() function allows you to use the result inside an expression
>>> without assigning it to a variable. Therefore, I think it encourages
>>> writing better code. It's very easy to write:
>>> print([p for p in people if p.id == '1234][0])
>>> (which has the problem of not verifying the assumption that there's no
>>> more than one result), and I find it easier to replace _[0] with one(_)
>>> than to be required to name a new variable, and instead of having an
>>> operation on the iterable, change the way I'm assigning to it.
>>>
>>> WDYT?
>>>
>>> Cheers,
>>> Noam
>>>
>>>
>>> ___
>>> Python-ideas mailing list -- python-ideas@python.org
>>> To unsubscribe send an email to python-ide

[Python-ideas] Re: Function suggestion: itertools.one()

2020-07-28 Thread Noam Yorav-Raphael
Thanks! It's good to hear that you too find it useful.

Since adding methods to built-in types is much heavier than adding one
function to a module, l suggest keeping this discussion focused on adding
just the one() function to itertools, and see if there is enough support
for this.

Cheers,
Noam

On Tue, Jul 28, 2020 at 10:47 PM Alex Hall  wrote:

> In my personal toolbox of utility functions, this is by far the function I
> use most often, although it's implemented slightly differently and I call
> it `only`. I think it's very useful and it would be great to have in the
> standard library to encourage people to write safer code.
>
> Often this is part of a larger expression, especially if I'm drilling into
> some nested data structure. This can lead to having a prefix operation (the
> function call) breaking a chain of postfix operations (attributes, method
> calls, subscripting...) which is ugly and less readable. It would be nice
> if this could also be available as a method on lists, tuples, and sets to
> keep the data flowing left to right. Plus it would save an import.
>
> On Tue, Jul 28, 2020 at 9:29 PM Noam Yorav-Raphael 
> wrote:
>
>> Hello,
>>
>> There's a simple function that I use many times, and I think may be a
>> good fit to be added to itertools. A function that gets an iterator, and if
>> it has exactly one element returns it, and otherwise raises an exception.
>> This is very useful for cases where I do some sort of query that I expect
>> to get exactly one result, and I want an exception to be raised if I'm
>> wrong. For example:
>>
>> jack = one(p for p in people if p.id == '1234')
>>
>> sqlalchemy already has such a function for queries:
>> https://docs.sqlalchemy.org/en/13/orm/query.html#sqlalchemy.orm.query.Query.one
>>
>> more-itertools has this exact function:
>>
>> https://more-itertools.readthedocs.io/en/latest/api.html#more_itertools.one
>>
>> Here is a simple implementation:
>>
>> def one(iterable):
>> it = iter(iterable)
>> try:
>> first = next(it)
>> except StopIteration:
>> raise ValueError("Iterator is empty")
>> try:
>> second = next(it)
>> except StopIteration:
>> return first
>> else:
>> raise ValueError("Iterator has more than one item")
>>
>> I brought this up on python-dev, but it should be discussed here.
>> Here is the discussion:
>>
>> https://mail.python.org/archives/list/python-...@python.org/thread/D52MPKLIN4VEXBOCKVMTWAK66MAOEINY/
>>
>> Brett Cannon said that this idea has been brought up at least twice
>> before. I found:
>>
>> https://mail.python.org/archives/list/python-ideas@python.org/thread/FTJ6JRDTZ57HUVZ3PVIZV2NHU2NLAC4X/#RMWV3SNZ2N4KZLPKPIDE42H46QDEIVHE
>>
>>
>> https://mail.python.org/archives/list/python-ideas@python.org/thread/REYDJFCXQNQG4SAWKELQMCGM77IZG47Q/#ITR2ILPVCKYR52U2D7RHGENASZTNVDHN
>>
>> The first thread hasn't reached any operative conclusion. The second
>> thread was very long, and seemed to focus mostly on another function,
>> first(), that doesn't check if there is more than one item. Joao S. O Bueno
>> said that it passed "general approval". I think that perhaps a new
>> discussion, focused just on one (no pun intended) function in the itertools
>> module may reach a conclusion.
>>
>> It was suggested that instead of an additional function, one can use
>> iterator unpacking:
>>
>> jack, = (p for p in people if p.id == '1234')
>> or
>> [jack] = (p for p in people if p.id == '1234')
>>
>> I still think that having a one() function would be useful, since:
>> 1. I think it spells the intention more clearly. It is not symbols that
>> you need to understand their meaning in order to understand that I expect
>> the iterable to have exactly one item, it's spelled in code.
>> 2. The exception would be easier to understand, since errors in tuple
>> unpacking usually mean something else.
>> 3. The one() function allows you to use the result inside an expression
>> without assigning it to a variable. Therefore, I think it encourages
>> writing better code. It's very easy to write:
>> print([p for p in people if p.id == '1234][0])
>> (which has the problem of not verifying the assumption that there's no
>> more than one result), and I find it easier to replace _[0] with one(_)
>> than to be required to name a new variable, and instead of having an
>> operation on the iterable, change the way I'm assigning to it.
>>
>> WDYT?
>>
>> Cheers,
>> Noam
>>
>>
>> ___
>> 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/6OLEL4XTUWXRI7ENODKEDOYFBRVDYKI7/
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
>
___
Python-ideas mailing list -- python-ideas@python.org
To un

[Python-ideas] Re: Function suggestion: itertools.one()

2020-07-28 Thread Alex Hall
In my personal toolbox of utility functions, this is by far the function I
use most often, although it's implemented slightly differently and I call
it `only`. I think it's very useful and it would be great to have in the
standard library to encourage people to write safer code.

Often this is part of a larger expression, especially if I'm drilling into
some nested data structure. This can lead to having a prefix operation (the
function call) breaking a chain of postfix operations (attributes, method
calls, subscripting...) which is ugly and less readable. It would be nice
if this could also be available as a method on lists, tuples, and sets to
keep the data flowing left to right. Plus it would save an import.

On Tue, Jul 28, 2020 at 9:29 PM Noam Yorav-Raphael 
wrote:

> Hello,
>
> There's a simple function that I use many times, and I think may be a good
> fit to be added to itertools. A function that gets an iterator, and if it
> has exactly one element returns it, and otherwise raises an exception. This
> is very useful for cases where I do some sort of query that I expect to get
> exactly one result, and I want an exception to be raised if I'm wrong. For
> example:
>
> jack = one(p for p in people if p.id == '1234')
>
> sqlalchemy already has such a function for queries:
> https://docs.sqlalchemy.org/en/13/orm/query.html#sqlalchemy.orm.query.Query.one
>
> more-itertools has this exact function:
> https://more-itertools.readthedocs.io/en/latest/api.html#more_itertools.one
>
> Here is a simple implementation:
>
> def one(iterable):
> it = iter(iterable)
> try:
> first = next(it)
> except StopIteration:
> raise ValueError("Iterator is empty")
> try:
> second = next(it)
> except StopIteration:
> return first
> else:
> raise ValueError("Iterator has more than one item")
>
> I brought this up on python-dev, but it should be discussed here.
> Here is the discussion:
>
> https://mail.python.org/archives/list/python-...@python.org/thread/D52MPKLIN4VEXBOCKVMTWAK66MAOEINY/
>
> Brett Cannon said that this idea has been brought up at least twice
> before. I found:
>
> https://mail.python.org/archives/list/python-ideas@python.org/thread/FTJ6JRDTZ57HUVZ3PVIZV2NHU2NLAC4X/#RMWV3SNZ2N4KZLPKPIDE42H46QDEIVHE
>
>
> https://mail.python.org/archives/list/python-ideas@python.org/thread/REYDJFCXQNQG4SAWKELQMCGM77IZG47Q/#ITR2ILPVCKYR52U2D7RHGENASZTNVDHN
>
> The first thread hasn't reached any operative conclusion. The second
> thread was very long, and seemed to focus mostly on another function,
> first(), that doesn't check if there is more than one item. Joao S. O Bueno
> said that it passed "general approval". I think that perhaps a new
> discussion, focused just on one (no pun intended) function in the itertools
> module may reach a conclusion.
>
> It was suggested that instead of an additional function, one can use
> iterator unpacking:
>
> jack, = (p for p in people if p.id == '1234')
> or
> [jack] = (p for p in people if p.id == '1234')
>
> I still think that having a one() function would be useful, since:
> 1. I think it spells the intention more clearly. It is not symbols that
> you need to understand their meaning in order to understand that I expect
> the iterable to have exactly one item, it's spelled in code.
> 2. The exception would be easier to understand, since errors in tuple
> unpacking usually mean something else.
> 3. The one() function allows you to use the result inside an expression
> without assigning it to a variable. Therefore, I think it encourages
> writing better code. It's very easy to write:
> print([p for p in people if p.id == '1234][0])
> (which has the problem of not verifying the assumption that there's no
> more than one result), and I find it easier to replace _[0] with one(_)
> than to be required to name a new variable, and instead of having an
> operation on the iterable, change the way I'm assigning to it.
>
> WDYT?
>
> Cheers,
> Noam
>
>
> ___
> 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/6OLEL4XTUWXRI7ENODKEDOYFBRVDYKI7/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/QTBJWXTPVE54LHS3BEFZ3B7NNOXVRFWL/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Function suggestion: itertools.one()

2020-07-28 Thread Noam Yorav-Raphael
Hello,

There's a simple function that I use many times, and I think may be a good
fit to be added to itertools. A function that gets an iterator, and if it
has exactly one element returns it, and otherwise raises an exception. This
is very useful for cases where I do some sort of query that I expect to get
exactly one result, and I want an exception to be raised if I'm wrong. For
example:

jack = one(p for p in people if p.id == '1234')

sqlalchemy already has such a function for queries:
https://docs.sqlalchemy.org/en/13/orm/query.html#sqlalchemy.orm.query.Query.one

more-itertools has this exact function:
https://more-itertools.readthedocs.io/en/latest/api.html#more_itertools.one

Here is a simple implementation:

def one(iterable):
it = iter(iterable)
try:
first = next(it)
except StopIteration:
raise ValueError("Iterator is empty")
try:
second = next(it)
except StopIteration:
return first
else:
raise ValueError("Iterator has more than one item")

I brought this up on python-dev, but it should be discussed here.
Here is the discussion:
https://mail.python.org/archives/list/python-...@python.org/thread/D52MPKLIN4VEXBOCKVMTWAK66MAOEINY/

Brett Cannon said that this idea has been brought up at least twice before.
I found:
https://mail.python.org/archives/list/python-ideas@python.org/thread/FTJ6JRDTZ57HUVZ3PVIZV2NHU2NLAC4X/#RMWV3SNZ2N4KZLPKPIDE42H46QDEIVHE

https://mail.python.org/archives/list/python-ideas@python.org/thread/REYDJFCXQNQG4SAWKELQMCGM77IZG47Q/#ITR2ILPVCKYR52U2D7RHGENASZTNVDHN

The first thread hasn't reached any operative conclusion. The second thread
was very long, and seemed to focus mostly on another function, first(),
that doesn't check if there is more than one item. Joao S. O Bueno said
that it passed "general approval". I think that perhaps a new discussion,
focused just on one (no pun intended) function in the itertools module may
reach a conclusion.

It was suggested that instead of an additional function, one can use
iterator unpacking:

jack, = (p for p in people if p.id == '1234')
or
[jack] = (p for p in people if p.id == '1234')

I still think that having a one() function would be useful, since:
1. I think it spells the intention more clearly. It is not symbols that you
need to understand their meaning in order to understand that I expect the
iterable to have exactly one item, it's spelled in code.
2. The exception would be easier to understand, since errors in tuple
unpacking usually mean something else.
3. The one() function allows you to use the result inside an expression
without assigning it to a variable. Therefore, I think it encourages
writing better code. It's very easy to write:
print([p for p in people if p.id == '1234][0])
(which has the problem of not verifying the assumption that there's no more
than one result), and I find it easier to replace _[0] with one(_) than to
be required to name a new variable, and instead of having an operation on
the iterable, change the way I'm assigning to it.

WDYT?

Cheers,
Noam
___
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/6OLEL4XTUWXRI7ENODKEDOYFBRVDYKI7/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Fwd: Re: Experimenting with dict performance, and an immutable dict

2020-07-28 Thread Brett Cannon
On Sat, Jul 25, 2020 at 12:58 PM Guido van Rossum  wrote:

> On Sat, Jul 25, 2020 at 12:45 PM Marco Sulla 
> wrote:
>
>> I also remembered another possible use-case: kwargs in CPython. In C
>> code, kwargs are PyDictObjects. I suppose they are usually not modified; if
>> so, fdict could be used, since it seems to be faster at creation.
>>
>
> That's an interesting idea. It has always vaguely bothered me that `*args`
> gives a tuple while `**kwds` gives a dict. Unfortunately it's impossible to
> change without breaking tons of existing code, since things like
> `kwds.pop("something")` have become a pretty standard idiom to use it.
>

And just to be clear for folks that don't know the idiom (it took me a
second to remember myself), it's common to do something like:

def spam(**kwargs):
"""Do 'something', then call bacon()."""
if 'something' in kwargs:
use_something(kwargs.pop('something')
bacon(**kwargs)

def bacon(**kwargs):
...

You see this in decorators, for instance, that add an extra argument to do
some pre-processing or something before calling the decorated function.
___
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/4XU3IECSVNQLFU2JWXLJY7A4ZRCTKPXM/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Alternative syntax for Callable type-hinting

2020-07-28 Thread Thiago Carvalho D' Ávila
I also like that one, both more intuitive than current syntax I think.


On Tue, 28 Jul 2020, 11:25 Guido van Rossum,  wrote:

> On Tue, Jul 28, 2020 at 05:42 Thiago Carvalho D' Ávila <
> thiagocav...@gmail.com> wrote:
>
>> The idea here is to use the same operator already used to type-hint the
>> return of functions `->` to define the return of a Callable.
>>
>> * Current syntax:
>>
>> Callable[[ArgumentList], ReturnType]
>>
>> eg.
>>
>> def x(method: Callable[[int, dict], None]) -> None:
>> pass
>>
>> * Proposed syntax:
>>
>> Callable[ArgumentList] -> ReturnType
>>
>> eg.
>>
>> def x(method: Callable[int, dict] -> None) -> None:
>> pass
>>
>
> Why not just ‘(int, dict) -> None’?
>
> Do you think this is more intuitive? Is it viable?
>>
>
> Definitively more intuitive. With the new PEG parser it *may* be viable.
>
> However it may make it harder in the future to introduce ‘(x, y) -> x+y’
> as a shorthand for lambda, which has also been proposed.
>
> I wouldn’t rush anything.
>
> —Guido
> --
> --Guido (mobile)
>
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/T35CXY7DQIMSU3HB727VQH36B7MP3MD4/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Idea: Extend "for ... else ..." to allow "for ... if break ..." else

2020-07-28 Thread Guido van Rossum
Rest assured this is not a problem. In any case it’s the compiler, not the
parser, that generates the bytecode, from the AST. The compiler always has
the full AST available before it is asked to generate any bytecode. The new
parser just allows more flexible syntactic constructs, esp. “soft keywords”.

*If* you want tou propose clearer syntax for this, please extend the loop
syntax, not the ‘if’ syntax. So, ‘case ... zero’ makes more sense than ‘if
[not] break’.

—Guido

On Tue, Jul 28, 2020 at 03:26 Jonathan Fine  wrote:

> Hi Rob
>
> You wrote:
>
> So:  You're asking that the bytecode generated for the for-loop depends
>> on something that happens (or not) after the end of the for-loop body
>> (which could be arbitrarily long).
>>
>
>
>> I speak from ignorance, but I suspect that even with the new parser,
>> which I am reliably informed can make the tea and implement world peace,
>> that would be asking a lot.
>>
>
> I'm also speaking from ignorance. However, here I'm the optimist.
> Ignorance is bliss. You're the pessimist. The devil is in the details.
>
> Until we have knowledge and wisdom on this, I think we need both points of
> view. So I'm grateful for your https://en.wikipedia.org/wiki/Grain_of_salt 
> (American
> English, pinch of salt in British English). I hope it makes my dish taste
> better!
> --
> Jonathan
> ___
> 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/AHONH5PRIXOK7KY5HSP2ATGVFXAOG5JS/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
-- 
--Guido (mobile)
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/2PI2OCE4KWPHTO3JNIGGE4O4J43EU5U5/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Alternative syntax for Callable type-hinting

2020-07-28 Thread Guido van Rossum
On Tue, Jul 28, 2020 at 05:42 Thiago Carvalho D' Ávila <
thiagocav...@gmail.com> wrote:

> The idea here is to use the same operator already used to type-hint the
> return of functions `->` to define the return of a Callable.
>
> * Current syntax:
>
> Callable[[ArgumentList], ReturnType]
>
> eg.
>
> def x(method: Callable[[int, dict], None]) -> None:
> pass
>
> * Proposed syntax:
>
> Callable[ArgumentList] -> ReturnType
>
> eg.
>
> def x(method: Callable[int, dict] -> None) -> None:
> pass
>

Why not just ‘(int, dict) -> None’?

Do you think this is more intuitive? Is it viable?
>

Definitively more intuitive. With the new PEG parser it *may* be viable.

However it may make it harder in the future to introduce ‘(x, y) -> x+y’ as
a shorthand for lambda, which has also been proposed.

I wouldn’t rush anything.

—Guido
-- 
--Guido (mobile)
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/JUHKHWFTOKKC6Y556JVJ4L4ULVEKUQDJ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: default parameter in fuctions to clean up flow

2020-07-28 Thread 2QdxY4RzWzUUiLuE
On 2020-07-28 at 11:04:25 -0300,
"Joao S. O. Bueno"  wrote:

> Anyway, that is feasible via a decorator.
> Since it can't be done the wya you are proposing as is, since
> having a function as a default argument is valid Python
> (and the function is not called) - and
> having new syntax for this would be more cumbersome
> than using  a decorator, I think that closes the gap.
> 
> If such a decorator would be useful enough to cut it into the
> stlib, is another question though - I'd probably find it occasionally
>  useful myself, but even so, I am +0 on this -
> it is not like
> 
> ```
> if parameter is sentinel:
> parameter = factory()
> ```
> would be too much to type.
> 
> On a second thought - proper documenting and giving visibility
> to a decorator like this could make it be used in patterns like
> ```
> @factoryargs
> def myfunction(a, b, c=list):
> pass
> ```
> and we could see a drop in the newcomers to Python
> putting a `[]` as default argument.

That's great, until I have something like this:

@factoryargs
def myfunction(a, b, c=list, d=3.4):
pass

Is c a factory?  Is d a factory?

> Ok - I just convinced myself - I am +1 for such a decorator now.

I don't mean to be a wet blanket, but what's wrong with a helper
function?

def time_diff_from_now(target_time):
return time_diff(target_time, datetime.datetime.now())

def time_diff(target_time, curr_time):
return curr_time - target_time

No decorators, no new syntax, explicit at the calling sites.

> On Mon, 27 Jul 2020 at 20:42, Richard Damon 
> wrote:
> 
> > On 7/27/20 10:01 AM, Peter Moore wrote:
> > > I have had a long standing unanswered question on on stackoverflow: is
> > it possible to pass a function to a default parameter so that you could do
> > in essence things like this.
> > >
> > > def time_diff(target_time,  curr_time= lambda : datetime.now() ):
> > > return curr_time - target_time
> > >
> > > this would be an syntactical improvement over this style where you have
> > if statement to initialize a missing parameter.
> > >
> > > def time_diff(target_time, curr_time=None):
> > >if curr_time == None:
> > >   curr_time = datetime.datetime.now()
> > >return  curr_time - target_time
> > I will point out that you CAN pass a function as the default value of a
> > function parameter, and it means that the parameter will be bound to the
> > function itself, so it becomes a callable (so doesn't help you in your
> > case). But this does become an impediment to trying to define it this
> > way, you need somehow to distinguish between the function itself being
> > the default value, or some magically invocation of the function at each
> > call.
> >
> > --
> > Richard Damon
> > ___
> > 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/64ZTCJWJO74KD2EFUOSICOPT6XTSBO2R/
> > Code of Conduct: http://python.org/psf/codeofconduct/
> >

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


-- 
“Whoever undertakes to set himself up as a
judge of Truth and Knowledge is shipwrecked
by the laughter of the gods.” – Albert Einstein
Dan Sommers, http://www.tombstonezero.net/dan
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/NUFVFDFI7QY67QVFIFS4Y7CRGEGCWRBF/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: default parameter in fuctions to clean up flow

2020-07-28 Thread Joao S. O. Bueno
Anyway, that is feasible via a decorator.
Since it can't be done the wya you are proposing as is, since
having a function as a default argument is valid Python
(and the function is not called) - and
having new syntax for this would be more cumbersome
than using  a decorator, I think that closes the gap.

If such a decorator would be useful enough to cut it into the
stlib, is another question though - I'd probably find it occasionally
 useful myself, but even so, I am +0 on this -
it is not like

```
if parameter is sentinel:
parameter = factory()
```
would be too much to type.

On a second thought - proper documenting and giving visibility
to a decorator like this could make it be used in patterns like
```
@factoryargs
def myfunction(a, b, c=list):
pass
```
and we could see a drop in the newcomers to Python
putting a `[]` as default argument.

Ok - I just convinced myself - I am +1 for such a decorator now.

Now, please, the S.O. link.
(that is me needing 2 more upvotes to round another 10K rep)

On Mon, 27 Jul 2020 at 20:42, Richard Damon 
wrote:

> On 7/27/20 10:01 AM, Peter Moore wrote:
> > I have had a long standing unanswered question on on stackoverflow: is
> it possible to pass a function to a default parameter so that you could do
> in essence things like this.
> >
> > def time_diff(target_time,  curr_time= lambda : datetime.now() ):
> > return curr_time - target_time
> >
> > this would be an syntactical improvement over this style where you have
> if statement to initialize a missing parameter.
> >
> > def time_diff(target_time, curr_time=None):
> >if curr_time == None:
> >   curr_time = datetime.datetime.now()
> >return  curr_time - target_time
> I will point out that you CAN pass a function as the default value of a
> function parameter, and it means that the parameter will be bound to the
> function itself, so it becomes a callable (so doesn't help you in your
> case). But this does become an impediment to trying to define it this
> way, you need somehow to distinguish between the function itself being
> the default value, or some magically invocation of the function at each
> call.
>
> --
> Richard Damon
> ___
> 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/64ZTCJWJO74KD2EFUOSICOPT6XTSBO2R/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/EGFSGULHXBRT2HNEDRN4GJ36DQUSR3RX/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Alternative syntax for Callable type-hinting

2020-07-28 Thread Thiago Carvalho D' Ávila
Hello,

The idea here is to use the same operator already used to type-hint the
return of functions `->` to define the return of a Callable.

* Current syntax:

Callable[[ArgumentList], ReturnType]

eg.

def x(method: Callable[[int, dict], None]) -> None:
pass

* Proposed syntax:

Callable[ArgumentList] -> ReturnType

eg.

def x(method: Callable[int, dict] -> None) -> None:
pass

Do you think this is more intuitive? Is it viable?

Kind regards,

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


[Python-ideas] Re: Idea: Extend "for ... else ..." to allow "for ... if break ..." else

2020-07-28 Thread Jonathan Fine
Hi Rob

You wrote:

So:  You're asking that the bytecode generated for the for-loop depends
> on something that happens (or not) after the end of the for-loop body
> (which could be arbitrarily long).
>


> I speak from ignorance, but I suspect that even with the new parser,
> which I am reliably informed can make the tea and implement world peace,
> that would be asking a lot.
>

I'm also speaking from ignorance. However, here I'm the optimist. Ignorance
is bliss. You're the pessimist. The devil is in the details.

Until we have knowledge and wisdom on this, I think we need both points of
view. So I'm grateful for your
https://en.wikipedia.org/wiki/Grain_of_salt (American
English, pinch of salt in British English). I hope it makes my dish taste
better!
-- 
Jonathan
___
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/AHONH5PRIXOK7KY5HSP2ATGVFXAOG5JS/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Idea: Extend "for ... else ..." to allow "for ... if break ..." else

2020-07-28 Thread Jonathan Fine
Thank you Rob, for your contribution. I find it very helpful. You've raised
important implementation questions.

Regarding the no-iterations case. Suppose we have
for i in items:
loop_body
case:
zero:
print('no items to process')

In this case, the Python compiler knows that the post-iteration block
contains a 'zero:' statement. And in other cases it knows that it does not.
So why not have the compiler produce bytecode that records this fact. (This
could be done by providing an additional bytecode, or if there's room
adding a flag to an existing bytecode.)

Depending on how we choose to implement, if we wish we could keep both the
bytecode and interpreter code exactly the same, for the currently allowed
post-iteration blocks.

I apologize that it wasn't clear to you from my example code, that for
example we allow any identifier as the 'label argument' in a break
statement. As in
break error_1
break error_2
break time_out

The compiler can and I think should ensure that all labels in the
post-iteration block occur in the iteration block. And a code analysis code
aka linter should warn about unreachable code. This unreachable code
should, of course, not generate any bytecode.

Thank you again for your comment. I hope this helps.
-- 
Jonathan
___
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/QN6VMQTTQVJGUF6I6C6TEMUS57677VVZ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Idea: Extend "for ... else ..." to allow "for ... if break ..." else

2020-07-28 Thread Jonathan Fine
There's been a discussion of the "for ... else ..." construction in Python.
Here's a suggestion as to how we might improve matters, and perhaps
usefully extend the language. I hope it might benefit some, without harming
anyone else.

Aside: I've not read the whole of the previous discussion, and it may be
that some or all of what I say has already been expressed there. So
apologies for any missing credits to others. The errors, I'm responsible
for.

Here's what happens at present.
for i in items:
LOOP_BODY
else:
print('exit via StopIteration')

I find the following clearer (where 'if break' is a new language 'compound
keyword').
for i in items:
LOOP_BODY
if break:
pass
else:
print('exit via StopIteration')

This would now allow us to write
for i in items:
LOOP_BODY
if break:
print('exit via break')
else:
print('exit via StopIteration')

Sometimes a loop has multiple break commands, which have different
purposes. So a further extension might be
for i in items:
LOOP_BODY
if break left:
print('exit via break left')
elif break right:
print('exit via break right')
elif break:
print('exit via some other break')
else:
print('exit via StopIteration')

To allow this to work, we extend the language to allow commands such as
break left
break right
as well as the usual
break

Here the identifiers 'left' and 'right' look like variable names, but in
fact they are labels. The compiler can, and I think should, produce a
hard-coded jump from command
break right
to the code block under
elif break right:

This is the basic idea, keeping the syntax close to Python as it now is
(but of course adding to the semantics). Some programmers, and I think I'm
one, might want a clearer distinction between
for i in items:
LOOP_BODY
if break:
do_something
and
for i in items:
LOOP_BODY
if broke:
do_something

For this reason I tentatively suggest instead
for i in items:
LOOP_BODY
case:
break left:
print('exit via break left')
break right:
print('exit via break right')
break:
print('exit via some other break')
else:
print('exit via StopIteration')

Some people have asked a built-in means to detect, at the end of the
iteration, whether theitems was empty to begin with. The syntax could
easily provide this, for example via
 case:
zero:
print('no items to process')

However, if we adopt this perhaps we'd also like to retain the simpler for
... if break ... else ... construct.

I hope this helps.

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