[Python-ideas] Re: dict.sort()?
FWI, this is a previous thread. https://discuss.python.org/t/add-a-dict-sort-method/5747 2021年5月30日(日) 1:57 Marco Sulla : > Since `dict` now is ordered, how about a `sort()` method? > It could have the same signature of list.sort(), with an optional > parameter "by" that can be "keys" or "values" ("keys" could be the > default). > ___ > Python-ideas mailing list -- python-ideas@python.org > To unsubscribe send an email to python-ideas-le...@python.org > https://mail.python.org/mailman3/lists/python-ideas.python.org/ > Message archived at > https://mail.python.org/archives/list/python-ideas@python.org/message/XXA2E5ILMAEMFLPWZIZN3T67FERJPBFF/ > Code of Conduct: http://python.org/psf/codeofconduct/ > ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/NLRSYBPC7PZKCRZSROXQTERHDXYEDZMF/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: dict.sort()?
On Sat, May 29, 2021 at 06:54:15PM +0200, Marco Sulla wrote: > Since `dict` now is ordered, how about a `sort()` method? > It could have the same signature of list.sort(), with an optional > parameter "by" that can be "keys" or "values" ("keys" could be the > default). Dicts keep their insertion order stable, that doesn't mean that they are sortable. They aren't lists where you can just reorder items, the implementation is more complex than a simple list of (key,value) pairs that can be sorted. My understanding of the implementation is that the only practical way to sort a dict is to sort the items ahead of time and then build it. I don't know the current implementation, but I think it *might* be something like Raymond Hettinger's proposal for a compact, order-preserving, key-sharing dict: https://mail.python.org/pipermail/python-dev/2012-December/123028.html If you can think of a way to sort something like that, without changing the way hash lookups work, and more efficiently than just sorting the items and building a new dict, remember that the implementation can change at any time. The bottom line here is that *dicts aren't lists* and it doesn't make sense to sort them. If you want a sortable data structure, stick to a list or a tree, or a specialised data structure designed for the task. -- Steve ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/FEKMJ4RBJ2BFHJDTAUJOFJPUVV5KXMDD/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Cleaner tracebacks from Python code
Hello, On Sat, 29 May 2021 17:29:26 -0300 André Roberge wrote: > On Sat, May 29, 2021 at 4:54 PM Irit Katriel > wrote: > > > > > You can control what the traceback of exceptions you are emitting: > > > > "raise e.with_traceback(None)" should clear everything before the > > current frame. > > > > I'm sorry, but I still don't see how. This particular line would > still show up. > > > Traceback (most recent call last): > File "test.py", line 2, in > d = date(2021, 13, 1) > File "C:\Users\andre\local_datetime.py", line 852, in __new__ > raise e.with_traceback(None) > ValueError: ('month must be in 1..12', 13) > > > Sorry if I am missing something obvious. In the example I gave, as a > user calling date() [from a library], I would only want to see that > line show up. It would be *very* confusing to see something like: > File "some/where/deep.py", line 2123, in > foo = bar(x, *y) > ValueError: ('month must be in 1..12', 13) You can start your stopwatch and see how much time it will take you to figure out that "bar" is a variable referencing "date" and sequence "y" has "month" somewhere in it. That already happens in CPython in some places, and it's quite confusing when you hit it: https://mail.python.org/archives/list/python-ideas@python.org/thread/MINLM7BBAAI44WJDHDZ2ZBHNQ4P4XCQG/ On the topic of "functions implemented in C provide clean tracebacks", on a couple of occasions, I found them to be terse up to being obfuscated. I really consider one sweet day to be able to implement feature to bring them closer to Python level of user-friendliness, e.g. > Traceback (most recent call last): > File "foo.py", line 2, in test > builtin_func(a) > File "~/projects/foo_module/src1.c", line 34, in builtin_func_impl > ValueError("wrong phase of moon") So it was possible to debug code across C extensions boundary more easily (instead of grepping loads of C code for confusing/generic error messages guessing which one was actually hit). Oh, and btw CPython importlib also implements some traceback obfuscation: https://github.com/python/cpython/blob/bb3e0c240bc60fe08d332ff5955d54197f79751c/Lib/importlib/_bootstrap.py#L233 Besides user satisfaction ("clean tracebacks"), I guess it contributes largely to the fact that only a few people know how Python import machinery works and are able to customize it. (At least, I found it pretty hard to work with - you literally need to go thru the entire importlib source code and remove those pesky _call_with_frames_removed() calls, and only then you start to get a picture what breaks where and how it all works together). > > > > > > Or you can get clever and construct a traceback with only the > > frames you want. > > > > > > On Saturday, May 29, 2021, 08:27:18 PM GMT+1, André Roberge < > > andre.robe...@gmail.com> wrote: > > > > What I am interested in is having a project-agnostic standardised > > Python way to specify what to show to an end-user when an exception > > is raised. > > > > -- Best regards, Paul mailto:pmis...@gmail.com ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/J7M3SM52W4ZXC7LM3GCIVXLYTZBCUFZH/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Cleaner tracebacks from Python code
On Sat, May 29, 2021 at 4:54 PM Irit Katriel wrote: > > You can control what the traceback of exceptions you are emitting: > > "raise e.with_traceback(None)" should clear everything before the current > frame. > I'm sorry, but I still don't see how. This particular line would still show up. Traceback (most recent call last): File "test.py", line 2, in d = date(2021, 13, 1) File "C:\Users\andre\local_datetime.py", line 852, in __new__ raise e.with_traceback(None) ValueError: ('month must be in 1..12', 13) Sorry if I am missing something obvious. In the example I gave, as a user calling date() [from a library], I would only want to see that line show up. > > > Or you can get clever and construct a traceback with only the frames you > want. > > > On Saturday, May 29, 2021, 08:27:18 PM GMT+1, André Roberge < > andre.robe...@gmail.com> wrote: > > What I am interested in is having a project-agnostic standardised Python > way to specify what to show to an end-user when an exception is raised. > > ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/EUDM54E3PDCYW4COZANAL7CQ77WMT2MS/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Cleaner tracebacks from Python code
You can control what the traceback of exceptions you are emitting: "raise e.with_traceback(None)" should clear everything before the current frame. Or you can get clever and construct a traceback with only the frames you want. On Saturday, May 29, 2021, 08:27:18 PM GMT+1, André Roberge wrote: What I am interested in is having a project-agnostic standardised Python way to specify what to show to an end-user when an exception is raised. ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/RMA5Y567KY7LYP3BFWGBR57NGD6JBBOJ/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Cleaner tracebacks from Python code
https://github.com/agronholm/anyio/blob/9eb4671547b01f5e3ba0e0ca602b6aceec15af86/src/anyio/_backends/_asyncio.py#L598 On Sat, 29 May 2021, 20:24 André Roberge, wrote: > > > On Sat, May 29, 2021 at 3:25 PM Thomas Grainger wrote: > >> pytest uses __tracebackhide__ >> >> https://doc.pytest.org/en/latest/example/simple.html#writing-well-integrated-assertion-helpers >> > > Thanks for the reminder. Pytest takes care of traceback formatting for > users. Individual projects can of course do that. But I want to do the > reverse: I want to limit what users of my projects will see in a traceback, > without having them specify something in their code. > > What I am interested in is having a project-agnostic standardised Python > way to specify what to show to an end-user when an exception is raised. > >> >> Eg anyio sets __tracebackhide__ = __traceback_hide__ = True to remove >> internal frames from user Tracebacks >> > > Do you have a specific link to this? I have looked in the documentation > as well as in a few modules (_core/_exceptions.py in particular) without > seeing any reference to this. I am not interested in custom formatting for > testing, which is something comparatively easy to do. > ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/4UK5HO5X3RLWGCSZYPDASZBVVQT5RRHE/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Cleaner tracebacks from Python code
On Sat, May 29, 2021 at 3:25 PM Thomas Grainger wrote: > pytest uses __tracebackhide__ > > https://doc.pytest.org/en/latest/example/simple.html#writing-well-integrated-assertion-helpers > Thanks for the reminder. Pytest takes care of traceback formatting for users. Individual projects can of course do that. But I want to do the reverse: I want to limit what users of my projects will see in a traceback, without having them specify something in their code. What I am interested in is having a project-agnostic standardised Python way to specify what to show to an end-user when an exception is raised. > > Eg anyio sets __tracebackhide__ = __traceback_hide__ = True to remove > internal frames from user Tracebacks > Do you have a specific link to this? I have looked in the documentation as well as in a few modules (_core/_exceptions.py in particular) without seeing any reference to this. I am not interested in custom formatting for testing, which is something comparatively easy to do. ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/AX3WADP4ZTKMO4VXV2JLDGZW2P76QIHU/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: A __decoration_call__ method for Callable objects (WAS: Decorators on variables)
On 29/05/2021 01:26, micro codery wrote: On Fri, May 28, 2021 at 5:07 PM Rob Cliffe Comailto:rob.cli...@btinternet.com>> wrote: On 29/05/2021 00:51, micro codery wrote: I also don't know what should happen for complicated assignments, and I think this has been the death of such variable decorator discussions in the past, so I would still push for only bare identifiers, with or without a type hint (but maybe it will be better received by more if the type hint is required?). Please, please, please, don't ever make type hints *required*! Some of us are perfectly happy not using them (and not having to learn them)! Rob Cliffe Fair enough! If this became accepted syntax I would use it without type hints. Even for those of us that do use type hints in places, it shouldn’t generally be necessary because the decorator will have a return type annotation. I think the original argument was that currently bare identifiers are not allowed unless they have annotation. I think I'm missing something (no, NOT just my marbles, something else ). Do you mean bare unbound identifiers? spam = 'eggs' spam # No problem Rob Cliffe But this is introducing a new multiline syntax, and it makes no more sense to take away the second line and expect a naked decorator to be valid than it does remove the decorator and expect the naked identifier to be valid. ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/DKU5YRG42H222RK2EC7USUHB6O72HOXB/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Cleaner tracebacks from Python code
On Sat, May 29, 2021 at 3:38 PM Irit Katriel wrote: > See this issue: https://bugs.python.org/issue31299 > > This issue refers to https://bugs.python.org/issue16217 which talks about lines "above" the one of interest (compared with those that I describe as being "below"). It also talks about filtering some specific modules -- something I already do in one of my projects. Still, interesting to see; thanks for the link. > > > On Saturday, May 29, 2021, 07:19:32 PM GMT+1, André Roberge < > andre.robe...@gmail.com> wrote: > > > With CPython, tracebacks obtained from code written in C can be extremely > clean compared with functionally equivalent code written in Python. > Consider the following test file where I am using a local copy of Python's > datetime.py module. > > ```py > from local_datetime import date > d = date(2021, 13, 1) > ``` > > Executing this code results in the following, very "clean" traceback: > ```pytb > Traceback (most recent call last): > File "test.py", line 2, in > d = date(2021, 13, 1) > ValueError: month must be in 1..12 > ``` > > A single line of code is shown, which is the one written by the end-user > of this library; all code details from inside the library module are hidden. > > As it turns out, the datetime module imports (if it is available) the > _datetime module written in C. If we comment out this import, so that the > pure Python code is used instead, > here is the new traceback: > > ```pytb > Traceback (most recent call last): > File "test.py", line 2, in > d = date(2021, 13, 1) > File "C:\Users\andre\local_datetime.py", line 847, in __new__ > year, month, day = _check_date_fields(year, month, day) > File "C:\Users\andre\local_datetime.py", line 422, in _check_date_fields > raise ValueError('month must be in 1..12', month) > ValueError: ('month must be in 1..12', 13) > ``` > > In addition to the call by the end-user of that library, we see some inner > code of that library that has no practical value to the end-user. > > We can suppress some lines of the traceback by replacing the line > > ```py > year, month, day = _check_date_fields(year, month, day) > ``` > by > ```py > try: > year, month, day = _check_date_fields(year, month, day) > except Exception: > _, _, tb = sys.exc_info() > tb.tb_next = None > raise > ``` > > which simplifies the traceback somewhat: > ```pytb > Traceback (most recent call last): > File "test.py", line 2, in > d = date(2021, 13, 1) > File "C:\Users\andre\local_datetime.py", line 848, in __new__ > year, month, day = _check_date_fields(year, month, day) > ValueError: ('month must be in 1..12', 13) > ``` > but there is still one line of code from inside the library. > === > Idea: it would be nice if one could somehow define **callables** with a > custom attribute that > would indicate that tracebacks should not include frames "below" it. > More explicitly, using the notation of the above example, imagine that we > could write > > ```py > date.__hide_tb__ = True > ``` > and that any call to `date()` that generate a traceback would not show > frames below the > calling frame, thus reproducing what we see when using the C code in this > example. > For library writers, this would be easily reverted when attempting to > debug. > For end users, this would result in much more readable tracebacks, > unencumbered by extra lines of code that are outside of their control. > > André Roberge > > > > > > > > > ___ > Python-ideas mailing list -- python-ideas@python.org > To unsubscribe send an email to python-ideas-le...@python.org > https://mail.python.org/mailman3/lists/python-ideas.python.org/ > Message archived at > https://mail.python.org/archives/list/python-ideas@python.org/message/WQN7QJUVV62IO3J7ALOJYHS6URYVRDFD/ > Code of Conduct: http://python.org/psf/codeofconduct/ > ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/3XCRIWFK6NB6WCY3KJZZXNI2TSDMH7WF/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Cleaner tracebacks from Python code
See this issue: https://bugs.python.org/issue31299 On Saturday, May 29, 2021, 07:19:32 PM GMT+1, André Roberge wrote: With CPython, tracebacks obtained from code written in C can be extremely clean compared with functionally equivalent code written in Python. Consider the following test file where I am using a local copy of Python's datetime.py module. ```pyfrom local_datetime import date d = date(2021, 13, 1) ``` Executing this code results in the following, very "clean" traceback:```pytbTraceback (most recent call last): File "test.py", line 2, in d = date(2021, 13, 1) ValueError: month must be in 1..12 ``` A single line of code is shown, which is the one written by the end-user of this library; all code details from inside the library module are hidden. As it turns out, the datetime module imports (if it is available) the _datetime module written in C. If we comment out this import, so that the pure Python code is used instead,here is the new traceback: ```pytbTraceback (most recent call last): File "test.py", line 2, in d = date(2021, 13, 1) File "C:\Users\andre\local_datetime.py", line 847, in __new__ year, month, day = _check_date_fields(year, month, day) File "C:\Users\andre\local_datetime.py", line 422, in _check_date_fields raise ValueError('month must be in 1..12', month) ValueError: ('month must be in 1..12', 13) ``` In addition to the call by the end-user of that library, we see some inner code of that library that has no practical value to the end-user. We can suppress some lines of the traceback by replacing the line ```pyyear, month, day = _check_date_fields(year, month, day) ```by```pytry: year, month, day = _check_date_fields(year, month, day) except Exception: _, _, tb = sys.exc_info() tb.tb_next = None raise ``` which simplifies the traceback somewhat:```pytbTraceback (most recent call last): File "test.py", line 2, in d = date(2021, 13, 1) File "C:\Users\andre\local_datetime.py", line 848, in __new__ year, month, day = _check_date_fields(year, month, day) ValueError: ('month must be in 1..12', 13) ```but there is still one line of code from inside the library.===Idea: it would be nice if one could somehow define **callables** with a custom attribute thatwould indicate that tracebacks should not include frames "below" it.More explicitly, using the notation of the above example, imagine that we could write ```pydate.__hide_tb__ = True```and that any call to `date()` that generate a traceback would not show frames below thecalling frame, thus reproducing what we see when using the C code in this example.For library writers, this would be easily reverted when attempting to debug.For end users, this would result in much more readable tracebacks, unencumbered by extra lines of code that are outside of their control. André Roberge ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/WQN7QJUVV62IO3J7ALOJYHS6URYVRDFD/ Code of Conduct: http://python.org/psf/codeofconduct/ ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/3HJEEPE7JPDE7N23HQVDP6YNR25E4TRI/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Cleaner tracebacks from Python code
pytest uses __tracebackhide__ https://doc.pytest.org/en/latest/example/simple.html#writing-well-integrated-assertion-helpers Eg anyio sets __tracebackhide__ = __traceback_hide__ = True to remove internal frames from user Tracebacks On Sat, 29 May 2021, 19:21 André Roberge, wrote: > With CPython, tracebacks obtained from code written in C can be extremely > clean compared with functionally equivalent code written in Python. > Consider the following test file where I am using a local copy of Python's > datetime.py module. > > ```py > from local_datetime import date > d = date(2021, 13, 1) > ``` > > Executing this code results in the following, very "clean" traceback: > ```pytb > Traceback (most recent call last): > File "test.py", line 2, in > d = date(2021, 13, 1) > ValueError: month must be in 1..12 > ``` > > A single line of code is shown, which is the one written by the end-user > of this library; all code details from inside the library module are hidden. > > As it turns out, the datetime module imports (if it is available) the > _datetime module written in C. If we comment out this import, so that the > pure Python code is used instead, > here is the new traceback: > > ```pytb > Traceback (most recent call last): > File "test.py", line 2, in > d = date(2021, 13, 1) > File "C:\Users\andre\local_datetime.py", line 847, in __new__ > year, month, day = _check_date_fields(year, month, day) > File "C:\Users\andre\local_datetime.py", line 422, in _check_date_fields > raise ValueError('month must be in 1..12', month) > ValueError: ('month must be in 1..12', 13) > ``` > > In addition to the call by the end-user of that library, we see some inner > code of that library that has no practical value to the end-user. > > We can suppress some lines of the traceback by replacing the line > > ```py > year, month, day = _check_date_fields(year, month, day) > ``` > by > ```py > try: > year, month, day = _check_date_fields(year, month, day) > except Exception: > _, _, tb = sys.exc_info() > tb.tb_next = None > raise > ``` > > which simplifies the traceback somewhat: > ```pytb > Traceback (most recent call last): > File "test.py", line 2, in > d = date(2021, 13, 1) > File "C:\Users\andre\local_datetime.py", line 848, in __new__ > year, month, day = _check_date_fields(year, month, day) > ValueError: ('month must be in 1..12', 13) > ``` > but there is still one line of code from inside the library. > === > Idea: it would be nice if one could somehow define **callables** with a > custom attribute that > would indicate that tracebacks should not include frames "below" it. > More explicitly, using the notation of the above example, imagine that we > could write > > ```py > date.__hide_tb__ = True > ``` > and that any call to `date()` that generate a traceback would not show > frames below the > calling frame, thus reproducing what we see when using the C code in this > example. > For library writers, this would be easily reverted when attempting to > debug. > For end users, this would result in much more readable tracebacks, > unencumbered by extra lines of code that are outside of their control. > > André Roberge > > > > > > > > > ___ > Python-ideas mailing list -- python-ideas@python.org > To unsubscribe send an email to python-ideas-le...@python.org > https://mail.python.org/mailman3/lists/python-ideas.python.org/ > Message archived at > https://mail.python.org/archives/list/python-ideas@python.org/message/WQN7QJUVV62IO3J7ALOJYHS6URYVRDFD/ > Code of Conduct: http://python.org/psf/codeofconduct/ > ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/MQIGFKW762O2BKXCA5HW7WVSQOI5DPHV/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Cleaner tracebacks from Python code
With CPython, tracebacks obtained from code written in C can be extremely clean compared with functionally equivalent code written in Python. Consider the following test file where I am using a local copy of Python's datetime.py module. ```py from local_datetime import date d = date(2021, 13, 1) ``` Executing this code results in the following, very "clean" traceback: ```pytb Traceback (most recent call last): File "test.py", line 2, in d = date(2021, 13, 1) ValueError: month must be in 1..12 ``` A single line of code is shown, which is the one written by the end-user of this library; all code details from inside the library module are hidden. As it turns out, the datetime module imports (if it is available) the _datetime module written in C. If we comment out this import, so that the pure Python code is used instead, here is the new traceback: ```pytb Traceback (most recent call last): File "test.py", line 2, in d = date(2021, 13, 1) File "C:\Users\andre\local_datetime.py", line 847, in __new__ year, month, day = _check_date_fields(year, month, day) File "C:\Users\andre\local_datetime.py", line 422, in _check_date_fields raise ValueError('month must be in 1..12', month) ValueError: ('month must be in 1..12', 13) ``` In addition to the call by the end-user of that library, we see some inner code of that library that has no practical value to the end-user. We can suppress some lines of the traceback by replacing the line ```py year, month, day = _check_date_fields(year, month, day) ``` by ```py try: year, month, day = _check_date_fields(year, month, day) except Exception: _, _, tb = sys.exc_info() tb.tb_next = None raise ``` which simplifies the traceback somewhat: ```pytb Traceback (most recent call last): File "test.py", line 2, in d = date(2021, 13, 1) File "C:\Users\andre\local_datetime.py", line 848, in __new__ year, month, day = _check_date_fields(year, month, day) ValueError: ('month must be in 1..12', 13) ``` but there is still one line of code from inside the library. === Idea: it would be nice if one could somehow define **callables** with a custom attribute that would indicate that tracebacks should not include frames "below" it. More explicitly, using the notation of the above example, imagine that we could write ```py date.__hide_tb__ = True ``` and that any call to `date()` that generate a traceback would not show frames below the calling frame, thus reproducing what we see when using the C code in this example. For library writers, this would be easily reverted when attempting to debug. For end users, this would result in much more readable tracebacks, unencumbered by extra lines of code that are outside of their control. André Roberge ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/WQN7QJUVV62IO3J7ALOJYHS6URYVRDFD/ 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] Re: dict.sort()?
On Sun, May 30, 2021 at 2:57 AM Marco Sulla wrote: > > Since `dict` now is ordered, how about a `sort()` method? > It could have the same signature of list.sort(), with an optional > parameter "by" that can be "keys" or "values" ("keys" could be the > default). Not really a thing - if you want that level of flexibility, try OrderedDict, which lets you move elements around. But if you're okay with constructing a new dict, you can do this: d = dict(sorted(d.items(), key=lambda kv: ...)) Your key function will receive a tuple of the key and the value. If you don't provide one, default tuple sorting will effectively sort the elements by their keys - probably a good default. ChrisA ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/XA5JDSWRDWQKZ722EHJJHABOIAWFZV4Q/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] dict.sort()?
Since `dict` now is ordered, how about a `sort()` method? It could have the same signature of list.sort(), with an optional parameter "by" that can be "keys" or "values" ("keys" could be the default). ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/XXA2E5ILMAEMFLPWZIZN3T67FERJPBFF/ 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: A __decoration_call__ method for Callable objects (WAS: Decorators on variables)
> > I just thought it looked better, but would you and others here like it > better if the > NEWLINE requirement was kept for all decorators? There is nothing in the > original > proposal that requires a single line. > I also don't know what should happen for complicated assignments, and I > think this > has been the death of such variable decorator discussions in the past, so > I would > still push for only bare identifiers, with or without a type hint (but > maybe it will be > better received by more if the type hint is required?). I still think such > a proposal is > strong enough on its own to be of value to the language. > > So now the syntax would be: > > @decorator > variable: Type > > @decorator("spam", eggs) > variable: Type > > become > > variable = decorator("variable") > > variable = decorator("spam", eggs)("variable") > > I'm not sure that the type hint shouldn't be passed as an additional > parameter, > especially if one is always required. Yes it is still different from a > function > decorator in that you are not getting the variable object (which may or > may not > exist) but instead its name as a string. However, decorators that expect > to be > applied to variables should already be drastically different. Even if they > did get > the variable object, there would be not necessarily be a __code__ or > __name__ or __dict__ attribute. They won't be callable (generally) where > most > current decorators attempt to call func, wrapped in an internal closure. > I think there's a fundamental difference between your original proposal and the OPs proposal in this thread, which is that you seem to envision variable decorators as granting access to just a name (and potentially a type-hint?), whereas the OP wants the decorators extended to assignment in general. Basically, your proposal is a subset of the OPs proposal. Any implementation of the OPs decorators would also allow us to do all the things you want to be able to do with variable decorators (as a happy side-effect), but would also offer a LOT more functionality. My view is that variable decorators should be legal for: 1) assignment statements (so that the decorator can modify or replace the object that is getting assigned) 2) bare type-hints, since these are arguably *a sort of* assignment operation that still carries useful info a decorator might want to capture (you're not assigning the name and its value to globals(), but rather the name and its type to globals()['__annotations__']) If there was huge pushback against point 2 I'd be happy to see it deferred and revisit it at a later point, but as far as I'm concerned point 1 is what actually interests me about this proposal. Your point about complicated assignment being a problem seems solvable using the following rules: 1) Variable decorators only capture the name (or names) on the LHS of a true assignment statement (or bare type-hint). Expressions that happen to bind names (such as the walrus operator, for loop, etc.) don't have their names available for use in the decorator. 2) The proposed __decoration_call__ is given the value, name, and type-hint from the decorated statement (and potentially the code object from the RHS, as OP suggested). We could provide the names as a series of useful pre-parsed parsed AST-like objects, like: @decorate some_obj.foo = first, _, third, *some_obj.rest = some_dict[(lost_name := ('ba' + 'r'))] = baz = (another_lost_name := [0, 1, 2, 3, 4]) such that __decoration_call__ receives: def __decoration_call__(self, obj, names, annotation): print(obj) # [0, 1, 2, 3, 4] print(names) # ParsedNames(names=[ # ObjectAssignment(obj={reference_to_some_obj}, name='foo'), # DestructuringAssignment(names=[ # BasicAssignment(name='first'), # BasicAssignment(name='_'), # BasicAssignment(name='third'), # ObjectAssignment(obj={reference_to_some_obj}, name='*rest') # ]), # ItemAssignment(obj={ref_to_some_dict}, name='bar'), # BasicAssignment(name='baz') # ]) print(annotation) # NOTSET Notice that as per point 1 above, `lost_name` and `another_lost_name` do not get captured, because they are not part of the assignment statement. They're only sub-expressions. Also, notice that expressions like 'ba' + 'r' are evaluated before being passed to the decorator, so that it actually receives 'bar' for the __setitem__ assignment name. 3) Augmented assignment gets expanded out to its true meaning before being passed to the decorator, so for example: foo = 3 @decorate foo += 2 behaves exactly the same as: foo = 3 @decorate foo = foo + 2 If there are still any issues given these rules that I can't think of I'd be happy for people to raise them. There are so many edge-cases in python assignment that I could very easily be forgetting about something. But I think this covers 99% of cases. class Colors(Enum): > @str > RED: str > @str >
[Python-ideas] Re: Introduce constants in Python (constant name binding)
Now it seems Python doesn’t need constant. There are many ways we can achieve constants. Though constants may increase performance. Yet again it can also be the opposite. From: Paul Sokolovsky Sent: Saturday, May 29, 2021 12:44:09 AM To: Shreyan Avigyan Cc: python-ideas@python.org Subject: [Python-ideas] Re: Introduce constants in Python (constant name binding) Hello, On Tue, 25 May 2021 11:53:20 - "Shreyan Avigyan" wrote: > I posted my previous idea regarding this on the mailing list. This > idea is a little different. This idea suggests introducing constant > name bindings. This is similar to const pointer in C/C++. Once a name > has been assigned to a data we can change the data (if mutable) but > we cannot change the name to point to a different data. The only way > the data the constant points can get deallocated is if it goes out of > scope, the program exits or the constant is manually `del` by the > user. The proposed syntax is as follows, > > constant x = 10 > constant y = ["List"] > constant z: str = "Hi" The idea of introducing constants on the core language level in Python is well-known topic and was brought up on multiple occasions both on the python-ideas and python-dev mailing lists. A random example: https://www.mail-archive.com/python-dev@python.org/msg110424.html "constants in Python: Starting simple and gradually adding more features, was: Re: Pattern Matching controversy" The matter is actually implementing it in different Python implementations. And some implementations had support for *some kind* of constants for many years (e.g. MicroPython with it's pre-annotation syntax of "FOO = const(1)"), while CPython still has it only on the level of external first-generation annotation module, "typing". As another example, I can give "strict mode" (https://www.mail-archive.com/python-ideas@python.org/msg25403.html) feature of my Python dialect, Pycopy (https://github.com/pfalcon/pycopy), which implements some (but again, not all) aspects of const'ness. E.g.: === print("In import-time") a: const = 1 a: const = 2 def __main__(): print("In run-time") global a a = 3 === Gives: In import-time Warning: strict mode: overriding (monkey-patching) const name 'a' In run-time Traceback (most recent call last): File "strict.py", line 9, in __main__ RuntimeError: strict mode: cannot override const name -- Best regards, Paul mailto:pmis...@gmail.com ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/PHU3YE47SI55JODFG3W53GZIJK6IH4FL/ Code of Conduct: http://python.org/psf/codeofconduct/ ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/5UU3IYKZZ5Z5WZQH2DKJILKYVVYRRDJQ/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Add static variable storage in functions
On Fri, May 28, 2021 at 07:37:57PM -0700, Brendan Barnwell wrote: > I see your point, but I don't agree that static function variables > are parallel to either closures or generators. Okay, this is an important point, I think. I argue that some sort of sugar for static storage in functions is exactly analogous to closures and generators. The history of Python demonstrates a pattern of using classes for complex data structures with state and *multiple* behaviours (methods), while using functions for the simple cases where you have only a single behaviour and a small amount of state, without the anti-pattern of global variables. Closures, generators and coroutines are all ways of doing this. > Closures are, to my mind, just an outgrowth of Python's ability to > define functions inside other functions. If you're going to allow such > nested functions, you have to have some well-defined behavior for > variables that are defined in the other function and used in the inner > one, and closures are just a reasonable way to do that. When closures and lexical scoping were first introduced, they were intentionally and explicitly limited because classes could do everything that closures can. Here is the history of the feature. Python didn't gain closures until version 2.1 (with a future import): https://www.python.org/dev/peps/pep-0227/ Before then, nested functions behaved quite differently. This is Python1.5: >>> x = "outside" >>> def function(): ... x = "inside" ... def inner(): ... print x ... inner() ... >>> function() outside That's a simple, reasonable behaviour. Inner functions were allowed by the language but they didn't add much functionality and consequently were hardly ever used. Lexical scoping changed that, and made inner functions much more useful. At the time people wanted a way to rebind nonlocal variables, but that was explicitly rejected because: "this would encourage the use of local variables to hold state that is better stored in a class instance" https://www.python.org/dev/peps/pep-0227/#id15 That comment has aged like milk. By the time Python 2.3 and 2.4 came along and people were talking about some future "Python 3000", it had already become clear that it would be useful to rebind nonlocal names and hold state encapsulated in a function without going to all the trouble of creating a class. And so in Python 3 we gained the nonlocal keyword and the ability to store and modify state in a closure. The proposed static statement would be sugar for functionality already possible: storing per function data in the function without needing to write a class. Classes are great, but not everything is a nail that needs to be hammered with a class. > As for generators, they are tied to iteration, which is a > pre-existing concept in Python. Generators provide a way to make your > own functions/objects that work in a `for` loop in a manner that > naturally extends the existing iteration behavior of lists, tuples, > etc. We already had a way to create our own iterable values: classes using the sequence or iterator protocols. Iteration using `__getitem__` and IndexError was possible all the way back to Python 1.x. The iterator protocol with `__iter__` and `__next__` wasn't introduced until 2.2 (and originally the second dunder was spelled `next`). https://www.python.org/dev/peps/pep-0234/ Generators were also introduced in 2.2, explicitly as a way for functions to *hold state from one call to the next*: https://www.python.org/dev/peps/pep-0255/ The motivation section of the PEP starts with this: "When a producer function has a hard enough job that it requires maintaining state between values produced, most programming languages offer no pleasant and efficient solution ..." and goes on to discuss alternatives such as functions with global state. (Global variables.) One alternative left out is to write a class, possibly because everyone acknowledged that writing a single function with its own state is so obviously superior to a class for solving this sort of problem that nobody bothered to list it as an alternative. (You *can* spread butter on bread using a surf board, but why would you even try when you have a butterknife?) The next step in the evolution of function-local state was to make generators two-way coroutines. (Alas, the name "corountine" has been hijacked by async for a related but different concept, so there is some unavoidable terminology confusion here.) https://www.python.org/dev/peps/pep-0342/ Generators now have send and throw methods, even when you can't use them for anything useful! >>> g = (x+1 for x in range(10)) >>> g.send >>> g.throw So that's yet another unobvious way to get static storage in a function: use a PEP 343 enhanced generator coroutine.