#461: This episdoe has a typo
About the show
Sponsored by us! Support our work through:
Connect with the hosts
- Michael: @mkennedy@fosstodon.org / @mkennedy.codes (bsky)
- Brian: @brianokken@fosstodon.org / @brianokken.bsky.social
- Show: @pythonbytes@fosstodon.org / @pythonbytes.fm (bsky)
Join us on YouTube at pythonbytes.fm/live to be part of the audience. Usually Monday at 10am PT. Older video versions available there too.
Finally, if you want an artisanal, hand-crafted digest of every week of the show notes in email form? Add your name and email to our friends of the show list, we'll never share it.
Michael #1: PEP 798: Unpacking in Comprehensions
- After careful deliberation, the Python Steering Council is pleased to accept PEP 798 – Unpacking in Comprehensions.
Examples
[*it for it in its] # list with the concatenation of iterables in 'its' {*it for it in its} # set with the union of iterables in 'its' {**d for d in dicts} # dict with the combination of dicts in 'dicts' (*it for it in its) # generator of the concatenation of iterables in 'its'Also: The Steering Council is happy to unanimously accept “PEP 810, Explicit lazy imports”
Brian #2: Pandas 3.0.0rc0
- Pandas 3.0.0 will be released soon, and we’re on Release candidate 0
- Here’s What’s new in Pands 3.0.0
- Dedicated string data type by default
- Inferred by default for string data (instead of object dtype)
- The str dtype can only hold strings (or missing values), in contrast to object dtype. (setitem with non string fails)
- The missing value sentinel is always NaN (np.nan) and follows the same missing value semantics as the other default dtypes.
- Copy-on-Write
- The result of any indexing operation (subsetting a DataFrame or Series in any way, i.e. including accessing a DataFrame column as a Series) or any method returning a new DataFrame or Series, always behaves as if it were a copy in terms of user API.
- As a consequence, if you want to modify an object (DataFrame or Series), the only way to do this is to directly modify that object itself.
- pd.col syntax can now be used in DataFrame.assign() and DataFrame.loc()
- You can now do this:
df.assign(c = pd.col('a') + pd.col('b'))
- You can now do this:
- New Deprecation Policy
- Plus more
-
- Dedicated string data type by default
Michael #3: typos
- You’ve heard about codespell … what about typos?
- VSCode extension and OpenVSX extension.
- From Sky Kasko:
Like codespell, typos checks for known misspellings instead of only allowing words from a dictionary. But typos has some extra features I really appreciate, like finding spelling mistakes inside snake_case or camelCase words. For example, if you have the line:
*connecton_string = "sqlite:///my.db"*
codespell won't find the misspelling, but typos will. It gave me the output:
*error: `connecton` should be `connection`, `connector`
╭▸ ./main.py:1:1 │1 │ connecton_string = "sqlite:///my.db"
╰╴━━━━━━━━━*
But the main advantage for me is that typos has an LSP that supports editor integrations like a VS Code extension. As far as I can tell, codespell doesn't support editor integration. (Note that the popular Code Spell Checker VS Code extension is an unrelated project that uses a traditional dictionary approach.)
For more on the differences between codespell and typos, here's a comparison table I found in the typos repo: https://github.com/crate-ci/typos/blob/master/docs/comparison.md
By the way, though it's not mentioned in the installation instructions, typos is published on PyPI and can be installed with uv tool install typos, for example. That said, I don't bother installing it, I just use the VS Code extension and run it as a pre-commit hook. (By the way, I'm using prek instead of pre-commit now; thanks for the tip on episode #448!) It looks like typos also publishes a GitHub action, though I haven't used it.
Brian #4: A couple testing topics
- slowlify
- suggested by Brian Skinn
- Simulate slow, overloaded, or resource-constrained machines to reproduce CI failures and hunt flaky tests.
- Requires Linux with cgroups v2
- Why your mock breaks later
- Ned Badthelder
- Ned’s taught us before to “Mock where the object is used, not where it’s defined.”
- To be more explicit, but probably more confusing to mock-newbies, “don’t mock things that get imported, mock the object in the file it got imported to.”
- See? That’s probably worse. Anyway, read Ned’s post.
- If my project
myproducthas user.py that uses the system builtinopen()and we want to patch it:- DONT DO THIS:
@patch("builtins.open")- This patches
open()for the whole system
- This patches
- DO THIS:
@patch("myproduct.user.open")- This patches
open()for just the user.py file, which is what we want
- This patches
- DONT DO THIS:
- Apparently this issue is common and is mucking up using
coverage.py
Extras
Brian:
- The Rise and Rise of FastAPI - mini documentary
- “Building on Lean” chapter of LeanTDD is out
- The next chapter I’m working on is “Finding Waste in TDD”
- Notes to delete before end of show:
- I’m not on track for an end of year completion of the first pass, so pushing goal to 1/31/26
- As requested by a reader, I’m releasing both the full-so-far versions and most-recent-chapter
Michael:
Joke: tabloid - A minimal programming language inspired by clickbait headlines
Episode Transcript
Collapse transcript
00:00
00:05
00:10
00:11
00:12
00:17
00:20
00:22
00:29
00:29
00:36
00:40
00:46
00:52
00:58
00:59
01:00
01:02
01:05
01:08
01:11
01:16
01:20
01:22
01:29
01:32
01:38
01:40
01:42
01:49
01:55
01:58
02:02
02:07
02:09
02:17
02:20
02:25
02:37
02:41
02:52
02:56
03:04
03:11
03:15
03:21
03:24
03:32
03:34
03:37
03:42
03:43
03:47
03:49
03:50
03:54
03:55
03:55
03:58
03:59
03:59
04:01
04:02
04:03
04:06
04:06
04:08
04:13
04:17
04:20
04:23
04:26
04:29
04:30
04:32
04:36
04:38
04:39
04:43
04:45
04:49
04:50
05:00
05:01
05:01
05:04
05:04
05:07
05:12
05:13
05:15
05:19
05:22
05:26
05:29
05:30
05:31
05:42
05:43
05:44
05:46
05:48
05:49
05:51
05:52
05:55
05:58
05:59
05:59
06:00
06:02
06:05
06:08
06:14
06:16
06:19
06:21
06:22
06:29
06:33
06:40
06:44
06:48
06:54
07:01
07:06
07:13
07:17
07:22
07:26
07:29
07:31
07:33
07:36
07:40
07:45
07:51
07:54
07:59
08:08
08:10
08:12
08:16
08:20
08:23
08:26
08:30
08:35
08:42
08:43
08:50
08:52
08:57
08:58
09:02
09:06
09:12
09:14
09:16
09:20
09:20
09:23
09:25
09:27
09:30
09:37
09:44
09:45
09:48
09:52
09:55
09:58
10:07
10:08
10:12
10:20
10:22
10:24
10:26
10:29
10:30
10:31
10:33
10:34
10:35
10:37
10:38
10:39
10:41
10:45
10:50
10:53
10:54
10:55
10:59
11:05
11:08
11:10
11:11
11:16
11:18
11:28
11:28
11:30
11:36
11:39
11:41
11:43
11:43
11:45
11:50
11:52
11:57
11:58
12:02
12:05
12:12
12:17
12:21
12:27
12:28
12:33
12:38
12:40
12:41
12:41
12:48
12:51
12:53
12:58
12:59
13:01
13:06
13:12
13:16
13:22
13:25
13:26
13:29
13:32
13:35
13:38
13:43
13:44
13:44
13:49
13:52
13:53
13:53
13:58
14:04
14:06
14:09
14:09
14:10
14:14
14:15
14:18
14:24
14:25
14:26
14:28
14:33
14:35
14:43
14:48
14:49
14:55
14:59
15:05
15:11
15:14
15:22
15:25
15:29
15:35
15:38
15:40
15:45
15:47
15:52
15:55
16:03
16:09
16:16
16:19
16:25
16:32
16:38
16:45
16:51
16:56
17:02
17:08
17:13
17:15
17:20
17:22
17:24
17:29
17:31
17:37
17:49
17:54
17:57
18:07
18:10
18:12
18:21
18:27
18:30
18:32
18:36
18:40
18:42
18:45
18:48
18:52
18:53
18:55
18:56
19:00
19:01
19:02
19:03
19:04
19:05
19:07
19:07
19:09
19:10
19:16
19:23
19:26
19:29
19:33
19:35
19:41
19:43
19:44
19:51
19:52
20:05
20:08
20:11
20:17
20:20
20:25
20:27
20:28
20:30
20:33
20:35
20:37
20:39
20:43
20:45
20:46
20:49
20:51
20:54
20:56
20:57
21:02
21:05
21:08
21:11
21:15
21:16
21:24
21:29
21:32
21:34
21:37
21:40
21:43
21:49
21:50
21:51
21:52
21:53
21:54
21:56
21:56
21:58
21:58
22:01
22:05
22:08
22:09
22:10
22:12
22:12
22:15
22:17
22:23
22:26
22:27
22:32
22:33
22:35
22:36
22:42
22:43
22:44
22:47
22:48
22:52
22:59
23:01
23:02
23:04
23:08
23:11
23:14
23:19
23:25
23:33
23:39
23:46
23:52
23:56
24:01
24:06
24:12
24:18
24:25
24:29
24:35
24:37
24:43
24:46
24:47
24:50
24:52
24:53
24:56
24:59
25:03
25:05
25:05
25:09
25:13
25:16
25:23
25:26
25:27
25:29
25:30
25:31
25:35
25:39
25:42
25:43
25:45
25:47
25:48
25:50
25:53
25:56
25:57
25:59
26:01
26:02
26:03
26:06
26:07
26:10
26:10
26:11
26:15
26:18
26:18
26:23
26:25
26:30
26:32
26:33
26:34
26:34
26:35
26:35
26:36
26:36
26:39
26:40
26:41
26:42
26:44
26:45
26:47
26:48
26:49
26:52
26:52
26:53
26:54
26:55
26:56
26:56
26:57
26:59
27:00
27:02
27:03
27:10
27:16
27:23
27:27
27:34
27:42
27:48
27:54
28:00
28:08
28:12
28:20
28:30
28:36
28:41
28:48



