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.
And I'm Brian Okken.
And I'm Brett Thomas.
And yes, we have a special guest this time, third co-host, Brett Thomas. Brett, welcome to the show.
Thank you very much.
Yeah, it's great to have you here. I also want to say thank you to Datadog for sponsoring the show.
Check them out at pythonbytes.fm/datadog. More on that later.
Brett, you want to just quickly tell everyone a little bit about yourself before we get into the topics?
Yeah, sure. I'm the chief technology officer of a company called FasterThanLight.dev.
And we do static code analysis tooling for, you know, the SAS model to help you analyze your code.
And I'll talk a little bit about that later.
All right. Awesome. Sounds good. Well, happy to have you here.
Brian, you want to kick us off?
Sure.
It's great to have sustainability. And like, it's almost like Earth Day for code.
And like, you always want to just have that in mind, right?
Earth Day for code?
Sustainability. Come on. You got to roll in the air.
Yeah, I'm really worried about what climate change is going to do to my code, but...
I ran across this article called Writing Sustainable Python Scripts by Vincent Burnett.
And most of my time, I'm not writing... 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 a long-lived script, yeah, we don't really care about it.
And there are things you can do to make it a little bit more maintainable.
And I like the things he put down.
And then the most obvious ones, which is 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.
Instead of doing like hard-coded stuff, you can have easily add some command line arguments with...
Defaults can be sort of hard-coded defaults, but having some way to make the script useful.
And then he goes into adding logging.
And I think it's kind of neat.
He includes how to do debug logging and hook that into the command line argument system, which is kind of a cool trick.
And then also for unattended scripts, being able to log to system logging.
And then finally, finishing it off with adding some simple tests to make sure that your code does what you think it does.
It's just a nice little article.
Yeah, it's easy to forget about maintaining these little scripts because like they're kind of throwaway, but actually then they're throwaway until they're not.
Go ahead.
And the more throwaway you think it's going to be, the more it's going to be the longest-lived part of your system, of course.
Of course.
Yeah.
Yeah, I have a bunch of these, and I find that I even forget that they exist.
Like, I'll be doing something super painful.
And I'm like, wow, this is really not fun.
Like, I've got to like rename all these files based on like certain stuff out of the database or something.
Like, man, I should automate this.
Like, wait a minute.
I think I did automate this.
And I'll go back and look.
I'm like, yeah, like I can just run this thing in the command line.
And like 100 files are properly renamed.
Why did I spend the last five minutes?
Why do my hands hurt now?
You know, like, 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 because it has dependencies.
Like I mentioned the database or whatever, the models and so on.
So what I'll do is I'll create an alias in my shell.
And then I just run the alias.
And so if I go and just like, if I forget, I'll go look at my aliases.
I only got like 50 or something.
Like, it's got to be one of these, which there it is.
And then I run it again.
And that's like, that's my system until my computer gets formatted.
Then I have to start from scratch.
That's the great thing.
I was actually went through and audited my like dot profile.
I know six months ago.
And I swear I've been, I've called around the same dot profile for, I think, two decades.
Right.
You know, it's like there's aliases to do things on the systems that I haven't had access to for 20 years.
I'm like, what?
Okay, maybe, maybe it's time to clean it up.
A little pruning.
Yeah.
But no, this is a great, a great article, Brian, to like remind people just to do these little simple things.
I don't know.
Maybe there's some threshold, right?
You just like play around, you do it once.
But like if you use it a third time, then you should go back and like refactor and clean up a little.
I don't know.
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.
If you're going to notice when it breaks, it works.
Yeah, it definitely depends.
Well, what do we got next?
Well, so the first thing I would like to talk about is a static code analysis using Bandit.
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?
I've actually recently heard somebody analogize it.
It's like spell check for a computer program.
The reason it's called static code analysis, it's that separate from what we usually do in testing, which is dynamic, right?
We run the program.
We give it various inputs.
We see if it does what we think it should.
But static code analysis is about the idea of examining either the source code or the object code and saying, okay, we're going to look for patterns that look troublesome, right?
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, you know, just an absolutely perennial security problem that's, you know, always in the OWASP top three.
Select star from quote plus input name.
Exactly, right?
I mean, and there's actually all kinds of great database performance reasons you want to bind your variables anyhow.
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, you know, the famous XKCP Little Bobby Tables cartoon.
And so anyway, so Bandit is an open source tool that you can just grab.
And in fact, I believe you can just pip install it and it will, you run it on your code and it tells you things that are problematic.
Now, of course, it doesn't know what your code's doing.
Sometimes, you know, 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, right?
They say, okay, well, this kind of pattern tends to be kind of dangerous, but they don't know that the way that you're using it is absolutely fine.
You know, another just kind of hard example that I got out of out of it one time is Flask.
You know, 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, 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 on authenticated.
You probably don't want to do that on the internet.
That is super bad.
And Django has the same problem.
And like there's tools that search for that.
It's a big deal.
You don't want to publish.
Yeah, exactly.
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.
Does Bandit do like Pythonic code?
Let's say this numeric four should be just like an enumerate loop or something like that.
Yeah, there's a number of different things that you can do that, you know, that kind of like range from, oh, hey, this is not a best practice or, you know, there's not this, you know, doesn't go with, you know, the correct coding style, for example.
And certainly if you are super into that, I think that can be a great resource for you.
You know, my personal focus on it, I think, tends to be more from the security side of things.
Somebody who has been running sensitive web apps on the Internet now for 20 years, that really is just in my DNA.
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.
That will make you a little bit paranoid.
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.
I can imagine that 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 four thousand dollars.
And I'm like, yeah, better not mess it up.
That's what you're talking about is a whole nother level.
So static code analysis and Bandit can help like find those types of problems as well there.
Absolutely.
I'm a fan of these things.
You know, it's the problem is you kind of got it.
And sometimes at least on large projects, you got to start using them early enough.
Yeah.
Because otherwise.
Absolutely.
You've just got you've got a huge thing to go through.
And actually, I got to admit, my company, what we're doing is my new company, Faster Than Light.
We're working on packaging this stuff up as a software as a service and definitely helping you manage that.
Like, oh, hey, you know, 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.
Right.
If you can put the little code comment or whatever that says, please suppress this warning here because we reviewed it.
Actually, a customer I was talking to, you know, it's like they've got an Android app they're shipping.
You know, well, the Android scanner and this is obviously not Python, but the Android scanner is like, whoa, you've got an API key, you know, in your code.
Ah, right.
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.
And so, like, it's okay, right?
You know, and it's, you know, 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.
It's not, it's, this isn't a problem.
So.
Cool.
Yeah.
All right.
So Bandit, pretty awesome.
I know it does a lot of good stuff for Python.
And they actually list out all the stuff they check on their site, right?
Yeah.
There's definitely a, you know, big document you can get with all their tests.
So.
Super.
All right.
So the next one I want to talk about is black.
And Brian, you're a fan of black, right?
Yep.
Brett, do you use black?
Do you know this code formatter?
No, I'm not familiar with it myself.
I'd love to hear.
It basically takes what, like, Flake 8 does and some of these other linting tools, a little bit like you were talking about.
Instead of saying, this file is too long, you should change it.
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.
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.
So it's really, really popular these days over the last year or so.
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?
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.
Does that work with the Flask debug console?
No, I don't think so.
I don't think so.
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're like, I can't look at this.
What is this?
Like these freshmen.
Control B.
Okay.
Freshman-itis is gone.
I can read this.
It's properly formatted like a professional.
Now let's review it.
Things like that.
I just think it really brings a cool tool to a new place.
And I'm sure it would be really welcome.
You answered my question that I had right away is, does it format just the current cell or the whole thing?
And yeah, there's two different keyboard options.
Control B and Control-Shift-B that do both of those.
Yeah.
Control-Shift-B is probably the one you want.
But there's also a little toolbar button if you are not a hotkey person.
So yeah, it's super simple.
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.
And then the only other requirement is that you have Black installed on the system or the virtual environment.
Because it has to like basically shell out to Black and figure out what's happening.
All right.
Before we get on to the next topic, though, let me just quickly tell you about Datadog.
So this episode, like many of ours, is sponsored by Datadog.
They're a cloud monitoring platform built by engineers for engineers, like all of us, right?
And so what it does is it auto instruments Django, Flask, Postgres, like 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 like what is the request doing.
Because it's great to like 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?
In the database or in the framework or whatever.
And so this brings it all together.
And it integrates with over 350 technologies.
Hadoop, Redis, all the good stuff.
So check them out.
They've got a free trial, pythonbytes.fm/Datadog.
And you also get a sweet Datadog t-shirt.
So like that alone makes it worth it, I think.
All right, Brian, what's this next one you got here?
Well, I'm glad that we checked ahead of time and make sure that we've had two Jupyter articles.
Yeah, right next to each other.
That's perfect.
Yeah.
This is involving Paper Mill.
And I think I'm pretty sure we've talked about Paper Mill before, at least briefly.
We covered Paper Mill live at PyCon.
Oh, yeah, right.
Yeah.
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.
So this Chris Moffitt wrote part one and part two of automated report generation with Paper Mill.
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.
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.
And then how to, if you're in a Linux box using Cron to set up a regular process for this whole thing.
I mean, the example is a simple thing like a monthly sales report that you want to have just go out.
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.
And just going through the, from the top to the bottom, the whole workflow, I thought was a real nice touch.
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 like a beautiful way, taking some of the really new and nice tools,
Paper Mill, Jupyter, and so on.
And it just automates it all.
So instead of like every Friday, you're like, oh, there's that two hours of like copying data from system to system for the report.
It's like, it just shows up in the email, right?
It's just on the internet or whatever, right?
This is really cool.
And just to summarize Paper Mill, basically it turns Jupyter Notebooks into like functions or command line style applications.
It can be called.
You provide data to it, inputs, it runs, and then output comes out.
So you have the general analysis report.
You feed like, hey, it's from July 1st to July 31st.
Drop the files here.
Go.
Yep.
It's nice.
Yeah, very cool.
Brett, you got any things like this that you guys got to do at Faster Than Light?
We are still new enough.
I've got to admit, I was 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.
So we actually still haven't completely fully launched.
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?
You know, is kind of what I would be getting here.
But yeah, that's definitely something that I'll be looking at as we start to do our release.
Yeah, you're in that beautiful place where the molasses of real life day-to-day business operations hasn't hit you yet.
You can go quick and build things.
Absolutely.
And I got to say, it is so strange having run four nines plus environment for, you know, a decade and a half to all of a sudden be like, oh, yeah, you know, production's down.
Nobody noticed, right?
You know, because you haven't actually done anything yet.
So it's a different world.
It's a different world.
Cool.
All right.
Well, you got the next item.
Tell us about it.
Actually, it's a little bit of a rant for me because it was something that was just kind of surprising to me given the how much is in the Python standard library and how much, you know, just, you know, there's one of the things that's really great about Python is this, hey, how do I do this thing?
And it's like, oh, wow, it's in the standard library and you just call a function and it works.
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.
And I discovered that Postgres is interval types, which, you know, is just, you know, when you're doing a timestamp and you go, okay, I want to add a week to this or a day or whatever.
There's an SQL type that's called an interval where you can just have arbitrary amounts of time that you can add to a timestamp.
Well, so Postgres lets you do anything completely arbitrary.
What turned out, Oracle didn't.
And it took me a little while to kind of understand why.
And I actually ended up having to write my own interval parser.
So I really had to, like, understand how all this stuff works.
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.
It's one of those two things.
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.
You know, 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.
But the other two is months and years.
And a month is not a constant number of seconds.
It's anywhere from 28 to 31 days.
And depending upon how many that is, that actually varies by what year it is.
And it's actually really kind of difficult to tease all that apart.
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.
Right.
You can't do, I can't tell you what a month from now is.
So that was just really surprising to me and really kind of frustrating 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 on to the credit cards now, but I wanted to be able to test it.
Right.
And so I want to say, okay, if we, you know, if you're, if we'll start your subscription, let's go a month and a day out and see if your subscription is still active because it shouldn't be.
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.
It's the date util 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.
So if you've got the problem of, oh, hey, I want to know what it is a month from now or 10 years from now, that'll let you calculate those timestamps.
Because, of course, the problem is that parsing that stuff, like when you write the library, when you're advancing months, I mean, it's got to be text based.
Right.
You got to go, okay, I'm going to turn this thing into a date string and then I'm going to 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.
So it's a much slower process from a calculation perspective.
And I suspect that's probably why the original Python library doesn't just support it out of the box.
Yeah.
But that is frustrating, right?
Because a totally reasonable thing.
And actually, the hardest of all things to compute is how many months from now is it?
Close to that.
It's how many years, right?
Yeah.
It can be just.
And of course, actually, we're running up, we're going to 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.
There are places, businesses that are trying to do things like generate a certificate that expires in 20 years.
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.
The Linux kernel is not doing a good job of handling all of that.
That's going to be an increasing problem as we get closer to that barrier.
Sounds like a great opportunity for consultants.
Oh, yeah.
I'm sure.
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.
Yeah, this is a good recommendation.
I like the DateUtil library.
I love the parsing for it.
I like parsing date times.
It's annoying in Python.
Parse, ST, I can't remember even.
Because I stopped using it.
Because I just import parse from DateUtil, and I'm good, right?
Yes.
It seems to be able to guess the format that you're going for really, really well.
I was doing a bunch of coding recently with DynamoDB, and it was just like the timestamps you get back out of the Boto3 library is just like one character off of what you can natively parse.
It was just like, why does this have to be so painful?
Did DateUtil take it?
Yeah, no, a 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, so I literally am doing like a text substitution on a particular character to turn it into something else so that it'll then parse it.
Cool.
I do that on XML to get rid of the namespaces all the time.
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.
So, there was a cool article recommended to us by one of the listeners.
It's not super new, but we haven't covered it, so I think it's totally relevant.
It's an article by Radu Raycia.
Hopefully, I'm getting that roughly right.
And it's called How and Why You Should Use Python Generators.
So, basically, it talks about what are generators, how you should use them.
And I wanted to cover this because 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,
Oh, this is simple.
I learned it in a weekend.
Let me write my code now.
Right?
And they're doing numerical for loops, and they're doing, you know, like tons of stuff that is not really Pythonic, right?
Right.
And they've got 27 Stack Overflow tabs open for, like, oh, how do I open a file again?
Right.
Yes, exactly.
And so, a lot of languages don't have this idea of generators or coroutines, which are just amazing, right?
Like, you've got a function.
It's going to process some huge amount of data.
Maybe it needs to read a 10-gigabyte file and parse it line by line.
Well, if you write that as a generator, if you only pull 10 lines from it, it only reads 10 lines.
Or even if you've got to go through all of it, it only loads one line into memory at a time.
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.
And code that doesn't exist doesn't have bugs in it.
That's a good point, yes.
Code that doesn't exist does definitely not have bugs in it.
So, this article is good if these generator ideas are new to you.
It talks about the lazy evaluation, which is really important to understand, and gives you a couple of simple examples.
It's not super deep.
So, if you're new, read through it.
If you really know it pretty well, you probably won't gain a whole lot about it.
But it's something you could shoot over to your coworkers.
You're like, why did you write this code?
Please don't do that again.
Use this.
Yeah, this is good.
Even myself, an experienced Python person, there's certain times where I'm like, why didn't I think of using a generator earlier?
Yeah, absolutely.
I mean, you don't always know that that's really the best path.
You just start writing the code.
You're like, I'm going to have a list.
I'm going to put stuff in the list.
I'm going to do this.
I'll get a dictionary, whatever.
Like, wait a minute.
Actually, I didn't need any of that.
I could do it way better, right?
So, you kind of got to have it in mind.
I would love it if tools like PyCharm and VS Code had a button to, like, refactor to generator, right?
Convert this list and return the list into, like, a generator.
It probably doesn't exist because, you know, like, the way you process the results has, you know, some kind of effect, right?
You can't, like, go through a generator twice, but you can go through a list twice or things like that.
But it still would be really cool if you could kind of, like, automate that a little bit.
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 iterin next to it so that it can be used, generators can be used with it.
Yeah, exactly.
You can fit it into that whole pipeline.
Cool.
Well, that's it for our main items this week.
You got anything else you want to quickly give a shout out to, Brian?
Well, I just saw that we've got a link to PyPI now supporting API tokens.
There's been a lot of recent changes to the PyPI interface to make it more secure.
And this is just one of the latest.
And I think it's a good way.
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.
Yeah, that's pretty good.
So you don't have to just do it on the immutable write only or write once real version.
Yeah, yeah.
Super cool.
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?
And the work that the PyPI did to move that along.
It's like now you can start seeing these new features coming in because previously it was like no one wants to touch that.
There's no way we're adding new features.
Like we're just trying to keep it from breaking.
Now it can grow.
It's cool.
Yeah, it's nice.
I've got a couple I want to give a quick shout out to.
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 Gita Van Rossum had written for Python 30 years ago.
And so now he's written another article talking about building a peg parser and moving towards it and so on.
So if that was interesting to you, you can check out that follow-up that he wrote.
And then finally, we've talked a lot about Homebrew 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?
You don't have Homebrew on Windows or many other things like that.
So Preston Daniel sent us over a quick message that, hey, if you guys get a chance, you should give a shout out to the chocolatey package manager on Windows.
Are you familiar with this, Brian?
No, I've never used it.
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.
Yeah, yeah.
So in a sense, you have the Windows UI, but it's kind of Linux-y in some of the tooling.
WSL was just kind of magic.
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.
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 lying around in order to not spend any money, right?
And so yeah, that's my development laptop is my old gaming laptop.
And so yeah, it's all WSL.
And I'm simulating AWS services on it so that I can develop offline and stuff.
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 Chocolaty 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 Chocolaty, 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?
Like it's right on top.
And they even do like limited virus scanning and like validation a little bit.
So yeah, it's a pretty cool little system.
And people should definitely check it out if they're doing work natively on Windows.
Yeah, nice.
Brett, anything else you want to throw out there while you're here?
That's probably all the great Python ideas that I have at the moment.
All right, super.
How about a joke?
Yeah, how about a joke?
I actually have a couple of jokes for you.
A programming joke and then just an adulting joke following up on that.
So it's more of, I guess, more of an assessment.
A good programmer is someone who always looks both ways before crossing a one-way street.
Does that connect with you, Brian, as a tester?
Yes, definitely.
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.
That's awesome.
Yeah, I'm always paranoid when I'm in London or in Australia.
Like, I'm like double checking both directions.
They're like, you just got to look that way.
I'm like, no, that's what you say now.
Then there's going to be the time I look the wrong way and one of those big red buses is going to 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.
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.
I want to throw one more in there, though.
Oh, go ahead, Brian.
No, I think that's good.
That's funny.
It's a little too real to be funny, though.
Like, we aren't laughing like, yeah, that hurt.
All right.
So, Brett, you started this one.
So I'm going to throw it out here for everyone.
Little Bobby Tables.
Brian, do you know about Little Bobby Tables?
Well, I remember it, but I probably couldn't explain it.
Yeah.
So it's XKCD.
And here, I'll just read it.
We'll just leave it out there for folks.
It's a mom answering the phone and says, hi, this is your son's school.
We're having some computer trouble.
Oh, dear.
Did he break something?
In a way.
Did you really name your son Robert, quote, parentheses, semicolon, drop table students, quote, semicolon, dash, dash?
Oh, yes.
Little Bobby Tables, we call them.
Well, we've lost years of student records.
I hope you're happy.
And I hope you've learned to sanitize your database input.
The thing I really love about this idea is that she has saddled this child with this terrible name for this one opportunity, right?
I mean, when he gets to be 24, it's never going to work again, right?
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.
It sounds crazy, but there's this pen tester, penetration tester, who has a Tesla.
And in the app, you can change the name of your Tesla.
He changed it to a JavaScript injection string.
And it went off when his car had to go get some service.
Yeah, I believe it.
I just have to say, as a general aside about anything, as somebody who ran, you know, a PCI DSS compliant thing for a long time, get pen tested.
Like, every time I got pen tested, those people came up with something creative and I learned something.
You know, like that's like, take the first dollar that you have to spend on security and hire a pen tester.
Yeah, that sounds like good advice for sure.
All right.
Well, that looks like it.
That's it for us, you guys.
Brian, thanks as always.
And Brett, thank you for coming this time.
My pleasure.
Yeah, thank you.
Yep.
Bye, everyone.
Bye-bye.
Thank you for listening to Python Bytes.
Follow the show on Twitter via at Python Bytes.
That's Python Bytes as in B-Y-T-E-S.
And get the full show notes at pythonbytes.fm.
If you have a news item you want featured, just visit pythonbytes.fm and send it our way.
We're always on the lookout for sharing something cool.
On behalf of myself and Brian Okken, this is Michael Kennedy.
Thank you for listening and sharing this podcast with your friends and colleagues.