Python Bytes - #184 Too many ways to wait with await?
Episode Date: June 5, 2020Topics covered in this episode: Waiting in asyncio virtualenv is faster than venv Latency in Asynchronous Python How to Deprecate a PyPI Package Another progress bar library: Enlighten Code Ocean E...xtras Joke See the full show notes for this episode on the website at pythonbytes.fm/184
Transcript
Discussion (0)
Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to your earbuds.
This is episode 184, recorded May 27th, 2020.
I'm Brian Ocken.
And I'm Michael Kennedy.
And this episode is sponsored by DigitalOcean.
Thank you, DigitalOcean.
Yeah, thanks, DigitalOcean. Really appreciate it.
Well, I'm waiting, Michael.
You're waiting? What are you waiting for?
I'm waiting for the next AsyncIO story.
I guess it's my turn, isn't it?
Okay.
Sorry, let me see if I can get this right.
So the topic I want to talk about is waiting in AsyncIO.
Yeah, so the magic of AsyncIO, which was introduced in Python 3.4,
never really appeared until Python 3.5 when the async and await keywords came into being, which let you
write code that looks like standard single-threaded serial code, but actually is multi-threaded,
or at least parallel concurrent to some degree. Depends on how you're running it, whether it's
truly multi-threaded. Anyway, there's a lot of options, let's say, on how you can interact with these co-routines and these tasks that are generated by the AsyncIO framework.
And anytime there's like four ways to do something in programming, you should be asking yourself,
one, why are there four ways to do this?
But more importantly, when does way one apply best?
And what scenario should i use way three and what is the trade-off between two and four and so on right so that's the case with async io
there's tons of ways to wait or await things and hank hennick get the pronunciation right for me
i know you got it you got it that's good yeah hank sorry that's just a running thing i can never get i know well i'm the problem is i think i had it
right and then we went back and forth so many times with so many variations now i'm i'm it's
broken uh sorry about mess up your name there so i wrote a great article though called waiting
in async io that does exactly that that says here are the ways, here's the pluses and here's the minuses
and the situations in which you apply them. So if you're like serious about using async IO and
you're building real things, basically this podcast episode is for you because I have this
and another one that bring two really cool ideas together. But let's talk about the waiting one first. So it's really easy to start doing some work, right? I can have two coroutines,
let's say F and G. And I could say I want the result of F by saying, you know, result equals
a wait calling F and then result G equals a wait calling. And that's fine. If what you're looking for
is more concurrent execution of that part of code, right? So this is say in a web method,
like a view, someone makes a request and there's not a lot you can do to make things go faster,
potentially for that one request, but you can say, let the server be less busy. So it could
handle like 10 or 20 times
more of the same requests, right? So this real simple, like just a weight calling these functions,
these async functions, it will allow your system to scale more, but it won't make things faster.
Like for example, if you're trying to crawl 20 web pages, this will not make it any faster. It'll
just make your code more complicated. So don't do right so there's other ways which you want to do that another thing that i think a lot of people don't
quite get is when you call one of these async functions like async def function name when you
call it it doesn't actually start it until you either await it or create a task from it. So if you call like F and then G,
and you think you're going to come back and get to them later,
now they're running.
No, actually they're not, unless you've created a task,
which starts them.
So you either have to await them, which blocks,
or create these tasks to like kick them off.
That's pretty interesting, right?
Like that's not super obvious, I think.
Normally when you call a function, it does a thing.
But here, not so much. So some other options, if you could call them both as create them as
tasks, and then you could await those tasks, right? Because they are tasks are already running. And
then you await them both, whichever one first finished first doesn't matter. You wait till the
first one's done and maybe the second one's already done. So that's probably the pattern
that most people are going to be using, but you can also use asyncIO gather that takes one or more awaitables as a star args.
And then it waits for them all to finish, which is pretty cool.
And that itself is a future thing that you can await, right?
So you would say await asyncIO.gather.
Oh, that's cool.
Yeah, gather is awesome because I can create all these tasks.
I just need them all to be done.
And when that's done, we can get the results and carry on.
And what's cool is when you await Gather,
you get a tuple of results.
So if I say asyncIO gather function one,
or task one, task two,
then it returns the result one comma result two as a tuple.
So you can gather them up and get all the answers back,
which is pretty cool.
Yeah, that's really neat.
Yeah. One of the problems with gather though, is you're saying I'm willing to wait forever
for this to finish. And sometimes that's fine, but sometimes things don't return correctly or
ever or in the right amount of time. So you can use wait for, which is nice and allows you to
pass a timeout. But what's a little bit better than a wait for
is there's an async timeout package on PyPI,
which I'd not heard of.
And you can basically create a block
that will, a with block that will timeout.
So you can say,
I want to have an async with timeout five seconds
and then do a whole bunch of function calls
and a waiting and all that.
And either they're all going to finish
or when five seconds passes, everything gets canceled that hasn't finished.
Oh, that's cool.
That's pretty cool, right? Another one that's really interesting is I start a bunch of work
and then I would like to say I kick off, I'm doing web scraping and I want to go get
the results of 20 web pages. I kick off 20 requests and then I want to process them as
they complete. Like the first one that's done i
want to work on that then the next one then the next one so you can create a task or an iterable
rather from saying async io dot as completed and you give it a bunch of tasks and it gives you an
iterator that you can four in over that gives you the first completed one then the second completed
one and just blocks until the next one is completed.
So you kick a bunch off,
and then you just say for completed task
in asyncio as completed,
and you give it your running task.
That's really slick, isn't it?
That is slick.
Looks like it has a timeout also that you can add to it.
Yeah, very nice.
Yep, you can give it a timeout indeed.
Now, there's a few more things covered in there, and I didn't go over the trade-offs too much.
You know, here's the scenario is this and that.
So if you really care about this, two things to do.
One is check out the article.
It's got a lot of details and each subsection has a little trade-offs.
Here's the good, here's the bad, which is nice.
And also you can check out my async course, which talks about this and a whole bunch of
other things on async as well.
So I'll put a link in the show notes for that as well.
Nice.
Yep.
So I was talking about waiting.
You're talking about what, being faster?
That sounds better than just waiting around.
Yes, being faster.
Well, maybe being faster.
I'm not sure.
So I'm still on the fence.
Anyway, so virtual environments.
I use virtual environments.
Do you use virtual environments?
Anytime I have to install any,
if pip install has to be typed,
there's a virtual environment involved, yeah.
Yeah, I use it for everything.
Even if I've got a machine, like a build machine,
that really only has one Python environment
and I'm only using it for one thing,
I still set up a virtual environment.
It's just always.
And I've been, since the Python 3 started,
Python 3 packaged VENV with Python. So you can create virtual environments just with the built
in VENV package. And I've been using that. Now, before that was in there, and if you were in
Python 2 land, you needed to use the pip installable virtual env package.
Now, it is still updated and it is still being maintained.
And I noticed this was a conversation that started on Twitter this morning that the virtual environment was still around and it was maybe you should use that.
So I went and checked it out again the
documentation for it and it says uh virtual env is a tool tool to create isolated python environments
we know this since python 3.3 i guess a subset of has been integrated into the standard library yep
the vnv module does not offer all the features of this library. Just to name some of the prominent ones,
VNV is slower and it's not extendable and it cannot create environments with multiple Python
versions and you can't update it with pip and it doesn't have a programmatic API. Now most of that
I just really don't care about.
But the slower part I do care about.
So I gave it a shot this morning.
I used time, the time function on the command line just to time a couple of commands,
created virtual environments with both VENV and Virtualenv.
And, yeah, VENV takes a little over two seconds, two and a half seconds to finish, whereas the virtual env version takes like quite a bit under half a second.
So that's a lot.
And I mean, if I'm doing a lot of virtual environments, I might care.
Now, one of the things I was like coming back and forth, why would I use VENV then if virtual environment, virtual env is faster?
Well, you have to pip install virtual env.
And so I'll have to remember to do that.
I don't think I'll start teaching people this because it's just one more complication thing.
And a couple of seconds isn't that big of a deal.
And I still like the prompt, the dash dash prompt.
Virtual env supports that too, but it handles it different. It doesn't
wrap your prompt in parentheses. And maybe that's just a nicety, but I kind of like it.
I'm not sure. I'm on the fence as to whether I should switch or use it.
To me, it feels like I'm going to stick with VEMV. For a long time, I saw virtual EMV as just like,
it's legacy stuff. It's there because before Python 3.3 you didn't have vmv built in so
you're going to need it a lot of the tutorials talked about it and whatnot we recently covered
it about why it got a big update and a lot of the things that it does that are nice and the speed is
cool you know maybe it wouldn't be that hard for to adopt the dash dash prompt dot feature right
it's open source right it could get a pr that does that. That would be pretty cool, actually.
It probably should just so it's consistent.
But to me, the idea of having another thing
I've got to install somewhere,
probably into my user profiles, Python packages,
so that then I can then create virtual environments
so that I can then install things over into that area.
It's just, it's fine for me.
But as somebody who does courses and teaching
and other stuff like presentations like it just seems like okay you just lost how many people
out of that right like you know what is the value like you say it's two seconds one of the things
what i would like to see and it would be really nice maybe that would even push me over the edge
is it drives me crazy
that I create a new virtual environment
from the latest version of Python
that I can possibly get on the planet.
And it tells me that pip is out of date.
Now, virtual environment didn't do that for me this morning.
So it created a virtual environment
with the newest pip in it.
Oh, okay.
See, now that's pretty nice
because it's annoying to say,
okay, what you do is create this virtual environment and you pip install this thing. Oh, look, there's always going to be a it. Ooh, okay. See, now that's pretty nice because it's annoying to say, okay, what you do is create this virtual environment
and you pip install this thing.
Look, there's always
going to be a warning.
So every single time
what you're going to do
is you're going to fix that warning
by doing this.
Right.
So if it grabs the latest,
that's actually kind of cool
now that I think of it.
I have a alias in my shell,
my startup,
that I just type V-E-N-V
and it does the Python-M-V mv and v and then it does an
upgrade of pip and first it activates it and then it does an upgrade of pip and setup tools all in
like four characters so that's what i've been doing these days yeah i've got like a little
snippet in my profile also that I'm using.
Funny enough, I shared it recently on Twitter, just my two-line snippet that I used.
And then people kept on telling me to use all these other tools.
Oh, you could just use this.
It's not just use this.
It's just a two-line snippet in a profile.
It's not a big deal.
I don't even have to know what it is.
I just typed these three characters.
I'm good.
Why are you bothering me?
Why is this such a big deal? I know, it's i just typed these three characters i'm good why are you bothering me right why is it such a big deal i know it's crazy yeah yeah what i would really like to see in none of these address is that something like kind of like node js where it just has the virtual
environment at the top level and it just walks up until it finds the virtual environment and maybe
complains if it doesn't or it it does something like that, right?
Like something to the effect where you say,
I know that this is a feature,
I forgot what it's called,
it's like the local Python or something like that,
but it's not just built into Python.
So if I just went into that directory
and tried to run it,
it's not going to find and use that version of Python.
Oh, well, the dirinv,
there are a few packages that do that.
And that's one of the
things that people are directing me to is Durinv. Durinv is cool. We should talk about it as a
separate item. It's worth it. But yeah, D-I-R-E-N-V is cool. Yeah, we should talk about that sometime.
Yeah, yeah, yeah. Don't use up all our items all on one show, man. Come on.
Okay, let's thank our sponsor. So DigitalOcean is sponsoring this episode. And DigitalOcean just launched their virtual private cloud and new trust platform.
Together, these make it easier to architect and run serious business applications with even stronger security and confidence.
The virtual private cloud or VPC allows you to create multiple private networks for your account or your team instead of having just one private network.
DigitalOcean can auto-generate your private network's IP address range, or you can specify your own. You can now configure droplets to behave as internet gateways. And Trust Platform as a new
microsite provides you one place to get all your security and privacy questions answered and
download their available security certifications.
DigitalOcean is your trusted partner in the cloud.
Visit pythonbytes.fm slash DigitalOcean to get a $100 credit for new users to build something awesome.
Yeah, awesome.
Thanks for supporting the show, DigitalOcean.
So before you had to wait on me, didn't you, Brian?
It was frustrating.
I did have to wait.
All right.
Let me tell you about when you might not even be awaiting stuff and things are still slow. So there's this
cool analysis done by Chris Wellens in an article called Latency in Asynchronous Python that I don't
know if it talks about problems with async IO directly, but it's more talks about when you have
a misconception of how something works over there and then you
apply a couple of patterns or behaviors to it it might not do what you think so for probably the
the best example would be there's he gives a good one there's a couple i'll focus on this this one
where it's basically generating too much work and what can be done about it. So he says, I was debugging a program that was having
some significant problems, but it was based on async IO and it would eventually take really long
time for network responses to come back. And it's made of basically two parts. One is this thing
that has to send a little heartbeat or receive a heartbeat or something. I don't remember if it's
inbound or outbound, but it has to go beep, beep once every let's say millisecond right so there's an async
function and it just rips through and just every one millisecond it kicks off one of these
heartbeats totally simple right you just say await async io dot whatever like sleep for one
millisecond then do the thing and then then go on, right? You can
basically allow other concurrent work to happen while you're awaiting this sort of like timeout,
and to do it on a regular timeframe. And then there's this other stuff that has to do some
computational work that takes not very long, like 10 milliseconds. So you're receiving a JSON request,
you have to parse that JSON and do like a little bit of work
right so because async io runs really on a single thread that 10 milliseconds is going to block out
and stop the heartbeat for for 10 milliseconds which is you know whatever it's fine it's like
there's some little bit of variability but it's no big deal however if you run a whole bunch of
these in his example chris said let's run 200 of these computational things and like just start them up so that they
can get put into this queue of work to be done well the way it works is it all gets scheduled
it says okay we have a heartbeat and we have these 200 little slices of work each of which
is kind of take 10 milliseconds and there's a bunch of stuff around them that makes them a
little bit slower the scheduling and whatnot and then we have a bunch of more heartbeats so it goes beep beep
block for two seconds beep beep beep where you would expect okay i've got all these heartbeats
going and i've got 200 little async things let's like mix them up right like kind of share it
fairly and it does not do that at all. So he talks about basically
what some of the challenges are there. One is probably you shouldn't just give it that much
work in some giant batch. You should, you know, give it less work at a time, like some kind of
like work queue or, you know, he said, let's see if a semaphore can work.
Now, I don't remember if semaphores are reentrant or not.
It didn't work.
The semaphore didn't help at all, actually.
He said we can use a semaphore to limit it to 10.
But if semaphores are reentrant, this is all one thread.
It doesn't matter.
Like the semaphore won't block itself.
So that's like this normal threading, locking, and stuff like that.
They kind of don't apply because there's not actual threading going on.
So that doesn't really help.
But he comes up with this example of that the async IO has a job queue, which allows you to push work into it.
And then you can like wait for it to be completed.
And there's all sorts of cool patterns and like producer consumer stuff that you can put on there.
So I actually put together an example.
He has like little code snippets.
I put together a running example
and one whole program that demonstrates this.
And I have a link to the gist in the show notes.
And I also would like to just point out
how much a fan of Unsync I am,
which I always talk about when I can
around this Async stuff.
Like Unsync is a library that is 128 lines of Python
and it unifies
multi-processing async io threading thread like the all these different apis into like a perfect
thing that fits with async in a way it's really really nice but applying like the standard
unsync adjustments to this code to say like what you do is just put a decorator at unsync on the
function that's it you still use a weight and async and a weight and all that kind of stuff
the problem is gone totally fixes it oh really like you don't have to go to like crazy queues
and all that like the problem is gone it's it's fixed well it's alleviated it may still be like
if you push it far enough under certain like more complex criteria but the
example that showed the problem you just make them unsync and you await them and it just runs like
you would have originally expected like unsync is so beautiful that's cool it doesn't change the way
async io works it basically says okay the async work is going to run on a background thread and
this other computational stuff will fit into the api but will technically run on its
own thread so it's it's not like changing the internals but you use the same code and then now
this doesn't have this problem because the way it slices them together is better i think anyway
it's pretty interesting it's worth a look also i have a copy of that on the gist and you can check
that out and run it too that's pretty cool So unsync allows you to possibly not think too much about whether you should have these things just be async or whether there should
be threads or something. It's really neat. It just cleans everything up, but I sure hope they
don't deprecate it though. Oh, that's a better transition. I was going to say, speaking of
cleaning things up, but we'll just do both transitions.
So how to deprecate a PyPI package.
So you've put up a PyPI package and for some reason you don't want it to be up there.
I don't want a puppy anymore.
Why do I have to take care of this?
Yeah.
So there's lots of reasons why this might happen.
One of them might just be you accidentally, you didn't use the test PyPI and use the live one and you put up foo or some
variant of foo and you didn't mean to maybe it's some other package that somebody took over and
it's handling it better and you want people to use something else but anyway there's lots of reasons
why you might a guy named paul mccann wrote a blog post about how to deprecate a PyPI package.
So he gives a few options, and I think these are cool.
One of the interesting things, as he mentions, is the PyPI doesn't really give you direction as to what it should look like, which one you should use.
So he's giving his opinion, which is great.
You might use a deprecation warning.
And this doesn't really apply to entire packages,
but let's say you've changed your API.
So it might as well be listed here.
It's a good thing to,
instead of just ripping out parts of your API,
leave them in there,
but make deprecation warnings in there.
They really should be errors instead of warnings.
If you're really taking them out
and just having the warning,
something like an assert is probably better.
But there is a good thing to think about
whether don't just rip it out, maybe.
I don't know.
But if you rip it out completely,
the assert will happen automatically.
So maybe that's a good thing.
As far as packages, though,
you could just delete it.
So you can, PyPI does allow you to remove packages.
I don't think that that's probably
the right thing to do usually ever
unless you just push something up and it was an accident then deleting it is fine. But if it's
been up there for a while and people are using it, deleting it has a problem that somebody else
could take over the name and possibly a malicious package could take over the name and start
have people having install it. So there's problems with that so it's
probably not a good choice most of the time the last two options are more reasonable there's a
redirect shim so this is an example like let's say there's an obvious package that is compatible
that is being better maintained and you want to push people over to there if it's really very
compatible you can add a setup, a shim that just,
and there's some code examples here to just,
if somebody installs it,
it just installs the other package also
that people should be using.
I know what you want, we'll give you that one.
Yeah.
And even having, if somebody imports your package,
it really just imports the other package too.
That's a little weird,
but it is interesting that it's an option.
The thing I really like that probably the best
is just a way to fail during install.
And there's a code example here
for if somebody at PIV installs something
and all the packaging works,
but the install part will throw a error
and you can put a message there
redirecting people to use a different package
or maybe just explain why you ripped this one out so i think i like the last one best
so most of those are my commentary but there's some options for how to deal with it so i thought
that was good yeah i really like the sort of i tried to pip install it and it gives you instead
of just failing or being gone it actually gives you a meaningful message.
Like, you should use this other package.
We're done.
If you really intend to delete it, that's probably it.
Yeah, and one of the interesting things,
the last couple, the redirect shim and the fail during install,
he gives example packages that do this.
And some of these are just mistyped things.
Like, if people mistype something try they maybe
they meant something else and and uh redirecting there yeah it seems so right only over at pipey
i and you know if uh you make a mistake it's it's not good so knowing what to do i mean people
depend on it right if you yank it out then it's trouble yeah but if it's mistake driven though
make sure you use the test interface first to play with things before you push garbage up there
there's also i'd really like people to not squat on names there's a lot of cool package names out
there that really have nothing meaningful there because somebody decided they wanted to grab a
name and then yeah didn't do anything with it that's lame don't do that yeah that's definitely
lame on the other hand there are some times I'm like,
how did you just get that name? There'll be like a new package, like secure or something like that.
Like, how did you get that after all this time? Right. It's crazy.
Yeah, definitely.
Yeah. Yeah. Or up to 236,000 packages. That's pretty insane.
Yeah.
So Brian, would you like me to enlighten you a little bit and the listeners?
Yes, please enlighten me.
So last time you brought up a cool progress bar, it was either the last time or the time before, and it did all sorts of cool stuff.
But here's yet another one.
Again, an example of our listeners saying, oh, here's three cool things you talked about, but did you know there are these four others you've never heard of?
Yeah. things you talked about but did you know there's these four others you've never heard of yeah so avram lubkin sent over his progress bar package called enlighten and it's actually pretty cool
like there's a bunch of cool progress bars with nice animations and stuff but there's a few
features of enlightened that might make you choose it one is you can have colored progress bars which
is nice but more importantly you can have multi- bars, which is nice, but more importantly, you can
have multicolored progress bars.
So let me throw out an example that I think would connect for you, given that you're a
fan of PyTest.
Like if you run some sort of series or sequence of operations and you want to show how far
you're making it, but they have multiple outcomes like red is failure, green is success, and
yellow is like skip or something like that you could have a progress bar that has three segments a red segment a yellow segment and a green segment and they could
it could be all one bar but it could kind of like show you as it grows here's the level of failure
here's the level of success and so on all with color 224 bit color not just like eight colors
either oh yeah that'd be great. That's good.
And the nice thing is those just go off.
The other one is a lot of these progress bars,
they'll sort of control, they'll be rewriting the screen, right?
They'll be putting stuff across as it's happening.
But if you happen to do like a print statement,
effectively writing a standard out or an exception that writes a standard error
or something like that, you know messes them all
up right so this one works well even allows you to write print statements while it's working so
the print statements kind of flow by above it but it's you know whatever part of the screen it's
taken over it still is managing that as well so it overrides what print means or standard out
and sends it where it belongs that's cool yeah that's
pretty cool it also automatically handles resizing except on windows and where it says except on
windows i'm not sure if that means on the new terminal windows terminal that they came out with
that's much closer to what we have over on mac and linux or if it just means it doesn't work on
windows at all i suspect it it might work on the new windows terminal that just got went 1.0 but certainly not on cmd okay who uses cmd okay i mean that's what comes with
windows if you don't like go out of the way to get something right like commander or the new
terminal or something like that yeah but you gotta install git at least on windows anyway and then
you got bash yeah it comes with it so that's true so like all good things that
have actions and behaviors and are visual there's a nice little animation even on the pi pi.org page
so if you go there you can watch and actually see the the stuff scrolling by it's like an animated
gif right on the pi pi page so very very nice well done you know the multi-colored progress
bars it does seem pretty awesome if that's your use case i want rainbow ones i want to do a rainbow yes maybe with like
little unicorns just shooting out of it and just like all sorts of crit yeah sounds good yes stars
and unicorns yes it would be perfect yeah let's have that and people are starting to catch on
that we like animations because they'll include it in the suggestion and by the way it has an animation because watch it here yeah good job bringing it up yeah
you're part of it awesome well nice work on that progress bar library it seems simple and
well done speaking of unicorns i want to talk about oceans wait unicorns don't live in the ocean
mermaids mermaids mermaids so i talk about CodeOcean. So this was contributed by Daniel Mulkey.
So this is a pretty neat thing.
So CodeOcean is a paid service, but there's a free tier.
And it's a research collaboration platform that supports researchers from the beginning of a project through publication.
So this is kind of this neat thing.
I'm going to read a little bit from their about page.
We built a platform that can help give researchers back 20% of the time they spend troubleshooting
technology in order to run and reproduce past work before completing new experiments.
And CodeOcean is an open access platform for code and data where users can develop, share,
publish, and download code
through a web browser eliminating the need to install software blah blah blah blah anyway uh
mission is to make research easier so this idea is you can have like code snippets like uh jupiter
and python and even things like matlab and c++ code running with the data in this kind of environment that you can
collaborate with other people and just sort of build up these data sets and the science and the
code and all bundled together. And it's pretty cool. It also collaborates with some, one of the
goals of it is to be able to have all of this reproducible code and data together in a form
that's acceptable to journals. And one of the reasons why it was contributed is Daniel said
that one of the peer-reviewed journals that he reads, it happened to be SPIE's Optical Engineering
Journal, recommended this platform for associating code with your article so if people trying to be do science and be published associating a code ocean space with it is an option that's cool and
if it gets accepted by editors as yeah that's what you do then it just makes it easier like
it's kind of like saying oh you have an open source project what's the github url
all right not is it on github just where on GitHub is it? Yeah. I do technically know that there's GitLab and other places,
but like most of the code lives on GitHub is what I was getting at.
Right?
Yeah.
Cool.
Well,
this looks pretty neat.
I do think there's a lot of interesting takes on reproducibility in science,
and that's definitely a good thing.
There's this,
there's binder,
which is doing a lot of interesting stuff,
although not as focused on exact reproducibility,
but still nice.
There's Gigantum,
which is also a cool platform for this kind of stuff.
So there's a lot of options
and it's nice to see more of them like CodeOcean.
Yeah, nice.
Well, that's our six.
Do you have anything extra for us today?
I'm going to try to connect this to Python
because I am excited about it.
How long has it been since astronauts have been launched into space from NASA and from the U.S.?
It's been a really long time, ever since the space shuttle got shut down four or five years ago.
I heard it was like over 10, but I could have heard run.
It's very possible.
It's been a very long time so today
i know this doesn't help you folks listening because the time it takes us to get this episode
out but hopefully this went well but i'm super excited for spacex's launch in collaboration
with nasa to send two astronauts up into space wow are those guys brave to get on to one of these
rockets and but also i think there's probably somewhere in
the mix a lot of python in action if you go to spacex they had last time i looked at one random
point a couple months ago they had 92 open positions for python developers oh wow i don't
know if that's 92 people they're looking for but at least there's 92 roles they were trying to fill.
There could be multiple people into any one role.
So that's a lot of Python.
And so somehow in this launch,
there's got to be some interesting stories around Python.
And this is mostly to say,
one, it's awesome that SpaceX and NASA are doing this.
Hopefully this goes well.
Lots and lots of luck to that. But also if anyone knows how to connect us with the people
inside spacex doing awesome rocket stuff with python those would make great stories we would
love to hear about those and introductions and whatnot yeah that would be cool i'd love to hear
more about that yeah i do hope it goes well later and i heard that possibly there was weather
problems that might crop up but well well maybe people will get to watch this.
Knock on wood.
Maybe it'll be delayed for a week.
We'll see.
Awesome.
How about you?
What do you got?
I just downloaded 3.90 beta 1.
So Python 3.9 beta 1 is available for testing.
If you are maintaining a package or any other maintaining your application,
you probably ought to download it and make sure your stuff works with 3.9.
Oh, yeah, that's cool.
And because it's a beta now, it should be frozen
in terms of features and APIs and stuff, right?
It's no longer changing.
So it's now time to start making sure your stuff works
and yelling if it doesn't.
Yeah, right.
And another reason to download it is the prompt,
virtual VNV with the prompt, virtual V and V
with the prompt
with the magic dot
that turns your directory name.
Yeah, that is in 3.9.
Yeah, super cool.
Awesome.
Well, that's not very funny,
but I could tell you
something that is.
And it's very relevant
to your item here, actually.
Okay.
You ready for this?
So open up this link here
and I'll put the link
in the show notes
because this is a visual
I got to describe it to you. So this was sent over by steven howell thank you for that and this
would be better during halloween but halloween's far away so we're gonna do it this way so there's
a person standing around and there's a ghost standing behind them right yeah the ghost says
boo person doesn't react boo person doesn't react boo person doesn't react. Boo. Person doesn't react. Boo. Person doesn't react.
The person says, Python 2.7.
Ah, the person runs away.
Yeah, this is great.
It's good, right?
Yeah.
You got what it was as well.
What do you got here?
Well, I'm going to get haters for this, but I'm going to say it anyway.
So somebody named Bert sent us a meta joke because we have used PyJokes before.
We love PyJokes.
And I'm going to modify it a little bit.
So what does PyJokes have in common with Java?
It gets updated all the time but never gets any better.
That's pretty funny.
I don't even really use Java, but I have a Java tool on my desktop.
And so I get like, Java's updated.
Do you want to do the update?
All the time.
Make it stop
yeah yeah that's funny yeah pyjokes is good if you all need some programming jokes just pip
install dash user pyjokes and then you can type by joke anytime you want yeah i had to change it
because the original joke was like about flash adobe flash and who has that is that even a thing
anymore yeah i don't even think it gets updated anymore.
I don't know.
Maybe it does.
I sure hope it's not on my computer.
Yeah.
It's a security flaw.
Yeah, it totally is.
Awesome.
All right.
Well, very funny.
All right.
Thank you.
Yep, you bet.
Bye-bye.
Thank you for listening to Python Bytes.
Follow the show on Twitter at Python Bytes.
That's Python Bytes as in B-Y-T-E-S.
And get the full show notes at pythonbytes. 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. This is Brian Ocken, and on behalf
of myself and Michael Kennedy, thank you for listening and sharing this podcast with your
friends and colleagues.