Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Touring More Changes

00:00 In the previous lesson, I demonstrated some new math items, a change to the regex library, and the array_hook argument to json.loads().

00:07 This lesson is a whirlwind tour of other features in Python 3.15. This next feature is a big deal, but takes a lot to properly demonstrate. As such, I’m not going to.

00:19 It isn’t just module loading that is lazy around here. If you want fast code, it’s a good idea to learn how to use a profiler. That’s a tool that shows you how long execution of each part of your code took.

00:31 CPython ships with a profiler called cProfile, which is a tracing profiler. That means each function call gets hooked, and you can see the timing data on all of them.

00:42 As you might imagine, that hooking is expensive. It’s useful to do when you’re debugging a performance issue, but not something you’d want to turn on in production.

00:51 Python 3.15 has added a new profiler. It lives in the profiling.sampling module and is codenamed Tachyon. If I’ve learned one thing from Star Trek, well, it’s never wear a red shirt.

01:03 If I’ve learned two things, it’s that tachyon pulses fix everything. Tachyon is a statistical sampling profiler. What that means is it takes a little sip of your code at predetermined intervals, checking out the current state of things on the stack. The result is very little overhead.

01:20 A long-running function will show up in a lot of those little visits, and so you can still find those problematic calls. On the other hand, short-lived calls might not show up at all.

01:31 That’s the downside. But the upside is you can run this in production without affecting your code’s performance. Depending on what you’re trying to track down, this is a lighter-weight tool for the job.

01:42 When you call open() on a text file, what encoding do you expect on the results? Well, unfortunately, the answer used to be, it depends. On Linux and macOS, you got UTF-8.

01:54 On Windows, you got

01:57 cp1252. And before you start snickering at those poor Windows devs, that UTF thing on Unix, well, there are situations where you might get ascii instead, like with certain kinds of shell scripts.

02:08 All of that is rather confusing. Python 3.15 has the answer, UTF-8 for all the places. You can still use the encoding argument to open() to be explicit, and there is a value you can pass in, locale, which invokes the previous behavior based on where the code is running, if that’s the way you want to do it.

02:29 Every Python release has additions to type annotations, and 3.15 is no different. When a type expression gets evaluated at runtime, it creates a type form object to contain the resulting information.

02:41 The new TypeForm type can be used to represent this data. See PEP 747 for full details on its usage. The TypedDict structure allows you to specify a dictionary with specific keys.

02:55 This can be useful to enforce things like the values available in a configuration file. Python 3.15 adds closed and extra_items arguments to TypedDict, allowing you to specify if new values can be added to the dictionary and if they can, what rules they have to conform to.

03:12 For a full list of the changes to type annotation, see the What’s New doc at python.org.

03:19 Okay, time for the speed round. Python 3.15 adds support for TOML 1.1. The new version of the spec allows trailing commas in lists, how very Pythonic of it, and newlines in inline tables.

03:33 The take_bytes() method on bytearray allows you to transfer data from a buffer to the caller without copying it. This is more efficient and useful for the low-level bit fiddlers.

03:44 A new method on asyncio.TaskGroup allows you to cancel all of the tasks associated with the group. And the wait() method for subprocesses has gone from using a polling loop to using event-driven timeouts inside of operating systems that support this mechanism.

04:00 This should mean more accurate response times when waiting on subprocess timeouts.

04:06 The speed round continues. The array module now supports half-floats (that’s 16-bit floating point) as well as complex floats. The binascii module has added a bunch of new encodings and has done some performance tweaking on the most common one, base64. Python isn’t just code, there’s also datasets inside of it.

04:28 New MIME types get added to the standard all the time, and Unicode folks are never sitting still. Python 3.15 adds more recent versions of this data to the release.

04:39 The pprint module now has more formatting options and supports the t-strings introduced in Python 3.14. The sys module has a new attribute, abi_info, which gives information about the interface extensions used.

04:53 And at risk of a massive oversimplification, work continues on free-threaded mode. In fact, that’s why abi_info got introduced. Work also continues on the JIT compiler.

05:04 Evidently, it’s coming along nicely, showing 10% performance improvements in a variety of cases. For a full list of improvements in the list, see the What’s New doc.

05:15 Releases aren’t just about in with the new, they’re also about out with the old. Some things have been deprecated and marked for removal in future releases.

05:24 With the addition of a new profiler, a new module structure was needed. There’s now a profiling module which has submodules for each of the profilers inside of it.

05:33 The original has been deprecated. Over a dozen modules in the code have version indicators in them. These will be going away in the future. Version information should be accessed from the sys module instead. ByteString was intended as an abstract parent for bytes and bytearray, but it never quite worked out that way, so it’s being removed.

05:55 Inside of the http.cookies module, Morsel.js_output() and BaseCookie.js_output() have been replaced with just Morsel.output() and BaseCookie.output().

06:06 The old names are going the way of the dodo. You can see a full list of deprecations in the What’s New docs. Some things deprecated in the past are now gone in 3.15, including the CGI flag for the command-line HTTP server. Jython is an alternative interpreter that uses the Java virtual machine to run Python code.

06:28 The platform module had a function for finding what version of Java was being run. Evidently, it was poorly maintained and didn’t always work, so it got ditched.

06:38 Did you know there was an undocumented older version of the regular expression mechanism in Python? Nope, neither did I. Well, now there isn’t. Sing it along with me, I think you know the words.

06:48 Yada yada, What’s New docs.

06:51 In the famous words of Porky Pig, that’s all folks. Well, almost. In the last lesson, I’ll summarize the course and point you at places to dig into this release in even more detail.

Become a Member to join the conversation.