Transcript #248: while True: stand up, sit down
Return to episode page view on github00:00 Hey there, thanks for listening. Before we jump into this episode, I just want to remind you
00:03 that this episode is brought to you by us over at Talk Python Training and Brian through his pytest
00:09 book. So if you want to get hands-on and learn something with Python, be sure to consider our
00:14 courses over at Talk Python Training. Visit them via pythonbytes.fm/courses. And if you're
00:21 looking to do testing and get better with pytest, check out Brian's book at pythonbytes.fm slash
00:27 pytest. Enjoy the episode. Hello and welcome to Python Bytes, where we deliver Python news and
00:32 headlines directly to your earbuds. This is episode 248, recorded September 1st, 2021. Gasp,
00:40 it's summer over. I'm Michael Kennedy. I'm Brian Okken. I'm Paul Everett. Yay, Paul Everett here.
00:46 Yay. Welcome, Paul. Joy to be here. Long time listener, first time caller. Yeah, I think you
00:51 made an appearance in the previous show in the live chat, but now you're... Oh yes, the live, yeah,
00:56 true. Or possibly I talk Python. I can't remember. It all blurs together. It wasn't as prepared as
01:00 this one. No, now you're on the big stage. So thank you for being here. You know, tell people about the
01:06 things that you've been up to or what you're doing or who you are before we jump into our first topic.
01:11 I'm developer advocate at JetBrains for Python and Web, which means PyTarm and WebStorm.
01:17 What a great gig. Love my job. I always joke that they should be... I should be paying them,
01:24 but don't tell them I said that. And I'm just embarrassed that here I am on Python Bytes,
01:30 and I didn't get a haircut in time. I know this is a podcast, but there's a video version.
01:35 That's right.
01:36 Looking at Brian rocking the do, I feel like I should have been better prepared.
01:40 Yeah. Brian and I have alternate philosophies, I guess. I've got like the knight's neat hair,
01:45 and Brian's just embracing it. And yeah, I would do that too, except for mine just looks like a giant
01:50 poofy thing on top of my head. It doesn't look cool. So yeah, not so much.
01:54 Oh, I want to see that.
01:55 Yeah. It's amazingly bad. Yeah. I've tried it. It's not amazing. All right. But you probably have
02:01 something amazing to tell us about, huh, Brian?
02:02 Well, I do. I actually... So this is an interesting article. I want to talk about both
02:09 Adders and Pydantic because we've talked about both of them on the show, and they're both great
02:15 libraries, I think. And so there's this article that I came across called Why I Use Adders Instead
02:21 of Pydantic. And there's actually a lot more in here than just that. So it was an interesting read.
02:29 Starts out right off the bat talking about basically one of the things that a lot of people
02:34 think about with Adders is, don't we have data classes? Do we need Adders anymore?
02:39 And it starts out talking about, not talking about Pydantic, but talking about data classes.
02:47 And that data classes really came about as a subset of the Adders functionality. So it's really pretty
02:55 easy to go back to using Adders. If you're familiar with data classes, it should be easy.
03:00 And actually, there's a lot of reasons to use Adders instead. For one, they're just faster,
03:06 which I didn't know that they were faster. But there's some examples about a lot of the boilerplate
03:13 stuff that goes into data classes that we don't really think about. But the Adders is pretty tight.
03:18 Adders has more features and has some validation code that isn't around for data classes. So that's
03:28 interesting. So then getting into talking about Pydantic. So I think of Adders as kind of like data
03:37 classes, but it does more. So Adders, this author summarized Adders is a library for generating the
03:45 boring parts of writing classes.
03:47 And like the hash, the equals, the not equals, that kind of stuff, right?
03:52 Yeah. And also like throwing in some validation if you want. So you can opt in. So putting in some validation,
03:59 you can set that up. There's, and there's a lot of stuff that Adders does. I mean, it's a lot more
04:04 than that. It's a, it's a pretty full library also. But what you get with Pydantic is you get that with
04:11 the classes that Pydantic provides, but you also have the validation library and structuring and unstructuring
04:18 and conversion to and from like from, from a different type, like say, Jason into, into a Pydantic class.
04:30 And all these components really are with Adders, you can do all of that. You just, you, you opt in instead of,
04:37 instead of having to opt out of it. And it's kind of a really interesting take on that. And I, I thought of it as kind of like, you know, I've got a lot of,
04:47 I've got a lot of, I've got a great screwdriver. I've got great knives, but I don't think of my Swiss Army knife as a great, anything. It's just that it has everything.
04:56 I don't think it was that harsh of a comparison, but we also think about that with like a Django and Flask where Flask is kind of build up your own framework.
05:05 And Django has a lot of built-ins already. There was, and it isn't even that simple. There's also some, there was an example of some of the validation that's just that,
05:16 that, that is built into Pydantic that just seems wrong. Like the example was, if you've got a list of a thousand integers,
05:25 do you really want Pydantic to go and you pass in a list of integers? You, you want to make sure it's passing in a list, but do you want to want it to go through and make sure absolutely all a thousand elements is an integer?
05:38 You might, in which case you're in luck. Cause that's what it does. But if you don't want it to do that, because it's, that's just too much time. you're out of luck.
05:47 the other, well, you also got to remember the, the origins of Pydantic were about accepting input from arbitrary things on the internet.
05:56 Oh yeah.
05:57 And when you're, your goal is like, I'm accepting unstructured data from random endpoint on a random endpoint. Like you need a different level of integrity.
06:05 integrity. Then I loaded this off of a JSON file and I know the app created it. It's not going to be broken, right? It's going to be self consistent, at least in the fact that like the data types are probably still consistent.
06:17 So, so it's probably a, a when to use a witch sort of thing as well.
06:21 Yeah. So that's the, that's the generated, yeah. Adders class and the generated Pydantic class. so it's, it's around validation. yeah, it is interesting. the other, the other aspect is, making sure that, that, data is validated when it's set, not just when it's created.
06:40 And I think I got lost here, but I correct me if I'm wrong, Paul, but I think it's that, Pydantic only validates on creation. Whereas you can set adders to be validating on setting values as well. but I could be wrong.
06:56 I believe you're right. I went and looked up a ticket in Pydantic. I didn't read the whole thing about it, but these are hard conversations. There's no free lunch. and this article I thought was a free lunch.
07:09 I thought was a fair treatment about the topic. Yeah. The conversion bit was a little interesting. Like for instance, date conversion. So if you pass in, date time to a Pydantic model, Pydantic already has date time conversions built in. So it'll automatically convert it. But if you are using like pendulum, which is a sub, the, the class is a subclass of date time. You're going to get a wrong conversion. It's just going to do it wrong. because it's not going to be wrong.
07:38 cause it'll, it'll assume it's a date time and not a pendulum object. So that's interesting. yeah, anyway, definitely, something to think about of the build your own versus, having it all in one. But, but I definitely think there's places for both. Like Michael said, especially with, input validation on the, on the web. If you know what you're doing, definitely. I think maybe you could roll your own or, or use all these adders and other tools. But
08:07 if you're just sort of playing at it and there's getting started, then, why not try Pydantic? It's, it's a great place for that.
08:14 Yeah. The other thing is about the, open API specification stuff with Pydantic, where if you just use them and you just say, I'm using this, it'll like automatically generate the documentation, which is a big bonus.
08:25 Yeah. It's interesting with the release of SQL model. It's like, you can kind of feel like Pydantic is its own little mini framework dispatcher thingy with hook points that you can plug into and almost treat, almost treat as its own little API surface for gluing things together.
08:45 Yeah. Yeah. Yeah. It's the, the data exchange bit. Pretty interesting. Brandon Brainer out in the live stream says, I think it comes down to the, using the right tool for the right job, which is yeah. And how you opened it. Right. Brian? Yeah.
08:56 All right. So we all work with the terminal every now and then, right?
09:01 Every day.
09:02 You might be working with the command prompt if you're on windows, but I strongly encourage you not to do that. You should, you should be switching over to the new Microsoft terminal with like, Oh my posh shell. And then you'll be, you'll be in the terminal world as well.
09:16 So Dunderdan on Twitter, send us a recommendation, which I want to cover called McFly, which I love the name. So what is it? It is a bit of rust code that extension for your terminal, super easy to install. Like you can brew, install it and other types of install it. And basically what it does is it lets you fly through your shell history. Okay. So depending on the shell you use, you may use this a lot, or you may use this a little, you can hit control R.
09:46 In your terminal. And it brings up a reverse history search. So like, if you knew that you type something to do with get, and it had to do with this repo, you could hit control R and like type parts of the repo name. And that would start to auto complete those commands. There's a couple of things that are kind of a bummer about that though. One is maybe the biggest one is you only see one of those at a time. Right. So if I go and say, show me my history, I get a line. And then that is the closest, most recent match to what I type.
10:16 Well, what I often might want is like, it's kind of like a get clone, but which one was it? And I want to see which ones of those are that like, that UI is not fantastic. So imagine if you could type, say, get clone, and then hit control R. And it gave you like a UI in the terminal that you could scroll through and pick. And then you could see what else to type a little bit more. That's McFly. So it's pretty awesome in that regard. But it also uses a little
10:46 little bit of AI, if you will, a little neural network, and some context awareness to help filter and order that I guess price sort is probably the biggest thing is it'll say, well, what, you know, we're searching for this. But usually when you're in this folder, you're often using this, this version of that command. But if you're in a different folder, you're doing a different version of get. And so it'll try to filter your history based on the context of where you are. What do you all think?
11:12 I think I think it looks pretty cool. I was luckily, so I, I don't know why anybody would use the built in Windows command prompt. So I'm even on Windows, I'm using bash. But
11:23 Oh, my posh shell plus pi. Power shell is pretty sweet in the new terminal. Carry on. Carry on. Sorry. Don't mean to derail it.
11:31 Anyway, searching history with the VI mode is pretty easy in bash. But I was glad to see that this, this isn't just for, for your command prompt or posh or anything you can use.
11:43 You can use this with a Z shell and fish and bash too.
11:47 Yeah, it works in a lot of them. And so I found it to be quite neat. So let's see, I'll run through some of the features. So you just rebinds control R, which is kind of nice. But one of the things it'll store your history in a little local SQLite database. So it can do more queries and more interesting stuff have richer information on it. But it also, like, injects the commands that it sees into your regular shell history. So if you stop using it, your shell history for say, Z shell is still totally good. That's pretty nice.
12:16 I will say that. I know you had Brett on recently. And so the rustification of Python bytes appears to be complete at this point. You can't go anywhere without bumping into rust.
12:28 I know you keep bumping into it. It is quite interesting here.
12:31 And my other comment is that I hate to say it, but I think the three of us were, we've been around so long, we were pair programming with Moses. And the idea that I really needed a small neural network for my shell.
12:46 That's a tough one.
12:47 Yeah, it's interesting, right?
12:48 Yeah, it is.
12:49 But I do think, I mean, I do think it adds quite a bit of interesting extensions for this stuff. Like, it's a really cool way to do, you know, I use, oh, my Z shell. So if I wanted like SSH somewhere, I could type SSH and just start hitting up arrow. And it's like a beautiful history map. Like I never use control R because there's a better one.
13:07 I got to make that jump.
13:08 Yeah, it's so good. But sometimes I don't remember exactly what it is, or there's like a lot of them. And so with this one, it'll give you that drop down list that fills the whole screen. So you can jump through them. You can also delete, you're like this one I did once, but I never want to actually don't even want it in my history. You can delete it from your history, which is kind of nice. And then also, let's go through some of the other things. So yeah, so in terms of prioritization, you know, that little neural network,
13:37 says it takes into consideration the directory where you ran the command, what you typed before the command. So if you did a get branch and then a checkout, I don't know, maybe that means something or I don't know, whatever.
13:49 But like the series of commands that preceded it influence what it suggests and how it orders it, how often you run it when you last ran it, what you've selected in it as it's dropped down. And also, it's exit status.
14:03 So if you ran a command, but the command failed, like it won't auto suggest that command again, because that one's the broken one. You know what I mean? Things like that. There's a lot of cool stuff.
14:11 Oh, that's cool.
14:12 And then I got one for you, Brian, down here. So it's easy to install this, you'd like, you know, brew install or where's the, I'll be an advocate install or something. Anyway, if I go down here, there's all sorts of ways to install it.
14:25 But here we are. Vim keybindings, Brian.
14:29 Yes. Okay.
14:31 So, okay. So you have Vim keybindings, which is by default, it uses Emacs. It definitely reminded me of like just firing up Emacs, but for the shell, which is kind of nice.
14:41 The other thing that I like about it, I haven't turned this on yet, is fuzzy searching. So sometimes I'll be like, ah, there's this command. I think it was this. But if you get it wrong, then it's like you get zero help, right? If you get one character wrong. But this one is, if you get close, can you get close and we'll give you some autocomplete on that. That's pretty cool.
14:59 Yeah, that's great. Because you might like be searching for a file name or something like that.
15:03 Yeah, yeah, exactly. Exactly.
15:05 Do you see that? There was an XKCD, I think, or some other comic of somebody. Now it's a different one, but somebody scrolling through their history for like an hour to get LS.
15:16 Yes.
15:17 No, I'm definitely going to try this out. This is pretty good.
15:22 Can you scroll? Yeah.
15:23 Oh, you're going on the XKCD.
15:25 No, sorry.
15:26 Can you scroll up to the commits? Number of commits?
15:29 Yeah, 350.
15:30 Yeah, this has the look of a project that's been refined, doesn't it?
15:34 Yeah. Yeah, it does. I don't know quite how long it's been around, but yeah, it looks like the oldest super obvious one is 14 months.
15:43 Yeah.
15:44 Yeah.
15:44 It's continuous integration. It was last configured 14 months ago, let's say.
15:48 No, it's the docs. The docs were two years ago.
15:51 Okay. The docs, there you go. I think this is nice.
15:54 I wasn't sure I would have wanted to use it. I'm like, oh, this is interesting. And people might, then I installed it. I'm like, oh, this is, this is pretty cool. I like it.
16:01 You know, all the cool stuff I like in Python, like PyPI and PipX and things like that. They all have a section about using this with fish, you know? And so I'm always taunted with my lack of foo when it comes to terminals.
16:16 Yeah. Yeah. I made the switch to Z shell. Oh my Z shell. I'm not looking back. Love it. All right. Patrick.
16:23 We'll be out in the live stream says McFly seems really interesting. I'm using Z shell for a month now and always thought the control R search lacks features compared to other plugins for sure. Absolutely.
16:32 And then David, pooch on out there says you covered that LS joke in the show. Yeah. That's beautiful. I love that one. It's been a couple of years, I think, but it was a good one.
16:41 Well, we don't have a joke history command. So yeah. Oh, McLaugh. He's writing McLaugh.
16:50 Something we never cover on the show is textual. So why don't you tell us about that, Paul?
16:54 Sure. switching over to me. Yep. We got me. I think it was episode two 41 when you had Brett on and Brian led with Will McGooghan talking about rich and I'll, I'll quote Brian because it was funny then. And it's funny now. how can I not have heard of it?
17:14 I'm a fan of the podcast and Brian loves this tool. So I'm going to go back to the well with the thing that was spun out of rich at that time textual, which has been covered. But I want to talk about a particular aspect of it. It was kind of interesting to me as a pattern. And then have a little debate where the two of you tell me that I'm wrong. and really ancient about this.
17:36 So, I've traditionally been against the convention over configuration camp in the world of Python. I come out of kind of the Zope tradition, the pyramid tradition pyramid is like, oh yeah, well, here's a configurator object. And it does 15 trillion things that you really ought to care about, but don't.
17:58 Because Chris McDonough has really great design sense, kind of Goldilocks knows exactly what to put in and leave out. And I just, that whole worldview fits into my head. And so I have this dislike about magic names, magic file names, magic variable names, can't auto complete them, can't refactor, can't navigate. If you can't memorize it and keep it all in your head, you know, and Python is explicit over implicit, blah, blah, blah.
18:25 I prefer like actual symbols that smart editors can operate on and not have like is a little bit that's going on with data classes right now. Each individual tool having to wire up special support for that template language or that this, that, or the other thing to look for these magic hand waves.
18:43 So, we'll have this thread and actually I should bring the thread up. we'll have this thread on Twitter, which made me feel a, like I was a little bit wrong and be like he had solved some of the issues that I had with it.
19:02 So what he wanted to do was remove some boilerplate. And in this, he gave some examples about before and after, here's the screenshot of it.
19:14 So that's before. And you see like in here, watch how much this changes when you go to this.
19:22 So kind of the noise, the ceremony, a lot of the stuff was reduced.
19:28 Okay.
19:28 Now anybody can look at this and say, wow, that's great. If you're optimizing for writing code, if you're optimizing for reading code and you want to walk back up to this later and know that there are some special semantics that, you know, then if the name starts with these three things, then the next thing is kind of a thing that is a, et cetera.
19:50 And so I worry about, I worry about those kinds of things, but he had done it in a way where my pie would still help you some.
19:58 And one of the innovations he had that I felt like, let's see, do you see, do you see me on Twitter? Nope, you don't. Cause I'm in the wrong window. Sorry about that.
20:09 Okay. My apologies. So into the screenshot, you see a before and after Brian, you see that?
20:15 Yeah.
20:15 All right. Good. Before and after. And so he's talking about boilerplate removal in this thread and some of the decisions such as like this, for any of you that do type annotations, type hints, you'll look at this and you will say, oh goodness, the type hint went away.
20:38 This is actually a perfect example. And you look at this and you think I just lost the typing information and I believe in type hinting. Well, not really because it can be inferred for, it can be deduced.
20:49 Right. So for people listening, the example is you've got like a variable colon type equals.
20:54 Oh yeah. Sorry. Yes. This is a podcast.
20:56 You can instantiate the type versus just drop the type annotation on the variable. But when you're, when you're allocating up the object right there, like all the editors in my pyre, like, you know what thing equals new object.
21:09 That's right.
21:09 It could be that object.
21:11 Yeah. And in these like titantic battles about type hinting, we forget that, well, you don't have to do all that typing all the time. Python and type checker static analysis can figure this kind of stuff out.
21:23 So I looked at that and I was pretty, you know, I was probably kind of seduced by that. But let me ask the two of you, maybe the audience as well. Do you think that three months from now, if you walked up to your textual application,
21:36 would you be able to remember that he had done these things and that the right hand side was telling you about the left hand side in order to save a little bit of typing?
21:48 Did I lose a little bit down the road and have to load up my future self? What do you think about that?
21:54 Right.
21:56 Well, I'll tell you what I'll tell you what I think. Is there a separation of where this happens? Like on the example that you're showing here, like object or variable equals new object. I never need help with that. I get super clear what that type is all the time.
22:11 Where it becomes not so obvious to me is where I've got like a class or something and it's got a field and then I'm creating that object and passing it in.
22:22 If my pie could still tell me, oh, this thing is one of these because the only time you ever use it is always passing this type.
22:29 But that's a separate file and I'm not looking at it side by side. Then to me that like starts to add additional work for me to keep track of in my mind.
22:38 The other one I would say is the autocomplete test. If I'm working with thing, I say variable dot and it goes, zoom, there's the list of things. There's a good chance I don't care about anything else.
22:49 Right. Like did it autocomplete the thing? And did it tell me if I put the wrong property field, whatever on it, because it knows what that list is. Right.
22:58 And if the magic name changes later, will I get a red squiggle?
23:00 Yes, exactly. Will the editor know that it was broken and will it help me write it so I don't have to look at the docs?
23:07 I don't have to go to the source. I just use variable dot and I just keep rocking until I really need to understand something.
23:13 Yeah.
23:13 I would say that that's where I come down on it.
23:17 The third thing is, if this is not relevant here necessarily, but if you're doing something like SQLAlchemy or Mongo Engine or Django ORM, so often what they do is they
23:27 have like two flavors of the thing.
23:29 I'm creating a class.
23:31 The class has a field.
23:32 It's called email.
23:33 Oh, wait, no.
23:34 What is it?
23:34 It's being set to a new Mongo Engine field of type string that has a regular expression on it.
23:42 Wait, that's not what I get at runtime.
23:44 At runtime, I get a string.
23:45 At code time, I get this.
23:48 So for those, I will say field colon type is string equals Mongo field is a Mongo string or whatever or SQLAlchemy column of type string because I want it to be explicit that it's not really what it says there because often the editors will give you column information, which doesn't make any sense.
24:08 Anyway, that's a long answer, but I gave Brian some time to think about his position here.
24:13 I'm actually just I'm very impressed with Will's design decisions on a lot of things.
24:18 And I am like there may be some magic hidden in there, but I would rather have less code to look at.
24:28 So less code to look at means less things to get wrong.
24:32 As far as I'm concerned.
24:33 I am coming down with you on this one.
24:38 I've been working for a long time on kind of a long project about static analysis and Python templating that is driven by type hints.
24:47 And looking at what he's done has made me step back and think, wow, there is some there's something some things you can do without throwing out type hinting that improves the readability and removes the boilerplate while keeping people on the rails.
25:02 Back to what you said about Will's design decisions.
25:05 Looking inside the code of textual is really fascinating to me.
25:10 Fascinating enough that first today Will announced that he is changing his job status so that he can work for the next three months on open source completely rather than at night and is looking to meet a target for GitHub sponsorship.
25:26 So let's all go out there and sponsor him so we can get these delicious looking treats that he keeps giving to us.
25:32 But second, I'm interested enough that I want to join the freaking project and learn from him.
25:37 I need a reactive system.
25:39 He's got one.
25:41 Yeah.
25:41 I wouldn't even know how to write a test for it.
25:44 And he's got that, too.
25:45 So I'm with you on that.
25:47 I love the way he writes his code, the way he talks about his thinking in public while being a gentle and encouraging public figure.
25:58 Yeah.
25:58 Well said.
25:59 Absolutely.
26:00 Well, very, very cool stuff.
26:02 There's a lot of neat things coming out of there.
26:04 And I think a lot of people's reactions are like astonishment.
26:07 Like, wait, that's a terminal?
26:08 That's insane that it does that.
26:09 Yeah.
26:11 Ah.
26:12 On to the next.
26:14 Speaking of testing, have either of you ever used DocTest?
26:19 Paul?
26:20 Yes, I have.
26:22 So I, way back when, when I started blogging about testing, I thought it'd be fun to compare the test frameworks because I wrote my own.
26:33 It wasn't fun.
26:34 So I looked at unit test.
26:36 I looked at DocTest.
26:37 I looked at pytest and Nose also.
26:42 And I, I actually thought, you know, maybe just, I didn't think it would go very far, but I tried to use DocTest as a, as a, end to end test tool.
26:53 it was difficult.
26:55 and there's still some cool things about DocTest.
26:59 So if, if people are unclear what DocTest is, DocTest is a, a package that's built into Python that you can write.
27:07 You can use it by saying Python-M docTest and point it at a file, one of your source files.
27:13 And within your doc strings, if you've got things that are like the, the three, I'll see if I've got it here.
27:21 So the, the three arrows or something like the prompt, the Python repl.
27:26 And you can type some examples in there and DocTest makes sure that the output really matches what you said.
27:33 So DocTest will go through and make sure your code examples within your code actually work.
27:37 This is a cool idea in principle.
27:40 In practice, it's very painful.
27:43 And, a lot of the pain points come around.
27:46 Well, I forgot to import anything.
27:48 So you have to, you have to include the imports in there, or I forgot to, there's a lot of stuff that can go wrong.
27:55 now pytest adds some things you can run docTest from pytest.
27:59 It's pretty cool.
28:00 What we're talking about now is a new project or a project new to me called xDocTest.
28:06 And xDocTest, it's got a whole bunch of cool features.
28:10 One of the things is docTest is a regex plate based thing.
28:14 It, like, pulls out the string, finds the code, runs it, looks at the output, makes sure they match.
28:20 xDocTest uses a, whatever the, the source tree thing.
28:25 abstract syntax tree.
28:28 That's, that's it.
28:29 Abstract syntax tree.
28:30 yeah.
28:32 so it's actually parsing it better.
28:34 And, there's a whole bunch of cool stuff you get with that.
28:38 The thing that I re there's, there's some highlights in there.
28:41 Like one of the things is, continue string continuation was pain, painful because you had
28:46 to include the little angle bracket things.
28:49 You don't have to do that with xDocTest.
28:50 The thing that I love the most though, is, one of the defaults, in docTest is it
28:58 does not do string normalize it white space normalization.
29:01 You can turn it on, but it doesn't do it by default.
29:04 xDocTest by default does white space normalization.
29:08 What that means is if in my code, I cut and pasted stuff and added like a tab or a space
29:15 at the end of my string, docTest will fail that because it's like, oh, that's, that string's
29:21 not the same as white space at the end.
29:23 I don't care about the white space at the end.
29:25 So, one of the things that xDocTest is just fixes that right off the bat.
29:30 So it's going to be way more pleasant just to work with.
29:33 But there's a whole bunch of other cool features of this that it, that it brought in.
29:37 It has a more sane skip, syntax, although they kind of had to read it for a while.
29:42 You have to say plus skip to, to start the skipping and then minus skip to turn it off.
29:47 yeah, anyway.
29:49 but it's pretty, pretty neat and flexible.
29:52 And I think if you're going to start out trying to do docTest stuff, I would totally use xDocTest.
29:58 Plus it has a built-in pytest support.
30:00 So if you have it installed, you can say pytest --xDocTest and run it on your code.
30:06 It'll run fine.
30:07 Yeah.
30:08 Very nice.
30:08 Paul, you've done.
30:09 You are two for two on predicting what I was going to talk about.
30:13 So, but I, what I really want to hear you do is say abstract syntax tree in a Daffy Duck voice.
30:19 No.
30:21 You.
30:23 No way.
30:23 That'll be in the bonus track.
30:25 Brett Cannon made us sing a song, from like Ren and Stimpy or something like that.
30:31 Oh my goodness.
30:31 Ren and Stimpy.
30:32 Yeah.
30:33 Was it that it was?
30:33 No, it was, pinky in the brain.
30:35 That's what it was.
30:36 Pinky in the brain.
30:36 Yeah.
30:36 Yeah.
30:37 Yeah.
30:37 It's all from the same general genre and era.
30:40 We should do a Ren and Stimpy skit sometime.
30:42 That would be fun.
30:43 God, Ren and Stimpy was awesome.
30:45 That was awesome.
30:46 The peak of civilization.
30:48 Yeah.
30:49 The red button.
30:50 Okay.
30:51 Don't press it.
30:52 All right.
30:53 what's next?
30:55 I'm next with this one.
30:56 Okay.
30:57 So I want to start with some code and then tell you more about it.
30:59 I want to tell you the code and then you can think about how complicated is it and then
31:03 what does this accomplish?
31:04 So here's some Python code.
31:05 It creates a little LED.
31:07 It's for like some embedded thing.
31:08 It imports the LED, imports time and imports random.
31:11 It says LED equals LED number 17 while true.
31:15 LED on sleep.
31:17 One second.
31:17 LED off sleep for between 45 and 60 minutes.
31:21 That's the entire bit of code.
31:22 What does it do?
31:24 This is how I automated my standing desk with a Raspberry Pi.
31:28 Pretty awesome, right?
31:31 Yes.
31:31 So this one comes to us from Joe Ridley.
31:37 Ridley.
31:37 Thank you, Joe.
31:38 And this is by David Kong.
31:40 It's apparently he's into sort of hacking his productivity in all sorts of ways.
31:44 So we got a standup desk and he said, I have this cool automated standup desk.
31:48 You can push a button for up, push a button for down.
31:49 You have presets of like where you like the up, where you like the down.
31:53 But he didn't press it very often.
31:55 So he's like, well, why am I not pressing it?
31:57 Because I am lazy and I want to stand up.
31:59 And then so he put reminders on his phone.
32:01 Says, you want to stand up?
32:02 He goes, no, I don't want to stand up right now.
32:04 And then he said, well, what if it just did it?
32:06 And I had to like adjust to it, right?
32:08 So he went along and there's like a couple of buttons, little programmable bits.
32:13 And he just pried the faceplate off of the control surface of his automatic desk.
32:19 You know, it was a works desk.
32:21 So whatever if it breaks, I guess.
32:22 Pry that off.
32:24 And he just has a few little like pins in the back.
32:27 And if you push the button down, it completes the circuit.
32:29 And he's like, well, really, all I needed to do is stand up.
32:32 I can push the sit down button when I'm tired of standing up again.
32:35 And so I went through about like, how do I do this?
32:37 I just need to connect something that will trigger electrical current on one of these bits here.
32:43 So I said, well, maybe I could use some little like super micro thing, some small things.
32:49 I said, you know what?
32:49 Actually, for five bucks, I can get a Raspberry Pi Zero.
32:52 And you'll go crazy, get a case and an SD card and all that from Adafruit for five bucks.
32:57 And just write some Python code.
32:59 And then you connect these little pin areas, like number 17, for example.
33:04 to a circuit.
33:06 And instead of turning on the LED, it just sends a current over to that little thing on the desk.
33:11 And it'll make it go.
33:12 Isn't that awesome?
33:13 That's great.
33:15 I want to do that.
33:15 I need a standing desk first, though.
33:17 I know.
33:18 Here I am saying, Will, who is in the audience, has magic method names.
33:25 How do I know?
33:26 How can I tab complete?
33:27 And this thing's like, hook it up to terminal 17.
33:30 I mean, oh, okay, not 18.
33:32 All right, great.
33:33 Exactly.
33:34 It's pretty janky.
33:35 No, but that's great.
33:37 That is, I've got a...
33:38 You have a standing desk?
33:39 Stand-up desk.
33:40 It has a different brand, but it looks like the exact same panel.
33:44 Well, stay tuned.
33:46 So one of the things is, I don't really need a UI, but maybe just a terminal.
33:50 And how do I talk to the Raspberry Pi?
33:52 So David goes on to talk about how he set up an SSH shell over to his Raspberry Pi from his MacBook using a USB cable because it's on the desk anyway.
34:03 And then just writes this little bit of code that I talked about, move desk.
34:07 And off it goes.
34:08 And off it goes.
34:09 Soldered a few things together.
34:11 And then just taped it to the bottom of the desk.
34:14 And now you have it going.
34:16 I would contend there's a few minor upgrades that should be added here.
34:19 Maybe a time check.
34:21 Like, you may freak a custodial person out if they come in the middle of the night and they go to get the...
34:29 The clone army has been activated.
34:32 Exactly.
34:32 We're going to empty the trash bin under your desk and it goes...
34:36 I mean, I would run for it.
34:38 But if that were me.
34:39 But, you know, so maybe like a web service call to check the time or just check the time and go, really just do this during work hours.
34:47 And like, honestly, this was a pre-COVID thing.
34:49 So it randomly raises and lowers it or...
34:53 Yes.
34:53 Between 45 and 60 minutes on the hour.
34:56 Okay.
34:57 That is fabulous.
34:58 Yeah.
34:59 If you look at the comments here, this is where you got to hang tight, Paul.
35:02 So people are digging it.
35:04 Someone down here a little bit further says, I have something called a VeriDesk.
35:10 But it turns out when I peeled the front off of my VeriDesk, it had exactly the same control board on the inside.
35:16 How about that?
35:17 Yeah.
35:18 So, Paul, if it looks the same, it may well be the same because someone else was saying that they did.
35:22 Now my desk is going to be smarter than me.
35:24 I mean, I've gotten used to my watch being smarter than me.
35:28 It will just have more willpower than you because you're like, I don't really want to stand up.
35:32 Well, I can't reach it anymore.
35:33 So I got to stand up.
35:34 The Fox and the Hedgehog.
35:35 Yeah, exactly.
35:37 All right.
35:37 Well, that's all.
35:38 But I thought it was a, I'm always thinking of like, we have these super cool devices that cost like five bucks and it's, they're so easy to program.
35:44 But I just, I don't usually have anything cool to do with them.
35:46 And this seems entirely attainable.
35:48 Yeah.
35:49 I think maybe hooking up a height adjustment with random adjustment to my webcam would be cool.
35:56 So I could just have different angles throughout the day.
35:59 What if there's like a pulley system that if you, that after a moment yanks the chair and if you don't get up, it's just going to dump you.
36:05 Like a little bit more urgency to the network.
36:08 Exactly.
36:09 Or score a gun if it finds you're still sitting or something.
36:12 Puts my coffee slightly farther away.
36:15 Exactly.
36:15 All right.
36:17 Paul, what's your last one?
36:18 This was a really interesting one for me.
36:21 I was on vacation in heaven in August.
36:26 And two things I did was when I was at the beach, I had the beta of Brian's book.
36:33 And when I was back at my mother-in-law's house, I was taking my six related Python projects and teleporting them into the future using the hypermodern Python cookie cutter.
36:46 And what do I mean by that?
36:48 Well, if you're doing a Python package, a library or something that you're going to distribute on PyPI, you know, Python development's gotten, the bar has been raised.
37:00 Let's put it that way, on quality control and tooling and things like that.
37:04 And my good friend, Brian Okken, long ago, 10 minutes, mentioned about xDocTest, which is also on here, I believe.
37:15 Yeah, xDocTest.
37:16 Along with 57 other things you might want to do, like Dependabot and Flake 8 and PreCommit and mypy and Black and GitHub Actions and all these other things.
37:27 And individually, they're achievable.
37:31 Collectively, they are a go on vacation in heaven, delete your repository and start over.
37:38 That's what I did.
37:39 I deleted all my repositories and started over with poetry and things like that.
37:44 This cookie cutter isn't just great because it's a cookie cutter that gets you in the ballpark out of the box.
37:52 It is a user guide that explains all the decisions made, including the why.
37:59 It's like teaching you how to become a modern Python packager programmer, someone who's going to distribute stuff.
38:07 And in fact, there was a blog, a series of blog articles before he did this.
38:13 Let's see if I can find that.
38:15 Yeah.
38:15 So often you'll see these articles of what you should do and then you just have to go do it.
38:19 And this is like, here's what you should do.
38:21 Indeed.
38:21 And then you run this command and then it's done.
38:24 But now you know why.
38:25 Indeed.
38:26 And in fact, I found the part you just described to be more valuable than the cookie cutter.
38:30 Yeah.
38:31 Because the last thing I wanted was to be teleported into 57 things I didn't understand.
38:38 Yeah.
38:39 And so just for the two of you, if you could look through that list, maybe anybody in the audience look through that list.
38:47 How many of these are things?
38:49 Brian, you've been distributing packages recently.
38:52 How many of these things are in your list of guilt that you're not doing?
38:58 Yeah.
38:59 No, a lot of these are great.
39:01 Some of these I'd like to add.
39:03 I'm not doing much type checking.
39:06 I'd like to do more type checking.
39:07 Sure.
39:08 I don't.
39:09 Some of the choices, I just don't agree with the choices.
39:11 So I was actually considering doing a fork of this with the choices that I would have made.
39:16 Knox is a cool project, but I've got no problem with Knox.
39:20 Yes, I knew you would say that and I agree with you.
39:23 I would change that too.
39:24 And I know you said you like poetry.
39:26 I know a lot of people love poetry.
39:28 It just doesn't fit my brain, so I don't use poetry.
39:31 But that's all right.
39:32 I'm only 50-50 on it.
39:33 I'm fighting it.
39:34 But a whole bunch of other stuff, like you said, things that maybe you didn't consider, like black and prettier.
39:41 I don't think I use both.
39:42 So I don't know what prettier gives me that black doesn't.
39:45 JavaScript and markdown-y things like that, JSON files, non-Python.
39:49 Oh, okay.
39:51 Don't know what release drafter is.
39:53 That looks neat.
39:53 The whole release drafter thing, I don't know if either of you have ever looked at release note automation in Python.
40:00 But there's a number of packages, semi-dead.
40:04 And most of them result in this dance of if you push before this thing runs, you can't get your notes on the tag.
40:12 Yeah.
40:13 Okay.
40:13 And so this is hooked up with a GitHub action, which makes a draft of your release notes for you as part of the merging a pull request to bump the version number process.
40:25 It's just fascinating.
40:27 I would have never figured this out, man.
40:29 Never.
40:29 Okay.
40:30 We got some cool comments.
40:31 One here.
40:33 It's not as from Exxon.
40:35 Yeah, that's a good point.
40:37 It's not as hyper modern as the title suggests.
40:40 It's often pretty solid advice.
40:42 I'm not sure if what he means by solid is a compliment or an insult.
40:47 I'm not sure.
40:47 I think what he means is hyper modern.
40:49 At least when I read it, I was like, the last thing on earth I want is bleeding edge on this stuff.
40:56 And then also, list of guilt would be a good title for this.
41:00 Yes.
41:03 One of the things I want to point out the article series.
41:06 So at the top of this, what we're going to link to, it links to hyper modern Python.
41:10 It's a list of articles.
41:12 The artwork in this is amazing.
41:15 So he's using some freely available artwork.
41:18 It's really cool.
41:19 It's a clunky thing.
41:19 Yeah.
41:21 Well said.
41:21 Did you read any of the articles, Brian?
41:23 Well, I read all of them when they first appeared, but it looks like there's some newer articles that I haven't read yet.
41:30 Yep.
41:30 Yep.
41:31 So Claudio, mega kudos.
41:35 That's another project I should join because there's a couple.
41:37 I would like to teleport him from Sphinx restructured text to Sphinx markdown.
41:44 Oh, yeah, definitely.
41:45 Which is what I've done in my, each time I did this, I did a commit immediately to replace it.
41:52 And it's a little bit of work.
41:53 And so it's a contribution I could actually make.
41:56 Yeah.
41:57 Sphinx markdown is the reason why I use Sphinx now.
42:00 Very good.
42:01 Very good.
42:01 So one last thing I'll close with on the X-Doc test, Brian.
42:05 I was using it from Hypermodern cookie cutter.
42:08 And I switched to this from Chris Withers, Sybil.
42:13 Sybil.
42:13 Nice name.
42:14 Which is, Chris is an old time Zopista.
42:17 And so what he does is he lets you, this is not about dot strings in your code.
42:23 This is about blocks in your Sphinx, blocks of code in your Sphinx and testing them.
42:29 But you wind up with this doing something pie testy.
42:34 And this lets you have fixtures and all these other things available in your doc test blocks.
42:41 Cool.
42:41 Cool.
42:41 We'll check it out.
42:42 Yeah.
42:43 Yeah.
42:43 Super, super cool.
42:44 And actually on said solid was intended as a compliment there.
42:49 Yeah.
42:49 Very nice.
42:50 All right.
42:51 Brian, you got any extras to wrap it up?
42:53 I don't other than just an apology.
42:55 Sorry about the solid comment.
42:58 Oh, well.
42:59 I know.
42:59 That was good.
43:00 Paul?
43:01 That was good.
43:01 Anything else?
43:02 Yeah.
43:02 I had a chance, I guess at the end of last week, if you've been to PyCon before, you'll know
43:13 some of the folks in the PSF.
43:15 Bessie Walshowski, who has been with the PSF forever and ever, was with O'Reilly before that.
43:22 She is now with OSI, the Open Society.
43:26 God, I know I would say that.
43:28 Open Source Institute.
43:30 I spent 10 years on a project with the Open Society Institute, the other OSI.
43:35 And she is working with OSI on their messaging and fundraising and things like that.
43:43 And it's a very interesting problem for us in the Python community that's similar to the
43:49 problem we had with the PSF, getting people to pay for the comments, if that makes sense.
43:58 Now, the comments for the world of open source is a lot squishier.
44:04 And the value proposition is a lot more indirect relative to the world of Python.
44:09 But I feel like there is a big there there that the world of open source is still relevant
44:17 and still has important next problems.
44:21 There is a commons.
44:22 There are things that will need to be done.
44:25 And we need a neutral agency that is an advocate for the commons to to work on things like that.
44:34 So she and I discussed what's next for the commons, things going on at OSI.
44:40 If any of you were around in the beginning of the words open source, you know, the problems
44:47 that were being solved then.
44:48 They feel like solved problems now.
44:51 But that's an open question.
44:52 And sometimes problems don't have a way of staying solved.
44:55 So keep an eye on OSI.
44:58 Keep an eye on what Betsy and Stefano and others are doing.
45:02 Keep an eye on open source itself and maybe share some thoughts in the show notes or anything
45:09 like that.
45:10 What do you think is the big mission for open source?
45:13 Yeah.
45:14 Maybe you reply to the Twitter thread announcing this episode, which will be out shortly.
45:18 That probably the best place or the YouTube, the YouTube live stream chat would be good.
45:23 Good places for that.
45:24 How about you, Michael?
45:25 Do you have any extra bits?
45:27 You know, I do.
45:30 First of all, I want to just really quickly on the hypermodern thing throughout.
45:33 Remember, we talked about readme.so?
45:35 Oh, yeah.
45:36 Gosh.
45:37 And this is readme as a service.
45:38 This is good to generate your readme.
45:40 And then you can use the release note thing to keep it going.
45:43 So, yeah, I just want to give another shout out to that because the idea of readme as a
45:46 service blew my mind.
45:47 Does it do badges?
45:48 God, badges are so hard.
45:50 I know.
45:51 If it doesn't do badges, it better.
45:52 That would be an awesome upgrade.
45:54 Okay.
45:54 A couple of quick things I want to throw a shout out to.
45:56 These are at the bottom of the show notes.
45:58 Active States, you know, they're one of the packages, distributors of more full featured,
46:05 holistic sort of prepackaged Python distributions.
46:08 They are running a survey called the Software Supply Chain Security Survey to, you know, supply
46:15 chain security of like pip vulnerabilities.
46:17 IPI package pollution vulnerabilities and stuff like that are big deals.
46:23 So they're interested in running a survey.
46:25 So I thought I'd give a shout out about that.
46:27 People can fill that out.
46:28 Python 397 and 3812 are out with, I think 397 might have some very minor new things.
46:37 And 38 is just a security update.
46:39 So bug fixes.
46:40 But the 391 didn't speak to me as anything super major, but you might check it out.
46:45 There's a few security things in there about like, if you pass this to like the IP class
46:51 or something like that, it could be an issue, but I don't really think there's anything super
46:56 important there.
46:56 But no.
46:57 Brian, this one, let me read the little description for you.
47:00 This one here comes from Shlomi Lanton.
47:04 Does Brian, you talked about having a history of all the files and a GitHub repo and finding
47:10 out how long the oldest one, like we were just looking around, like how old is this project?
47:14 Maybe two years looks like lasting change.
47:15 So he wrote a thing called grandpa.
47:18 And the idea is simply find the oldest modified files in the repo that you can run it standalone.
47:25 You can make it a GitHub action and so on.
47:27 So it just goes through and finds the oldest files.
47:30 Last week, I talked about wake pi, which will let you keep a process awake.
47:35 No, keep your computer awake while your process, your Python process is running.
47:39 You do like a context manager, you know, with keep awake, do the stuff you don't want the
47:43 computer to go to sleep during.
47:44 And then when you leave the computer can go back to sleep.
47:47 And I said that there was a problem on macOS.
47:49 PR is accepted that things back to good.
47:51 So thank you for that.
47:52 Really quick shout out to some, oh my Z shell.
47:56 Not my Z shell.
47:56 Oh my posh shell.
47:58 Look at all that good stuff, Brian.
47:59 That's, that could be your, that could be your, power shell on windows.
48:03 Does it have VI key bindings?
48:06 If not, I can't use it.
48:07 Just, I honestly don't know.
48:09 Anyway, I think it's pretty cool, but people, and it's not just for power shell.
48:15 It just happens to be one of these really nice extensions that also works for power shell.
48:19 Oh really?
48:19 Yeah.
48:20 All right.
48:21 It took me forever to know what posh meant.
48:22 I'm like posh.
48:23 What, what shell is that?
48:25 Posh is power shell, right?
48:27 I, it probably is actually.
48:29 Yeah, it probably is.
48:30 It sounds cooler than power shell though.
48:32 Okay.
48:32 Cool.
48:33 Cool.
48:34 All right.
48:34 I think that's it for, for those.
48:36 Are y'all ready for a joke?
48:37 Yes.
48:38 All right.
48:39 Here we go.
48:39 So here's a tweet from monkey user at is monkey user.
48:43 And they have a mess.
48:44 They have like a, this sort of planning diagram here, like a flow chart.
48:48 If you will remember a flow chart, but there's like real high level.
48:50 And it's about trying to find, a meaning and as a software developer.
48:55 So if the person enters to the workflow, quit.
48:58 Question mark.
48:59 Yes or no.
49:00 Yes.
49:01 Do you have paid time off?
49:02 Then, then what you can do, is you can go in and you change your JavaScript.
49:09 I think it's JavaScript.
49:10 Change your JavaScript framework.
49:11 Do you acquire new skills?
49:13 Are you burnt out?
49:13 No.
49:15 You go back.
49:15 You change your JavaScript framework again.
49:18 It's a little starving.
49:19 Have you changed your JavaScript framework in the last two, two months?
49:22 If, if, no, then you need to change it again.
49:25 It burns.
49:26 It burns.
49:26 Yeah.
49:27 You've got some, some backlog here.
49:29 It goes to in progress and that gets shipped.
49:30 It gets done.
49:31 You get paid.
49:32 Do you have burnout?
49:32 Yes.
49:33 Are you dead?
49:34 Whoops.
49:34 Not yet.
49:35 Do you have paid time off?
49:36 Then you can change your JavaScript framework again.
49:38 No.
49:38 Then you ask, have it, has it changed in two months?
49:41 If, no, then you change it again.
49:43 Otherwise you go to the backlog.
49:45 And I thought this part right here, Ryan, you might particularly like, is it ready for QA?
49:49 Nothing goes to that.
49:50 It's just like an orphaned input box right there.
49:57 This should be, this should be the logo for HTMX.
50:01 Yes, it actually should.
50:02 Yeah.
50:02 This would be awesome.
50:03 Cause it really, it just tells you the churn.
50:06 And another person walks up and says, Hey, are you, are you trying to find a new workflow
50:10 for how we're working this?
50:11 No, I'm trying to figure out why I'm still doing this.
50:14 Well, there's, there's no way to go back to quit.
50:17 And there's, yeah.
50:22 Yeah.
50:22 And you found the Easter egg.
50:24 Yeah.
50:24 Well, also why is there still a separate QA department?
50:28 I love the leveraging of paid time off.
50:31 Yeah.
50:35 Backlog.
50:36 Backlog is like an afterthought.
50:38 If there's nothing else you can do, maybe you can work on the backlog.
50:41 Yeah, exactly.
50:43 Nice.
50:45 Awesome.
50:45 Well, thanks.
50:46 That's it.
50:47 Yeah.
50:47 That's it for our show, Brian.
50:48 Thank you.
50:48 As always.
50:49 Great to have you here.
50:50 And Paul, thanks for joining us.
50:51 Thanks for having me.
50:52 Love the show.
50:53 Love everything the two of you have been doing for the last few years and hope to tell you
50:58 this in person soon, but probably not.
51:01 Yeah.
51:02 That's wrong.
51:03 You said for me to interrupt you and tell you when you were wrong.
51:06 I forgot to.
51:07 Okay, great.
51:09 Keep happy thoughts.
51:11 Do you promise not to cut your hair until we see each other again?
51:14 Yes.
51:14 Yes.
51:16 I want to be cousin it by next year at this time.
51:19 Love it.
51:23 All right.
51:23 Bye.
51:24 Bye, guys.
51:25 Thanks for listening to Python Bytes.
51:26 Follow the show on Twitter via at Python Bytes.
51:29 That's Python Bytes as in B-Y-T-E-S.
51:32 Get the full show notes over at pythonbytes.fm.
51:35 If you have a news item we should cover, just visit pythonbytes.fm and click Submit in the
51:40 nav bar.
51:41 We're always on the lookout for sharing something cool.
51:43 If you want to join us for the live recording, just visit the website and click Livestream to
51:47 get notified of when our next episode goes live.
51:50 That's usually happening at noon Pacific on Wednesdays over at YouTube.
51:55 On behalf of myself and Brian Okken, this is Michael Kennedy.
51:58 Thank you for listening and sharing this podcast with your friends and colleagues.