Transcript #142: There's a bandit in the Python space
Return to episode page view on github00:00 Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to your earbuds. This is episode 142, recorded July 31st. I'm Michael Kennedy.
00:10 And I'm Brian Okken.
00:11 And I'm Brett Thomas.
00:12 And yes, we have a special guest this time, third co-host, Brett Thomas. Brett, welcome to the show.
00:17 Thank you very much.
00:18 Yeah, it's great to have you here. I also want to say thank you to Datadog for sponsoring the show.
00:22 Check them out at pythonbytes.fm/datadog. More on that later. Brett, do you want to just quickly tell everyone a little bit about yourself before we get into the topics?
00:29 Yeah, sure. I'm the chief technology officer of a company called FasterThanLight.dev, and we do static code analysis tooling for the SaaS model to help you analyze your code.
00:39 And I'll talk a little bit about that later.
00:40 All right. Awesome. Sounds good. Well, happy to have you here.
00:42 Brian, you want to kick us off?
00:44 Sure.
00:44 It's great to have sustainability and it's almost like Earth Day for code.
00:48 And you always want to just have that in mind, right?
00:51 Earth Day for code?
00:52 Sustainability. Come on. You got a role in the air.
00:55 Yeah, I'm really worried about what climate change is going to do to my code, but...
00:58 I ran across this article called writing sustainable Python scripts by Vincent Burnett and most of my time I'm not right I mean I don't really think about it too much for little scripts but or little helper utilities we've got lots of them around work but there is an issue that I think this is a reasonable thing to talk about is if it's only going to be a short-lived script yeah we don't really care about it too much but if it's going to be around for a while or it's running from a cron job or something it is there's a few things you can do to make it a little bit more maintainable.
01:31 And I like the things he put down.
01:33 The most obvious ones, which some people forget, is throwing a doc string at the top of the file to let people in the future know what problem you're trying to solve and kind of describe what it is.
01:45 Instead of doing hard-coded stuff, you can easily add some command line arguments.
01:51 The defaults can be sort of hard-coded defaults, but having some way to make the script useful.
01:58 And then he goes into adding logging.
02:01 And I think it's kind of neat.
02:02 He includes how to do debug logging and hook that into the command line argument system, which is kind of a cool trick.
02:10 And then also for unattended scripts, being able to log to system logging.
02:15 And then finally, finishing it off with adding some simple tests to make sure that your code does what you think it does.
02:22 It's just a nice little article.
02:23 - Yeah, it's easy to forget about maintaining these little scripts because they're kind of throwaway, but actually, then they're throwaway till they're not.
02:31 Go ahead, Brad.
02:32 - And the more throwaway you think it's gonna be, the more it's gonna be the longest lived part of your system, of course.
02:37 - Of course.
02:38 - Yeah.
02:39 - Yeah, I have a bunch of these, and I find that I even forget that they exist.
02:43 Like, I'll be doing something super painful, and I'm like, wow, this is really not fun.
02:47 Like, I've gotta rename all these files based on certain stuff out of the database or something.
02:52 Man, I should automate this.
02:53 Like, wait a minute, I think I did automate this.
02:55 And I'll go back and look, and I'm like, yeah, I can just run this thing, the command line, and like 100 files are properly renamed.
03:01 Why did I spend the last five minutes?
03:03 Why do my hands hurt now?
03:04 And so the way I got around solving that problem, often that involves like setting up a virtual environment, activating it, then running that script 'cause it has dependencies, like I mentioned the database or whatever, all the models and so on.
03:18 So what I'll do is I'll create an alias in my shell, And then I just run the alias.
03:22 And so if I go and just, like, if I forget, I'll go look at my aliases.
03:25 I only got like 50 or something.
03:26 Like, it's gotta be one of these, which, there it is.
03:29 And then I run it again.
03:30 And that's like, that's my system until my computer gets formatted, then I have to start from scratch.
03:35 - That's the great thing.
03:36 I was actually went through and audited my like dot profile, I know six months ago.
03:39 And I swear I've been, I've called around the same dot profile for I think two decades, right?
03:44 You know, it's like, there's aliases to do things on the systems that I haven't had access to for 20 years.
03:49 I'm like, okay, maybe it's time to clean that up.
03:51 - A little pruning.
03:52 Yeah, but no, it's a great article, Brian, to remind people just to do these little simple things.
03:58 I don't know, maybe there's some threshold, right?
03:59 You just play around, you do it once, but if you use it a third time, then you should go back and refactor and clean up a little, I don't know.
04:06 - Sometimes logging doesn't really make sense, and you can just, and sometimes testing, I mean, I'm shocked that I'm the person to say this, but sometimes manually testing stuff is fine.
04:17 If you're gonna notice when it breaks, - It works.
04:19 - Yeah, it definitely depends.
04:20 - What do we have next?
04:21 - Well, so the first thing I would like to talk about is a static code analysis using Bandit.
04:27 And for anyone who's not aware of what static code analysis is, static code analysis is basically running a computer program on your computer program, right?
04:36 I've actually recently heard somebody analogize it as like spell check for a computer program.
04:41 The reason it's called static code analysis, it's that separate from what we usually do in testing, which is dynamic, right?
04:46 We run the program, we give it various inputs, we see if it does what we think it should.
04:51 But static code analysis is about the idea of examining either the source code or the object code and saying, okay, we're gonna look for patterns that look troublesome, right?
05:00 And so for example, one thing static code analysis might help you look for might be SQL injection attacks, right, where you've got unbound SQL variables, which is just an absolutely perennial security problem that's always in the OWASP top three.
05:14 - Select star from quote plus input name.
05:17 - Exactly, right?
05:18 I mean, and there's actually all kinds of great database performance reasons you want to bind your variables anyhow.
05:23 But if you don't know, definitely when you're doing SQL statements, you should be using placeholder variables and binding them instead of actually interpolating strings, especially if those strings come from some random person on the internet, as in the famous XKCD, Little Bobby Tables cartoon.
05:39 And so anyway, so Bandit is an open source tool that you can just grab.
05:43 And in fact, I believe you can just pip install it and it will, you run it on your code it tells you things that are problematic.
05:49 Now, of course, it doesn't know what your code's doing.
05:51 Sometimes, one of the rubs on static code analysis tools is that they tend to false positive a lot because they don't understand the context.
05:59 They say, "Okay, well, this pattern tends to be dangerous," but they don't know that the way that you're using it is absolutely fine.
06:06 Another just hard example that I got out of at one time is Flask.
06:11 If you're making a Flask app and you turn debugging on when you create the Flask object, which seems like a reasonable thing to do.
06:18 It actually enables a debug console, if you know the right place to go to on your web app, that allows you to execute arbitrary Python code unauthenticated.
06:27 You probably don't want to do that on the internet.
06:29 - That is super bad.
06:30 And Django has the same problem.
06:32 And like there's tools that search for that.
06:34 It's a big deal.
06:35 You don't want to publish it.
06:36 - Yeah, exactly.
06:37 I mean, and that's just one of literally dozens or scores of things that Bandit can help you find, you know, those kinds of errors in your code.
06:43 - Does Bandit do like Pythonic code?
06:45 - Well, let's say this numeric four should be just like an enumerate loop or something like that.
06:52 - Yeah, there's a number of different things that you can do that kind of like range from, oh, hey, this is not a best practice, or this doesn't go with the correct coding style, for example.
07:03 And certainly if you are super into that, I think that can be a great resource for you.
07:08 My personal focus on it, I think, tends to be more from the security side of things.
07:12 Somebody who has been running sensitive web apps on the internet now for 20 years.
07:16 That really is just in my DNA.
07:19 My prior position, actually, I was responsible for keeping several hundred million credit cards safe at a PCI DSS level one service provider called Vendicia.
07:27 - That will make you a little bit paranoid.
07:30 - Yeah, I mean, I don't know if you see the gray hairs there, but yeah, I sleep a lot better now that I don't have that weight on my shoulders, I have to admit, so.
07:38 (laughing)
07:39 - I can imagine.
07:40 One of the most stressful bit of codes I wrote was the credit card processing system for this company where the individual purchases would be like three or $4,000.
07:48 And I'm like, yeah, better not mess it up.
07:50 That's what you're talking about is a whole nother level.
07:53 So static code analysis and Bandit can help find those types of problems as well there, huh?
07:57 Absolutely.
07:58 I'm a fan of these things.
08:00 The problem is you kind of got to--
08:02 sometimes, at least on large projects, you've got to start using them early enough.
08:05 Yeah.
08:06 Because otherwise, they'll just kill you.
08:08 Absolutely.
08:08 You've just got a huge thing to go through.
08:10 And actually, I gotta admit, my company, what we're doing is, my new company, Faster Than Light, we're working on packaging this stuff up as software as a service, and definitely helping you manage that, like, oh, hey, I've already looked at this, and it's not a problem kind of thing for large projects is one of the things that we're really trying to work on fixing for people.
08:28 - Right, if you can put the little code comment or whatever that says, please suppress this warning here, because we reviewed it.
08:34 - Actually, a customer I was talking to, it's like they've got an Android app they're shipping.
08:39 well, the Android scanner, and this is obviously not Python, but the Android scanner is like, whoa, you've got an API key in your code, ah, right?
08:46 You know, and it's like, well, yeah, but it's an API key that has been carefully restricted so that it can only make one read-only call.
08:53 And so like, it's okay, right?
08:55 You know, and it's kind of like having, you know, kind of like that extra nervous person who occasionally freaks out and you're like, no, no, no, no, really, it's okay.
09:03 It's not, this isn't a problem, so.
09:05 - Cool, yeah.
09:05 All right, so Bandit, pretty awesome.
09:07 I know it does a lot of good stuff for Python.
09:08 - And they actually list out all the stuff they check on their site, right?
09:11 - Yeah, there's definitely a big document you can get with all their tests.
09:14 - Super.
09:15 All right, so the next one I wanna talk about is Black.
09:18 And Brian, you're a fan of Black, right?
09:20 - Yep.
09:20 - Brett, do you use Black?
09:21 Do you know this code formatter?
09:22 - No, I'm not familiar with it myself.
09:23 I'd love to hear.
09:24 - It basically takes what Flake 8 does and some of these other linting tools, a little bit like you were talking about.
09:30 Instead of saying, this file's too long, you should change it.
09:34 This variable name is unused, or this indentation is not right, or whatever, instead of just giving you a bunch of warnings, it just rewrites your code to conform to its standard.
09:44 And long as you are willing to live with a standard, a lot of people put it as like a GitHub pre-commit hook or something like that, and then just the whole team is just straight up on this type.
09:55 So it's really, really popular these days over the last year or so.
09:59 However, one of the things that's super annoying is there's a lot of places where you write code where you cannot apply these kind of tooling, and a lot of it is in places like Jupyter Notebooks or online editors, and you're like, well, you can type your code in here, but it's like, well, but I can't format my code in here, and I'm doing space a lot to line up stuff, and it's making me crazy, like that kind of stuff, right?
10:21 So if you use Jupyter, there's a thing that came out called Jupyter-Black, Jupyter Black, and it's a super simple Jupyter Notebook plugin that gives you a hotkey to apply black formatting to your Jupyter Notebooks online.
10:35 Does that work with the Flask debug console?
10:37 - No, I don't think so.
10:38 I don't think so.
10:39 But yeah, so I think this is super helpful for the data scientists who are out there writing code or maybe even if you're a teacher and you're getting other people's code, you know, like, I can't look at this.
10:49 What is this?
10:50 Like these freshmen.
10:51 (laughing)
10:52 You know, control B, okay, freshmanitis is gone.
10:55 I can read this.
10:56 It's properly formatted like a professional.
10:58 Now let's review it.
10:59 Things like that.
11:00 I just think it really brings a cool tool to a new place and I'm sure it'd be really welcome.
11:05 You answered my question that I had right away, is does it format just the current cell or the whole thing?
11:10 And yeah, there's two different keyboard options, Control + B and Control + Shift + B, that do both of those.
11:17 - Yeah, Control + Shift + B is probably the one you want.
11:19 But there's also a little toolbar button if you are not a hotkey person.
11:23 So yeah, it's super simple.
11:24 It just plugs in like a standard Jupyter Notebook extension, which I don't really do a ton with, but it sounds really easy to install it.
11:31 And then the only other requirement is that you have black installed on the system or the virtual environment, 'cause it has to like basically shell out to black and figure out what's happening, all right?
11:41 Before we get onto the next topic though, let me just quickly tell you about Datadog.
11:45 So this episode, like many of ours, is sponsored by Datadog.
11:50 They're a cloud monitoring platform built by engineers for engineers like all of us, right?
11:56 And so what it does is it auto instruments Django, Flask, Postgres, MongoDB, AsyncIO, all these different things, and will allow you to trace your requests across servers, across processes, and bring you basically a holistic view of what is the request doing?
12:14 'Cause it's great to profile your Python code, but there's a whole lot of other stuff happening that's maybe where most of the stuff is happening, right?
12:21 In the database or in the framework or whatever.
12:23 And so this brings it all together and it integrates with over 350 technologies, Hadoop, Redis, all the good stuff.
12:29 So check them out.
12:31 They got a free trial, pythonbytes.fm/datadog, and you also get a sweet Datadog t-shirt.
12:36 So that alone makes it worth it, I think.
12:38 All right, Brian, what's this next one you got here?
12:40 - Well, I'm glad that we checked ahead of time and make sure that we've had two Jupyter articles.
12:44 - Yeah, right next to each other, that's perfect.
12:46 - Yeah, this is involving Paper Mill, and I think I'm pretty sure we've talked about Paper Mill before, at least briefly.
12:53 - We covered Paper Mill live at PyCon.
12:55 - Oh yeah, right.
12:56 So I included this because it's a two-part article series that talks about the entire workflow, which that's where it seemed, it looked pretty interesting to me.
13:04 So this, Chris Moffett wrote part one and part two of automated report generation with Paper Mill.
13:10 So it's taken Jupyter Notebooks that use Pandas and Matplotlib to create a report, and then using NBConvert to take that and create an HTML report, and then go through and use Paper Mill to parameterize the input of this entire process and to set up execute blocks.
13:31 And then he completed the process, talked about the rest of the workflow, about using a new tool that I've never heard of before, which is called rclone, to clone different cloud directory services and keep the same directory on lots of different cloud services.
13:45 And then how to, if you're in a Linux box, using Cron to set up a regular process for this whole thing.
13:54 I mean, the example is a simple thing, like a monthly sales report that you want to have just go out.
14:00 Somebody can pop in the data in a spreadsheet or something like that, but then all the reporting and the data analysis and everything can happen afterwards.
14:08 And just going through from the top to the bottom, the whole workflow, I thought was a real nice touch.
14:13 I love this because it takes the boring stuff that you don't want to do, and it just hands it over to the computers in a beautiful way.
14:21 some of the really new and nice tools, Paper Mill, Jupyter, and so on, and it just automates it all.
14:28 So instead of like every Friday, you're like, "Oh, there's that two hours of copying data from system to system for the report," it's like, "It just shows up in the email.
14:37 It's just on the internet," or whatever, right?
14:39 This is really cool.
14:40 And just to summarize Paper Mill, basically it turns Jupyter Notebooks into functions or command line style applications, it can be called.
14:48 you provide data to it, inputs, it runs, and then output comes out.
14:52 So you have the general analysis report.
14:55 You feed like, hey, it's from July 1st to July 31st, drop the files here, go.
15:00 - Yep, it's nice.
15:01 - Yeah, very cool.
15:02 Brett, you got any things like this that you guys gotta do at Faster Than Light?
15:04 - We are still new enough.
15:06 I've gotta admit, I literally was just thinking to myself this morning about how I really need to start writing some nightly reports that tell me what all everybody was doing in the system yesterday.
15:15 So we actually still haven't completely fully launched.
15:18 So thankfully there isn't too much yet that I need to know about that's, you know, it's like, oh yeah, how many tests did I run yesterday?
15:25 You know, it was kind of what I would be getting here.
15:28 But yeah, that's definitely something that I'll be looking at as we start to do our release.
15:34 - Yeah, you're in that beautiful place where the molasses of real life day-to-day business operations hasn't hit you yet.
15:40 You can go quick and build things.
15:41 - Absolutely, and I gotta say, it is so strange having run four nines plus environment for a decade and a half to all of a sudden be like, oh yeah, production's down, nobody noticed, right?
15:54 'Cause you haven't actually done anything yet, so.
15:55 - It's a different world, it's a different world.
15:57 Cool, all right, well you got the next item.
15:59 Tell us about it.
16:00 - Actually, it's a little bit of a rant for me because it was something that was just kind of surprising to me given how much is in the Python standard library and how much just, there's one of the things that's really great about Python is this, hey, how do I do this thing?
16:13 And it's like, oh wow, it's in the standard library and you just call a function and it works.
16:18 And that is that quite a while ago, I ported a database from an application from a Postgres database to an Oracle database, which I know is a ridiculously stupid thing to do, but a customer was paying us a lot of money to do it.
16:29 And I discovered that Postgres is interval types, which is just when you're doing a timestamp and you go, okay, I wanna add a week to this or a day or whatever.
16:40 There's an SQL type that's called an interval where you can just have arbitrary amounts of time you can add to a timestamp.
16:45 Well, so Postgres lets you do anything completely arbitrary.
16:48 What turned out, Oracle didn't.
16:50 And it took me a little while to kind of understand why.
16:52 And I actually ended up having to write my own interval parser.
16:54 So I really had to like understand how all this stuff works.
16:57 And it turns out that all date intervals really at the end of the day, boil down to a number of seconds or a number of months.
17:04 It's one of those two things.
17:06 Because if you think about it, a week is a number of days and a day is a number of hours and an hour is a number of minutes and a minute is a number of seconds.
17:14 And if you've been a developer for any length of time, you probably know off the top of your head that there are 86,400 seconds in a day because it just comes up all the time and you remember it.
17:24 But the other two is months and years, and a month is not a constant number of seconds.
17:29 It's anywhere from 28 to 31 days.
17:32 And depending upon how many that is, that actually varies by what year it is.
17:36 And it's actually really kind of difficult to tease all that apart.
17:39 And so it actually turns out if you use the date time library that comes with Python and you use the time delta object that comes with it, and you try to set an offset of months or years, it just says, "Sorry, can't do that." I can't tell you what a month from now is.
17:55 That was just really surprising to me and really frustrating.
17:59 Because actually, the reason why I needed this is actually I was setting up our subscriptions service, although I will say, of course, I'm not actually hanging onto the credit cards now.
18:07 But I wanted to be able to test it.
18:09 I want to say, "Okay, we'll start your subscription.
18:13 let's go a month and a day out and see if your subscription is still active because it shouldn't be.
18:17 And said, oh wow, okay, you can't do that. So there is another package out there that you can just get off of pip.
18:22 It's the dateutil package and it has a time delta replacement called relative delta that just supports months and years and works very similar to the time delta thing.
18:32 So if you've got the problem of, oh, hey, I want to know what it is a month from now or ten years from now, that'll let you calculate those timestamps.
18:41 'Cause of course the problem is that parsing that stuff, like when you write the library, when you're advancing months, I mean, it's gotta be text-based, right?
18:47 You gotta go, okay, I'm gonna turn this thing into a date string, and then I'm gonna increase the number of months and see if I've overflowed the number of years, increase the number of years, and then turn it back into a timestamp.
18:59 So it's a much slower process from a calculation perspective.
19:03 And I suspect that's probably why the original Python library doesn't just support it out of the box.
19:08 - Yeah, but that is frustrating, right?
19:09 'Cause that totally reasonable thing and actually the hardest of all things to compute is how many months from now is it?
19:15 Close to that is how many years, right?
19:16 - Yeah, it can be just, and of course, actually we're running up, we're gonna run up against the Unix 2037 thing right now, which by the way, I saw someone point out, I hadn't actually thought about this.
19:25 There are places, businesses that are trying to do things like generate a certificate that expires in 20 years.
19:30 Like you can actually run into that problem in your code now if you're still running on, if you're not running on 64 bit native code, which is actually, as I understand, a bit of a problem still in Linux.
19:40 The Linux kernel is not doing a good job of handling all of that.
19:43 That's gonna be an increasing problem as we get closer to that barrier.
19:47 - Sounds like a great opportunity for consultants.
19:49 - Oh yeah, I'm sure.
19:50 I mean, it would not surprise me if I, in my career as a year 2037 consultant, right, as one of the last people who still knows how to program those old systems.
20:00 - Yeah, this is a good recommendation.
20:01 I like the DateUtil library.
20:03 I love the parsing for it, right?
20:07 - Parsing date times, it's annoying in Python.
20:10 Parse, ST, I can't remember even, 'cause I stopped using it, 'cause I just import parse from dateUtil, and I'm good, right?
20:18 - Yes.
20:18 - It seems to be able to guess the format that you're going for really, really well.
20:22 - I was doing a bunch of coding recently with DynamoDB, and it was just like the timestamps you get back out of the Bodo3 library is just like one character off of what you can natively parse.
20:33 It was just like, why does this have to be so painful?
20:37 - The date you tilted?
20:38 - Yeah, you know, the date I was getting out of Boto3, I don't remember the exact details, but the date I was getting out of Boto3 had like one, it was like, it was like, so I literally am doing like a, you know, a text substitution on a particular character to turn it into something else so that it'll then parse it.
20:51 - Cool, I do that on XML to get rid of the namespaces all the time.
20:54 All right, so Brian, before we've spoken about understanding the language and some of the core language features, and I just want to come back to this topic a little bit and focus on Python generators.
21:07 So there was a cool article recommended to us by one of the listeners.
21:11 It's not super new, but we haven't covered it, so I think it's totally relevant.
21:14 It's an article by Radu Racia, hopefully I'm getting that roughly right, and it's called How and Why You Should Use Python Generators.
21:22 So basically it talks about what are generators, how you should use them, and I wanted to cover this 'cause I feel like there's a lot of people that come from other languages, and it's both a blessing and a curse of Python that people can come from C or Java or JavaScript or other languages and just go, ah, this is simple.
21:41 I learned it in a weekend.
21:42 Let me write my code now.
21:44 And they're doing numerical for loops.
21:46 And they're doing tons of stuff that is not really Pythonic.
21:49 And they've got 27 Stack Overflow tabs open for, oh, how do I open a file again?
21:55 Yes, exactly.
21:56 And so a lot of languages don't have this idea of generators or coroutines, which are just amazing.
22:02 You've got a function.
22:03 it's gonna process some huge amount of data.
22:05 Maybe it needs to read a 10 gigabyte file and parse it line by line.
22:09 Well, if you write that as a generator, if you only pull 10 lines from it, it only reads 10 lines.
22:15 Or even if you gotta go through all of it, it only loads one line into memory at a time.
22:19 And often the implementation of the generator using the yield keyword is actually simpler, shorter, cleaner than if you were to try to build it up into a list and then return that list and all those kinds of things.
22:28 - And code that doesn't exist doesn't have bugs in it.
22:31 - That's a good point, yes.
22:32 code that doesn't exist does definitely not have bugs in it.
22:35 So this article is good if these generator ideas are new to you.
22:39 It talks about the lazy evaluation, which is really important to understand, and gives you a couple of simple examples.
22:45 It's not super deep, so if you're new, read through it.
22:47 If you really know it pretty well, you probably won't gain a whole lot about it.
22:51 But it's something you could shoot over to your coworkers.
22:52 You're like, why did you write this code?
22:54 Please don't do that again.
22:55 Use this.
22:56 Yeah, this is good.
22:57 Even myself, an experienced Python person, there's certain times where I'm like, Why didn't I think of using a generator earlier?
23:04 - Yeah, absolutely.
23:05 I mean, you don't always know that that's really the best path.
23:09 You just start writing the code.
23:10 You're like, "Ah, I'm gonna have a list.
23:11 "I'm gonna put stuff in the list.
23:12 "I'm gonna do this.
23:13 "I'll get a dictionary, whatever." Like, wait a minute.
23:15 Actually, I didn't need any of that.
23:16 I could do it way better, right?
23:17 So you kind of gotta have it in mind.
23:18 I would love it if tools like PyCharm and VS Code had a button to refactor to generator, right?
23:24 Convert this list and return the list into a generator.
23:27 It probably doesn't exist because way you process the results has some kind of effect, right?
23:33 You can't go through a generator twice, but you can go through a list twice, or things like that.
23:38 But it still would be really cool if you could automate that a little bit.
23:41 Yeah, I was thinking more along the lines of when I have my custom data structure that is essentially a container structure, and I forget to add it or next to it so that generators can be used with it.
23:53 Yeah, exactly.
23:54 You can fit it into that whole pipeline.
23:56 Cool.
23:56 Well, that's it for our main items this week.
23:58 You got anything else you want to quickly give a shout out to, Brian?
24:01 -Well, I just saw that we've got a link to PyPI now supporting API tokens.
24:07 There's been a lot of recent changes to the PyPI interface to make it more secure.
24:14 And this is just one of the latest.
24:16 And I think it's a good way.
24:18 They're doing well about making sure that these changes are supported on the test server as well, so that you can test out the changes first.
24:26 -Yeah, that's pretty good.
24:28 So you don't have to just do it on the immutable right only or right once.
24:32 Real version.
24:33 Yeah.
24:34 Yeah.
24:34 Super cool.
24:35 So I think this is like evidence, you know, there was a big push and that funding that grant from Mozilla to basically modernize PyPI, right.
24:43 And the work that the PIPA did to, to move that along.
24:46 It's like, now you can start seeing these new features coming in because previously it was like, no one wants to touch that.
24:52 There's no way we're adding new features.
24:53 Like we're just trying to keep it from breaking.
24:55 Now it can grow.
24:56 It's cool.
24:56 Yeah.
24:57 It's nice.
24:57 I got a couple I want to give a quick shout out to.
24:59 Last week, we covered possibility of this exploration of moving to PEG parsers, as opposed to the original sort of one-off version of the parser that Guido van Rossum had written for Python 30 years ago.
25:15 And so now he's written another article talking about building a PEG parser and moving towards it and so on.
25:20 So if that was interesting to you, you can check out that follow-up that he wrote.
25:24 And then finally, we've talked a lot about Homebrew.
25:26 and obviously people know about Apt and other package managers on Linux, but I don't think we've really talked that much about Windows, right?
25:35 You don't have Homebrew on Windows or many other things like that.
25:38 So, Preston Daniel sent us over a quick message, said, "Hey, if you guys get a chance, "you should give a shout out "to the Chocolaty package manager on Windows." You familiar with this, Brian?
25:48 - No, I've never used it.
25:49 - No, I've never used it.
25:50 Actually, I do all of my Python, or a lot of my Python development actually under Windows, but I'm using WSL, so I don't actually do anything natively in Windows.
25:59 - Yeah, yeah, so in a sense, you have the Windows UI, but it's kind of Linux-y in some of the tooling.
26:04 - WSL was just kind of magic.
26:06 I mean, it definitely is in that, the thing that's amazing here is not how well the bear dances, but that it dances at all.
26:13 But yeah, I have a Windows gaming laptop I bought years ago, and now that I'm in a startup, of course, I'm using whatever hardware I had laying around in order to not spend any money, right?
26:21 And so, yeah, that's my development laptop is my old gaming laptop.
26:25 So yeah, it's all WSL and like I'm like simulating AWS services on it so that I can develop offline and stuff It's just I'm just it boggles me that you can actually do all of this stuff at all. Yeah, that's super cool. That's super cool Yeah, so chocolatey is like homebrew basically but for Windows so you can say Choco install such-and-such and I link to Python Right. So actually on Chocolatey you can now install Python 374 which is kind of impressive right that came out like a couple weeks ago But if you actually look at the versions, you can install Python 3.8 Beta 3, which came out yesterday, right?
27:00 Like it's right on top.
27:02 And they even do like limited virus scanning and like validation a little bit.
27:06 So yeah, it's a pretty cool little system.
27:09 And people should definitely check it out if they're doing work natively on Windows.
27:12 - Yeah, nice.
27:13 - Brett, anything else you wanna throw out there while you're here?
27:15 - That's probably all the great Python ideas that I have at the moment, so.
27:19 - All right, super.
27:20 - How about a joke?
27:21 - Yeah, how about a joke?
27:22 I actually have a couple of jokes for you.
27:23 a programming joke and then just an adulting joke following up on that.
27:27 So it's more of, I guess, more of an assessment.
27:30 A good programmer is someone who always looks both ways before crossing a one-way street.
27:35 (laughing)
27:37 Does that connect with you, Brian, as a tester?
27:38 - Yes, definitely.
27:39 Having just gotten back from wandering around in London and always looking the wrong way when crossing a one-way street, that resonates with me.
27:47 - That's awesome, yeah, I'm always paranoid when I'm in London or in Australia.
27:50 Like, I'm like double checking both directions.
27:52 They're like, "You just gotta look that way." I'm like, "No, if that's what you say now, "then there's gonna be the time I look the wrong way "and one of those big red buses is gonna crush me." And I'm just, you know, so I'm just like a paranoid squirrel trying to cross the street in the UK, it's great.
28:06 Yeah, so then related to that, not quite programming, but adulthood is like looking both ways before crossing the street and then getting hit by an airplane.
28:14 (laughing)
28:15 All right, I wanna throw one more in there, though.
28:17 Oh, go ahead, Brian.
28:18 - No, I think that's good, that's funny.
28:20 - It's a little too real to be funny, though.
28:21 Like we aren't laughing like, yeah, that hurt.
28:25 All right, so Brett, you started this one.
28:27 So I'm going to throw it out here for everyone.
28:30 Little Bobby Tables.
28:31 Brian, do you know about Little Bobby Tables?
28:33 Well, I remember it, but I probably couldn't explain it.
28:35 Yeah, so it's XKCD.
28:37 And I'll just read it.
28:38 We'll just leave it out there for folks.
28:40 It's a mom answering the phone and says, hi, this is your son's school.
28:44 We're having some computer trouble.
28:46 Oh dear, did he break something?
28:48 In a way.
28:49 Did you really name your son Robert quote, parenthesis, semicolon, drop table students, quote, semicolon, dash dash?
28:56 Oh yes, little Bobby Tables we call him.
28:58 Well, we've lost years of student records.
29:01 I hope you're happy.
29:02 And I hope you've learned to sanitize your database in foot.
29:04 (both laughing)
29:06 - The thing I really love about this idea is that she has saddled this child with this terrible name for this one opportunity, right?
29:14 I mean, you know, when he gets to be 24, it's never gonna work again, right?
29:18 I mean, I guess unless he goes on to be a teacher, then he can just cause havoc wherever he goes for the rest of his life.
29:23 - It sounds crazy, but there's this pen tester, penetration tester, who has a Tesla.
29:27 And in the app, you can change the name of your Tesla.
29:31 He changed it to a JavaScript injection string, and it went off when his car had to go get some service.
29:38 - Yep, I believe it.
29:40 I just have to say, as a general aside about anything, as somebody who ran a PCI DSS compliant thing for a long time, get pen tested.
29:47 Like every time I got pen tested, those people came up with something creative and I learned something, you know?
29:52 Like that's, like take the first dollar that you have to spend on security and hire a pen tester.
29:57 - Yeah, that sounds like good advice for sure.
29:59 All right, well, that looks like it.
30:00 That's it for us, you guys.
30:02 Brian, thanks as always.
30:03 And Brad, thank you for coming this time.
30:04 - My pleasure.
30:05 - Yeah, thank you.
30:06 - Yep, bye everyone. - Bye bye.
30:07 - Thank you for listening to Python Bytes.
30:09 Follow the show on Twitter via @pythonbytes.
30:11 That's Python Bytes as in B-Y-T-E-S.
30:14 And get the full show notes at pythonbytes.fm.
30:17 If you have a news item you want featured, just visit pythonbytes.fm and send it our way.
30:22 We're always on the lookout for sharing something cool.
30:24 On behalf of myself and Brian Okken, this is Michael Kennedy.
30:27 Thank you for listening and sharing this podcast with your friends and colleagues.