[Python-ideas] Re: Extract variable name from itself
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
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
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
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
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
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
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)
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)
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
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!
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)
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
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
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
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
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?
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?
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
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
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
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
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
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
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
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
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
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
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
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
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
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
>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
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
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?
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?
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
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
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
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
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
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
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()?
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
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
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
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
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
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
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
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
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
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
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
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
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?
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)
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
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?
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?
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?
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?
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?
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
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?
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?
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.
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.
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__
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
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
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
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
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
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
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
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)
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
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
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
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
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
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
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
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
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
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]
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]
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
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
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
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
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
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
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
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
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
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
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
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
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/