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

2023-09-18 Thread Jonathan Fine
Hi Dom

In your original post you used your proposed addition to write code that
provides a way of handling defaults different from the standard mechanism,
and perhaps in your opinion better.

The following example tells us something about defaults mechanism already
provided by Python:

>>> def f(a, b=1, c=2): return a, b, c
...
>>> f(0)
(0, 1, 2)
>>> f.__defaults__
(1, 2)
>>> f.__defaults__ = (0, 1, 2)
>>> f()
(0, 1, 2)
>>> f.__defaults__ = (2, 1, 0)
>>> f()
(2, 1, 0)

I am suspicious of your example in your original post because it does not
explicitly consider the possibilities already provided by Python for
changing default values on the fly.

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


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

2023-09-17 Thread Jonathan Fine
Hi Dom

To support your proposal you provided an example. Well done for providing
evidence to support your idea. Doing that makes the discussion more
productive.

I'm going to use the words 'good' and 'bad', but with two provisos. The
first is that they are judgemental, and often judgement is little more than
personal opinion presented in an objective language. The second is that
'good' and 'bad' depend on context. The usual C-Python is not good at
writing code where high performance is critical (but is fairly good at
linking to external libraries that do provide high performance). However,
often high-performance is of no importance when writing a prototype. For
prototypes the forces are quite different than for production.

With these provisos, a major purpose of a programming language is to make
good code easier to write, and bad code harder to write. Hence the
importance of you providing a coding example to support your idea. And also
my request that you provide more information about the example code you
kindly provided.

Based on your example, I suspect that your proposed addition will make bad
code easier to write. However, we don't need to discuss that now. I suggest
that for your proposal to gain support an example of how it makes good code
easier to write would be helpful. And also if you wish an example of how it
makes bad code harder to write.

Please note that my use of 'good' and 'bad' are subject to the provisos
mentioned earlier.

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


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

2023-09-16 Thread Jonathan Fine
Hi Dom

In your original post you said you're writing some code to improve handling
of defaults (perhaps only in some situations). You also said that the
feature you're suggesting would make your improved default handler easier
to write.

Python already handles default values at least fairly well in many
situations. Please would you provide at least one example of how your
proposed default handler would be better than that already provided by
Python.

Please don't worry about the implementation. Please focus on the syntax and
semantics and comparison with what Python does.

I will value your response to my request more highly if it shows that you
have a clear understanding of Python's present behaviour. I'd also welcome
any example you provide of weaknesses in Python's present behaviour.

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


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

2023-09-14 Thread Jonathan Fine
POSTSCRIPT

We can also use locals() to 'inverse search' to get the name, much as in
the original post.

>>> locals()['x']
(0, 1, 2, 3)
>>> id(x)
139910226553296
>>> id(locals()['x'])
139910226553296
-- 
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/MPPLJ6MXZDNA7J75T7H76LNYZGHCEG37/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2023-09-14 Thread Jonathan Fine
Perhaps use the id of an object instead of its value. Here's how it might
work

>>> store = {}

>>> def wibble(fn):
...   val = fn()
...   name = fn.__name__
...   store[id(val)] = name
...   return val

>>> @wibble
... def ddd():
... return tuple(range(4))

>>> ddd
(0, 1, 2, 3)
>>> store[id(ddd)]
'ddd'
>>>

>>> x = ddd
>>> ddd = None
>>> store[id(x)]
'ddd'

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


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

2023-06-13 Thread Jonathan Fine
The original example is:

numbers = (i for i in range(5))
assert 5 not in numbers
sorted(numbers)

I like this example. It provides an opportunity to improve the
documentation.

The problems goes away if we write any of the following
numbers = [i for i in range(5)]
numbers = tuple(i for i in range(5))
numbers = tuple(range(5))
numbers = list(range(5))

It also goes away if we write any of
numbers = [0, 1, 2, 3, 4]
numbers = (0, 1, 2, 3, 4)

In fact, the various ways of making the problem go away produce either a
list or a tuple 0, 1, 2, 3, 4.

A simpler way to create the problem is
x = iter(range(5))
4 in x
sorted(x) # returns an empty tuple.

If instead we write
   x = range(5)
then the problem goes away.

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


[Python-ideas] Re: len(Enum) should raise TypeError

2023-04-04 Thread Jonathan Fine
Hi

Here's a similar example

$ python3
> Python 3.10.6 (main, Nov 14 2022, 16:10:14) [GCC 11.3.0] on linux
> Type "help", "copyright", "credits" or "license" for more information.
> >>> from collections import Counter
> >>> cnt = Counter # Oops!
> >>> cnt.update('abcde')
> >>> cnt
> 
>

This is what happens without the typo.

>>> cnt = Counter()
> >>> cnt.update('abcde')
> >>> cnt
> Counter({'a': 1, 'b': 1, 'c': 1, 'd': 1, 'e': 1})
>

Here's a link to the source for Counter.update:

https://github.com/python/cpython/blob/3.11/Lib/collections/__init__.py#L658-L690

-- 
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/UXD6EAUTFGLHPALMHVJQ53A5SG3DFRAF/
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-20 Thread Jonathan Fine
Hi

Some of us might believe that a currently legal syntax should only
exceptionally be given a new meaning, even if there is no evidence
whatsoever that this legal syntax is actually in use. My own belief is more
pragmatic. If there's very strong evidence that the syntax is not in use,
I'm happy to consider changing the meaning.

I wrote:

> 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.
>

In response Chris wrote:

> Hard no. That is currently-legal syntax, and it's also clunky.


Although
  a, b, StopIterating = iterable
is currently legal syntax, I believe that no-one has ever used it in Python
before today. My evidence is this search, which gives 25 pages.
https://www.google.com/search?q=%22stopiterating%22+python&nfpr=1

These pages found by this search do match "StopIterating", but do not
provide an example of their use in Python.
https://stackoverflow.com/questions/19892204/send-method-using-generator-still-trying-to-understand-the-send-method-and
https://julia-users.narkive.com/aD1Uin0y/implementing-an-iterator-which-conditionally-skips-elements

The following are copies of the stackoverflow page.
https://mlink.in/qa/?qa=810675/
https://www.796t.com/post/MmFubjI=.html
https://qa.1r1g.com/sf/ask/1392454311/

-- 
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/QHQ2JKYWOF7IMN3QBQXKSR3AU74HC3FL/
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-20 Thread Jonathan Fine
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.)

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.

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


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

2022-06-19 Thread Jonathan Fine
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 affect the
benchmarks?
2. Is there an across-the-board change that would speedup this line-offsets
task?
3. To limit splitlines memory use (at small performance cost), chunk the
input string into say 4 kb blocks.
4. Perhaps anything done here for strings should also be done for bytes.

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


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

2022-06-17 Thread Jonathan Fine
Steve D'Aprano wrote of an incompleteness in this PEP

This is not just some minor, trivial implementation issue, it cuts right
> to the core of this feature's semantics [...]


For comparison, please look at the PEP for the statistics module. Steve
wrote both PEP and the standard library module. In my opinion the PEP is
deficient in its description of core semantics, and I don't see a reference
implementation prior to acceptance.
https://peps.python.org/pep-0450/

Of course, that was nearly 10 years ago. The recently discussed  problems
with type conversion in the statistics module together with what's missing
in PEP 450 together support Steve's request that the PEP discussed in this
thread be improved, so that we better avoid future problems.

-- 
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/Z435E4ZW3GFPNKH5JQFELVWX3J27IG7I/
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 Jonathan Fine
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.

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


[Python-ideas] Re: Python array multiplication for negative values should throw an error

2022-05-31 Thread Jonathan Fine
Here is another problem in this general area. Multiplying an array by a
float already raises a type error.
>>> []*0.0
Traceback (most recent call last):
TypeError: can't multiply sequence by non-int of type 'float'

This problem can arrse 'by accident'. For example, consider
   >>> x = {0.0}
   >>> x.update(range(3))
   >>> list(x)
   [0.0, 1, 2]

Let's now return to the feature (of the builtin list, tuple and str
classes):
>>> [1] * (-1) == []
True

On the one hand I expect there's code that relies on the feature to run
correctly. On the other hand I expect there's code that should raise an
exception but doesn't, because of this feature.

@ericfahlgren
It would be most helpful if you could provide or create a reference to
support your claim, that there is already a lot of code that would fail if
this change was made.

@fjwillemsen
It would be most helpful if you could provide real-world examples of code
where raising an exception would enable better code.

Examples relating this are of course welcome from all, not just the two
named contributors.
-- 
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/6M6SRF6TGKR26BCCC2JIQEKFEFYLADZQ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Heterogeneous numeric data in statistics library

2022-05-12 Thread Jonathan Fine
Hi Steve

Today's XKCD is on 'Selection Bias' and it is set in a statistics
conference: https://xkcd.com/2618/

According to its PEP the statistics module provides "common statistics
functions such as mean, median, variance and standard deviation".

You ask "if you are a user of statistics, how important to you is the
ability to **mix** numeric types, in the same data set".

Asking your question here introduces a selection bias. To compensate for
this, I suggest you also ask a similar question elsewhere, such as
comp.lang.python and at some forum for Python in education.

Do look at https://xkcd.com/2618/, it makes the point quite nicely.
-- 
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/5QN2E5F3L4S2SEEWOFJCMOGZ6CFDVQSJ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Adding a .find() method to list

2022-05-07 Thread Jonathan Fine
Hi Paul

You wrote:

> You [the original poster] seem to want a function[to express the
> criteria], but it's not obvious to me why you need that.


 A function has several advantages.
1. It can be reused.
2. It can be tested (a special case of 1).
3. It can be passed as a parameter (a special case of 1).
4. It can be imported from a different Python module (a special case of 1).
5. The code that uses function can be reused (if the function is passed as
a parameter).

These advantages were sufficient for me at the time to accept the original
poster's desire "to retrieve one of its elements that fits a certain
criteria". That is not to say that in every case a function is the best way
to do things. It's enough that in some (or many) cases using a function is
a good thing.

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


[Python-ideas] Re: Adding a .find() method to list

2022-05-07 Thread Jonathan Fine
Hi Lucas.rs

You wrote:

> In its current implementation, the list type does not provide a simple and
> straightforward way to retrieve one of its elements that fits a certain
> criteria.
>

Thank you. You've asked a good question. I hope my answer will be helpful.

Here's my preferred solution, using Python builtins:
  >>> users = [
  ... {'id': 1,'name': 'john'},
  ... {'id': 2, 'name': 'anna'},
  ... {'id': 3, 'name': 'bruce'},
  ... ]
  >>> func = (lambda user: user['id'] == 2)

  >>> next(filter(func, users))
  {'id': 2, 'name': 'anna'}

For comparison, here's your solution using your subclass of list.
  >> my_list.find(func)
   {'id': 2, 'name': 'anna'}

I prefer using the builtin filter function because:

1. I already know what 'filter' means.
2. I already know what 'next' means.
3. I already know what will happen if the object is not found (or if there
are several solutions.
4. It's fairly easy to modify the code to given different behaviour, eg
  >>> list(filter(func, users))
  [{'id': 2, 'name': 'anna'}]

Finally, perhaps your code would be better if the items in the 'user' list
were members of a class, rather than being bare dicts. And once you've done
that, you could create a new class for holding a collection (or set) of
members. And now we're moving towards how Django (and other frameworks)
handle interactions with a database.

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


[Python-ideas] Re: Less is more? Smaller code and data to fit more into the CPU cache?

2022-03-27 Thread Jonathan Fine
Hi

Thank you Inada for your prompt and helpful reply. Here's a link for cached
hash in bytes object: https://bugs.python.org/issue46864

What I have in mind is making selected objects smaller, for example by
using smaller pointers. But how to know the performance benefit this will
give?

I think it would be helpful to know how much SLOWER things are when we make
Python objects say 8 or 16 bytes LARGER. This would give an estimate of the
improvement from making all Python objects smaller.

I've not done much performance testing before. Anyone here interested in
doing it, or helping me do it? (Warning - I've never built Python before.)

with best regards

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


[Python-ideas] Less is more? Smaller code and data to fit more into the CPU cache?

2022-03-22 Thread Jonathan Fine
Hi

As you may have seen, AMD has recently announced CPUs that have much larger
L3 caches. Does anyone know of any work that's been done to research or
make critical Python code and data smaller so that more of it fits in the
CPU cache? I'm particularly interested in measured benefits.

This search
  https://www.google.com/search?q=python+performance+CPU+cache+size
provides two relevant links

https://www.oreilly.com/library/view/high-performance-python/9781449361747/ch01.html

https://www.dlr.de/sc/Portaldata/15/Resources/dokumente/pyhpc2016/slides/PyHPC_2016_talk_14.pdf
but not much else I found relevant.

AnandTech writes about the chips with triple the L3 cache:

https://www.anandtech.com/show/17323/amd-releases-milan-x-cpus-with-3d-vcache-epyc-7003
"As with other chips that incorporate larger caches, the greatest benefits
are going to be found in workloads that spill out of contemporary-sized
caches, but will neatly fit into the larger cache."

And also:

https://www.anandtech.com/show/17313/ryzen-7-5800x3d-launches-april-20th-plus-6-new-low-mid-range-ryzen-chips
" As detailed by the company back at CES 2022 and reiterated in today’s
announcement, AMD has found that the chip is 15% faster at gaming than
their Ryzen 9 5900X."

I already know that using Non Uniform Memory Access (NUMA) raises the
difficult problem of cache coherence.
  https://en.wikipedia.org/wiki/Non-uniform_memory_access
  https://en.wikipedia.org/wiki/Cache_coherence

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


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

2022-01-27 Thread Jonathan Fine
Hi

Steve D'Aprano started this thread on 16 Jan, referencing
https://bugs.python.org/issue46393.

In the 95th message in this thread, on 27 Jan, Stephen J. Turnbull wrote:

I think for many of us (specifically me, but I don't think I'm alone) it's
> equally important that we aren't persuaded that there's a need for a
> frozenset literal great enough to overcome the normal reluctance
> to add syntax.  A number of important cases are already optimized
> to frozensets, and use cases and (more important) benchmarks showing
> that this optimization is important enough to add syntax so the
> programmer can hand-code it are mostly to entirely lacking.
>

On 17 Jan, Serhiy Storchaka wrote to the b.p.o issue Steve D'Aprano
referenced:

As Steven have noted the compiler-time optimization is not applicable here
> because name frozenset is resolved at run-time.


In these cases where a set of constants can be replaced with a frozenset of
> constants (in "x in {1,2,3}" and in "for x in {1,2,3}") the compiler does
> it.


And I don't think there is an issue which is worth changing the language.
> Creating a frozenset of constants is pretty rare, and it is even more rare
> in tight loops. The most common cases (which are pretty rare anyway) are
> already covered.


This is message 96 in this thread. Perhaps something bad (or good) will
happen when we get to message 100.
 https://www.theregister.com/2022/01/27/linux_999_commits/

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


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

2022-01-19 Thread Jonathan Fine
Joao's
{1, 2, 3}.frozen()
shows real originality, arising from deep creative thought about the roots
of the problem. I was both surprised and delighted when I saw it, and I
think some others were too. (I agree with others that here 'freeze' is
better than 'frozen'.)

Obviously, each of the two proposals
   f{1, 2, 3}
   {1, 2, 3}.freeze()
has advantages and disadvantages when compared to the other.

Both deserve full and fair consideration.
-- 
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/THJCZLVTTQHHTHOGEHADEUYHKBGZK3IX/
Code of Conduct: http://python.org/psf/codeofconduct/


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

2022-01-17 Thread Jonathan Fine
Earlier today in https://bugs.python.org/issue46393, Serhiy Storchaka wrote:

As Steven have noted the compiler-time optimization is not applicable here
because name frozenset is resolved at run-time.

In these cases where a set of constants can be replaced with a frozenset of
constants (in "x in {1,2,3}" and in "for x in {1,2,3}") the compiler does
it.

And I don't think there is an issue which is worth changing the language.
Creating a frozenset of constants is pretty rare, and it is even more rare
in tight loops. The most common cases (which are pretty rare anyway) are
already covered.

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


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

2022-01-17 Thread Jonathan Fine
The compiler can figure out that the value of
   {1, 2, 3}
is a set containing the elements 1, 2 and 3.

The problem with the value of
frozenset({1, 2, 3})
is that the value of frozenset depends on the context. This is because
frozenset = print
is allowed.

According to help(repr):
repr(obj, /)
Return the canonical string representation of the object.
For many object types, including most builtins, eval(repr(obj)) ==
obj.

Consistency suggests that if
x = f{1, 2, 3}
gives always gives frozenset as the value of x then
repr(x)
should be the string 'f{1, 2, 3}'. At present, I think, repr(x) always
returns a literal if it can.

However, changing the repr of frozenset introduces problems of backwards
compatibility, particularly in doctests and documentation.

Another way to achieve consistency is to make frozenset a keyword, in the
same way that None, True and False are identifiers that are also language
keywords.

Both proposals as stated have negative side-effects. I suggest we explore
ways of reducing the above and any other side effects.

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


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

2022-01-16 Thread Jonathan Fine
Summary: Further information is provided, which suggests that it may be
best to amend Python so that "frozenset({1, 2, 3})" is the literal for
eval("frozenset({1, 2, 3})").

Steve D'Aprano correctly notes that the bytecode generated by the expression
x in {1, 2 ,3}
is apparently not optimal. He then argues that introducing a frozenset
literal would allow
   x in f{1, 2, 3} # New syntax, giving a frozenset literal
would allow better bytecode to be generated.

However, the following has the same semantics as "x in {1, 2, 3}" and
perhaps gives optimal bytecode.
>>> import dis
>>> dis.dis("x in (1, 2, 3)")
  1   0 LOAD_NAME0 (x)
  2 LOAD_CONST   3 ((1, 2, 3))
  4 COMPARE_OP   6 (in)
  6 RETURN_VALUE

For comparison, here's the bytecode Steve correctly notes is apparently not
optimal.
>>> dis.dis("x in {1, 2, 3}")
  1   0 LOAD_NAME0 (x)
  2 LOAD_CONST   3 (frozenset({1, 2, 3}))
  4 COMPARE_OP   6 (in)
  6 RETURN_VALUE

Steve states that "x in {1, 2, 3}" when executed calls "frozenset({1, 2,
3})", and in particular looks up "frozenset" in builtins and literals.

I can see why he says that, but I've done an experiment that suggests
otherwise.
>>> bc = compile("x in {1, 2, 3}", "filename", "eval")
>>> eval(bc, dict(x=1))
True
>>> eval(bc, dict(x=1, frozenset="dne"))
True

I suspect that if you look up in the C-source for Python, you'll find that
dis.dis ends up using
frozenset({1, 2, 3})
as the literal for representing the result of evaluating frozenset({1, 2,
3}).

The following is evidence for this hypothesis:
>>> frozenset({1, 2, 3})
frozenset({1, 2, 3})
>>> set({1, 2, 3})
{1, 2, 3}
>>> set([1, 2, 3])
{1, 2, 3}
>>> set([])
set()

To conclude, I find it plausible that:

1. The bytecode generated by "x in {1, 2, 3}" is already optimal.
2. Python already uses "frozenset({1, 2, 3})" as the literal representation
of a frozenset.

Steve in his original post mentioned the issue
https://bugs.python.org/issue46393, authored by Terry Reedy. Steve rightly
comments on that issue that "may have been shadowed, or builtins
monkey-patched, so we cannot know what frozenset({1, 2, 3}) will return
until runtime."

Steve's quite right about this shadowing problem. In light of my plausible
conclusions I suggest his goal of a frozenset literal might be better
achieved by making 'frozenset' a keyword, much as None and True and False
are already keywords.

>>> True = False
  File "", line 1
SyntaxError: can't assign to keyword

Once this is done we can then use
   frozenset({1, 2, 3})
as the literal for a frozenset, not only in dis.dis and repr and elsewhere,
but also in source code.

As a rough suggestion, something like
from __future__ import literal_constructors_as_keywords
would prevent monkey-patching of set, frozenset, int and so forth (just as
True cannot be monkeypatched).

I thank Steve for bringing this interesting question to our attention, for
his earlier work on the issue, and for sharing his current thoughts on this
matter. It's also worth looking at the message for Gregory Smith that Steve
referenced in his original post.
https://mail.python.org/pipermail/python-ideas/2018-July/051902.html

Gregory wrote: frozenset is not the only base type that lacks a literals
leading to loading values into these types involving creation of an
intermediate throwaway object: bytearray.  bytearray(b'short lived bytes
object')

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


[Python-ideas] Re: Compiler from python to WebAssembly

2021-12-05 Thread Jonathan Fine
Hi Ricard

Python to web assembly is a good idea that is already being developed.

The first result from this search
https://www.google.com/search?q=python+webassembly
is the project https://github.com/pyodide/pyodide.

Also relevant is https://www.theregister.com/2021/11/30/python_web_wasm/
You loved running JavaScript in your web browser. Now, get ready for Python
scripting

with kind regards

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


[Python-ideas] Re: PEP 671 proof-of-concept: A less invasive implementation

2021-10-31 Thread Jonathan Fine
Hi Chris

Again you ask good questions.

Q: How to find the bare string '#wibble'? It's optimised out during
compilation.
A: Very good. I didn't know that. For current Python we'll have to use a
different marker. For future Python we could change the compiler so that it
directly sets fn.__wibble__ without needing the @wibble decorator.

Q: You have at least added some source code to help(fn), if it's available.
But what if the function came from a .pyc file?
A: It will work the same as tracebacks work, and in exactly the same
circumstances. I think that's exactly what we want. Any other solution
would increase the size of .pyo files, which is to be avoided.

Thank you for your interest. 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/YDAKBG553PE4RIVZ3NRFQ46OU3LMEKLC/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: PEP 671 proof-of-concept: A less invasive implementation

2021-10-31 Thread Jonathan Fine
Hi

I've just had a brainwave that may give an even less invasive
implementation of PEP 671. It relies on every function having a dict, as
provided by https://www.python.org/dev/peps/pep-0232/.

Consider:
def fn(a, b, c): pass
fn.__wibble__ = 123
fn.__wibble__ # Give 123, of course.

Now consider:
@wibble
def fn(a, b, c=None):
'''Usual docstring goes here.'''
if c is None: c = []
'#wibble'

return c.extend([a, b])

The @wibble decorator sets fn.__wibble__ to point to the end of the line
just before '#wibble'.

We can now define Help(fn) to produce something like:
fn(a, b, c=None)
Usual docstring goes here.
--
if c is None: c = []

There we go. The functionality asked for, in a way that works with existing
Python. If nothing else, we can use this for experiments to explore the
idea. Often in Python there are functions whose source is self-explanatory.

Example:
@wibble
def fahr_to_cent(fahr):
return (fahr - 32) * 5 /9
'#wibble'

And now for Help(fahr_to_cent) we get:
fahr_to_cent(fahr)
--
return (fahr - 32) * 5 /9

Final word. Does anyone use PEP 232, function attributes? If not, perhaps
remove it as a waste of space.

with kind regards

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


[Python-ideas] Re: PEP 671 proof-of-concept: A less invasive implementation

2021-10-30 Thread Jonathan Fine
Hi Chris

I like your questions. You ask: How would fn.__wibble__ be different from
checks at the top of fn.__code__?

They'd be in two different code blocks. I see a function call going as
follows.
1. Process the supplied arguments in the usual way.
2. Create a new frame object and place it on the stack.
3. In that new frame execute fn.__wibble.
4. When fn.__wibble__ is done, execute fn.__code__ IN THE SAME FRAME.

I think step 4 is a tail call, as in https://en.wikipedia.org/wiki/Tail_call,
which includes the concept of tail recursion.

Your other question is: And, seeing something in help(fn) largely
necessitates that the source code be retained.

Yes, this is true whatever syntax is used. In help(fn) inspect.signature
repr() is used to produce help text. There's no extra storage overhead for
that. Both your implementation and mine will require source text to be
stored (unless the module is compiled as optimised).

Oh, but I've made a mistake. If the module is compiled non-optimised then
the compile code contains points to the source file. These are used in
traceback when an exception occurs.

I'm not to say at this point which approach is best for the person who
reads help(fn), except the lawyer's answer "it just depends". At this point
my focus is on designing a less invasive implementation.

Your good questions have led me to rethink. The tail call in my proposed
implementation can be removed and then fn.__wibble__ would not be needed.
It would be the same as checks at the top of fn.__code__.

But instead of fn.__wibble__ we have a pointer (as in fn.__code__) to some
location in the body of fn. (Or  as fn.__code__ is already well equipped
with pointers, we equip fn with a pointer to one of these pointers.)

So all that's required now is
1. A syntax in source files that allows the author of fn to specify the end
of the 'preamble extra help' in the body of fn.
2. An addition to help(fn) that provides the 'preamble' of fn as an extra
help message.

with kind regards

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


[Python-ideas] PEP 671 proof-of-concept: A less invasive implementation

2021-10-30 Thread Jonathan Fine
Hi

One of the motives for PEP 671 is that the signature of a function fn, and
hence the associated help(fn) is sometimes opaque regarding default values.
I won't repeat the excellent examples already given.

In the current implementation default values are handled outside the
compiled code of the function, which is available at fn.__code__. Instead
they are stored in 'metadata' associated with the function.

Here's one way to see this.

from inspect import signature as sig
def fn(a, b=1, c=2): return a, b, c
sig(fn) # Gives 
fn.__defaults__ = ('hi', 'there')
sig(fn) # Gives 

We can also change the __code__ object, but care is needed here.

def gn(): return (1, 2, 3)
fn.__code__ = gn.__code__
fn() # Gives (1, 2, 3).
sig(fn) # Gives 
fn.__defaults__  # Gives ('hi', 'there')

The signature of fn, together with the arguments actually supplied, is used
to initialise the code frame which is put on the top of the stack, and in
which fn.__code__ executes.

I suggest that an implementation which provides additional flexibility in
the manner in which the code frame is initialised would be less invasive.
Necessarily, PEP 671 allows programmer supplied code to be used in the
'initialisation phase'. The previous attempts place that code in
fn.__code__.

I suggest that the implementation adds a new attribute fn.__wibble__ to fn,
which can either be None or a code object. And if fn.__wibble__ is not
None, then it is used to initialise the code frame in which fn.__code__
executes. It would as before take as input the arguments actually supplied
by the user.

I stop here, saying nothing for now about two important questions. First,
what is the programmer syntax for creating such a 'two-part' function fn.
Second, what does the user see as a result of help(fn). Or in other words,
how to extend the semantics of inspect.signature.

with kind regards

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


[Python-ideas] Re: PEP 671: Syntax for late-bound function argument defaults

2021-10-24 Thread Jonathan Fine
Hi Chris

You wrote:

In fact, on subsequent consideration, I'm inclining more strongly
> towards SyntaxError, due to the difficulty of explaining the actual
> semantics. Changing the PEP accordingly.


Your PEP, so your choice. I now think that if implemented, your PEP adds to
the Python compiler (and also runtime?) tools for detecting and
well-ordering Directed Acyclic Graphs (DAG).

Here's another problem. Suppose
  def puzzle (*, a=>..., z>=...)
gives rise to a directed acyclic graph, and all the initialisation
functions consume and use a value from a counter. The semantics of puzzle
will now depend on the linearization you choose for the DAG.

(This consumption and use of the value from a counter could be internal to
the initialisation function.)

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


[Python-ideas] Re: PEP 671: Syntax for late-bound function argument defaults

2021-10-24 Thread Jonathan Fine
Hi

Please forgive me if it's not already been considered. Is the following
valid syntax, and if so what's the semantics? Here it is:

def puzzle(*, a=>b+1, b=>a+1):
return a, b

Aside: In a functional programming language
a = b + 1
b = a + 1
would be a syntax (or at least compile time) error.

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


[Python-ideas] Re: def variable = value

2021-10-24 Thread Jonathan Fine
Hi Serhiy

Thank you for so clearly explaining how names get passed to function and
class constructors.

You also wrote:

> We do not have generalized way to call arbitrary constructor with
> automatically passing __name__, __qualname__ and __module__. And it would
> be convenient.
>
> create namedtuple Point(x, y, z=0)
>  [further examples snipped]


We can already do something similar by writing (not tested)
class Point(Hack): namedtuple = lambda x, y, z=0: None
provided Hack has a suitable value.

I don't see a way to do much better than this, without introducing a new
language keyword. For example allow
signature(x, y, z=0)
to be an EXPRESSION that returns a function signature.

By the way,
class Point(Hack): def namedtuple(x, y, z=0): pass
gives a syntax error at 'def'.
-- 
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/CRSD2XZXJTRD4VNPRAUAFPKBELMA2FG3/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: def variable = value

2021-10-23 Thread Jonathan Fine
>From my phone.

An important thing about def x and class A is that the strings x and A are
made available to the constructor for x and A respectively. The same is not
true for x=val.

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


[Python-ideas] Re: Addition of a "plus-minus" binary numeric operator

2021-09-14 Thread Jonathan Fine
Hi Yahbai

You might wish to reconsider your proposal in light of existing behaviour
>>> 1+-1
0

Consider also your proposed
>>> a, b = 2 +- 1
We know that {a, b} = {1, 3}. But which is which?

In your use case you might be better off introducing a custom type
>>> lims = pm(2, 1)
>>> lims.lo, lims.hi
(1, 3)

I hope this helps you with your code.

best wishes

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


[Python-ideas] Re: New 'How to Write a Good Bug Report' Article for Docs

2021-08-16 Thread Jonathan Fine
Jonathan Goble wrote:


> Is there a reason why we can't just link to the Wayback Machine copy like
> you did here?
>

I agree with that as immediate first aid. It seems that wikipedia practice
now is to link to both the original article and to a copy on the wayback
machine.

I've found some perhaps useful pages by searching for "Bug report writing
guidelines" (with quotes).
http://www.jieranqiche.com/developer/docs/mozilla/qa/bug_writing_guidelines/
https://github-wiki-see.page/m/deegree/deegree3/wiki/Bug-Report-writing-Guidelines
https://github.com/deegree/deegree3/wiki/Bug-Report-writing-Guidelines

It might be helpful to provide links to some well-written bug reports, and
perhaps some that could do better.

with best regards

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


[Python-ideas] Re: writelines2?

2021-07-13 Thread Jonathan Fine
Thank you Paul. I used my default Python, which is Python 3.6. However,
with 3.7 and 3.8 I get the same as you. I've promoted you 'works for me' on
b.p.o to 'not a bug'. Thank you again.

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


[Python-ideas] Re: writelines2?

2021-07-13 Thread Jonathan Fine
The interactive help message for writelines gives no help. I've made an
enhancement request to b.p.o.

help(open('/dev/zero').writelines) gives no help
https://bugs.python.org/issue44623

Please take a look.

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


[Python-ideas] Re: CACHEDIR.TAG for __pycache__ on Linux

2021-07-02 Thread Jonathan Fine
Hi Leon (and Bryan)

Here's some comments on your interesting suggestion.

Bryan Ford's CACHEDIR.TAG proposal is supported by gnu tar. See:
https://www.gnu.org/software/tar/manual/html_node/exclude.html

By the way, I've copied Bryan.

There's a cachedir_tag module on PyPi, by Alex Willmer:
https://pypi.org/project/cachedir-tag/

This search shows some other systems use or think of using CACHEDIR.TAG.
https://www.google.com/search?q=CACHEDIR.TAG

Other than tar, I don't see any Linux / GNU tools that use CACHEDIR.TAG.

Further, in 2004 Bryan Ford opened a Mozilla request to use CACHEDIR.TAG.
This was closed in 2014 as WONTFIX. This discussion is useful.
https://bugzilla.mozilla.org/show_bug.cgi?id=252179

The change requested is small. However, it implies an endorsement of Bryan
Ford's elegant and well presented idea, which is a much larger matter.

Rather than saying NO, perhaps a discussion of ALL the problems involved in
__pycache__ might be better.

Here's one that interests me. How do we efficiently and elegantly support
__pycache__ on read-only file systems? A leading example is Ubuntu's:
https://en.wikipedia.org/wiki/Snap_(package_manager)

For example, on my Ubuntu PC there's a read-only folder that contains
__pycache__ folders.
/snap/core/11187/usr/lib/python3/dist-packages/

Suppose we want to use the version 11187 dist_packages with multiple
versions of Python? We're stymied, unless we know the Python versions prior
to creating (or mounting) the read-only file system.

By the way, on my Ubuntu PC all the /snap folders are in fact mounted
SquashFS images. These images are stored in:
/var/lib/snapd/snaps/

Thus, there's little reason to archive / backup the /snap folder. It's
/var/lib/snapd/snaps that needs backing up.

Finally, Bryan Ford has a focus on systems security.  The architecture of
Ubuntu's snap architecture seems to reduce the attack surface, although
there's more work to be done:
https://snapcraft.io/blog/where-eagles-snap-snap-security-overview
https://en.wikipedia.org/wiki/Snap_(package_manager)#Configurable_sandbox

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


[Python-ideas] Re: disallow assignment to unknown ssl.SSLContext attributes

2021-06-28 Thread Jonathan Fine
Thomas Grainger wrote:

It looks like there's a consensus being reached, should I create a bpo?
>

Perhaps first state what seems to be the consensus and invite further
comments before going to bpo.

Disclaimer: I'd like to see both:

1. Something on PyPi to help persons who are using ssl on current Python.
2. Something in a future version of Python, that constrains attribute
access.

We can do (1) first, and it will help inform (2).

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


[Python-ideas] Re: disallow assignment to unknown ssl.SSLContext attributes

2021-06-25 Thread Jonathan Fine
It may help to think separately about existing code using ssl, and about
new code. However, I'm not a user of ssl, so please doubt my opinions below.

EXISTING CODE
Those maintaining existing code might welcome an easy way of checking that
the code doesn't have a misleading assignment. They might also appreciate a
quick fix, such as using a subclass of type(context) that does have
__slots__. (Such devices might not work well with all existing code.)

NEW CODE
Those creating new code might appreciate a new API that has been redesigned
to simplify the interface and better support security audits. For example:

>>> context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
>>> context


Perhaps better is that type(context).__repr__ show the attributes of the
context object (and anything inherited from the parent class).

BITWISE OPERATIONS
Also, the sample code (in docs ssl.html)

ctx = ssl.create_default_context(Purpose.CLIENT_AUTH)
ctx.options &= ~ssl.OP_NO_SSLv3

contains bitwise operations whose meaning requires some thought.
-- 
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/E5JEVSXRNDZF3AUH7XZZ5XXXJE4JNIDU/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: disallow assignment to unknown ssl.SSLContext attributes

2021-06-25 Thread Jonathan Fine
Thank you Thomas for concisely and fairly reporting your experience, and
based on that suggesting a way to improve Python. Thank you for taking the
time to do this.

Here's a typo that caused a bug (which inconvenienced the original poster):

context.miunimum_version = ssl.TLSVersion.TLSv1_3
> context.minimum_version = ssl.TLSVersion.TLSv1_3
>

Here's the fix the original poster suggested:

I'd like invalid attribute assignment to be prevented at runtime
>

This can already be done, if type(context) is defined using __slots__.
However, a search in the docs for slots is not so helpful.
 https://docs.python.org/3/search.html?q=slots

Some of the better search results (for the question asked) seem to be:

https://docs.python.org/3/reference/datamodel.html?highlight=slots#object.__slots__
https://docs.python.org/3/reference/datamodel.html?highlight=slots
https://docs.python.org/3/howto/descriptor.html?highlight=slots

I see two ideas here. One idea is to improve the documentation for
__slots__, and perhaps provide tools that make it easier to create a class
that uses slots.

Here's a challenge. Find a page in docs.python.org that describes clearly,
with helpful examples, when and how to use __slots__.

The second idea, which the OP asks for, is a change to type(context) in the
standard library ssl module. Here note:

https://docs.python.org/3/library/ssl.html
Warning Don’t use this module without reading the Security considerations.
Doing so may lead to a false sense of security, as the default settings of
the ssl module are not necessarily appropriate for your application.

Given that context is important for security, perhaps it's worthwhile
closing the door to spelling errors creating security holes.

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


[Python-ideas] Off topic: Rational discursive thought and helping others

2021-06-22 Thread Jonathan Fine
Off-topic

Someone on this list wrote:

Mu.
>
> https://en.wikipedia.org/wiki/Mu_(negative)#%22Unasking%22_the_question


This is a koan, a device in Zen Buddhism used by a teacher to help the
student liberate themselves from being imprisoned by rational discursive
thought.

Here is another koan.

A Zen student told Ummon: "Brilliancy of Buddha illuminates the whole
universe."

Before he finished the phrase Ummon asked: "You are reciting another's
poem, are you not?"

"Yes," answered the student.

"You are sidetracked," said Ummon.


Here's my commentary. The teacher neither agrees or disagrees with the
student's statement. This is "Mu" if you wish.  Instead the teacher
directly observes the student's mental processes, confirms the observation,
and provides helpful advice.

The teacher is not trapped by rational discursive thought. Here the teacher
uses only 12 words. Sometimes a teacher uses a single word, or no words at
all.

You'll find this koan and further commentary at
https://www.sacred-texts.com/bud/glg/glg39.htm.
--
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/4BB6H5IDADCFOBWQTPDG7442P2DXWYRI/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: The name Ellipsis should be a constant

2021-06-01 Thread Jonathan Fine
We have the following.

>>> 12 = True
SyntaxError: can't assign to literal

>>> True = False
SyntaxError: can't assign to keyword

>>> ... = False
SyntaxError: can't assign to Ellipsis

We also have (works better in monospaced font)

>>> d[] = True
d[] = True
  ^
SyntaxError: invalid syntax

Beginners might appreciate having instead as error messages:

SyntaxError: can't assign to literal: 12
SyntaxError: can't assign to keyword: True
SyntaxError: can't assign to literal: ...

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


[Python-ideas] Re: dict.sort()?

2021-05-29 Thread Jonathan Fine
On Sat, May 29, 2021 at 6:01 PM Chris Angelico

> But if you're okay with constructing a new dict, you can do this:
>
> d = dict(sorted(d.items(), key=lambda kv: ...))
>

Or to keep the same dict (not tested)

tmp = list(sorted(d.items()))
d.clear()
d.update(tmp)

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


[Python-ideas] SEMANTICS for 'variables' produced by a decorator

2021-05-29 Thread Jonathan Fine
There's been a discussion in this list on extending Python to provide
SYNTAX such as
@decorator
name = EXPRESSION
and also suitable semantics. (Here 'name' is an identifier, in the
discussion called a 'variable'.)

This post is about providing SEMANTICS for such decorator syntax. We can do
this within the existing Python syntax for decorators.

Recall that
@decorator
def fn():
# body
is usually equivalent to
def fn():
# body
fn =  decorator(fn)
and that decorator is just a callable that returns something. It need not
return another function. It could return a 'variable', such as the result
of calling fn.

Here's a proof of concept. Consider the following
BEGIN
$ cat work.py
from collections import namedtuple
Locn = namedtuple('Locn', 'doc module name')

def locn_from_fn(fn):
name = fn.__name__
module = fn.__module__
doc = fn.__doc__
return Locn(name=name, module=module, doc=doc)

def decovar(fn):
locn = locn_from_fn(fn)
return fn(locn)

@decovar
def variable(locn):
return ('value', locn)

def deconamedtuple(fn):
locn = locn_from_fn(fn)
nt = namedtuple(locn.name, fn())

nt.__doc__ = locn.doc
nt.__module__ = locn.module
nt.__name__ = locn.name

return nt

@deconamedtuple
def Point():
'''Return a point (x, y) in the plane.'''
return 'x y'

print(variable)
print(Point)
print(Point.__doc__)
END

Here's what we get when we run the script.
BEGIN
$ python3 work.py
('value', Locn(doc=None, module='__main__', name='variable'))

Return a point (x, y) in the plane.
END

It should now be clear that this approach allows us to pass much useful
information to the decorator.

I claim that this approach gives most or all of the semantic benefits of
'decorators on variables', and within the current Python syntax. If so, and
the semantic benefits are strong, then here's part of a good case for
extending the syntax in a future version of Python.
-- 
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/QJACDY45QEAIY5XTXGBQBGXGOLWRJK3U/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: symbolic math in Python

2021-05-19 Thread Jonathan Fine
Martin wrote:

as you might have noticed, I am trying to improve the syntax and semantics
> for symbolic math in Python. Until now, I have to say, my ideas were not
> that well received, but I learned from the discussion and maybe this time I
> come up with something people like.
>

For about 10 years I've used PARI/gp for computer algebra, mainly for
integer linear algebra and polynomials. One day I might use its number
theory features.
http://pari.math.u-bordeaux.fr/

Lately it's acquired good Python bindings, and most likely for my next
project I'll start using them.
https://pari.math.u-bordeaux.fr/Events/PARI2019/talks/jeroen.html
https://pypi.org/project/cypari2/
https://cypari2.readthedocs.io/en/latest/

Regarding semantics, I'm very happy to go along with PARI/gp. This is in
part because of its deep roots in computational number theory and the
community it has around it.

See also: Integer Factorization Software: PARI/GP, Mathematica, and SymPy
https://dzone.com/articles/integer-factorization-software-parigp-mathematica

Regarding syntax, I'd be pleased to see a paritools package that makes it
easier to use the cypari2 bindings for common purposes. This perhaps could
become part of sympy. It's also worth looking at sage.
https://doc.sagemath.org/html/en/reference/libs/sage/libs/pari.html

This is what I would like. Other people will most likely have different
wishes for improving symbolic math in Python.

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


[Python-ideas] Re: division of integers should result in fractions not floats

2021-05-15 Thread Jonathan Fine
Martin wrote:

In general, doing symbolic math in Python is not very beautiful.


I think this is a problem worth investigating. (Disclaimer: I do research
in pure mathematics.)


> The number of hoops you have to jump through is large, mostly because
> syntax is abused for things it was not actually meant for.
>

I don't completely agree with this diagnosis. I think there are more
serious difficulties. I'd be interested in a discussion on symbolic math in
Python sometime, but perhaps not on this list. I'd like the people who use
and develop https://www.sagemath.org/ to be involved.

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


[Python-ideas] Re: division of integers should result in fractions not floats

2021-05-14 Thread Jonathan Fine
Martin wrote

So, if you show them (the following is fake)
>
> >>> 1/2 + 1/3
> 5/6
>  1 / 2 + 1 / 3
> 0.83
>
> They will immediately spot what's going on.
>

I'm sighted. I can see the difference. I suspect a blind person using a
screen reader would struggle a lot to spot the difference. (I don't know
enough about screen readers to be sure.)

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


[Python-ideas] Re: division of integers should result in fractions not floats

2021-05-14 Thread Jonathan Fine
Hi Martin

I think it important to realise there are at least two issues. The first is
whether sometimes fraction is better than float, and vice versa. The second
is whether the default behaviour for int / int should be changed.

A third issue is whether some of the benefits you are seeking can be
achieved in some other way. Finally, well done for changing the Python
source to implement your idea. That's something I wouldn't have the courage
to do.

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


[Python-ideas] Re: division of integers should result in fractions not floats

2021-05-14 Thread Jonathan Fine
Martin wrote:

when dividing two integers, the result is a float, which means we
> immediately lose precision. This is not good if you want to use code which
> supports higher precision.


I am of course in favour of keeping precision, if there is no cost. But
here there is a cost. Arbitrary precision arithmetic (and roots) uses more
memory and takes longer. Therefore, the system must allow the programmer to
choice what's wanted (either explicitly or implicitly).

Python has been set up to make 1/3 evaluate to a float (an implicit
choice), and have Fraction(1, 3) be a fraction (an explicit choice).

I don't think it fair to say that this decision is "not good". Rather, it's
good for some use cases and not so good for others. On balance, I'm happy
with that decision.

That said, as a pure mathematician who does integer calculations, I'd like
numpy to have better capabilities for integer linear algebra.

I hope Martin that you agree with me, that this change would not be an
improvement for everyone.

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


[Python-ideas] OT: Accessibility: Jana Schroeder's Holman Prize Application

2021-05-10 Thread Jonathan Fine
Perhaps Off Topic, but for a good cause.

This year I met Jana Scroeder, a blind person forced to change jobs as part
of the social cost of Covid. Her outsider experience of computer coding
training became a wish to make things better. She has applied for a Holman
Prize ($25,000 over a year) to fund this. She's also set up a survey to
reach and know better those with similar wishes.

One simple way to help open to many is to volunteer to be a sighted helper
for a code and math variant of BeMyEyes.org. I encourage you to listen to
Jana's pitch for a Holman prize, and if you want to help complete the
survey (whether you're blind or sighted, code or math, young or old). I've
learnt a lot about accessibility from Jana.

*Jana Schroeder's Holman pitch* (90 seconds):
https://www.youtube.com/watch?v=3ywl5d162vU

*Jana Schroeder's survey* (15 minutes):
https://tinyurl.com/blindcodersurvey

Finally, *The Holman Prize*:
https://holman.lighthouse-sf.org/

best regards

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


[Python-ideas] Re: String comprehension

2021-05-03 Thread Jonathan Fine
Summary: The argument in list(arg) must be iterable. The argument in
str(arg) can be anything. Further, in [ a, b, c, d ] the content of the
literal must be read by the Python parser as a Python expression. But in
"this and that" the content need not be a Python expression.

Hi David

I find your suggestion a good one, in that to respond to it properly
requires a good understanding of Python. This deepens our understanding of
the language. I'm going to follow on from a contribution from Brendan
Barnwell.

Please consider the following examples

Similarity.
>>> list( x*x for x in range(5) )
[0, 1, 4, 9, 16]
>>> [ x*x for x in range(5) ]
[0, 1, 4, 9, 16]

Difference.
>>> tmp = (x*x for x in range(5)) ; list(tmp)
[0, 1, 4, 9, 16]
>>> tmp = (x*x for x in range(5)) ; [ tmp ]
[ at 0x7fec02319678>]

Difference.
>>> list( (x*x for x in range(5)) )
[0, 1, 4, 9, 16]
>>> [ (x*x for x in range(5)) ]
[ at 0x7fec02319620>]

Now consider ,
>>> str( x * 2 for x in 'abc' )
' at 0x7fec02319728>'

This last one genuinely surprised me. I was expecting 'aabbcc'. To
understand this, first note the quote marks in the response. Next recall
that str returns the string representation of the argument, via
type(obj).__str__(obj).

My understanding of the situation is that the list comprehension [ x*x for
x in range(5) ] is a shorthand for list( x*x for x in range(5) ). It works
because list takes an iterable as its argument (if it has one argument).
But str with one argument gives the string representation of an arbitrary
object. Here's an example.

>>> list(None)
TypeError: 'NoneType' object is not iterable
>>> str(None)
'None'

Here's what Brendan wrote: The difference between your proposal and
existing comprehensions is that strings are very different from lists,
dicts, sets, and generators (which are the things we currently have
comprehensions for).  The syntax for those objects is Python syntax, which
is strict and can include expressions that have meaning that is interpreted
by Python.  But strings can contain *anything*, and in general (apart from
f-strings) their content is not parsed by Python.

In a nutshell: The argument in list(arg) must be iterable. The argument in
str(arg) can be anything. Further, in [ a, b, c, d ] the content of the
literal must be a Python expression, whereas in "this and that" the content
need not be a Python expression.

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


[Python-ideas] Re: String comprehension

2021-04-30 Thread Jonathan Fine
On Fri, Apr 30, 2021 at 6:00 PM Chris Angelico  wrote:

For those cases where you're merging literal parts and generated
> parts, it may be of value to use an f-string:
>
> >>> f"[{','.join('0123')}]"
> '[0,1,2,3]'
>
> The part in the braces is evaluated as Python code, and the rest is
> simple literals.
>

For readability, reuse and testing I think it often helps to have a
function (whose name is meaningful). We can get this via
   as_list_int_literal = gensep(',', '[', ']')

It would also be nice to allow as_list_int_literal to have a docstring
(which could also be used for testing).

I accept that in some cases Chris's ingenious construction has benefits.

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


[Python-ideas] Re: String comprehension

2021-04-30 Thread Jonathan Fine
Hi David

I see where you are coming from. I find it helps to think of sep.join as a
special case. Here's a more general join, with sep.join equivalent to
genjoin(sep, '', '').

def genjoin(sep, left, right):
def fn(items):
return left + sep.join(items) + right
return fn

Here's how it works

genjoin('', '', '')('0123') == '0123'
genjoin(',', '', '')('0123') == '0,1,2,3'
genjoin(',', '[', ']')('0123') == '[0,1,2,3]'

All of these examples of genjoin can be thought of as string
comprehensions. But they don't fit into your pattern for a string
comprehension literal.

By the way, one might want something even more general. Sometimes one wants
a fn such that

fn('') == '[]'
fn('0') == '[0,]'
fn('01') == '[0,1,]'

which is again a string comprehension.

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


[Python-ideas] Re: Adding syntax for the empty set

2021-04-09 Thread Jonathan Fine
In August 2020, in the context of PEP 472 I suggested
>>> {-}
for the empty set literal. At present the closest we can do for an empty
set literal is
>>> {0} - {0}
set()

The context for this is whether PEP 472 should make
>>> something[]
a syntax error. If we do then, what about the workarounds
>>> something[*argv]
>>> something[**kwargs]
which so to speak convert the syntax error to a run-time error.

Because
>>> something[]
was ugly and easily misunderstood I suggested
>>> something[-]
and hence
>>> {-}
as new syntax.

The thread from August 2020 can be found (with >>> prompts as quotes) at
https://mail.python.org/archives/list/python-ideas@python.org/thread/2QANGFBMGUSCYOLU3GJ6AOGV6Q2ATC72/#QOBONXUPUMC3ULCGJU6FVHOCIZQDT45W

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


[Python-ideas] Re: Itertools generator injection

2021-03-20 Thread Jonathan Fine
Hi

I see two issues. The first is present behaviour. The second is alternative
ways of ordering the elements of a Cartesian product.

Here's an example of the present behaviour.

>>> iter_range = iter(range(100))
>>> prod = itertools.product(iter_range, "abcdef")
>>> next(iter_range)
Traceback (most recent call last):
  File "", line 1, in 
StopIteration

It's not what I expected before I read this thread, and it is what I
expected after I read this thread. I regard it as a bug. I expect iterators
to be lazy rather than greedy when consuming input. This helps make for
efficient and non-blocking pipelines. I see no reason for the product to
consume any items until it has been asked to yield a member of the product.

The second issue is that there are at least three sensible ways to iterate
a Cartesian product. The itertools.product function is, as said in the
docs, equivalent to nested for loops. On ordered input it's equivalent to
lexicographic ordering.

The squares on a chessboard are labelled a1, a2, a3,  b1, b2, b3, ... ,
g7, g8 (using lexicographic order. There are as many fractions as there are
counting numbers. The usual way to prove this is to order unsimplified
fractions p/q via the TRIPLE (p + q, p, q). This gives a diagonal ordering.
The third order is via subsquares. In other words order via the TRIPLE
(max(p,q), p, q).

I suggest on the basis of batteries included that all three methods be
included in itertools, perhaps with names lexicproduct, diagproduct and
maxproduct. Finally, product is a synonym for lexicproduct. This allows the
programmer to say without writing a comment that they've considered the
alternatives and chosen the function also known as product.

with best regards

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


[Python-ideas] Off-topic: What costs NaN pounds for a null amount?

2021-01-14 Thread Jonathan Fine
Hi

There's interest here in arithmetic operations on NaN . I've just seen a
product listed as costing NaN pounds to buy a null amount. That was written
as £NaN/null.

The bargain item is Glade Shake & Vacuum Citrus, and you can see it at
https://www.tesco.com/groceries/en-GB/products/253732570

Searching on this site for 'NaN' brings up many entries for
https://en.wikipedia.org/wiki/Naan bread.

with best regards

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


[Python-ideas] Off-topic: Happy Birthday, Don Knuth (and Python coroutines)

2021-01-10 Thread Jonathan Fine
Hi

Don Knuth, author of The Art Of Computer Programming and creator of the TeX
typesetting system is 83 today. Happy Birthday Don. Thank you for TeX and
everything else.

You're warmly invited to join me online to celebrate Don's life and work.
The virtual party is on Thursday 14 January, 6:30 to 7:30pm UK time.

You'll find the zoom details at (and a goto tribute) at:
https://jfine2358.github.io/post/2021/01/10/happy-birthday-don-knuth/

This link also contains a discussion of how merging two binary trees
provides a good example of how coroutines can be useful, as in Python's
async and wait.

with best wishes

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


[Python-ideas] Re: (Off-topic) Different object, same id

2021-01-01 Thread Jonathan Fine
Bravo, Jeff. I couldn't have chosen a better example.

However, I'd expect large ints to be stored in two parts. A (class,
pointer) pair which has fixed size. And memory referenced by the pointer,
large enough to store the value of the large int.

However, that's part of the language implementation, and not part of the
language definition.

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


[Python-ideas] Re: Standard tool for iterating over recursive data structures?

2021-01-01 Thread Jonathan Fine
Hi Richard

You wrote

I believe that one solution to detecting the cycles is to create a set
> of the object IDs you have visited and started to print. If you come
> across an ID you have already seen, this point is in a cycle. Sets are
> fairly compact and intentionally fast to search for an item.
>

Indeed. But I see a flaw. The problem is that we want to know about
EQUALITY of nodes, not equality of the ID (memory address in disguise) at
which the node is stored.

In other words, as stated earlier, things are easier and quicker if the
nodes are hashable. Only hashable objects can be stored in a set, and
equality of NODE doesn't imply equality of ID. (The converse is trivially
true.)

Here's an example
>>> def f(): return 10**1000
>>> list(map(id, (f(), f(
[139927013695536, 139927013696008]

By the way, this surprised me. Would anyone like to explain this?
>>> id(f()), id(f())
(139927013695536, 139927013695536)

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


[Python-ideas] Re: Standard tool for iterating over recursive data structures?

2021-01-01 Thread Jonathan Fine
Hi Jeff

> But you're right, that's a better word for discussing the problem.
> Steven's problem data structures are cyclic graphs. I don't agree that such
> structures are a sign one is doing something wrong (outside the naive
> approach to printing them out).
>

Thank you for agreeing with me, and nicely disagreeing with me. However,
the problem of 'walking a graph' to find a spanning tree is first of all a
matter of choosing an algorithm. The algorithm to be used and the
representation of the graph are two different matters.

Suppose the vertices are well ordered, for example (0, 1, 2, 3, .., n).
Write each edge as an ORDERED pair, with the first vertex being less than
the second vertex. Now list the edges in lexicographic order. That solves
the problem, and gives a unique representation, provided we are given a
well ordering of the vertices.

Under certain circumstances, we can use the Python id to provide the well
ordering of vertices. However, that doesn't always work. Two strings (or
large ints, or tuples) can be equal even though they have different ids.
However, I think it reasonable to assume that we have a sensible equality
relation on the vertices.

Now things get interesting. For a very large graph, it would be very
helpful if every vertex has a hash. This would make determining equality
easier. But if the data structure representing the graph has Python cycles
in it (as in Steven's use case) then there won't be a hash available.

Do you agree with me, Jeff, that the problem of printing out a
vertices-and-edges graph is much easier (or at least quicker) if each
vertex has a hash. More exactly, we want a quick and easy way to determine
if two vertices are equal.

It would be nice to have some further input from Steven, whose original
post stated the problem he wished to solve.

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


[Python-ideas] Standard tool for iterating over recursive data structures?

2021-01-01 Thread Jonathan Fine
Hi Jeff

You wrote:

Detecting cycles will involve a lot of bikeshedding. (Sorry, couldn't
> resist.)
>

Indeed. That really brought a smile to my face. Thank you.

As I recall, bikeshedding is endless discussion (cycles again) of the
COLOUR to paint the bikeshed. And in mathematics there's the topic of
https://en.wikipedia.org/wiki/Graph_coloring.

By the way, according to wikipedia, the convention of using colors
originates from the coloring of the countries of a map, as in the famous
https://en.wikipedia.org/wiki/Four_color_theorem.

Once again, thank you for your careful attention and sense of humour.

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


[Python-ideas] Re: Standard tool for iterating over recursive data structures?

2021-01-01 Thread Jonathan Fine
Hi Richard

You suggested

A very simple and in my mind reasonable use for this is to build a
> representation of a graph, where each node is represented by a list (or
> some other collection), and the connections are denoted by adding to
> that collection the nodes that are adjacent (or maybe a tuple of the
> node and the distance). This naturally creates a recursive structure
> unless connections are unidirectional and the graph is acyclical (i.e. a
> tree).
>
> For example, a 3 node fully connected graph might be:
>
> a = []
> b = []
> c = []
>
> a.append(b)
> a.append(c)
> b.append(a)
> b.append(c)
> c.append(a)
> c.append(b)
>

 According to https://en.wikipedia.org/wiki/Graph_theory#Graph, a graph is
an ordered pair
>>> G = (V, E)
where V is a set of vertices, and E is a set of edges, where an edge is an
unordered pair of vertices.

You've given the complete graph on 3 vertices (although without explicitly
stating the vertex set V).
https://en.wikipedia.org/wiki/Complete_graph

If we use the wikipedia definition (with vertices 'a', 'b' and 'c') we have
>>> V = {'a', 'b', 'c'}
>>> E = {{'a', 'b'}, {'a', 'c'}, {'b', 'c'}}

I've shown how to represent graphs, by directly translating the
mathematical definition into Python (without introducing any additional
classes). You've produced a different way to represent graphs.

Mathematically, your representation is this. There is a set V of vertices.
Further, for each v in V there is associated a subset V_v of V. Further, if
w in V_v then v in V_w.

I wouldn't call what you've written down the Python representation of this
mathematical definition. To explain this, I'll write down what I think it
should be.

Suppose G is a graph with vertices {'a', 'b', 'c', 'd'}. Using a dict to
represent the map that v goes to V_v, we can write G as
{
'a': {...},
'b': {...},
# etc
'e': {...},
}

My initial post suggests that, purely on the basis of the loop in the data
structure, there's a code smell in the representation you provided. I'd say
that not agreeing with its own mathematical definition is a code smell (or
worse).

I'll put it another way. Suppose our vertices are called (or represent)
Alice, Bob, Carol, Dave and Eve. Now let G be the graph whose edges
represent the existence of cryptographically secure communication between X
and Y. I claim that your code isn't able to represent such a graph.

Thank you Richard for forcing me to think things through and find what I
consider to be a flaw in the code you supplied.

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


[Python-ideas] Re: Standard tool for iterating over recursive data structures?

2021-01-01 Thread Jonathan Fine
Hi

I'd say the problem isn't recursion. Here I'm using the definitions given
in:
https://en.wikipedia.org/wiki/Recursion
https://www.cs.utah.edu/~germain/PPS/Topics/recursion.html

Rather, it's that the data has a loop (or cycle) in it. A simple example of
this is
>>> x = []
>>> x.append(x)
>>> x
[[...]]
>>> x[0] is x
True

So far as I know, it's not possible to create such using only immutable
objects. And anything created using only immutable objects will have a hash.

A beginner can easily by mistake create an object such as x above, and
without the short-circuit provided by
>>> x
[[...]]
the result is an unprintable object, that further raises an exception (or
worse). That's really bad for the poor beginner.

As a first approximation, my opinion is that data having such a loop /
cycle in it is at least a code smell, and perhaps worse. However, there may
be examples that I've not considered that would make me change my mind.

By the way, in the mathematics of the symmetric group (permutations) the
two tuples
>>> (0, 1, 2, 3)
>>> (1, 2, 3, 0)
are different representations of the same cycle (where here the word cycle
has a different meaning).

Also by the way, determining if two vertex-edge graphs are isomorphic is a
hard problem. I've been told that the best tool for this is
https://www3.cs.stonybrook.edu/~algorith/implement/nauty/implement.shtml

To summarise, it's loops / cycles in the representation of the data that's
the problem. Without a use case to the contrary, I'd say don't do this.
That's my opinion. Yours may be different.

Final idea. Perhaps a tool to detect cycles in data might be a good idea.

Finally, Happy New Year.

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


[Python-ideas] Re: A PEP to encourage people to mind docstrings in stub files

2020-12-22 Thread Jonathan Fine
Hi Alexey

You wrote that docstring-related software generally fails to handle
docstrings properly in stub files. I don't have experience of this,
probably because I don't use such software. Please would you provide some
examples. Ideal would be issued that have been raised (by you if need be)
for such docstring-related software.

This would help the people on this list get a better sense of the size and
importance of this problem.

best regards

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


[Python-ideas] Re: Possibility to decorate single code line or code block?

2020-12-21 Thread Jonathan Fine
Hi Christopher

I did notice the unusual command line, but didn't think any more of it. I
thought everything I needed to look at was already in the message.

A reference to https://pypi.org/project/importhook/ would have helped me. I
don't see importhook providing a practical implementation of the original
poster's request.

Going back to that, I don't see why something like
a = Timer(time_consuming_function)()
shouldn't actually provide the semantics wanted for
@Timer
a = time_consuming_function()

My preference is for code that's easier to read rather than quicker to
type. It's said that easy reading is hard writing.
https://quoteinvestigator.com/2014/11/05/hard-writing/

I'm also reminded of Einstein's (or is it?) Everything Should Be Made as
Simple as Possible, But Not Simpler.
https://quoteinvestigator.com/2011/05/13/einstein-simple/

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


[Python-ideas] Re: Possibility to decorate single code line or code block?

2020-12-21 Thread Jonathan Fine
Hi Paul

I get a syntax error. The code won't even compile. I don't see how your
code can avoid it. Are you sure your example works?

$ python3.8
Python 3.8.0 (default, Oct 28 2019, 16:14:01)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> @TimeIt
... time.sleep(1)
  File "", line 2
time.sleep(1)
^
SyntaxError: invalid syntax

By the way, I noticed that python 3.9 implements pep 614, but I don't see
how that could allow your example to work.

If I've made a stupid mistake, please be kind to me.

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


[Python-ideas] Re: Make for/while loops nameable.

2020-12-03 Thread Jonathan Fine
Hi

On Thu, Dec 3, 2020 at 2:02 PM Chris Angelico  wrote:

> well... uhhh Technically you can do that already
>
> for a in aaa:
> for b in bbb:
> if condition(a, b):
> break
> else:
> continue # We didn't break from b, so continue a
> break # We did break b, so break a


This is ingenious. Thank you. Here the "else ... continue" block is for
normal exit, and the suite of statements containing the break statement is
for unusual exit.


> But I don't think anyone's actually doing that :)
>

 We're sort of using the 'break ... continue' as a goto, that goes to the
suite after the else block. And though not in name a goto, it has the same
problems as a honest goto statement.

I consider your example, Chris, to be an argument in favour of allowing
'for ... if break ... else ...'.

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


[Python-ideas] Re: Make for/while loops nameable.

2020-12-03 Thread Jonathan Fine
Hi Jonatan

Please consider
for a in aaa:
for b in bbb:
if condition(a, b):
break
KEYWORD:
break
where KEYWORD is like else, but with the opposite semantics. I think this
does exactly what you asked for, in your example.

In July this year Олег Комлев suggested this addition to the syntax and
semantics, with "if break" as the KEYWORD.

New clause in FOR and WHILE instead of ELSE
https://mail.python.org/archives/list/python-ideas@python.org/thread/WNKNETPRGQ3MPQOVG4KG2QV6L7KAPNWM/

I think this is less of a change to the language, and therefore more likely
to be accepted, than what you proposed.

To me
   for a in aaa:
for b in bbb:
if condition(a, b):
break
# more code here perhaps
if break:
break
reads quite nicely. If we exited the look with a break, then please do
break again. This also avoids the problem of having to remember and type
label names.

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


[Python-ideas] Re: Fwd: Re: Global flag for whether a module is __main__

2020-11-14 Thread Jonathan Fine
The module __main__ is somewhat special. It's there from the very beginning
(so far as I can tell).
$ python3 -c 'import __main__; print(__main__)'


And without importing __main__.
$ python3 -c 'import sys; print(sys.modules["__main__"])'


In light of this, it seems to me that the technical implementation of the
proposal amounts to

1. When creating a new module object, set
__main__ = False

2. When initializing the built-in __main__ module, set
__main__ = True

I don't see a technical problem in the implementation of this idea. (I
suspect the same rules will also work for C-coded modules.)

Whether a good idea or not is another question.

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


[Python-ideas] Re: Ricky Teachey's email to me on PEP 637, and my responses

2020-10-28 Thread Jonathan Fine
Christopher Barker and Stephen J. Turnbull wrote:

> As a statement clause separator, which becomes ambiguous:
>
> if thing: x
>

Yes. Very good.  Well done, both of you.

Now consider this. PEP 643 allows for things like
obj[a=x:y]
and "may open up the open the possibility" of allowing
fn(a=x:y)

The so-to-say obvious way to allow
fn(a=x:y)
is to allow a bare
x:y
to function as an expression. This is because at present in the syntax
fn(a=SOMETHING)
the SOMETHING is an expression. Why would we want to change that? There's a
cost, particularly when we read and write code, in changing that syntactic
rule.

With me so far. Now consider
if x:y:z

What could it mean? (I'm assuming bare slices are allowed.) It could be
either of
if (x:y): z
if x: (y:z)

Now let's go back to PEP 643 allowing
obj[a=x:y]
which "may open up the open the possibility" of allowing
fn(a=x:y)

Here's how I see things. Allowing both of
obj[a=x:y]
fn(a=x:y)
opens up the possibility of
   if x:y:z
which in my opinion is a can of worms. Please, let's not go there.

Not convinced?  Both
if a:b:
x = y
and
if a:b:
x = y
are valid syntax after 'promoting' some colons into slices. But we have to
look ahead to the next line, to figure what to do.

For this reason I think it better to forbid the short-cut
obj[a=x:y]
and allow the explicit statement
obj[a=(x:y)]
by making
(x:y)
and similar constructs valid syntax for an slice expression, which can be
used anywhere.

While we're here
def fn(u:v=w): pass
is valid syntax for a function where
u has type v
u had default value w

I say allow
def fn(u:v=(x:y)): pass
def fn(u:v=(:)): pass
and forbid
def fn(u:v=x:y): pass
def fn(u:v=:): pass

I think PEP 637 would prefer the other way around. By the way, there's a
gap in PEP 637. This PEP talks about slice notation in function calls, but
not in function definitions. But default values are values that migrate
from a function definition to a function call.

I'm warming to the idea of a PEP concerned solely with the syntax for

1. item access
2. function definitions and calls
3. slices

Finally, thank you Christopher and Stephen, for your concise and deep
contribution.

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


[Python-ideas] Ricky Teachey's email to me on PEP 637, and my responses

2020-10-23 Thread Jonathan Fine
SUMMARY:
I share with you extracts from a personal email Rick Teachey sent me, on my
involvement in PEP 637 (keyword arguments in item access), and my answers
to some important questions he asks.

BACKGROUND:
Last week, prior to my publicly stating my resignation as a co-author of
PEP 637, Ricky Teachey sent me a personal email. I found it so deep and
perceptive that I asked him for permission to share extracts with you on
this list. I'm pleased that he's allowed this, and I'm most grateful to him
for this.

The rest of this post consists of extracts from his email, and some brief
comments from me.

RICKY'S EMAIL and MY RESPONSES:

Ricky Teachey wrote:

> It is clear to all-- not a secret-- you take a different view on the
> desirability of what is currently the favored proposal. It seems to me what
> has happened here is, Guido, Steven, and now Stefano believe that your
> involvement in the PEP (one that is championing that proposal you have
> significant disagreements with) has been undertaken by you out of a
> motivation to either get it drastically changed, or (again, in their
> belief) perhaps even to replace it totally with something else.



> Now I want you to know I don't get that impression from you. I get the
> impression you joined the PEP team out of a simple desire to make it
> better, even though you disagreed with parts of it.


PEP 1 says:

> The PEP author is responsible for building consensus within the community
> and documenting dissenting opinions.


[The PEP] should clearly explain why the existing language specification is
> inadequate to address the problem that the PEP solves.


I want keyword arguments in item access to be added to Python, and I want
it to be done well. Something that won't cause difficulty 3 to 5 years
from now. PEP 1, as above, has good advice that contributes to this goal.
These are areas I particularly wanted to contribute to, as a PEP author. I
have no wish to use improper methods to obtain what I think is best.

>
Ricky Teachey wrote:

> I also understand, though, that at least part of the motivation [for
> developing kwkey] is something else; you believe that if people experiment
> a bit ahead of time using actual code, the deficiencies of the current
> proposal will feel worse than people are imaging in their minds. I wouldn't
> suggest you back down from saying that outright, too. But if you can say
> so, I would emphasize that the primary purpose is helping people experiment.


At least when convenient, I'm all for experiments prior to making
hard-to-reverses changes to Python.

PEP 1 says:

> For a PEP that adds new functionality or changes language behavior, it is
> helpful to include a section on how to teach users, new and experienced,
> how to apply the PEP to their work.


A basic idea of kwkey is an equivalence between
d[1, 2, a=3, b=4] = val
X(1, 2, a=3, b=4)[d] = val
provided X and item keyword access are given the same semantics. This idea
will I think help greatly with the 'teach users' section of the PEP.

Observation, experiment and theory are fundamental to science. Astronomy
has the observatory. Biology, chemistry and physics have the laboratory.
All research scientists publish. We can use kwkey to do experiments,
without first having to create a new version of Python. It makes
experiments cheap.

My opinions result in predictions for the result of these experiments. But
rather than discuss opinions, I'd like us to do experiments and share our
experience. I've been surprised by the results of my own experiments using
kwkey! We can all learn from experiments, particularly if we're observant.

Ricky Teachey wrote:

> However, on the other hand, if the first is not really your purpose-- if
> what you really want is for people to use the package and realize the
> proposal needs to be changed, I would [...] suggest asking to write a
> competing PEP, and promote kwkey a great tool that the steering council can
> use to make a good choice between competing PEPs.


I applaud your suggestion, that the steering council use kwkey as part of
making a choice. And
I think we're getting closer to having a second PEP.

Here's an idea. At present both of
d[1:2]
d[1:2, 3:4, 5, 6]
are valid syntax, but neither of
d[(1:2)]
d[(1:2, 3:4, 5, 6)]
are valid syntax. This is, I think, a bit of an anomaly.

I suggest a PEP that extended the syntax to allow
(1:2)
(1:2, 3:4, 5, 6)
to be expressions (to be used as function arguments, with the existing item
access semantics). I think this is something which most supporters of
keyword arguments in item access could support. And which few opponents of
keyword arguments in item access would oppose. It's a small and fairly safe
change.

And this change would, via constructs such as
   X((1:2), a=(3:4))[d] = val
allow us to get perhaps 75% of the benefits provided by the larger (and
more risky) change that would allow
d[1:2, a=3:4] = val

I think we could get (1:2) etc expressions into the

[Python-ideas] I'm no longer a co-author of PEP 637 - keyword args in item access

2020-10-13 Thread Jonathan Fine
Hi

The following is copied and pasted from
https://github.com/python/peps/pull/1650

Stefano Borini
===

Commit message:
PEP 637 I've asked Jonathan Fine to resign as PEP author, and he's agreed
to do so. Details in the pull request

Pull request comment:
Hi Jonathan

Thank you for accepting my invitation to be a co-author of PEP 637. I
regret that because of disagreeing direction for the PEP I think it best
for the community that I ask you to resign as co-author.

Thank you for your help
===

Jonathan Fine
===
Hi Stefano

I'm sorry things didn't work out, the way either of us wanted.

Yes, there were disagreements! Particularly on python-ideas, involving also
PEP sponsor Steve D'Aprano.

I'd like the PEP to be improved before it is submitted.

Jonathan
===

with best regards

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


[Python-ideas] PEP 637 - problems not solved by existing language

2020-10-06 Thread Jonathan Fine
SUMMARY
This post asks for some examples that will improve PEP 637, by providing
examples where the existing language specification is not adequate (but PEP
637 is). The rest of this post should tell you why I want these examples,
and what they should look like.

DISCLAIMER
I'm an editor of PEP 637, writing in my personal capacity. And I'm also the
author of package kwkey mentioned below.

SUMMARY
PEP 637 adds to Python's syntax and semantics. It adds statements such as
   >>> x[1, 2, a=3, b=4] = val
to the syntax, and adds new associated semantics.
https://www.python.org/dev/peps/pep-0637/

PEP 1, which defines the PEP process, states that any PEP that changes the
existing language specification should clearly explain "why the existing
language specification is inadequate to address the problem that the PEP
solves".
https://www.python.org/dev/peps/pep-0001/#what-belongs-in-a-successful-pep

As part of addressing this question of existing Python being adequate, I
wrote a new package kwey. This package provides, I believe, a class B such
that
>>> B(1, 2, a=3, b=4)[x] = val
is equivalent to
>>> x[1, 2, a=3, b=4] = val
once PEP 637 is implemented. (And if not, please report a bug, and if you
can provide a patch.)
https://pypi.org/project/kwkey/

GOAL
The current version of PEP 637 doesn't mention kwkey. I'd particularly like
us to look for problems where using kwkey as above is not adequate but PEP
637 is adequate.

Aside. Please treat this as a semantic problem, or in other words assume
that
>>> x[SOMETHING]
>>> f(SOMETHING)
impose the same constraint on a well-formed expression SOMETHING.

Here's why. PEP 637 allows syntax such as
>>> x[1:2, 3:4, a=5:6, b=7:8]
and even after PEP 637 (as it currently is)
>>> f(1:2, 3:4, a=5:6, b=7:8)
is forbidden syntax. But PEP 637 is much more than a syntax extension.

Recall that we already have literal expressions such as
>>> [1, 2, 3] # List literal
>>> (1, 2, 3) # Tuple literal
>>> {1, 2, 3} # Set literal
in Python. If current Python turns out to have adequate semantics, then
perhaps adding
>>> (1:2:3) # Slice literal
might by itself be enough. This is why I want particularly semantics
examples. They're worth more.

CONCLUSION
I'd like to see semantic examples of problems that can be adequately solved
by PEP 637, but not by using kwkey. The PEP process says, in so many words,
that such examples should be provided.

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


[Python-ideas] Package kwkey v0.0.2 provides items-keys duality to support PEP 637

2020-09-30 Thread Jonathan Fine
I'm pleased to announce v0.0.2 of my kwkeys package.
https://pypi.org/project/kwkey/

The main new feature is items-key duality. Based on that, it emulates the
semantics proposed by D'Aprano and van Rossum. It also emulates the
semantics proposed by myself.

What does this mean? Here, by duality I mean treating
items[key]
key[items]
as roughly equivalent. This allows us to move the keyword arguments outside
the square brackets.

In other words, the following
items[1, 2, a=3, b=4] = val
X(1, 2, a=3, b=4)[items] = val
are roughly equivalent. Here, X should implement the semantics one wishes
to use for
items[1, 2, a=3, b=4] =val
and the other item access methods (ie setitem and delitem).

I've already implemented three options for X. They are:
* class A: The current semantics
* class B:  The semantics proposed by D'Aprano and van Rossum
* class C: The semantics proposed by Fine (ie myself)
and more can readily be provided. Experiments cost little.

Here's something nice. You can with current Python implement a class that
will work today via duality calls such as
X(1, 2, a=3, b=4)[items] = val
and after the implementation of PEP 637 the class will continue to work.

In other words, with post PEP 637 Python this
items[1, 2, a=3, b=4] =val
will work, provided you choose the value of X that Python implements.

For more information see
https://www.python.org/dev/peps/pep-0637/
https://pypi.org/project/kwkey/
https://github.com/jfine2358/python-kwkey

Guido: Apologies for calling you von Rossum in the README. I know you're
Dutch. I've already fixed it in the source. Perhaps next time I'll use the
safer GvR.

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


[Python-ideas] Re: Package kwargs to support Guido's favoured semantics

2020-09-03 Thread Jonathan Fine
Oops. Should read
Subject: Package kwkey to support Guido's favoured semantics

Please accept my apologies.
-- 
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/M4DZCG4EJFS4FMJG6MU6UHRZPPEYEMTA/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Package kwargs to support Guido's favoured semantics

2020-09-03 Thread Jonathan Fine
The next release of kwkey will provide a class A with the following
property.

It is that
>>> A(1, 2, a=3, b=4)[d] = 'val'
will result in
>>> d.__setitem__((1, 2), 'val', a=3, b=4)

This is precisely the same call that would result from
>>> d[1, 2, a=3, b=4] = 'val'
using the semantics that Guido currently favours.

Further, to better support exploration, the call instead will be
   >>> d._A_setitem__((1, 2), 'val', a=3, b=4)
when d._A_setitem__ exists. (And of course similar behaviour for getitem
and delitem.)

This will allow experiments via subclassing an existing class, for example
from xarray. Using _A_setitem__ etc means that the new
>>> A(1, 2, a=3, b=4)[d] = 'val'
semantics can be implemented via the already existing
   >>> d[SOMETHING] = 'val'
implementation.

Both the commands
>>> d[SOMETHING] = 'val'
>>> A(1, 2, a=3, b=4)[d] = 'val'
can thus work on the same mapping / sequence instance d. The two
implementations can peacefully co-exist.

For clarity, when available
>>> d[1, 2, a=3, b=4] = 'val'
is most likely to be better than
>>> A(1, 2, a=3, b=4)[d] = 'val'
and I introduce the A second form as a useful stopgap, until the first form
is available.

A reminder. The purpose of kwkey is to provide a convenient way for people
to experiment with different approaches to implementing the semantics of
>>> d[1, 2, a=3, b=4] = 'val'
and, perhaps, to provide a compatible implementation in present day Python.
For fairness, I hope also to provide a class B that supports the __keyfn__
semantics.

I hope to make this release next week. Comments are welcome.

https://pypi.org/project/kwkey/
https://github.com/jfine2358/python-kwkey/issues/3

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


[Python-ideas] Re: Proposed new syntax for subscripting (was PEP 472)

2020-09-01 Thread Jonathan Fine
Hi Steven

Thank you, for reviewing and combining your previous statements into a
single message. This is a great help, for the creation and editing of the
revised PEP.

I intend to do something similar myself. Perhaps others might also want to
do something similar.

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


[Python-ideas] Re: PEP 472 - new dunder attribute, to influence item access

2020-08-29 Thread Jonathan Fine
Paul Moore wrote:

Again, obvious. But you still haven't given any reason why we would want to
> do that. No-one's arguing that these things aren't possible, or that the
> proposals can't be implemented. What I'm asking, and you aren't answering,
> is what is the use case? When, in real world code, would this be used?
>

The canonical answer to this question is
https://www.python.org/dev/peps/pep-0472/#use-cases

I'd like the examples there to be expanded and improved upon. To help
support this I've created https://pypi.org/project/kwkey/, which emulates
in today's Python the proposed enhancement. I'd like us to write code now
that can use the enhancement, if and when it arrives.

By the way, thank you Paul and your colleagues for your work on creating
and developing pip. It's one of our most important tools.

I'm all for having real-world use cases, and where possible working
solutions, as a key part of the discussion. I admit that there has been a
past deficiency here. I hope that we will correct this soon. For my part,
I'm working on an enhanced kwkey, which will provide a wider range of
emulation.

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


[Python-ideas] Re: PEP 472 - new dunder attribute, to influence item access

2020-08-29 Thread Jonathan Fine
Thank you, Guido, for your interest in this discussion.

You wrote:

> So __keyfn__ has literally only two allowed values, None and True.
>

That's my proposal, for now. I'm happy for further allowed values to be
added via another PEP. In fact, that is my preference.

You also wrote:

> Could you just start over? And explain the name? And why it can't be
> False/True?


Consider
>>> d[1, 2] = 'val'
>>> d.__setitem__((1,2), 'val')

Here I call (1, 2) the key. As in
def __setitem__(key, val):
# set the value

The passage
>>> d[1, 2] = 'val'
>>> d.__setitem__((1,2), 'val')
goes via tuple. If tuple didn't already exist, we'd have to invent it. And
so here tuple is what I call "the key function".

The key function is the function that is the intermediary between
>>> d[EXPRESSION]
>>> d.__getitem__(key)

When there is a key function, the signatures are
__getitem__(key)
__delitem__(key)
__setitem__(key, val)

So we're allowed to have
class A:
__keyfn__ = None
def __setitem__(self, val, a, b, c d):
# set the value

Recall that dict has, implicitly, a way of getting a key from permitted
arguments. The meaning of
class B:
 __keyfn__ = True
def __getitem__(key):
# Get the value
is that the key is produced by exactly the same method as in dict.

The meaning of
__keyfunc__ = True
is "produce a key from the arguments, in exactly the same way as in dict".
Or in other words, "Yes, it's True. We do have a keyfn. Use the default,
dict, keyfn."

I think (None, True) works better than (False, True). This is because a
further PEP might allow the user to supply a custom keyfn. So while it is
at this time a binary choice, there might be further choices in future.


> Can you explain (in words or with examples) what happens in each case? You
> were so excited to show off one case that you never showed how the other
> case would work
>

How about:

class A:
__keyfn__ = None
def __setitem__(self, val, x=0, y=0, z=0):
print((val, x, y, z))

>>> a = A()
>>> a[1, z=2] = 'hello'
('hello', 1, 0, 2)

[Above copied from
https://mail.python.org/archives/list/python-ideas@python.org/message/P3AW6GNIYDDOTVQ2FKWYD7XYNZ5P5QBS/
]


And also

class C:
__keyfn__ = True
def __setitem__(self, *argv, **kwargs):
print(f'argv={argv} | kwargs={kwargs}')

>>> c = C()

>>> c[1] = 'val'
argv=(1, 'val') | kwargs={}
>>> c[1, 2] = 'val'
argv=((1, 2), 'val') | kwargs={}

>>> c[a=1] = 'val'
TypeError: __keyfn__ got unexpected keyword argument 'a'

[Above copied from
https://mail.python.org/archives/list/python-ideas@python.org/message/RNQFT4USRCTYTSLAUNPTWGMC6WLZEPKH/
]

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


[Python-ideas] Re: PEP 472 - new dunder attribute, to influence item access

2020-08-29 Thread Jonathan Fine
Paul Moore wrote:

But you don't give any reason why you'd want to do that. Why are you
> using subscript notation rather than a simple function call?


Good point. Consider
>>> def f(*argv): pass
>>> d = dict()

Now compare
>>> f(1, 2) = 3
SyntaxError: can't assign to function call
>>> d[1, 2] = 3
>>> d[1, 2]
3

Item assignment (ie __setitem__) is the one thing that a function call
can't do. If we want keywords in our __getitem__ and so on commands, then
one route for item assignment is to allow
>>> d[1, 2, a=3, b=4] = 5
as valid syntax.

By the way, another route is to use a simple function call, like so
>>> d[o(1, 2, a=3, b=4)] = 5
which is already possible today. Some of us don't like this route.

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


[Python-ideas] Re: PEP 472 - new dunder attribute, to influence item access

2020-08-29 Thread Jonathan Fine
I wrote:

Ricky has given some examples. Here are more, all assuming
> __keyfn__ = True
>

My mistake. It should be
__keyfn__ = None

I'm sure you've already figured that out. Still, please accept my apologies.

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


[Python-ideas] Re: PEP 472 - new dunder attribute, to influence item access

2020-08-29 Thread Jonathan Fine
For me, a satisfactory outcome from the current PEP process would be a new
dunder, which I am calling __keyfn__, that has two possible values,
namely None or True. (And of course, the associated syntax and semantics
changes. And documentation changes. These are not minor matters.)

As __keyfn__ has only two values, storing the choice in the class requires
only a single bit (not byte, but bit). That's the memory cost. And the
run-time performance cost would also be small.

Ricky has given some examples. Here are more, all assuming
__keyfn__ = True

First, this use of __keyfn__ would allow
   >>> d[1, 2, z=3]
to result in
   >>> d.__getitem__(1, 2, z=3)

Some further examples:
>>> d[1, 2]
>>> d.__getitem__(1, 2)

>>> d[(1, 2)]
>>> d.__getitem__((1, 2))

>>> d[a=1, b=2]
>>> d.__getitem__(a=1, b=2)

I find the above easy to understand and use. For Steven's proposal the
calls to __getitem__ would be

>>> d[1, 2, z=3]
>>> d.__getitem__((1, 2), z=3)

>>> d[1, 2]
>>> d.__getitem__((1, 2)

>>> d[(1, 2)] # Same result as d[1, 2]
>>> d.__getitem__((1, 2)) # From d[(1, 2)]

   >>> d[a=1, b=2]
>>> d.__getitem__((), a=1, b=2)

I find these harder to understand and use, which is precisely the point
Ricky made in his most recent post. That's because there's a clear and
precise analogy between
>>> x(1, 2, a=3, b=4)
>>> x[1, 2, a=3, b=4]

I think it reasonable to argue adding a single bit to every class is not
worth the benefit it provides. However, this argument should be supported
by evidence. (As indeed should the argument that it is worth the benefit.)

I also think it reasonable to argue that now is not the time to allow
__keyfn__ to have values other than None or True. And that allowing further
values should require an additional PEP.

I don't recall seeing an argument that Steven's proposal is as easy to
understand and use as mine (with __keyfn__ == None).

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


[Python-ideas] Re: PEP 472 - new dunder attribute, to influence item access

2020-08-28 Thread Jonathan Fine
This is a continuation of my previous post. I wrote:

Here's an example of how the new dunder might work in practice.
>
> class A:
> __keyfn__ = None
> def __setitem__(self, val, x=0, y=0, z=0):
> print((val, x, y, z))
>
> >>> a = A()
> >>> a[1, z=2] = 'hello'
> ('hello', 1, 0, 2)
>

 To continue, suppose that True is the default value for __keyfn__.
Consider now

class C:
__keyfn__ = True
def __setitem__(self, *argv, **kwargs):
print(f'argv={argv} | kwargs={kwargs}')

Here's one option for what should happen.

>>> c = C()

>>> c[1] = 'val'
argv=(1, 'val') | kwargs={}
>>> c[1, 2] = 'val'
argv=((1, 2), 'val') | kwargs={}

>>> c[a=1] = 'val'
TypeError: __keyfn__ got unexpected keyword argument 'a'

By the way, I've not tested this code.

In short, the present behaviour continues, except that that the compile
time error
>>> c[a=1] = 'val
SyntaxError: invalid syntax
is replaced by the run-time error
>>> c[a=1] = 'val'
TypeError: __keyfn__ got unexpected keyword argument 'a'

Some of us want
>>> d = dict()
>>> d[a=1] = 'val'
to raise an exception. I've just described how having True as the default
value for __keyfunc__ allows that to happen, should the Python community so
decide.

I hope this message 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/RNQFT4USRCTYTSLAUNPTWGMC6WLZEPKH/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: PEP 472 - new dunder attribute, to influence item access

2020-08-27 Thread Jonathan Fine
Here are two examples, which I hope help us understand our options.

Here's an example of how the new dunder might work in practice.

class A:
__keyfn__ = None
def __setitem__(self, val, x=0, y=0, z=0):
print((val, x, y, z))

>>> a = A()
>>> a[1, z=2] = 'hello'
('hello', 1, 0, 2)

Here's my understanding of Steven's proposal. (Please correct me if I've
got something wrong.)

class B:
def __setitem__(self, argv, val, *, x=0, y=0, z=0):
print((val, argv, x, y, z))

>>> b = B()
>>> b[1, z=2] = 'hello'
('hello', 1, 0, 0, 2)

By the way, I've not tested this code.
-- 
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/P3AW6GNIYDDOTVQ2FKWYD7XYNZ5P5QBS/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] PEP 472 - new dunder attribute, to influence item access

2020-08-26 Thread Jonathan Fine
SUMMARY
Sequences and mappings are both similar and different. Let's introduce and
use a new dunder attribute, to give item access appropriate behaviour. This
proposal is based on an earlier thread - see Acknowledgments for URL.

INTRODUCTION
In Python, there are two sorts of builtin objects that have item access.
They are mappings and sequences. They have different abstract base classes.
Mappings and sequences have fundamental similarities, and also fundamental
differences.

To see an example of this, let's consider
>>> x = dict() # Mapping
>>> y = [None] # Sequence

Consider now
>>> x[0] = 'hi'
>>> x[0] == 'hi'
True
>>> 0 in x, 'hi' in x
(True, False)

Compare it with
>>> y[0] = 'hi' # Similar
>>> y[0] == 'hi'
True
>>> 0 in y, 'hi' in y # Different
(False, True)

THE PROBLEM
Not taking into account the fundamental differences between mappings and
sequences can, I think, cause of difficulty when considering the semantics
of
>>> z[1, 2, a=3, b=4]

If z is a sequence (or multi-dimensional array) then many of us would like
to think of item access as a function call. In other words, ideally,
>>> z[1, 2, a=3, b=4]
>>> z.__getitem__(1, 2, a=3, b=4)
are to be equivalent.

But if z is a mapping, then perhaps ideally we'd like an object
>>> key = K(1, 2, a=3, b=4)
such that
>>> z[1, 2, a=3, b=4]
>>> z.__getitem__(key)
are equivalent.

PRESENT BEHAVIOUR
At present
>>> z[1, 2, a=3, b=4]
roughly speaking calls
>>> internal_get_function(z, 1, 2, a=3, b=4)
where we have something like
def internal_get_function(self, *argv, **kwargs):
if kwargs:
raise SyntaxError
if len(argv) == 1:
key = argv[0]
else:
key = argv
type(self).__getitem__(self, key)

PROPOSAL
I think it will help solve our problem, to give Z = type(z) a new dunder
attribute that either is used as the internal_get_function, or is used
inside a revised system-wide internal_get_function.

That way, depending on the new dunder attribute on Z = type(z), sometimes
>>> z[1, 2, a=3, b=4]
>>> z.__getitem__(1, 2, a=3, b=4)
are equivalent. And sometimes
>>> z[1, 2, a=3, b=4]
is equivalent to
>>> key = K(1, 2, a=3, b=4)
>>> z.__getitem__(key)
all depending on the new dunder attribute on Z = type(z).

I hope this contribution helps.

ACKNOWLEDGEMENTS
I've had much valuable help from Ricky Teachey in preparing this message.
I've also been influenced by his and others contributions to an earlier
thread, which he started 3 weeks ago.
https://mail.python.org/archives/list/python-ideas@python.org/thread/FFXXO5NNUTMDKDAWIQS7JCHPA27Y7637/#FFXXO5NNUTMDKDAWIQS7JCHPA27Y7637

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


[Python-ideas] Re: keyword arguments before positional arguments- syntax inconsistency

2020-08-25 Thread Jonathan Fine
Ben's right regarding the facts. Here's my examples.

Python 3.6.9 (default, Jul 17 2020, 12:50:27)
>>> def foo(*argv, **kwargs): return argv, kwargs
>>> foo(*'ab', x=1, y=2, *'cd', z=3)
(('a', 'b', 'c', 'd'), {'x': 1, 'y': 2, 'z': 3})

Python 2.7.17 (default, Jul 20 2020, 15:37:01)
>>> def foo(*argv, **kwargs): return argv, kwargs
>>> foo(*'ab', x=1, y=2, *'cd', z=3)
SyntaxError: invalid syntax

Also, in Python 3.6.9
>>> foo(**{}, *())
is a SyntaxError, but
>>> foo(x=1, *())
is not.

I think the change happened as a result of
PEP 448 -- Additional Unpacking Generalizations
https://www.python.org/dev/peps/pep-0448/

It reads, in part,

> Function calls may accept an unbounded number of * and ** unpackings.
> There will be no restriction of the order of positional arguments with
> relation to * unpackings nor any restriction of the order of keyword
> arguments with relation to ** unpackings.


Ben also asked: This is against the understanding of unpacking, is this
intentional?

I was surprised at the unpacking behaviour. My first thought was that Ben
had made some mistake regarding the facts. So I made the check you see
above.
-- 
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/W2ACGW2RCK4RQUZTKPXD6Z3O4H4HDS5A/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: PEP 472 - slices in keyword indices, d[x=1:3]

2020-08-25 Thread Jonathan Fine
Hi Todd

You wrote:

> Why would that be the case?  d[1:3] is allowed but d(1:3) isn't.  The
> interpreter replaces "1:3" with "slice(1, 3)" behind-the-scenes.
>

>>> s ='hello'
>>> s[1:3]
'el'

>>> s[(1:3)]
SyntaxError: invalid syntax

>>> f(x=1:3)
SyntaxError: invalid syntax

My understanding is that the syntax errors arise because the parser is
expecting, but not getting, an expression. (The conversion of "1:3" to a
slice is semantics, not syntax.)

My understanding is that if we make "1:3" an expression, as described in my
previous post, then it will also follow that
   >>> { :: :: :}
is valid syntax.

To allow
>>> d[x=1:3]
while forbidding
>>> { :: :: :}
will I think require changes in several places to Python.asdl.

I think it reasonable to require the PEP to explicitly state what those
changes are. If not you then perhaps some supporter of this change can
provide such changes, to be included in the PEP.

By the way, Python.asdl is included verbatim in the docs page

https://docs.python.org/3/library/ast.html#abstract-grammar
https://github.com/python/cpython/blob/3.8/Doc/library/ast.rst#abstract-grammar

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


[Python-ideas] Re: PEP 472 - slices in keyword indices, d[x=1:3]

2020-08-24 Thread Jonathan Fine
Christopher wrote: Why not allow slice syntax as an expression everywhere?

In reply, Todd wrote: That is a very different discussion, and not directly
related to keyword indexes.  Would it be possible to start a new email
thread to discuss it?

I think they are closely related matters, at least in terms of
implementation. For details see rest of this message. I hope this helps our
understanding, even if it shows difficulties lying ahead.

My non-expert understanding is that if
   >>> d[a=1:2:3]
is allowed by making a minimal change to Python's abstract grammar, then
   >>> f(a=1:2:3)
will also be allowed. (Extra work would be required to forbid it.)

It is also my non-expert understanding that
>>> {0:1:2:3:4:5}
would then be equivalent to
>>> {slice(0, 1, 2): slice(3, 4, 5)}
and further that
>>> { :: :: : }
would become valid syntax!

My non-expert understanding is based on
https://docs.python.org/3/library/ast.html#abstract-grammar

To me it seems that in for example
   >>> d[::, ::]
the AST is constrained by
slice = Slice(expr? lower, expr? upper, expr? step)
  | ExtSlice(slice* dims)
  | Index(expr value)
while in
   >>> f(x=SOMETHING)
   >>> f[x=SOMETHING]
the SOMETHING is an expr, and the AST is constrained by
expr = BoolOp(boolop op, expr* values)
 | NamedExpr(expr target, expr value)
 | BinOp(expr left, operator op, expr right)
 | UnaryOp(unaryop op, expr operand)
 | Lambda(arguments args, expr body)
 | IfExp(expr test, expr body, expr orelse)
 | Dict(expr* keys, expr* values)
 ...
 | List(expr* elts, expr_context ctx)
 | Tuple(expr* elts, expr_context ctx

If this is correct then adding Slice to the choices for expr would extend
the AST to allow slices in keyword indices. And then the rest follows.
-- 
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/EEJM4N6AVT7HZCEZCVQQSFE2XSYXSGZD/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: PEP 472 - regarding d[x=1, y=2] and similar

2020-08-20 Thread Jonathan Fine
Hi Todd

You wrote:

I think this is a bad idea, since it would mean classes could seem to
> support keyword arguments but silently do the completely wrong thing,
> especially if someone accidentally uses an older version.
>

I don't see this happening, and certainly don't see it as a new problem. To
help me understand, please provide an example where this happens.

It would be best to wait a few days first, after I've fixed
https://github.com/jfine2358/python-kwkey/issues/2

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


[Python-ideas] Re: PEP 472 - regarding d[x=1, y=2] and similar

2020-08-20 Thread Jonathan Fine
Hi Todd

I still don't see how testing it will help anything at this point.
>

 Well, you and I have a difference of opinion here. I don't think it's
worth discussing this further now. Perhaps next month it will be.

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


[Python-ideas] Re: PEP 472 - regarding d[x=1, y=2] and similar

2020-08-20 Thread Jonathan Fine
Todd wrote:

It has the same capabilities, the question is whether it has any additional
> abilities that would justify the added complexity.
>

The most obvious additional ability is that always
>>> d[SOME_EXPRESSION]
is equivalent to
>>> d[key]
for a suitable key.

This is a capability that we already have, which would sometimes be lost
under the scheme you support.  Also lost would be the equivalence between
   >>> val = d[key]
   >>> getter = operator.itemgetter(key)
   >>> val = getter(d)

More exactly, sometimes it wouldn't be possible to find and use a key. Docs
would have to be changed.
See: https://docs.python.org/3/library/operator.html#operator.itemgetter

As I understand it, xarray uses dimension names to slice data.  Here's an
example from
http://xarray.pydata.org/en/stable/indexing.html#indexing-with-dimension-names
>>> da[dict(space=0, time=slice(None, 2))]

Presumably, this would be replaced by something like
>>> da[space=0, time=:2]

Now, the commands
   >>> da[space=0, time=:2]
   >>>  da[space=0, time=:2] = True
   >>> del da[space=0, time=:2]
would at the begging of the call, presumably, do the same processing on the
keyword arguments. (Let this stand for a wide range of examples.)

It is arguable that making it easier for the implementer of type(da) to do
all that processing in the same place would be a REDUCTION of complexity.
Allowing the processing to produce an intermediate object, say
>>> key = dict(space=0, time=slice(None, 2))
 would help here.

Real world examples are required, I think, to ground any discussions of
complexity and simplicity. We want to optimise for what people do, for the
problems they face. And this is a new feature.

We have a perfectly good way of handling keywords, so it is up to you to
> explain why we shouldn't use it.
>

The scheme you support does not distinguish
>>> d[1, 2, x=3, y=4]
>>> d[(1, 2), x=3, y=4]
I don't regard that as being perfectly good.

In addition, I would like
>>> d = dict()
>>> d[x=1, y=2] = 5
to work. It works out-of-the-box for my scheme. It can be made to work with
a subclass of dict for the D'Aprano scheme.

I think that is enough for now.

I'd prefer to discuss this further by writing Python modules that contain
code that can be tested. The testing should cover both the technical
correctness and the user experience. To support this I intend not to focus
on the next version of kwkey.
https://pypi.org/project/kwkey/

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


[Python-ideas] Re: PEP 472 - regarding d[x=1, y=2] and similar

2020-08-20 Thread Jonathan Fine
Todd wrote:

Only Jonathan seems to want to do it differently.  We are trying to find
> out exactly why he prefers this approach.  So far the only advantage I have
> seen is that it is easier to experiment with.
>

I think it's good to make experiments before making a decision. That's
where I'd like us to do next. Let's learn from shared experience.

By the way, using
>>> d[o(1, 2, a=3, b=4)]
for a suitable 'o' and item function decorator has I believe all the
capabilities of any scheme proposed (for a suitable 'o' and decorator).

I'd rather make my case by doing experiments using various values of 'o'
(and the associated function decorator).

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


[Python-ideas] Re: PEP 472 - regarding d[x=1, y=2] and similar

2020-08-17 Thread Jonathan Fine
Here's a few words on whether we should allow and whether we can forbid:
>>> something[]

First, in
>>> something[x=1]
what I call the argv is empty, as it is with
>>> something[]

If we represent an empty argv by passing the empty tuple () to __getitem__,
then how are
>>> something[(), x=1]
>>> something[x=1]
to be distinguished from each other? Or perhaps they shouldn't be.

Next, if
>>> something[*argv]
is allowed, then what was a syntax error becomes a run-time error. Put
another way, an optimising compiler might want to raise syntax error for
   >>> something[*()]
although I think that would be wrong. Compare with
>>> 1 if True else 1 / 0
1
as its possible that something[*()] won't be called.

Finally, even if we forbid
   >>> something[*argv]
in order to prevent the empty key, the door is still open. We can use
>>> something[**dict()]
to access something with the empty key (assuming ** arguments are allowed).

And one more thing. There's rightly a strong association between [] and an
empty list literal. To my mind, this makes
>>> d[]
look very odd. We're expecting something, but there's nothing there. Perhaps
   >>> d[-]
would work better for signifying an empty key. Here, '[-]' is a special
syntactic token.

Aside: Consistent with this, we could use
   >>> {-}
for the empty set literal. At present the closest we can do for an empty
set literal is
>>> {0} - {0}
set()

I hope all 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/QOBONXUPUMC3ULCGJU6FVHOCIZQDT45W/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: PEP 472 - regarding d[x=1, y=2] and similar

2020-08-15 Thread Jonathan Fine
Hi Steven

You wrote:

why are we even considering a language change to force every single
> subscriptable object to accept arbitrary keyword-only arguments unless the
> maintainer changes their class to
> explicitly reject them?


I think there might be a misunderstanding here. I'd like to see an example
of where such a change would be required (see my conclusion below).

Recall that my proposal implies
>>> d = dict()
>>> d[a=1, b=2] = 42
>>> d[a=1, b=2]
42

Recall that your proposal implies
>>> d = dict()
>>> d[a=1, b=2] = 42
TypeError: wrapper __setitem__ doesn't take keyword arguments

Your statement above helps me understand the motivation for your proposal,
for which I'm grateful. However, there might be a misunderstanding.

I'd like now to show you a consequence of my proposal.  First consider
>>> lst = []
>>> lst['a']
TypeError: list indices must be integers or slices, not str

A dict will accept any hashable object as the key, but every list raises a
type error if a string is passed as the index. No special action is
required, for the list to reject a string as the index.

Let's see what happens when we pass a keyword key to a list.
>>> from kwkey import o
>>> lst = []
>>> lst[o(a=1)]
TypeError: list indices must be integers or slices, not K

My proposal implies that the following be equivalent
>>> anything[o(1, 2, a=3, b=4)]
>>> anything[1, 2, a=3, b=4]
for a suitable definition of 'o'. And kwkey I believe will provide such an
'o' (once the bugs have been removed - see below).

CONCLUSION
You wrote

> why are we even considering a language change to force every single
> subscriptable object to accept arbitrary keyword-only arguments unless the
> maintainer changes their class to
> explicitly reject them?


I don't see how this is a consequence of my proposal. To help me
understand, please provide an example such as
>>>  something[o(1, 2, a=3, b=4)] = 42
>>>  something[o(1, 2, a=3, b=4)]
whose behaviour is unexpected or unwelcome. (You might want to wait until
I've fixed the bug stated below.)

CONFESSION
There's a serious bug in kwkey. We don't have
>>> o(key) == key
True
but we should have that. Please accept my apologies.

I've reported the bug, and there'll be a new release next week.
https://github.com/jfine2358/python-kwkey/issues/2

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


[Python-ideas] Re: PEP 472 - regarding d[x=1, y=2] and similar

2020-08-15 Thread Jonathan Fine
Message below sent in error. Please ignore. I'll send a replacement in a
few minutes. Please accept my apologies.

On Sat, Aug 15, 2020 at 4:30 PM Jonathan Fine  wrote:

> Hi Steven
>
>
> Recall that my proposal implies
> >>> d = dict()
> >>> d[a=1, b=2] = 42
> >>> d[a=1, b=2]
> 42
>
> Recall that your proposal implies
> >>> d = dict()
> >>> d[a=1, b=2] = 42
> TypeError: wrapper __setitem__ doesn't take keyword 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/7RNITRYNTORZ5VY547L5QPWXD5SKPB47/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: PEP 472 - regarding d[x=1, y=2] and similar

2020-08-15 Thread Jonathan Fine
Hi Steven


Recall that my proposal implies
>>> d = dict()
>>> d[a=1, b=2] = 42
>>> d[a=1, b=2]
42

Recall that your proposal implies
>>> d = dict()
>>> d[a=1, b=2] = 42
TypeError: wrapper __setitem__ doesn't take keyword 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/XR66NQ4LJ4CFK3JAQHQXJLDJGK5MAF6V/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: PEP 472 - regarding d[x=1, y=2] and similar

2020-08-14 Thread Jonathan Fine
Hi Greg

Thank you, for your support for d[x=1, y=2] being valid syntax.

You ask if I have any use cases in mind for a general keyword key class
being part of standard Python. Good question.

Anyone who is experimenting with keyword keys would, I think, appreciate
having something they can use straight away. Thus, I think, any use case
for PEP 472 is also a use case for the general keyword class I'm
suggesting. No use cases for PEP 472 would of course be fatal.

Storing function call results would be a use case. For this, look at the
implementation of functools.lru_cache.

I am keen to develop, with others, examples of how PEP 472 could help us in
real-world programming. Even if convinced that PEP 472 is a good idea, the
examples would help us get the details right, and also help with formal and
informal documentation.

For a specific example, a simple ad hoc way of recording data. For example
>>> height[x=10, y=14] = 2010

We can already use dictionaries in this way, as in
>>> height[10, 14] = 2010

So this is a bit like using named tuples instead of tuples.

I think that's enough for now.

-- 
Jonathan

On Fri, Aug 14, 2020 at 12:28 PM Greg Ewing 
wrote:

> On 14/08/20 10:03 pm, Jonathan Fine wrote:
> > NO POSITIONAL ARGUMENTS
> > I'd like
> >  >>> d[x=1, y=2]
> > to be valid syntax. It's not clear to me that all agree with this.
>
> If keywords are to be allowed, it seems reasonable to me
> that this should be legal.
>
> >  >>> d[x=1, y=2] = 42
> >  >>> d[x=1, y=2]
> >  42
> >  >>> d[a='alpha', g='gamma', z=12] = 'cheese'
> >  >>> d[a='alpha', g='gamma', z=12]
> >  'cheese'
> >
> > My question is this: Should such a class ... be part of standard Python,
>
> Do you have any use cases in mind for this?
>
> To justify being built in, it would need to have a wide range
> of uses.
>
> --
> Greg
>
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/32SPMNMIGALVORKBX4ZT7JSUGGAAKX6M/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] PEP 472 - regarding d[x=1, y=2] and similar

2020-08-14 Thread Jonathan Fine
I'd like to sound out consensus regarding mapping access, where none of the
keys are positional. In particular, I suggest that PEP 472 allow syntax and
semantics such as
>>> d[x=1, y=2] = 42
>>> d[x=1, y=2]
42
and ask whether the class
>>> X = type(d)
should be part of standard Python.

NO ARGUMENTS
At present, item access requires an argument, as a matter of syntax.
>>> d[]
SyntaxError: invalid syntax

Compare this to
>>> fn()
NameError: name 'fn' is not defined

I'd like d[] to become valid syntax.

SEMANTICS OF NO ARGUMENTS
I can see two basic ways of allowing no arguments. One is for the
interpreter to construct an object that is the argument passed to
__getitem__ and so forth. The other is to not pass an argument at all. I
see this as a secondary question.

NO POSITIONAL ARGUMENTS
I'd like
>>> d[x=1, y=2]
to be valid syntax. It's not clear to me that all agree with this. Even if
there are no objections, I'd like positive confirmation.

CONSEQUENCE
Suppose
   >>> d[x=1, y=2]
is valid syntax. If so, then there is I think consensus that
>>> d[x=1, y=2] = 42
>>> d[x=1, y=2]
42
can be implemented, where d is an instance of a suitable class. Otherwise,
what's the point?

QUESTION
Suppose we have
>>> d[x=1, y=2] = 42
>>> d[x=1, y=2]
42
where d is an instance of a suitable class X that has no special knowledge
of keywords.

In other words, we also have for example
>>> d[a='alpha', g='gamma', z=12] = 'cheese'
>>> d[a='alpha', g='gamma', z=12]
'cheese'

My question is this: Should such a class
   >>> X = type(d)
be part of standard Python, as part of PEP 472? (My answer is: Yes, it
should be in standard Python.)

At this time, I'm interested in canvassing opinions. Discussion of
different opinions perhaps can take place later, or elsewhere. My main
concern is to know if there is at present a rough consensus regarding the
above.

-- 
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/2QANGFBMGUSCYOLU3GJ6AOGV6Q2ATC72/
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 Jonathan Fine
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.

There is a proposal, that
d[1, 2, a=3, b=4]
d[(1, 2), a=3, b=4]
be semantically equivalent.

I find this troubling, for example because
   fn(1, 2, a=3, b=4)
   fn((1, 2), a=3, b=4)
are semantically different.

Here's another example. If we are allowed to write
d[*argv, a=3, b=4]
then the proposal makes this equivalent to
   d[argv, a=3, b=4]
when type(argv) is tuple.

Consider now
>>> def fn(*argv): print(argv)
>>> argv = 'key'
>>> fn(*argv)
('k', 'e', 'y')

I think it would be a trap for the unwary, that the equivalence of
   d[argv, a=3, b=4]
   d[*argv, a=3, b=4]
depends on the type of argv.

The root of the proposal that
d[1, 2, a=3, b=4]
d[(1, 2), a=3, b=4]
be semantically equivalent is this: At present
d[1, 2]
d[(1, 2)]
are semantically equivalent.

Why not instead , as part of the proposed semantics, make
d[1, 2]
d[(1, 2)]
semantically different, but only for those classes that ask for it. (This
would automatically preserve backwards compatibility.)

I believe this is possible and straightforward in the future, and also in
the present via the 'o' and K mechanism. I'm happy to implement this in
kwkeys, when I have time.

An aside: I also strongly believe that writing and studying examples that
use the new syntax, via the 'o' and K mechanism, is essential to making
good choices regarding the semantics, the writing and approval of the PEP,
and the success of the extension to Python (should the PEP be accepted).

I hope this helps us come to a shared understanding.
-- 
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/L3TSE4FZ2L7ETEW2JUD3W24LTFOJMEHF/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Package kwkey and PEP 472 -- Support for indexing with keyword arguments

2020-08-06 Thread Jonathan Fine
Hi Todd

You wrote:

I guess the thing I don't understand is why you favor that API.  Could you
> please explain what you think are the advantages of your approach, ideally
> with some examples where you think your approach is clearer?
>

 I've created a github issue for this, which I'll answer here.
https://github.com/jfine2358/python-kwkey/issues/1

In kwkey, I provide 3 interfaces, namely the 'o' and 'K' interface, the
jfine interface, and the sdaprano interface. I will explain my reasons, in
that order.

Recall that we wish to emulate
   d[1, 2, a=3, b=4]
in current Python. I use
d[o(1, 2, a=3, b=4)]
as a present day syntax that emulates the future syntax. I think this is
sufficiently obvious, as to not require explanation.

When there are keyword arguments, 'o' gives an object of a new type, namely
'K'. The reason is backwards compatibility. Suppose instead
>>> key = o(1, 2, a=3, b=4)
>>> key == ((1, 2), dict(a=3, b=4))
True

Now suppose that the expression
d[(1, 2), dict(a=3, b=4)]
appears in legacy code. Because it's legacy code, it can't represent
d[1, 2, a=3, b=4]
in the new syntax.  But how can I distinguish it? That's why I introduce a
new class 'K'.

It's worth saying that 'o' used the K class only when it has to. This is to
give legacy compatibility. Today,
d[1, 2]
d[(1, 2)]
are equivalent.

To finish on 'o' and 'K', so far as I can see, what I've done
1. Provides all information that would be available from a minimal syntax
extension.
2. Doesn't provide any information beyond that (hence K used only when
necessary).
3. It continues to work with an ordinary dict.
4. The C-Python implementation is minimal (provided adding K isn't too
hard).

Now for the jfine interface, implemented by key_to_jfine signature changing
decorator. Here I give what I think is a straightforward interface (for the
function wrapped by the decorator) that will provide many programmers with
an interface that is straightforward to use. In particular, for setitem the
signature is
fn(self, val, *key.argv, **dict(key.kwargs))

If you don't like the signatures you provide, choose your own signatures,
and then if you wish to write a signature changing decorator.

Now for the sdaprano interface, implemented by the key_to_sdaprano
signature changing decorator. Here I provide an interface to what is my
understanding of Steven's proposal. This is so he and others can use it if
they wish.

By the way, as previously noted
d[1, 2]
d[(1, 2)]
are at present equivalent. However, in the new syntax
d[1, 2, a=3]
d[(1, 2), a=3]
are not equivalent. (The first has three arguments, the second two, the
first of which is a tuple.)

Finally, as to which interface is the better, I have as the implementer of
kwkey tried to be neutral as to the various interfaces.

I hope this helps. If you wish, please ask for more information or help.

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


  1   2   3   4   5   >