1. 41
  1. 36

    Ah, Python for Workgroups :-)

    1. 2

      I was thinking “Beautiful disaster” but that works too.

    2. 8

      It’s really nice when languages announce better error messages! The more that languages approach or improve on the quality of their error messages, the better off everyone is because it helps train developers to really read the error messages because they’ve learned to expect error messages to be useful!

      1. 5

        when is python losing the GIL?

        1. 4

          Until somebody comes up with a way to somehow get C extensions to work without the GIL or make the old C extension interface that requires the GIL a second-class citizen, probably not any time soon. Sam Gross’s nogil branch looks very promising, but it’s not there yet.

          I’m looking forward to it, but it’s going to break a lot of people’s code, because far too many people implicitly depend on the GIL in their pure Python code. A good example is all the people who mistakenly use collections.deque for interthread communication, who are going to get a rude awakening when their code on a GIL-less Python interpreter starts having lots of race conditions.

          1. 1

            There was a relatively promising update on nogil efforts built on Python 3.9. I wonder what happened since–if core devs are interested in the pieces being brought up to date with current Python and landed.

            1. 4

              It looks like at least some ideas from the nogil effort are making their way into CPython. There’s been a PEP recently targetting 3.11 about introducing immortal objects. That’s one of the ideas from the nogil fork.

              Personally, I think multiple interpreters combined with per-interpreter GIL is a more feasible path forward as it doesn’t entail breaking (as many) C-extensions.

          2. 2

            Also slated for 3.11 is ARM64 support for Windows!

            1. 2

              PEP 654 … introduces ExceptionGroups. With them, we’re able to raise multiple exceptions simultaneously

              I’m not familiar with the pattern of raising multiple exceptions. What other languages support this? I’m interested to see where and how they become useful.

              try:
                  raise ExceptionGroup("Validation Errors", (
                      ValueError("Input is not a valid user name."),
                      TypeError("Input is not a valid date."),
                      KeyError("Could not find associated project.")
                  ))
              except* (ValueError, TypeError) as exception_group:
                  ...
              except* KeyError as exception_group:
                  ...
              
              1. 4

                The ExceptionGroups has primarily been introduced to support proper error handling in the asyncio TaskGroups

                1. 1

                  That’s interesting. In Go, I have a multierror that I use to consolidate errors when running concurrent gorountines. Of course, errors are just a normal interface in Go, so it’s pretty easy to just add an Error method to a slice of errors. It doesn’t need any special language support.

                  I wrote a gist to try to combine Python exceptions once, but it was sort of a kludge. It’s nice that it will be a first class thing now.

                  1. 1

                    That’s basically what asyncio.gather() already does, but PEP 654 exists to make the process less cumbersome.

                2. 3

                  It’s not built-in, but if I’m understanding the feature correctly it wouldn’t be difficult to do with Common Lisp conditions.

                  1. 1

                    This reminds me a bit of pydantic: if you have errors in your model it should give you multiple validation errors instead of blowing up on the first one. Maybe it would also be useful in that context?

                    1. 4

                      I don’t think it’s for that use case. Within a single library, you can do:

                      from typing import List
                      
                      class ValidationError:
                          line_number: int
                          reason: str
                      
                      class ValidationErrors(Exception):
                          errors : List[ValidationError]    
                      

                      So based on above discussion it sounds like it’s more about combinations of multiple different exceptions.

                      1. 2

                        Django’s forms library has something similar; instead of forms having a potential attached error, they have a a potential list of attached errors, produced by catching and collecting every django.forms.ValidationError raised during the validation process.

                        1. 1

                          Seeing as we’re talking about new features in recent versions of Python, you don’t need from typing import List anymore, since 3.9 you can just write:

                          class ValidationErrors(Exception):
                              errors: list[ValidationError]
                          
                          1. 1

                            Good to know! And I guess I actually have one project where I can use Python 3.9 features, but everything else only just dropped 3.6. Going to be a while…

                            1. 1

                              TIL that you can do from __future__ import annotations as of Python 3.7 for this.

                      2. 2
                        class Shape:
                            def set_scale(self, scale: float) -> Self:
                                self.scale = scale
                                return self
                        

                        Is returning self for chaining? Like I want to do

                        shape = Shape().set_scale(1).set_diameter(3).rotate(7)?

                        1. 3

                          Can be used for copying as well. Also worth noting that it works well with subclasses, so for example if you define class Circle(Shape), set_scale() is marked to return a Circle, not a Shape that you’d get by using Shape as a return type in the set_scale() function. The PEP has a bunch of nice examples illustrating the uses.

                          1. 2

                            Yes, looks like it. This commonly occurs with Builder patterns.

                          2. 0

                            Two questions:

                            • what did they break this time?
                            • what’s up with the nuclear pasta in the release notes haha?