Python Bytes - #443 Patching Multiprocessing
Episode Date: August 4, 2025Topics covered in this episode: rumdl - A Markdown Linter written in Rust * Coverage 7.10.0: patch* * aioboto3* * You might not need a Python class* Extras Joke Watch on YouTube About the show C...onnect with the hosts Michael: @mkennedy@fosstodon.org / @mkennedy.codes (bsky) Brian: @brianokken@fosstodon.org / @brianokken.bsky.social Show: @pythonbytes@fosstodon.org / @pythonbytes.fm (bsky) Join us on YouTube at pythonbytes.fm/live to be part of the audience. Usually Monday at 10am PT. Older video versions available there too. Finally, if you want an artisanal, hand-crafted digest of every week of the show notes in email form? Add your name and email to our friends of the show list, we'll never share it. Michael #1: rumdl - A Markdown Linter written in Rust via Owen Lamont Supports toml file config settings Install via uv tool install rumdl. ⚡️ Built for speed with Rust - significantly faster than alternatives 🔍 54 lint rules covering common Markdown issues 🛠️ Automatic fixing with -fix for most rules 📦 Zero dependencies - single binary with no runtime requirements 🔧 Highly configurable with TOML-based config files 🌐 Multiple installation options - Rust, Python, standalone binaries 🐍 Installable via pip for Python users 📏 Modern CLI with detailed error reporting 🔄 CI/CD friendly with non-zero exit code on errors Brian #2: Coverage 7.10.0: patch Ned Batchelder Actually up to 7.10.2 as of today patch allows coverage to run better when a covered project uses subprocesses os._exit() execv family of functions Looking at subprocess “Coverage works great when you start your program with coverage measurement, but has long had the problem of how to also measure the coverage of sub-processes that your program created. The existing solution had been a complicated two-step process of creating obscure .pth files and setting environment variables. Whole projects appeared on PyPI to handle this for you.” From release notes for 7.10.0 A new configuration option: “[run] patch” specifies named patches to work around some limitations in coverage measurement. These patches are available: patch = _exit lets coverage save its data even when <code>os._exit()</code> is used to abruptly end the process. This closes long-standing issue 310 as well as its duplicates: issue 312, issue 1673, issue 1845, and issue 1941. patch = subprocess measures coverage in Python subprocesses created with <code>subprocess</code>, <code>os.system()</code>, or one of the <code>execv</code> or <code>spawnv</code> family of functions. Closes old issue 367 and duplicate issue 378. patch = execv adjusts the <code>execv</code> family of functions to save coverage data before ending the current program and starting the next. Not available on Windows. Closes issue 43 after 15 years! Michael #3: aioboto3 via Pat Decker Wrapper to use boto3 resources with the aiobotocore async backend aiobotocore allows you to use near enough all of the boto3 client commands in an async manner just by prefixing the command with await. With aioboto3 you can now use the higher level APIs provided by boto3 in an asynchronous manner. Brian #4: You might not need a Python class Adam Grant This is an important periodic reminder to everyone coming into Python from other languages. Many other languages lean on classes a lot more than we need to in Python Adams suggestions Simple Data Containers: Use Named Tuples or Data Classes Stateless Utility Functions: Just Use Functions Grouping Constants: Use Modules Managing State with Simple Structures: Use Dictionaries or Lists Simple One-off Operations: Use Lambdas or Comprehensions I’ll add “just use functions” Avoiding Complexity: Built-in Libraries When You Actually Need a Class I’ll add You probably don’t If you think you do, ask a friend. Friends don’t let friends create extraneous classes in Python. If you think your case is an exception, it probably isn’t If you think dataclasses aren’t right for you, check out attrs Extras Brian: PyPI Incident Report: Phishing Attack -Sent in by listener John Hagen Both of Adam Johnson’s recent-ish interviews are now up on Test & Code 236: Git Tips for Testing - Adam Johnson 235: pytest-django - Adam Johnson Michael: Dive into uv webcast with me and Will Vincent Joke: Default text editor
Transcript
Discussion (0)
Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to your earbuds.
This is episode 443, recorded August 4th, 2025, and I'm Brian Ocken.
And I'm Michael Kennedy.
And you can reach us on the socials at on Blue Sky or Mastodon.
Check out the show notes to or the website, PythonBytes.fm to find all those links.
And if you'd like to be watch us live, you can check out PythonBytes.fm to find all those links. And if you'd like to be, watch us live,
you can check out PythonBytes.fm slash live
and it's usually Mondays at 10 a.m. Pacific time.
But you can go there for all the older,
to link to the YouTube channel
to get all the older episodes as well.
And this episode we have, is sponsored by you guys,
by the offerings that both Michael and I have This episode we have is sponsored by you guys,
by the offerings that both Michael and I have,
and you supporting us through that really helps us
going through getting courses, buying books,
that's pretty much it.
Also Patreon, so thanks Patreon people.
Let's kick it off.
What you got Michael?
I have something sent in from Owen Lamont.
And so Owen, thank you for sending this in I
Believe we've talked about markdown
Formatting stuff before but I want to look at this one because it's it's got some rough vibes
Are you FF not RO you gh?
rough vibes in that it's a
formatter written in Rust, seems insanely fast.
And even though it's a general purpose thing,
and it's written in Rust,
it has special love for the Python people.
So there's a PyPI wrapper,
basically a wheel that wraps up the commands going to it.
So you can pip install it,
UV pip install it, more importantly, UV tool install.
It also has a pre-commit hook and pyproject.toml support.
Pretty neat, right?
Very cool.
Yeah.
I just ran it on a project I'm working on and apparently, what did it say?
How many errors?
14.
14 errors I found in my, and it will fix them in a similar way if you do a dash dash fix,
I believe.
So that's pretty cool.
High performance
markdown formatter. So you can install it in lots of ways but I would just uv tool install it. It
has 54 linting rules which are apparently common markdown issues. Like if I have a heading there
should be a line break between the heading and the content of that section. You can fix most of them with dash dash fix, like I said, which is beautiful. No dependencies, single binary, highly configurable,
which is great because a lot of the warnings I get when I run it are this line length of 102
exceeds the 80 character limit. I don't know, like when do people, when do we move on from the 80
character limit in like things, Python and other?
I have a 4k monitor, 32 inch 4k monitor. If I put stuff in 32 or 80 columns, it's like on the left and the 80 columns is
like, well, that's the default size of a terminal.
Like, okay.
Is that where most of our markdown is done?
Probably not, but I don't know.
Um, I'd say make it long and let it wrap.
The reason I don't like that rule particularly
for Markdown is I use Taipura, which I love.
But Taipura, it keeps a little more
of the formatting visually there.
So even if I was to do the Markdown
and render it to a webpage or to a PDF,
those, the line breaks would disappear
because you have to have two line breaks, right?
They got a blank line.
But in Taipura, while you're editing it you see them and so you would see like chunks
So if I make my editor wider it like stops going if I make it skinnier though
Then it like has like weird half line breaks because it's wrapping the 80 lines to like 60 and then there's 20 more and like
It's just I hate that rule. So why am I ranting so much? Well, because I rant apparently.
But, it's also super configurable.
So you can go to a Tommel file down here,
and once you find it, in here,
it has a bunch of examples,
I think up at the top here, there.
And you can go in here and it gives you examples,
like I can say, disable rule MD013,
or in my case, yes, that's the one.
Of course it's 13, it's unlucky.
But you can also configure the rules,
like say rule seven is about indentation.
How many characters, how many spaces do you want
to indent by or different things, right?
Don't apply the line length considerations
to code blocks or tables,
but override the line length to be 100.
Again, I'm turning that off, but still,
I guess I could set it to infinity.
That would be fine, right?
But isn't this cool?
Yeah, it is really cool.
I wanna jump on the line length pen
by getting a little bit here though.
Let's do it.
The line, I agree, I'm glad this is configurable
because like in writing a book or something
or a tutorial,
I'm gonna have long paragraphs and I'd rather have those
just wrap and I don't wanna limit my language.
So I would turn that off if I'm writing long form stuff.
Yeah, I'm thinking my blog posts and things like that,
right, which are all marked down.
But for the markdown in a project,
like even if it's a documentation project,
in maybe, I guess, I could see it for like readmes or something
or things that are changing a lot
because you're doing diffs more.
You do have to be aware of the diffs.
But I think diff tools deal with WordRap fine now.
So anyway, I don't know.
Yeah, that's a fair issue, fair point.
But if you got long form writing, it doesn't make sense.
Yeah, it doesn't make sense at all. Yeah, that's weird.
It's not like in Word or Google Docs, like, where do you want to break your lines? Like,
no, I want it to just go across the page. Can we just let me write?
Yeah.
Interesting.
But it's super cool. You can, like I said, UV tool install it even has instructions for UV
or you can use UV tool run and so you can run
it without even actually installing it just to test out how it might go.
Yeah so what's the big do you know what the biggest mistake is you usually make
for Markdown? I haven't done enough messing with it yet but I can
report back to you. Okay mine I haven't even used the tool yet but I'm looking
forward to trying it because the thing that always trips me up is a space before an unordered list. So if you write a sentence with a colon
and then you do a new line and then you start like, you know, do the asterisks or dash or
something like that and start a list, some tools will automatically understand that you
intended it to be a list and some of them don't and you just get a bunch of
asterisks in a paragraph. So yeah, I need something to fix that for me. Definitely. All right,
on to the next topic. I want to talk about coverage because Ned Batchelder released,
this is a blog post from the end of July, July 24th,
coverage 710.0 with Patch.
So we're actually up to 710.2 now,
but it's the Patch that's like the super cool news.
And I just read about this,
and I am like really excited about it.
So one of the things, it adds three things.
So if we go to the change log, um, it's adding, adding patch sub
process, patch exec V and patch exit or underscore exit or something.
And, um, I'll do the, like the, the weird ones first.
I don't, I don't really see exec V around, but the issue with exec V and exit is
that that's a way that like something happens in you in your
Stuff gets torn down before coverage has a chance to write its stuff. It just like processes stop and that's um, that's not cool
But there's this with this you can fix that so and there there've been workarounds for these other things
And so that's not really the big news. The big news, I think, is sub-process.
Because there were ways to, if you're trying to run coverage
on a project that has sub-processes,
you have to have some way to cover all of those processes
and then combine them later.
And there were ways to deal with it,
but it was a little clunky.
Now, we've got a way to do it built in.
You just say patch equals subprocess
and coverage does it for you.
How cool is that?
And multiprocessing, it'll count multiprocessing
execution for coverage.
That's, yes, thank you, thank you, thank you, Ned.
So I'm really excited about this.
It's pretty cool.
Anyway, that's it really.
Awesome, yeah, that's a really good one.
Short and sweet.
This one comes to us from Pat Deckert, I believe.
I hope I'm remembering that right,
because I forgot to write it down.
So someone else sent it in, I apologize.
I'm pretty sure it's Pat sent this over.
And it's AIO Boto3.
So Boto3 is the Python package to talk to things
like S3
and other stuff in Amazon, okay, in AWS.
Don't get me started on Boto3.
It's a bit of a insane package, the way it's created.
But what I wanna talk about is AIO Boto3,
which is a wrapper on top of Boto3 resources
that leverages the AIO Boto Core async backend.
So what's going on from here?
This is a package by Terri Kane,
and she created, I think, to basically
make higher level operations,
which you would use from the Boto3 level
instead of the BotoCore, which is more low level,
detailed interaction with AWS.
But there was a async low level one,
but not an async high level one. And so now there's an async low level one, but not an async high level one.
And so now there's an async high level one.
So for example, do you wanna work with S3 contents
asynchronously?
Well, here you go.
So you can do things like create a session
and then say async with, go to a resource for S3,
then await get in a bucket,
and then loop over asynchronously with an async for across all the items in that bucket.
So if you want to do a bunch of S3 type of work,
or DynamoDB, or Kinesis, whatever,
then you want to do that asynchronously, well,
here you go.
Also, she has an example of working with a DynamoDB table
and reading and writing objects into it,
which is pretty sweet.
What's kinesis?
What is kinesis? Good question.
Is that a, that's a AWS thing? Yeah.
Looking that up.
That's not how you spell it, but luckily.
It's a family of services provided by AWS for processing and analyzing real time
streaming data at a large scale.
I'm glad you asked because this is what I've been working for a long time
Okay, sorry. No
Apparently you like data streaming data lake data processing analytics. Okay. Okay. Cool. That's it
That's all I got to say about it
But if you're basically if you're using boto 3 and you want to do a sync AIO boto 3. All right. Well, I
Sorry for the distraction, but I wanted to.
Anyway, I have a Kinesis keyboard.
That's why I'm like, what?
Yes, you do, don't you?
Tell people what it is.
I was trying to put one up on the screen.
Yeah, I was trying to look for one.
Kinesis keyboard, images.
Oh, here we go.
Did you find one?
No.
No.
There we go.
I had one for a while. I'm like, I don't, I'm not sure I can do this.
Oh, I love it. So I just did the image search, but, um, yeah, they're split like this. Uh,
and it's in there. And also your, your keys are in little, little divots.
Yeah. And like, I'll maybe see if I could describe it for people, right? Like imagine
you took an orange, you cut the orange in half you took out the orange
Fleshy bit and you lined the inside of the orange peel with keys
That's what typing on is like you type into like these round holes
Okay, but I would say like coconuts maybe because it's bigger
But we're like a coconut where you just work with like the lower third and the top third
Yeah, but one of the things that's cool about these is they're in, uh, do you
remember the men in black movie?
Oh yeah.
Yeah.
They're, I did until they flash me, but you know,
well, the men in black movie had, um, if you, the, the office scene in the first,
first, uh, one, um, everybody's weren't using kinesis.
It's pretty cool.
Oh, were they?
Okay.
How awesome.
All right. Um, were they? Okay, how awesome. All right. I wasn't going to talk about keyboards, but what am I talking about?
I want to talk about you might not need a Python class by Adam Grant. So I think we've probably
talked about this before, but it's worth reminding people because there's a lot of people that come
in to Python from other languages and classes are used a lot
in other languages and you don't really have to use them
here so much.
So I'm just gonna run through some of the options.
One is for simple data containers,
think about named tuples which are great or data classes.
Actually I'd probably data class first
and then if it's not quite right, named tuple.
But here's an example of
somebody doing a custom class with point and also
The indenting is wrong here Adam, but well anyway
Examples of how to use that with a name tuple and or just a data class. So it works pretty good
You don't usually have to create your own classes. All right
I don't really see that so like if you're creating a class with a static variable,
there's a really good chance that should just
be a module level variable.
Modules themselves often can behave in the same way
that people do classes.
I want to group the functions together
and have some shared data.
That's a module.
Exactly.
Exactly.
Yeah, so that's one thing that's not in this
but I but I one of the things I've taught people for a long time is if you think you
need a singleton pattern in Python it's just a module just do a module 100% and there isn't
any really cool and if you're afraid of global data in Python it's not really global it's
just global to the yes it's accessible to anything but it's in Python, it's not really global. It's just global to the, yes, it's accessible to anything,
but it's just module global.
It's not a big deal.
Anyway, examples with points.
But there's some surprising stuff in here.
Stateless utility functions just use functions.
And here's a, yeah, this is somebody
that must have came from, if everything's a stat,
like you said, if everything's a static method,
then it doesn't need to be there.
Just make it a function. Grouping constants also use modules. If everything's a static method, then it doesn't need to be there.
Just make it a function.
Grouping constants also use modules.
Well, there's also enums that you can do.
But anyway, yeah, if you're just having some constants and you're trying to group them
together, just put them in a module.
For some reason, this freaks people out sometimes.
I think it's just the people that are new to Python. Yeah, I think, I came from C Sharp,
which had a lot of class, very much,
like everything had to be in a class at the time
that I was doing it, like literally everything.
So I was very much in that space, but I've moved on.
Also, on the constants, I agree,
but maybe throw in a typing final of type.
So they've got like a host and a port,
you could have a typing.final bracket str and a typing.final. So they've got like a host and a port. You could have a typing dot final bracket stir
and a typing dot final bracket int.
Oh yeah.
Yeah, so then at least the editors and stuff go,
yeah, like don't edit this.
Don't edit it, yeah.
Unless you're meant to, but the way they say
the word constant, that probably means not so much changing.
Yeah, but also having it in a class
doesn't stop people from changing it either.
No, at least you get a warning.
Yeah. Tells you you're bad if you want to be bad. in a class and it stopped people from changing it either. Now, at least you get a warning.
Tells you you're bad if you want to be bad. Managing state with simple structures,
use dictionaries or lists, definitely.
A lot of this, the gist is Python has a lot of
built-in stuff that you can just learn how to use
dictionaries and lists well.
It'll take care of a lot of stuff.
This one's surprising to me, simple one-off operations,
use lambdas or comprehensions.
I mean, sure, the example works for a lambda
and comprehension, but also you could just use a function.
If you're gonna grab a lambda,
you could just write a function.
Yeah, lambdas are great.
Avoiding complexity, use built-in libraries.
Don't reinvent the wheel.
There's probably something,
just an example with config parser or JSON,
they usually, they can do a lot.
Yeah.
And then this is, I'm glad we tie into your first topic,
when you actually need a class.
Well, there's a bulleted list,
but they didn't do a new line.
So I'm pretty sure it
was a markdown that didn't get converted correctly. So anyway, and I'd like to add, what are my
additions? If you think you need a class, you probably don't. If you really do think you do,
ask a friend because friends don't let friends create extraneous classes in Python. And then if you think you're the exception,
it probably isn't an exception. Um, but, uh, and then finally,
I'd like to say if you, um, if you think you need data classes,
but cloud data classes aren't quite cutting it for you, check out adders.
Adders is still around and adders is awesome. So, yeah, or pedantic.
Yeah. Or pedantic. Yeah. When, when you actually need a class. Yeah. I'm, I agree with this. I like it. Yeah. Well, so what Yeah. When you actually need a class, yeah, I agree with this.
I like it.
Yeah.
Well, so what did he say?
He said, if you need to encapsulate state or behavior,
yes, but also you can use a data class or a module.
If your objects have clear behavior methods,
behavior slash methods associated with their data
and your modeling complex hierarchical structures.
I'm thinking the middle one.
If you have data that is tied to an instance of the class,
you need to have multiple ones of those
and the methods operate on that particular data.
Like that's when you need it, right?
Not for all the other jumps and hoops
people used to use it for.
And as far as inheritance hierarchies go, I have, since I've been using Python, I have multiple
times created class hierarchies and then regretted it. I don't think I have any that were legitimate
reasons to use a class hierarchy. But also after using Python so much, I don't recreate class hierarchies in C++ much anymore
either because I like using what, containment instead of inheritance, I think is a cleaner
model.
So anyway, that's enough.
Yeah, composition over inheritance indeed.
That's it.
It goes a long way.
All right.
Those are our topics.
Do you have any extras?
I have at least one extra. Let's see what I can do about that. So this Thursday, as in three days from now,
8 o'clock Pacific time, I will be doing a live webcast with Will Vincent from PyCharm.
Yeah, so we're talking about basically UV, what is UV, all the
way that you can apply to your projects. Should be a lot of fun. I'm really
looking forward to it. I wasn't entirely sure what we're gonna cover. Will and I
talked about it today. Have a bunch of great ideas. Cool. So if you want to see
UV in action, you know, we talked about that post from Armand Roenacher, I don't know,
a few months ago or whatever. If, why are you not using UV? If you're not, why? A lot
of people are like, what's UV? Or it's too hard to move from or it doesn't you know
whatever like we'll kind of like address all that kind of stuff plus maybe some
fun Docker things some performance things all over the place.
Awesome. I have a couple extras.
Alright.
So first off this was sent to us by listener John Hagan.
The PyPI blog has a incident report about a phishing attack.
So apparently there was some targeted phishing emails.
There were some, and I didn't read this that closely,
but it's creepy because it was a phishing attack
that involved a fake PyPI that was a phishing attack that involved a fake PIPI that had a phishing
domain that was in the middle.
So if somebody clicked on the link, it all behaved just like PIPI, but there was somebody
in the middle capturing stuff.
That's really creepy.
What was it?
It involved the fact that in some
fonts, I and J look identical. So the it was a pipe PJ.org domain. Yikes. Anyway, I just wanted
to have people aware of that. It was apparently found and fixed relatively quickly. There were,
I guess, four, four user accounts successfully phished. They're either
disabled. So what is that? Right. There's some recommendations, takeaways, calls to action.
If you have a dormant PyPI account, so if you have a PyPI account you're not really using,
consider removing it. You can always create another one if you need to later. If you have an
older PyPI account and you're not using 2FA yet, please sign up for that.
Even if you only pop in once a year,
make it more secure, be good.
And use WebAuthn via browser hardware security
or hardware security keys.
Wow, I don't even know what,
is that just web authentication?
I don't know, I don't know what this is.
I think it's like UBKey type stuff. Okay. I don't do it though, so I don't know. I don't know what this is. I think it's like UBKey type stuff.
Okay.
I don't do it though, so I don't know that one.
I'm all about the 2FA,
and I'm all about the 45 character password,
but I'm not doing web authentication.
45 characters?
Wow.
Or whatever.
I'm so frustrated there's so many websites out there
that you'll set, like, I used to have a default,
I think it maybe was 36
and one password for randomly generating a password.
That should pretty much stop it.
You know what I mean?
And God forbid there's a moment or two
where you've gotta type it in.
Like for example, on Windows, if you get a new system,
you gotta log into your Microsoft account
before you get into the system, the first boot or something.
Like, oh God, I gotta type it.
So you don't want it to be like a paragraph.
But so many websites go, no, your passwords have to be
less than 16 characters or less than 12 characters.
I think my bank would limit it to like less than 10.
I'm like, my bank, what is wrong with you people?
If anybody should accept a big password,
but it's a tech support, they're like,
well somebody's gonna say they're locked out of their account
because somebody put a long password
and they can't type it in or you know.
There's all these crappy reasons.
What gets me is when people like passwords get,
when they exclude common characters like colon or quote mark or like really your system is
not able to handle colons and a password that's just like insane anyway.
Yeah, I agree. Yeah, I agree.
But anyway, okay. So, fishing attack, I've got a couple other quick extras. I do have some,
I'm not dedicated to the weekly testing code,
but lately it's been weekly. So testing code,
I got a couple had an interview with Adam Johnson that was two topics.
We split it into two episodes. Both are now available.
We had PyTest Django that we talked about.
And then we talked about Git tips for testing and the top,
especially the, some of the stuff on the get diff,
get stash and get bisect sections are pretty interesting.
So some good stuff there.
Yeah, very nice.
And those are my extras.
All right.
Do you have a joke?
I do, but this joke, you know how they say jokes
are not funny if you gotta explain them.
I'm gonna explain this anyway.
But not the joke itself, I'm going to explain
the foundational information people need to know.
So a lot of times people say these days, Brian,
they say Visual Studio, I'm using,
like what editor do you use?
Oh, I use Visual Studio.
They're not using Visual Studio.
They're using something called Visual Studio Code
or VS Code, right?
Yeah.
There is, there has been since the 90s
an editor called Visual Studio.
It is not Visual Studio Code.
It is a beast of a beast.
It's like a 5 gig download.
It manages Azure.
It does data.
It does Team Foundation Server.
It does all this stuff.
It's like a really heavyweight editor.
And VS Code was basically created
to make a lightweight little editor that is not visual studio
Proper right? Yeah. All right
So I got to just set that because I know a lot of people especially younger folks
Visual studio is visual studio code, but now are you ready for the joke? Yeah. All right, let's do it
So there's a nurse talking to a guy
Do you have any history of mental illness in your family? The guy looks over and goes, well,
my brother uses Visual Studio 2022
as a default text editor.
Yeah, that's good.
It's pretty good, right?
Pretty good, because that thing is big
and it's slow to start and it's like ridiculous.
Default text file editor. Yeah, that's the joke. it's slow to start and it's like ridiculous. For what? Default text file editor.
Yeah, that's the joke.
That's what I got you.
So I haven't had to use Visual Studio for a while,
but we did used to.
I was using it for compiling stuff.
And I can't remember what the short code was for compiling.
It was like F7 or F11 or F2.
One of the F keys was just to compile.
And so whenever anybody asked me,
or do you use Visual Studio?
I'm like, just as a really big thing to hit F7 with.
Or whatever.
Yeah, yeah, yeah, yeah.
So yeah, and it's true.
I would edit in like way back in the day.
It was before Visual Studio, or VS Code.
So I was probably editing it in like Vim or Sublime
or something like that.
And then I'd have Visual Studio off to the side
and I would just like go over to it
and hit the F7 key to compile and then go back to my day.
But yeah, this is what it is.
This is a good one, I like it.
Nice, I do too. I used to use good one, I like it. I do too.
I used to use Visual Studio and I enjoyed it.
I thought it did cool stuff,
but as a default text editor for just simple files,
it is not what it was for.
Yeah, I had people like composing their email
in Visual Studio and then.
Oh my gosh.
Really?
This is what you know, okay.
All right, fair, fair.
Well, I mean, they probably do have
a history of mental illness then.
When they open up Outlook and send it and you know, for sure,
there's something going on there.
The only, the only thing on my desktop that if I hit a control F,
it doesn't find stuff. It forwards an email.
Yeah, exactly.
doesn't find stuff. It forwards an email. Yeah, exactly. So, uh, well, uh, excellent episode again. Thanks, Michael. Thanks everybody for listening. You bet. See you later. Bye
everyone. Bye.