8 ms·
What's New in Python 3.12
- didip 3y agoThe number on the performance improvements are pretty good. I like this release.
- reallymental 3y agoI've been using python for the past 10+ years, and I've got to say that the new Syntactic formalization of f-strings (PEP 701) has got to be one of the most "huh?" changes I've seen in a while. Was this such a big problem? In my experience, the GIL, faster start-up times are so much higher on the totem pole, why this now?
- __s 3y agoIt's a small problem with a small solution
- masklinn 3y agoBecause someone got annoyed enough to write a pep then implement it? Python is not a company and GvR is not a CEO handing out marching orders from on high. Hell, personal testimony, I don't give a rat's ass about the GIL or start-up times, but f-string limitations are a daily pain in the ass. So I'm absolutely grateful for whoever worked on this and looking forward to it.
- atxbcp 3y agoAnd in my experience, nesting f-strings and using quotes in f-strings is more useful than the GIL and faster start-up times, so YMMV.
- jwkane 3y agoTwo reasons seem obvious. F-strings are relatively new -- the code is maturing and the edge cases are being filled in. Second, everyone can't be working on the GIL and start-up times. There is a tipping point at a relatively low head count where adding developers decreases productivity.
- martinky24 3y agoIt's an open source project. If a developer wants to go out of their way to make a really cool improvement, goes through the approval process, has a clean implementation that doesn't add any backwards incompatibilities, why do you care? This isn't some private company where management tells people what to do and they have to do it. People are so out of touch with how OSS, and the volunteer maintainers that operate it, work. It's a shame. The sense of entitlement in a subset of the userbase ("Why aren't they fixing MY issues RIGHT NOW!") is mindblowing.
- 9967d2cad_askhn 3y agoNo. You’re missing one constituent part of a for-profit corporate-backed language platform. You cannot just step in the ring with Ali because you think you can box. Politics, other forces, compellation will emerge as a stronghold barrier to your meritocratical hopes and dreams.
- makr17 3y ago"Due to the changes in PEP 701, producing tokens via the tokenize module is up to 64% faster."
- thrdbndndn 3y agoPerformance improvement is obviously nice but I personally don't even care about it. Being able to just use any quotes in f-strings is just godsend QOL change and probably would be the biggest reason I upgrade to 3.12 (for my pet project).
- gnulinux 3y agoMakes the grammar simpler which makes new implementations to implement tokenizer much faster/cheaper. It's a simple problem with simple solution that has been causing a medium sized issue, so why not fix it?
- klyrs 3y agoNot everybody needs to work on the biggest problem, that's the "waterfall" approach to project management. If CPython was a single-developer project, that might be a valid criticism, but it's not. For me that formalization is nice because they've brought f-strings into the PEG parser which can point at the precise location of a syntax error. I'm wary of the implications of arbitrarily nested f-strings for legibility... but oh well.
- mmebane 3y agoIt's a nice quality of life improvement. Most other languages I've used with some form of string interpolation allow quotes in nested expressions to be the same as the quotes on the top-level string, and this has IMO been a weird wart in Python. I'm happy to see it fixed.
- h4l 3y agoA few releases back they replaced the python parser with a more capable PEG parser. At the time nothing really changed, but it was done to enable this kind of improvement and make it practical to evolve the syntax over time. This change isn't so much done for the sake of being able to next quotes in f-strings, it's done because there was a dedicated extra parser for the python syntax inside f-strings, but with the new parser this can be parsed without this special case extra parser. It's all to manage technical debt.
- serjester 3y agoAs a data scientist using dataframes, I'll often do print(f"Total for X is {df["col"].sum()}"). It's annoying to have to remember to switch the type of quotation mark to avoid a crash. I suspect, a lot of people that spend time in jupyter notebooks are in the same boat. You could argue I should be setting a variable but these are experimental scripts and it's annoying. I welcome it!
- Tommstein 3y ago> In my experience, the GIL, faster start-up times are so much higher on the totem pole, why this now? Are you aware that more than one change can be worked on at a time?
- bjornasm 3y agoYeah, I find it a bit telling that they had to show completely ridiculous toy examples: >f"""{f'''{f'{f"{1+1}"}'}'''}"""
- BoumTAC 3y agoWhat I would love to see in a future version of python is being able to do `user["email"]` or `user.email` independently of the reason. Sometimes both work, sometimes only one of the two and an error in throw for the other one. I don't care why, I just want it to work, it's such a basic feature. Something even crazier would be to have an equivalent of `console.log` in python. It would be an amazing feature but I think I'm the only one wanting it. I know I can use `print` or different logger. But it's a lot more complicated to use and the output is a lot less navigable than in javascript. PHP also has `var_dump`. But we don't have any equivalent in python.
- masklinn 3y ago> What I would love to see in a future version of python is being able to do `user["email"]` or `user.email` independently of the reason. Sometimes both work, sometimes only one of the two and an error in throw for the other one. I don't care why, I just want it to work, it's such a basic feature. It's an absolutely terrible idea and I'm thankful that there's so little chance it'll ever happen. I don't want random objects to become mappings, nor do I want mapping entries and their attributes to conflict. Javascript is a bad language and this is one of its worst features. > Something even crazier would be to have an equivalent of `console.log` in python. It would be an amazing feature but I think I'm the only one wanting it. I know I can use `print` or different logger. But it's a lot more complicated to use and the output is a lot less navigable than in javascript. You... can just call `logging.whatever()`, after having called `logging.basicConfig()` to set up your basic config? I fail to see how that would change anything to navigability. `console.log` is not inherently navigable, it's the browser's console UI which provides some navigability.
- __s 3y agohttps://docs.python.org/3/library/functions.html#dir https://docs.python.org/3/library/functions.html#dir
- jwkane 3y agoIf you want to write javascript, use javascript. There are ways to get what you're asking for depending on your use case. types.SimpleNamespace in the standard library provides one approach. "There should be one-- and preferably only one --obvious way to do it." (zen of python) I do agree that python logging is a weak point. It is too easy to do it wrong -- particularly when you are a few modules deep.
- gnulinux 3y agoPEP 695 is great. I've been using mypy every day at work in last couple years or so with very strict parameters (no any type etc) and I have experience writing real life programs with Rust, Agda, and some Haskell before, so I'm familiar with strict type systems. I'm sure many will disagree with me but these are my very honest opinions as a professional who uses Python types every day: * Some types are better than no types. I love Python types, and I consider them required. Even if they're not type-checked they're better than no types. If they're type-checked it's even better. If things are typed properly (no any etc) and type-checked that's even better. And so on... * Having said this, Python's type system as checked by mypy feels like a toy type system. It's very easy to fool it, and you need to be careful so that type-checking actually fails badly formed programs. * The biggest issue I face are exceptions. Community discussed this many times [1] [2] and the overall consensus is to not check exceptions. I personally disagree as if you have a Python program that's meticulously typed and type-checked exceptions still cause bad states and since Python code uses exceptions liberally, it's pretty easy to accidentally go to a bad state. E.g. in the linked github issue JukkaL (developer) claims checking things like "KeyError" will create too many false positives, I strongly disagree. If a function can realistically raise a "KeyError" the program should be properly written to accept this at some level otherwise something that returns type T but 0.01% of the time raises "KeyError" should actually be typed "Raises[T, KeyError]". * PEP 695 will help because typing things particularly is very helpful. Often you want to pass bunch of Ts around but since this is impractical some devs resort to passing "dict[str, Any]"s around and thus things type-check but you still get "KeyError" left and right. It's better to have "SomeStructure[T]" types with "T" as your custom data type (whether dataclass, or pydantic, or traditional class) so that type system has more opportunities to reject bad programs. * Overall, I'm personally very optimistic about the future of types in Python! [1] https://github.com/python/mypy/issues/1773 https://github.com/python/mypy/issues/1773 [2] https://discuss.python.org/t/extend-type-hints-to-cover-exceptions/23788/4 https://discuss.python.org/t/extend-type-hints-to-cover-exce...
- dragonwriter 3y ago> If a function can realistically raise a "KeyError" the program should be properly written to accept this at some level By definition, it is, because there is defined behavior for unhandled exceptions. If you want to—and this is a valid preference—wrap all exceptions thrown at a lower level and present an API where they are part of the return type that must be addressed by code to pass typechecking, then you do that and return actual values of an appropriate type (you can still use exception types, if you wish) instead of raising exceptions. Exceptions which you force client code to handle to typecheck are not exceptions, they are return values and should be converted to explicitly that, rather than adding checked exceptions.
- flakes 3y agohttps://docs.python.org/3/whatsnew/3.12.html#whatsnew312-pep692 https://docs.python.org/3/whatsnew/3.12.html#whatsnew312-pep... "PEP 692: Using TypedDict for more precise *kwargs typing" seems pretty great. That'll be really helpful for nested method calls which proxy a lot of their arguments along. I can also see that helping out when creating stub libraries.
- chrismorgan 3y ago… but the Unpack[…] wrapping required is awful, required because they initially defined kwargs type annotations in a rather baffling way. (I don’t know about others, but it was obvious to me from the start that the way the *args and **kwargs type annotations refer to the sequence values rather than the args/kwargs bindings was always going to cause confusion, and was very likely to cause problems down the line when they wanted more precise typing; and that day has arrived for kwargs, no idea if they have any plans for similar on args, which is sometimes useful. They should just have required `*args: List[T], **kwargs: Dict[str, T]` from the start.)
- SushiHippie 3y agoIs there a reason this is on the frontpage, were there updates? Because 3.12 is out since two weeks. Am I missing something?
- hbcondo714 3y agoNot sure but Python 3.12 was indeed discussed here on HN a couple weeks ago with 600+ upvotes and 300+ comments: https://news.ycombinator.com/item?id=37737519 https://news.ycombinator.com/item?id=37737519
- NoboruWataya 3y agoI suspect people will use these comments to share their wishlist of Python features, so let me add that I really wish Python had a safe navigation operator, for when you are dealing with nested objects that could be None. I have been trying to parse a lot of XML and JSON in Python lately and a feature like that could really help reduce boilerplate checks. https://en.wikipedia.org/wiki/Safe_navigation_operator https://en.wikipedia.org/wiki/Safe_navigation_operator
- nullwarp 3y agoWhile not as short as a proper operator .get("key", {}) does work.
- woolion 3y agoOf course this only works at one level and not arbitrarily deeply, but you still need to check for None with this code; it may actually be better to write `x.get("key") or {}` so that you always get an empty dict. I write 'may' because the difference between None and an empty dict may be very subtle and rarely does the API specify with enough precision what are supposed to be the semantics of each case.
- ddejohn 3y ago> Of course this only works at one level and not arbitrarily deeply It does though, you can chain as many of these as you want: some_dict.get("level_1_key", {}).get("level_2_key", {}).get("level_3_key", {})... edit: >> but you still need to check for None with this code > Not sure what you mean here. You only have to check for None if you use `.get("key")` and don't provide a fallback value. GP was talking about `{"foo": None}` and trying to drill deeper, which I misunderstood. Still, a simple try/except allows you to short-circuit the deeply nested access.
- smilliken 3y agoThe issue is if the dictionary has a key defined and the value is None. Your get expression will return None, causing your next access to raise an error.
- kkielhofner 3y agoShameless self-plug but with my project Willow[0] we have a management server implementation to deal with multiple devices, etc. We have a new feature called "Willow One Wake" that takes the incoming audio amplitude when wake word is detected and uses our Willow Application Server (python) to only activate wake on the device closest to the person speaking. Old and tired compared to the commercial stuff but a first in the open source space. The asyncio improvements in Python 3.12 especially (plus perf generally) have been instrumental in enabling real world use of this. With Python 3.12 asyncio, uvloop, and FastAPI it works remarkably well[1]. As the demo video shows not only does it not delay responsiveness, it has granularity down to inches. [0] - https://heywillow.io/ https://heywillow.io/ [1] - https://youtu.be/qlhSEeWJ4gs https://youtu.be/qlhSEeWJ4gs
- bnchrch 3y ago[flagged]
- pjmlp 3y agoIt is a great language for UNIX scripting, unless one happens to still live in Perl world, and a good enough modern replacement for BASIC.
- vitorsr 3y agoI find the feature-happy kitchen sink product philosophy in programming languages quite insufferable. It has become an unpleasant chore to keep up with PEP squabbles and accepted changes.
- xxpor 3y agoWhy do you have to keep up with them?
- penguin_booze 3y agoOn the principle that it works best when you know your tools. The lament is about the features piling up at such fast pace--and of questionable utility, too--that it's exhausting to keep up/master over. You go for a vaccation, and the language you once knew, mastered, and loved, has left you behind. On the utility of features, the arbitraty nesting of f-strings stands out. Why in tarnation would anyone need such nesting? Isn't it simpler and readable to keep non-trivial expressions out of the f-string itself?
- Denvercoder9 3y ago> Isn't it simpler and readable to keep non-trivial expressions out of the f-string itself? But then you have to define what non-trivial expressions are, and more importantly, people using the language have to learn that definition too. By having f-strings accept all valid expressions, the language actually becomes simpler.
- xxpor 3y agoThis sounds like a personal problem, honestly. Do you read every diff too? If not, you can't deeply think through the performance implications of how existing features are changing. What about the rest of your userland? No one expects anyone to do that.
- 9967d2cad_askhn 3y agoSo many breaking changes promulgated with covert version numbers—an unfortunate truth for Python and why the writing on the wall is clear—Python is not dependable—Go is the safer choice for business applications and services.
- Doxin 3y ago> So many breaking changes promulgated with covert version numbers This has been the new strategy to avoid another python2-python3 debacle. As long as you're aware it's not semver and minor versions can have breaking changes it's no biggie.
- pjmlp 3y agoJava and C# are much safer options, with almost 30 years of deployment production, and an ecosystem of programming languages across the JVM/ART and CLR, that aren't afraid to let programmers express themselves.
- deleted 3y ago[deleted]
- deleted 3y ago[deleted]
- thatxliner 3y ago“The new syntax allows declaring TypeVarTuple and ParamSpec parameters, as well as TypeVar parameters with bounds or constraints:” ``` ... type IntOrStrSequence[T: (int, str)] = Sequence[T] # TypeVar with constraints ``` Why can’t the syntax be ``` type IntOrStrSequence[T: int | str] = Sequence[T] ```
- bayangan 3y agoI think because that conflicts with the `bound` syntax which expects a single type.
- thatxliner 3y agoUnless I’m mistaken, bound constrains the type to a specific protocol while this constrains the type to specific types.
- samtheprogram 3y ago> Of note, the distutils package has been removed from the standard library. How is this not a major version change if a module is removed from the standard library? Other breaking changes too. This is confusing to me.