We all love the Python language, but it's the 200,000 plus packages that actually make Python
incredibly useful and productive. But installing these packages and even installing Python itself
can vary across the different platforms. In particular, Windows has had a hard time.
Many of the library authors don't use Windows, and so they don't test their packages on that
platform. Tutorial authors often start their tutorial steps by activating a virtual environment.
That's great. That's the great first step, but it is usually source venv slash bin slash activate,
and that doesn't work on Windows. Yet over 50% of all developers programming in Python do so on
Windows. In this episode, we'll welcome back Steve Dower. He works at Microsoft and is a Python core
developer. He has a bunch of statistics around Python and Windows for us. He also has tons of
good news on how Python and Windows is getting much better. This is Talk Python to Me, episode
243, recorded on location at Microsoft Ignite in Orlando, Florida, November 8th, 2019.
Welcome to Talk Python to Me, a weekly podcast on Python, the language, the libraries, the ecosystem,
and the personalities. This is your host, Michael Kennedy. Follow me on Twitter where I'm at,
mkennedy. Keep up with the show and listen to past episodes at talkpython.fm, and follow the show on
Twitter via at talkpython. Hey everyone, Michael here. I'm excited to tell you about our latest course.
Yes, we just released one a week or two ago, but here's another. This time, it's a nine-hour course
called Python for the .NET Developer. The idea is, if you have experience with C# and .NET,
would like to get better at Python, we'll take a bunch of common applications from the .NET space
and recreate them in Python. For example, we'll take a data-driven web app in ASP.NET and Entity
Framework and recreate that in Flask and SQLAlchemy. This means you can take all the concepts and ideas
that you know if you're a .NET developer and quickly transition to being an effective Python
developer. Are you the sole Python developer at a .NET shop? Maybe your team or co-workers could quickly
use their .NET background to get up to speed on Python to make it an important part of your tech stack.
There's even a For My Team button. Just click that and enter the number of team members you have,
and you'll probably get a discount to boot. I was also just a guest on the excellent .NET
Rocks podcast with Carl Franklin and Richard Campbell. If the idea of the Python for .NET
developer course intrigues you, just visit .NET Rocks.com? show equals 1665 to hear us discuss this from
both sides of the technology fence. So check out the course at hawkpython.fm slash .NET, D-O-T-N-E-T,
and convert those C-sharp skills to Python skills. Now, let's go talk with Steve.
Steve, welcome back to Talk Python to Me. Thanks for having me back. It's great to have you here.
We're recording on location here at Microsoft Ignite, so a lot of fun to do that at the conference
here. Yeah, is this your first time at Ignite? It is my first time at Ignite. How have you found it?
I've been a couple of times. I am very surprised at this place, to be honest. So to me, big conferences
are PyCon, Microsoft Build is a pretty big conference. This thing is like six times,
seven times as large as those. The scale is crazy. This is 30,000 attendees, at least on the first day.
I feel like it drops off. I don't think there's 30,000 today. We're on the last day. It's kind of
quiet. Yeah, it's way, way more quiet. But yeah, I actually found it really nice. I've made a lot of
cool connections and met a lot of people. I've met a lot of Python people even here running to some
folks. So I'm finding it to be a cool event. He had an interesting person come up and ask you about
your laptop. Oh, yeah, yeah. So it is the mix of the audience. It's not really a developer crowd,
right? It is sometimes, it is a developer crowd, but it's also an IT crowd. It's a SharePoint crowd.
It's a DevOps crowd. It's a cloud person. There's like all these different,
like all the computing IT folks brought together. So I was sitting around actually getting ready for
this interview to talk to you. I was taking some notes about what we're going to talk about. And
this guy comes up next to me. He's like, hey, that's a cool Surface book you got there. I don't
think I've seen that one before. I'm like, it's really cool, but it's a Mac book, not a Surface
book or Surface laptop or whatever he called it. So yeah, it's just, it's really funny. And I think that
actually is, it's an interesting angle to what we're going to talk about today.
Yeah, it's such a different crowd here compared to the Python conferences where we'd normally hang
out. I feel like, I feel like I've invited you into my house for this one.
Yeah, I've come to visit you this time, not the other way around. That's right. So yeah, I think
at PyCon, non-Windows computing or development is pretty common. And here, like, no joke,
they were mistaking my Mac for a Windows machine and like, oh, well, I only do C#. I'm like,
okay, that's cool. Yeah, I know C# too, but now I'm doing Python over here right now,
you know, things like that. And it's cool to be part of these different communities.
And it has been really exciting to see the change at Ignite over the years and Build, in fact,
because they are very different communities. But the growing Python that's showing up in them,
I feel like the first or second time I was at Build and Ignite, which would have been
2014 or so, about five years ago, people were asking, you know, what's Python? Why are you here?
Which is, you know...
What are you doing at our conference? Why did you invade it with your open source weirdness?
Right, exactly. It's like, what's your angle here? And they were kind of suspicious. And now it's at
the point where I actually had someone come up to me yesterday and say, you know, because I was here,
because I was actually here and saw everything going on, I now want to learn Python.
And that, I mean, I've never heard of that happening at the Microsoft conferences before,
but that's really exciting.
It's super exciting. Yeah, it is exciting. You know, I don't know, maybe they saw some kind of
machine learning presentation or something. They're like, wow, that I thought this was a
scripting language. Look what they're doing.
Yeah, we had a lot this year. I think two years ago, I was the only Python presentation at the entire
conference, which was...
There's a lot of presentations at this. That's like a very small percentage, right?
There's like, I don't know, we have this huge screen behind us with about eight sessions
running in parallel. And that's just this end of the rebroadcasting. There's probably like
15 tracks or something crazy going on.
Yeah.
But no, this year we had like 30 or so sessions about Python. And yeah, ranging a lot of machine
learning, a lot of data science, a lot of app development stuff. It's...
Yeah.
We're covering a lot more angles now and it's really exciting.
Yeah, it's super cool. It's not exactly what we're talking about today, but we'll talk about it
at some point in the future. You gave a really interesting talk on Python security and plugging
that into like operating level security, right?
Yeah.
Maybe talk really quickly about some of the stuff that's coming there and what you talked
about.
I kind of like move from project to project that I'm working on. One of the biggest things
I've been working on recently is getting auditing hooks, which was PEP 578 into CPython.
So that released in 3.8?
That released in Python 3.8.
Okay.
And now it's time for me to go around and teach everyone what you're meant to use them for.
Because it's like they don't actually do anything on their own right now. It's just a way of raising
low-level events from inside the runtime. So you'll get notifications from the socket module every
time it connects to a socket or every time a file gets opened, every time Ctypes gets used,
all of the stuff that you really want to know is going on, but Python doesn't really give you a
way to see it. And so the security applications of that are essentially logging. You want to collect
all that information. And as I said, in some variants of the talk, build a haystack of every
single event so that when you figure out there's a needle in there, which is someone attacking your
systems, then you've got a chance of figuring out what they were doing.
At least you have a record of it. It's not just like, well, it's hacked into, nobody knows why.
Right. It's like, oh, I know we got hacked because people are buying our customer database off the
dark web. It's like, yeah. And honestly, I think a lot of customers find out they were hacked by
saying, I only gave this email address to this, you know, they do like the plus thing,
like such and such plus, right? Site name or whatever at Gmail.
Or you get one of those emails. It's like, I know your password and here it is.
You're like, how did they get that?
Yeah. Yeah. Well, that speaks to a whole nother level of badness.
You know, just, I recently had to like sign into a bunch of a bank accounts. I'm trying
to consolidate just some like retirement, boring stuff. But I finally broke down and like said,
I have to do this. So here I go. And I tried to log into the bank. There was some workflow
where I created an account and I used a 30 character randomly generated password. And I couldn't log in
again. And I kept getting like an error too long sort of thing. And they were saying, well,
the password has to be 16 characters or less. And you know, the hash of a password is always the
same size, no matter how large the input. So what are they doing with that password? If they care
about the length of it? I'm not going to speculate on that one, but it's not, it's probably not good.
That may not be where you want to consolidate all of your retirement savings.
I was trying to get away from that place. So I feel all right about that. All right. So,
but what you were talking about with the Python stuff is there's really interesting hooks that you can
plug into for like compile or evaluate or like execute code. There's a bunch of neat stuff that
you got going on, right? Yeah. And that's one of the really scary things that Python can do that,
that most other tools installed on your system can't do is you can obfuscate the command line.
And so you can pass in the example I showed was like a big fat base 64 string wrapped up in a little
bit of decoding and eval to dynamically essentially decrypt code and run it without anyone actually being
able to see what it is. And so you, you don't know what it's doing until you go through and decrypt it.
The sample I showed then went off and downloaded more code off the internet and decrypted that.
Yeah. Cause once it started, then, then it's trouble.
Yeah. And so being able to hook the compile event, every time a bit of Python code gets exact or evaled,
you, you see what's going on and it's really hard. People have tried to, you know, sandbox Python
and just take those things out. And it turns out that doesn't work well firstly, because you need them
for a variety of things in the, in the language and standard library. And it's, there are other
ways to fight to work around that and to still compile code. So this way you don't block it hard,
but you get to see everything that goes through it. And then if something bad does happen, at least
you know about it.
Yeah. It's, it looks really positive and you know, I don't want to talk more about it cause
that's not really the topic of the show, but there was,
Let's do that one later.
Yeah. We'll do that as another show, but that's what you were here talking about. And the audience
was full, right? Like people were really interested in this.
Yeah. There's a lot more security minded people here. I did run around and do a quick survey
or just a quick chat with everyone who was attending and it was a really interesting,
What was the mix?
Diverse crowd. It was equal parts developers, security administrator, IT management. it was
a pretty good spread across all the roles that would be interested in, in managing where and how
Python is used in their setup.
Yeah. Yeah. The people asking questions afterwards were like, I'm not a developer,
but I have to sort of oversee the execution and protection of this stuff and so on. So help me,
help me understand how to do that with Python. That's pretty cool. All right. Now let's talk
about Python and windows because it's okay. Actually. Yeah. It's okay. Yeah. Actually. Yeah.
That's awesome. You know, when I go to a lot of conferences and like, especially I think PyCon
falls under this banner, you walk in and it does feel like most people are on some kind of Mac or maybe
running Linux. Like there's some windows folks there, there's, you know, some surfaces and whatnot,
but it doesn't seem to be very, doesn't seem to be the majority. Does it?
There are more and more surfaces, which we're very excited about, but yeah, the, there is always an
army of glowing fruit staring back at you while you're speaking to that crowd.
That's right. They just stand out mocking you there with a little bite. Yeah. So it feels like
it can feel like to a lot of Python developers and especially, I think it's the most relevant
audience is the people building Python packages, right?
Yeah. Yeah. So it is certainly the most popular platform that, that and Linux for, for the people
that are building the open source stuff that we know and love and rely on. And I think what's really
interesting is that that's about the only data point that really looks like that. It's a bit of
conference bias, I think as we see it ignite as well, it's biased in the other way. Yeah. And just
through that kind of selected audience, you're going to see a certain set of people. But the problem with
that and the problem with kind of all, you know, diversity type topics is if that's all you see,
and that's what you believe reflects reality. Right, right. How would you know otherwise?
Exactly. It's not exactly the, you know, the same thing, but Scott Hanselman also from Microsoft has
a really interesting saying, he did a blog post on dark matter developers. Are you familiar with this
idea? Yeah. Yeah. Yeah. It's that there's a whole bunch of folks out there who write code,
they go to work, maybe they work at some big company. They're not so passionate that they're on
Twitter all the time, right? They're not going to conferences or the meetups. They just, you know,
they're happy programming, they do their job and they go home and they're not blogging, tweeting,
podcasting about it. And that world probably looks a little bit different, right? Like what those people
need, but it's still, they're a really important consumer and user of programming languages.
Yeah, absolutely. And I've met quite a few of those developers in through visiting like any of the big
companies or financial institutes at like in New York, I've gotten to meet some of those guys and
it's like, yeah, they show up in a suit and then they go home and they stop thinking about coding
completely for the night. That's fine. Right. Like if that's one of those, it sounds great. I wish I
could stop thinking about coding at night. I know exactly. Exactly. So let's talk about it. So it feels like
conference reality is like, I don't know, 70% Mac, 15% Linux, 15% Windows. But then in your presentation
you did at PyCon, you talked about, well, that might be what the like survey around here is, but let's just
look at the numbers, right? The real numbers. Yeah. So what are some of the numbers? Yeah. So I went and
tracked down, there's a few data sources that everyone has access to that I went and looked at. And there's a few
that I've managed to speak to some people individually and get some numbers out.
PyPI is a great source of who's downloading various packages. And so I pulled that one up and
checked out, checked out a few packages. There's no easy way to kind of query the whole thing. And it
doesn't, it doesn't really make sense to do that. It doesn't make any sense to measure like PyWin32 or
something like that, right? Right. PyWin32 is, is, doesn't get installed very often on Mac,
oddly enough. If it only badly, right? So, so, you know, I tried to look at the ones that get
installed everywhere in it and it turned out that it was roughly, you know, majority Linux and,
and roughly equal Windows and Mac, which already is saying, okay, this is different from the PyCon
crowd. Yeah. And interestingly, since then we've done some more analysis on the PyPI data and found
that there's a few packages that have long lists of dependencies that may be skewing those numbers
even further. Okay. In favor of Linux. So, so there's one particular package that, that I, I won't name,
but it's, it's one of the major cloud providers tools. All right. So if you grab it and then it's
going to grab 20 other things. So that counts as like 20 downloads from Linux or something like that.
Yeah. That counts as, well, it's going to count as a Linux download for those. And we found that that
particular package had a massive, massive spike on Linux for some reason. And I don't think anyone's dug
into exactly why, but it's like in the tens of thousands of downloads a day, well beyond where
any other reasonable package should be. Right. Okay. So those numbers are still skewed, but,
but they are saying it's majority Linux, whereas a conference is not majority Linux. I had a chat with
the, the Anaconda folks to see what they could tell me about people downloading from Condor.
Yeah. I feel like they're a little more enterprise focused and that might have a different crowd.
They're a little more enterprise focused as well. You see the, the percentage of windows
downloads increasing there. So it's roughly double what it is for Mac and Linux is still
about half of the overall downloads. Okay.
The PSF survey. And, and we've had two of these now, and I believe that there's one going on right
now. I think that's probably be over by the time we finish the time we release it. So it's a little
bit, I wish I could, we could encourage people to take it, but it'll be great to look at the 2019
results. I'm, I suspect we'll see some interesting trends.
Yeah. So, so the interesting thing that happened with that is they changed the question slightly
between the 2017 and the 2018 one. So in 2017, they didn't actually ask the question and they
looked at people's huge user agents to figure out which OS they were coming from. Right. Right.
And that one showed you half of all the survey respondents were on windows and fewer on Mac,
fewer on Linux. And then, then there was a big gap, which some of us speculated it's probably Android
in iOS phones. Yeah. Cause you can take the survey on whatever you're on, but half the people
responding were on windows, which means that's kind of like a max level, I feel like, but then the
following year they asked the question again and, but this time they let you choose multiple responses
and they say, which ones you develop for. And so the interesting, the only thing that really changed
between the two sets of data is that windows are still 50% and Linux went from about 10% up to 60%.
Wow. And so people are devving on windows, but pushing to the cloud on, on Linux.
My hypothesis, and we haven't checked it. And hopefully the current survey is going to
help clarify this is people develop on windows and deploy on Linux and, or they work on windows.
Yeah. Deploy to Linux. And so you already have a much bigger chunk of windows showing up there
than you ever see at a conference.
How much do you think Docker influences this? Because Docker is like, I feel like it would
overcount the Linux side of things. Cause you so often recreate these images and they reinstall
and reinstall, you know, like...
Definitely. But virtual environments are going to be much the same thing. So I think there's,
there's a lot of repetition, but, but I guess virtual environments are now cached for things
like PyPI. So you're not actually going to count the download again.
Yeah. Yeah. Yeah. Yeah. But a fresh, like a fresh change of like a low level part of a Docker image
might as well, or CI as well, but CI is probably cached. I don't know.
Ultimately the point that, that I eventually got to with all these numbers is we don't have a good
answer for how many people are using this. Like you go and look at, at the editors that we also
have numbers for us, a VS Code, PyCharm and their majority windows, either slim or significant
majority windows and smaller Mac, very, very little Linux. And about all we can really say is that
the numbers don't line up. They definitely don't line up with what we see at a conference. And when
you walk around PyCon and you come away going, literally everyone is running on a Mac. Then all we
can say is we know that that's not true. Right.
So I feel like conservatively, probably half the, the Python community, half the Python user base
is running on windows either for development and deployment or just for development, then deploying
to another platform. Sure. And that's, so the other stat that I pulled out just for fun, because it's a
big number, but is obviously biased. So the Python.org downloads, which is mostly where the,
mostly where windows developers will get their Python from. And we see that in the stats that's,
that is vast majority windows, but the number it's, I ran some of the analysis for one month,
uh, about, about a year ago now. And there was 20 million unique downloaders in that month,
which is my windows for windows. Yeah. And most estimates of the size of the Python community,
like five to 6 million developers. And we got 20 million downloads for windows in that month.
So how interesting. So we don't know the exact numbers, but I think we can say that it's certainly
not a minority of the Python community. I would, I'd estimate it's about half, maybe more. Yeah. And
it's certainly a big number. Yeah. And that's about all I'm prepared to say concretely. Yeah. Yeah.
Sure. And so, I mean, maybe one of this, the takeaways from this section is we need to treat the windows
dev story importantly in the Python community because a lot of people are doing that and they're either
having a good experience and liking Python more or a bad experience and not feeling welcome.
Right. And so the thing that concerned me out of that is where, where are, like, where are these
developers at our conferences? Yeah. We have all of these Python conferences all the time and, and the
numbers vary, but there's, there is nowhere near a representative number of windows devs coming to our
Python conferences. And there's also not a representative amount of kind of pain and suffering
that you hear online. I mean, I, this is my area. So I watched the Twitter feed for, you know,
Python and windows and, and there's a lot of pain out there for a variety of reasons. and so I just
wonder how much is people try and get started using Python on windows and give up or they just don't feel
welcome because things are painful and it seems like they're just not, you know, no one's aware
of them. No one sees them. No one knows they're there. Yeah.
This portion of talk Python to me is brought to you by Linode. Whether you're working on a personal
project or managing your enterprise's infrastructure, Linode has the pricing support and scale that you
need to take your project to the next level with 11 data centers worldwide, including their newest
data center in Sydney, Australia, enterprise grade hardware, S3 compatible storage, and the next
generation network. Linode delivers the performance that you expect at a price that you don't get
started on the node today with a $20 credit and you get access to native SSD storage, a 40 gigabit
network industry leading processors, their revamped cloud manager at cloud.linode.com root access to your
server along with their newest API and a Python CLI. Just visit talkpython.fm/Linode when creating
a new Linode account and you'll automatically get $20 credit for your next project. Oh, and one last
thing they're hiring. Go to linode.com slash careers to find out more. Let them know that we sent you.
How many of those do you think are students? I do have some slightly more demographic data from the
Python in the Windows store distribution. So that gives me a little bit more information. There's some
age banding and some regional information. And that does certainly make it look like the majority of
people installing Python on Windows are college students in the US and China primarily. Okay. Oh,
that's pretty interesting. Yeah. Okay. Well, and it might not be that they're developing on it. They
might just need it to run something as well. They may just need it to run, but given how new the
Windows store distribution is, it's kind of unlikely that you'll find it unless you're looking for it.
Right. Okay. Yeah. So I guess the story is here's the numbers that you're giving us.
Right. We've got a lot of different sources and they all seem to point at generally the same trend.
Now what? What do we do about that? Yeah. Well, and so I was giving a conference talk,
right? So I had to speak to the people in the room. There's only so much value in getting up in front
of a crowd of people and telling them that someone else has to do something. Yeah. I don't like doing
that. So I was like, okay, what pieces can the people here help with? Because it's no one's fault,
really. It's like when a conference doesn't reflect the general population for its area,
it's really hard to say whose fault that is, but I think it's easier to say, knowing who you are,
who's here, here are things you can do that will be net positive.
Right.
So PyCon, as we said, it's a lot of library developers, a lot of enthusiasts, it's people
writing codes, people publishing code.
People who are getting paid to do Python development already. So they're in a different demographic and
whatnot to some degree as well, right?
Right. And so from that, I'm like, well, okay, these are the people who are potentially writing
the libraries that just grate a bit on Windows. Like for one little reason don't work well for
this Windows crowd and maybe, you know, contributing to that old Python community doesn't really think
about Windows. And so I built the talk around that and kind of went through some of the major
kind of cross-platform mistakes or assumptions that I see people make that don't actually translate
cross-platform well. Python already does a fantastic job of, you know, hiding most of that.
Right.
And then there's some things that bleed through that, that can, you know, if you're not aware
of them, then you are going to make code that doesn't work well on other platforms.
And the best part about it all is when I started going through those and find, and, you know,
planning out the right way to do things, turned out they're all just best practices anyway.
Right.
And they make you code better on all platforms.
Right.
Like don't treat paths as strings, treat them as, you know.
Right. Treat them as path objects.
Yeah, exactly.
So yeah, that's, that's one of the big ones because most people are aware, you know, Python,
not Python, Windows uses backslashes to separate path segments and POSIX uses forward slashes.
And so that's kind of an immediate difference where if you've written your code using the
string functions and it's all, you know, string dot split forward slash, that doesn't split
anything on Windows.
Yeah.
That's a bad time.
Let's start the story of like what we can do on Windows, which you say is really is kind
of like actually just best practices for Python code anyway.
But, you know, we got to get started by having Python on Windows.
Yeah.
Right.
And you've done some interesting work there.
Right.
And the fun thing is this, this actually happened between two of the times I gave this talk.
And so I had to go back and, and, and say, you know, you assume that this is true.
And yeah, and now you're right because I fixed it in between.
So, so yeah.
I fixed your assumption.
People have, have kind of got the hang of installing Python from the Python.org installer.
And one of the big differences that that has from, if you install it on Mac or Linux is it
doesn't put Python on path by default.
And there's a checkbox, but you got to check it and you got to know that it matters.
There's a checkbox, which I really don't like.
Like I put that there under protest.
Okay.
And I don't like it because when you put a directory on path in windows, it's not the
same thing as putting a symlink in kind of an already shared directory.
So you do that on, on Linux and, you know, you put it in the user's bin directory and then
it just shows up.
And the only thing that they get access to is Python.
But on windows, when you do this, you're injecting an entire path with every single file in that
directory.
All the executable stuff that's hanging out with Python.exe, right?
All the dynamic libraries.
So if some other application tries to load the Python DLL, it might find the one that
you put on path because that's how the resolution works.
Right, right, right.
And maybe that's like version one of, I don't know, some D library and they are actually looking
for version two.
And of course they're compiled against the header for version two.
So they are going to like hard crash because that's not going to line up and whatnot.
Right.
It's a big problem.
Yeah, exactly.
So, so I, I'm not a fan of putting Python on path.
That said, my, my fix for this, which I'll get to is I'm, I'm very happy with, but it
also doesn't come as like a Python three dot XE or Python three dot seven dot XE.
It would, it would just be a Python, which goes against all of the instructions that are out
there on how to run it.
Right.
All the getting started tutorials say type Python three, this pip three, that probably sources
thrown in there or dot.
Oh yeah.
Source activate.
Yeah.
There's just all these kind of little rough differences.
And the first few times I gave the talk, I pointed those out.
The last time I gave the talk, I got to actually say, Hey, there's a new package for this.
There's a new installer for Python, which comes through the Microsoft store.
It's still released by the Python software foundation.
Like it's exactly the same as the one that you get from Python.org.
It just comes in different packaging.
And the nice thing about this is this one has a more POSIX like system for putting shortcuts
on path.
Okay.
So it already comes with, it has a directory that's already on the user's path that only
has essentially symlinks in it.
I see.
And so in there, I was able to put a Python three, oh, a Python, a Python three and a Python
three dot seven or three dot eight shortcut that doesn't have any of the downsides of putting
all the other directories on there as well.
And so that now makes all of the commands available on windows as well as Mac and Linux in
exactly the same way.
Yeah.
That's such a positive thing.
So you can go there and you can now type Python three on windows and it, it means basically
the same thing.
You don't have to be an admin on the box to install it.
Right.
Yeah.
As long as you can get the store, it just lives on.
You probably are not even affecting other users on that window system, right?
No.
The only impact it may have on other users is if they install Python from the store, then
windows will go, oh, I've already got this once.
I'll give you the same one.
Yeah.
And, and it still separates everything by user, but it, it does save them the download.
Right.
But it's not, you're not going to break one of their apps by installing.
You can't install anything in their space.
They can't install anything in yours.
It's a good setup for multi-user Python.
That's super cool.
Another thing that's worth pointing out is even if you don't do that on windows 10 now, if
it's properly updated to the latest and you type Python three, it doesn't say Python not
found or Python three not found.
Right.
That was one of the big benefits of putting it in the store is it made it really easy
for the windows team to come around and say, well, what if we just put a shortcut in there?
It's like, everyone's been asking for years, you know, can you just put Python in windows?
And we figured out the best we could do without taking on a massive maintenance burden, which
was, we'll just put a shortcut in there.
And so you run Python, you run Python three and it'll bounce you to the store where it's
then one click to actually get the Python and Python three.
Then you type it again, then you're good.
Type again and you're good.
And we're actually seeing literally thousands of people a day installing Python through that.
And they, they probably maybe didn't even know that that was what they needed to do.
They just wanted to run Python.
They typed it and said, you don't have it, but click this button and you'll have it.
I've recommended it to a few kind of trainers and teachers and they absolutely love it because
they can now go into a classroom and say, just type Python three on your machine.
See what is it?
What happens?
And if it pops up with this, click install and now type Python three again.
And everyone in the room is ready to go.
Yeah.
A lot of those training situations as well.
Those folks don't have permission to install the wide open MSIs and all sorts of stuff that
will like shut down a class.
You're like, okay, the first thing we're going to do is install this.
We can't install it.
Well, this is going to be a real short presentation.
Yeah.
The next two hours are going to fly by.
Exactly.
Just, you just have to watch.
All right.
So I think we kind of started on the first thing is like, how do I run Python?
Right?
Not, things are not always in the path.
The, the path story is, is different.
Typing Python three until recently used to be a problem they would run into.
People would have to Google about like, well, why does Python three not work?
How do I get Python three?
It says I have Python installed in like my installed apps, but I type Python three and
it doesn't work.
So I think people still need to be cognizant of that because even though the fix is now
there, it's going to be a while before all the windows machines live in that world.
Right?
Yeah.
It always takes time to roll out new things and hopefully over time as more and more
people see it, then we'll see more instructions.
I'm really looking forward to people not posting new instructions every day on how to install
Python the old way.
Yeah.
And we start seeing some more, more people posting how to, how to install it the new way.
Right.
Here's the store.
Click it.
Yeah.
And, and so in an effort to do that, we actually convinced some of the, the Microsoft documentation
team to put our own, how to install Python on windows page up.
Okay.
So, so I will have to double check the URL, but I think docstopmicrosoft.com slash windows
slash Python.
We'll get you to some of our getting started with Python on windows page.
That's pretty cool.
that, you know, we invested in writing up and, and getting good steps and it'll take
you all the way through to, oh, you're a student.
Here's how to build your first game with Pygame.
You're a system admin.
Here's how to build, here's how to write a script that'll do like some file scanning.
Yeah.
So, you know, we're trying to, to move the entire world forward rather than leaving everyone
in the, you know, here's how to install Python 3.4 instructions, which I still saw pop up
recently.
Oh my goodness.
Yeah.
I definitely looking forward to a world where there's not a bifurcation of every step until
you actually get to run in your code is, is what do on Mac and Linux is what do on windows,
right?
Like another thing that, that varies is pip three, right?
Yeah.
So pip's always been a little bit better off because it would generate the, the versioned shortcuts.
It's done that for quite a while.
One of the downsides of the, the windows store installation is that you can't, you can only
add shortcuts into that directory if you're actually the installer itself.
So I have to pre-declare all of those in the package.
And it means that when you pip install a package, it can't update those global shortcuts.
And so they go into a directory that's not on your path.
Pip these days will print a message saying you should add this to your path.
And if you do that, then you'll be just fine.
Okay.
But, but it does mean that most kind of command line tools that you might install with pip,
you won't get to through the usual name.
Right.
Like black or pip x or something like that.
Exactly.
Okay.
And that's always been an issue that's always kind of run into problems here and there on
Python.
Yeah.
And the recommendation for a long time for, for all platforms, in fact, has been to use
Python three dash M and the name of that command rather than trying to use where it
is.
Python knows exactly where it is.
Yeah.
And the other advantage is if you know, like that's the Python you're working with.
So we generally recommend this for pip as well, because if you pip, if you pip install
something and then Python try and import it and your path is messed up and this can happen
on any OS.
It happens on Linux, happens on Mac, happens on Windows.
Then you'll go, why can't I import that package?
Right.
You like, like you type pip instead of pip three and it accidentally goes into Python two
because that's earlier or something like that.
Right.
Yeah.
And so we definitely recommend, you know, Python three dash M pip, even for pip.
Yeah.
Brett Cannon just wrote a big article about that, talking about how we recommend Python
three dash M.
Yeah.
And for all the different things.
This portion of talk Python to me is brought to you by brilliant.org.
Let me knock something off your holiday to do list.
Gifts.
Spread the love to your loved ones by gifting them brilliant.
This really excites me because it's such a fun way to nurture curiosity, build confidence
and develop problem solving skills crucial to school, job interviews or to their career.
Brilliant's thought provoking content breaks up the complexities into bite size, understandable
chunks that will lead them from curiosity to mastery.
Go to talkpython.fm/brilliant and grab a gift subscription to help your loved ones finish
their day a little smarter this season.
That's talkpython.fm/brilliant or just click the link in the show notes.
I'll call out some false assumptions that you had that people often make about writing code.
So we touched on this first one a little bit like everyone uses forward slash for path.
Yeah.
I see this assumption pop up a lot and it normally looks like, you know, using the string functions.
So string dot split dot partition and just passing in a forward slash.
That works fine as long as, you know, every platform you're on is using forward slashes, but
there's plenty that don't.
I use the built-in path lib or os.path style to process that, even if I know it's only going to run on a POSIX system
because I don't want to have to deal with thinking about that, right?
Yeah.
As a string.
There's a lot of, Python has about five different ways you can do this,
but certainly the os.path module is very useful.
And the nice thing about that is you can also import POSIX path directly or NT path directly.
If you know you need cross-platform behavior, if you like specific platform behavior.
Okay.
And so I've definitely written code that uses os.path for some things and POSIX path for other things
because that's, you know, it's going to look more like a URL or it's going to be sent to a different system.
So you have that option there.
But really, we have path lib now and we've had path lib since I think Python 3.4.
And that's just so much nicer.
Yeah.
Path lib is really nice.
And yeah, but definitely not strings, right?
Definitely not strings.
Okay.
Because I guess the tie back to Windows is right.
Like it will break on Windows.
You should do it anytime, but it will actually break, not just be less convenient.
It will break because if you get a Windows path.
And so the thing that Windows makes a little more complicated here is if you give Windows a path that has forward slashes,
it will go through and correct it for you most of the time.
Yeah.
Not all the time, but most of the time it'll correct forward slashes to back slashes.
But any path that it gives you or any path that a user gives you is going to have back slashes in it.
And you can't split on forward slash then.
Yeah.
Because you'll always get one element back and that's probably not what you wanted.
No, that's not good.
Also, route paths are kind of funny, right?
Like it could be weird maps or volumes or other stuff, right?
Yeah.
Not just C colon backslash.
It gets very interesting, the kind of range of shortcuts for identifying a drive or amount point.
So there's the kind of internal system representation, which for a drive often looks like a GUID.
Like it's a globally unique identifier and no one's typing those.
So we have a shortcut that's going to be like C colon or D colon.
There's SMB shares, which are, you know, backslash, backslash, computer name, backslash to N slay.
Which part of this is the root of the drive?
It's like if I'm dotting up the directory, how far do I go before I have to stop?
Because it varies and it's different.
And the Python libraries know how to handle that.
We've built that logic in.
Yeah.
So just don't use strings for paths.
Don't use strings for path.
Yeah.
Thank you.
Absolutely.
Use pathlib.
Speaking of paths, tilde.
tilde slash is always good.
That gets me home, right?
There's no place like tilde slash.
No place like tilde slash.
Yeah.
People love putting their configuration files in tilde slash.
Yeah.
And, you know, so Windows doesn't have tilde.
Like tilde is just a path character.
You can put that anywhere you want.
And it's just another part of the name.
That lives in the working directory.
Right.
That lives exactly where you are right now.
It's where your heart is, not where you want to be.
But people do make the, you know, they do very quickly figure out, oh, I should be using the user profile environment variable or figure out the home directory some other way to do that.
But even that, depending on what you're planning to use it for, doesn't necessarily line up.
Like you see tilde slash, you know, dot and something for a lot of configuration files on Linux.
But on Windows, that just gets thrown into the root of the user's directory, which actually has a set of subdirectories for different purposes.
And you start digging down, particularly for...
Like app data, local app data roaming, all that kind of stuff.
And they all have different reasons and different behaviors.
So like app data roaming will actually propagate between different machines on a network if that's configured for that.
So anything you put there is going to be copied or maybe copied onto a network share and automatically copied down if the user logs in somewhere else, which is really handy.
But if you're using it for, you know, 10 gigabytes worth of log files, then everyone's going to be real upset about saturating the network and login taking so long.
Yeah, exactly.
The domain controller is out of disk space.
We don't know why or wherever it gets stored.
But the other thing is that's a very hidden directory to users.
Like it isn't...
It's about as hidden as, you know, a dot file.
Yeah.
But if you're creating something that you want the user to see and modify, then they have a documents folder for that.
And you probably want a subdirectory in that documents folder anyway, just for organizational purposes.
And so you start looking at a very different layout from where you would keep all of this stuff on a POSIX-based system.
It makes me crazy when every program thinks it's projects folder needs to live in the root of my user directory.
Like, yeah.
Wouldn't need to be topmost.
Come on.
Doesn't need to be top.
And that doesn't even help on Windows because it's such a pain to get there.
Yeah.
Because all of the shortcuts go deeper.
Yeah.
Documents is really easy to get to.
Pictures is really easy to get to.
Videos is really...
That random folder you created is very hard to get to if you don't know how.
Gotta use the address bar of the file stuff.
Yeah.
For sure.
So the fix for all the path problems were to use some of the built-in path libraries.
What's the fix for this?
So this one, the recommendation I have is to use Apters, which is a module made for this purpose.
It's slightly opinionated.
So you will see, you know, good programs not behaving exactly like it does.
But it's a very simple module.
It's a single file.
So you may even just copy it into your project and keep it around.
But it lets you query for a specific kind of purpose.
And so you can say, give me the user's data directory.
Give me the user's configuration directory.
Give me a cache directory.
Give me the documents directory.
Yeah.
I believe it will give you the documents directory.
I think that may be one of the ones that's missing.
Okay.
Well, you could obviously get the home directory and add documents.
And that's exactly it.
And that one's not too difficult to add in if you find yourself needing that.
But it does it cross-platform.
So you import the module and you query for a directory.
And it will pick depending on what platform you're on and give you a sensible layout that's
not going to surprise, not going to upset anyone who's using it.
Yeah.
That's great.
Strings.
Strings are also interesting.
Well, yeah.
Unicode.
Unicode is the interesting thing.
I had this section of my talk got better and better every time I gave it because people
came and gave me more context and more information.
Yeah.
All right.
But let me pose you a trivia question here.
Which was invented first or which was released first?
Windows 1.0 or the Unicode standard?
I would initially guess Unicode, but I'm thinking this might not be right.
You'd think so.
Unicode has been around for a long time.
Stuff in quotes.
It doesn't seem like that's totally new.
It seems like that should have been right at the beginning.
It should have been.
Unfortunately not.
Windows came out first.
There were no emojis.
That's the problem.
Yeah.
No one wanted emojis at that point yet.
But because Windows came out first, they had to handle internationalization without Unicode,
which is why the code page system is there.
And there were previous systems that were already using it.
So this well predates Unicode regardless.
But it was released in Windows.
And about six years before Unicode even came out, it was released in Windows.
Which means that you have this very ingrained system of code pages and 8-bit character encodings
that now you have a compatibility burden.
And so when Unicode did come out, then it just wasn't possible to go back and say,
well, forget all of that.
We're going to switch to Unicode.
Because so much of it was at the C level where you pass char pointers.
Yeah.
The char pointers are the wrong size for Unicode.
And so, okay, trivia question number two.
Which came first?
UTF-8 or UTF-16?
You start with a smaller one, right?
You start with a smaller one, yeah.
UTF-8?
Afraid not.
UTF-16.
In fact, UCS-2.
So the two-byte character encoding was the first one.
Yeah.
And turns out Windows did actually go, oh, we should adopt this because this is now the
standard.
And that's why the Unicode encoding is two bytes throughout Windows because that was the
official standard at the time Windows said, oh, hey, let's do this.
And then UTF-8 came, it was proposed like four or five years later.
And eventually, and now that's the standard.
And I have no doubt that if Windows kind of restarted.
It would just be pure UTF-8.
Absolutely.
You do get some bloat on a number of languages and a number of very important languages to
Windows.
So arguably, there's a kind of equalization of kind of memory wastage for certain character
sets.
If you're in English, then yeah, UTF-8 is vastly more efficient.
But as soon as you get into kind of many of the Asian languages and some of the European
languages, the 16 bits...
It takes more bytes to actually do the UTF-8 stuff?
You end up with every single character taking four or five UTF-8 bytes.
Okay.
That can be a lot.
Whereas it would only be one or in some cases two UTF-16 words.
Yeah.
Which averages out to be smaller.
So maybe there's a case for either of those.
But just for historical reasons, Windows has ended up with UTF-16 as kind of the default
choice of Unicode.
And there's no real way to go back and undo that at this point without massively disrupting
the entire ecosystem.
No one's rewriting Windows with breaking changes that big.
Yeah.
And so what that leads to, as far as Python's concerned, is a kind of fundamental difference
in how paths get passed around as strings.
Because on POSIX, it's bytes.
In the lowest level, it's bytes.
And when it comes into Python, then you can keep it as bytes and pass it back out as bytes
and kind of make sure that nothing changes and gets disrupted in the way there.
And Windows has the APIs for that.
But it's doing a silent conversion in the background through the old legacy code page system.
Okay.
Which can lose data.
It can absolutely lose data.
And it seems semi-random.
This was a big Python 2 problem, was it would do this.
And so you get...
This is one of the major breaking changes from 2 to 3, honestly, right?
Like in terms of the effect that it had.
In terms of the...
Yeah, in terms of the effect.
But it's also one of the most positive ones.
Because I heard from many, many students in particular...
Sure.
...who logged into Windows with their name.
And their name is Chinese characters or Korean characters.
It's a language that Python 2 could not support.
And sometimes they do it on machines where the code page, the legacy support for Windows, can't handle it either.
I can't even say my name.
Yeah.
That's crazy.
They couldn't even print their own...
It made them feel terrible.
Yeah.
So I'm...
You know, the break for that for Python 3 was painful.
But then you have...
It was needed.
But then you have a handful of other libraries that still use bytes for paths because it's more performant in their context.
But it's also going to break these people again, even on Python 3, if you're forcing all the file system stuff to go through this arbitrary encoding.
And so the preferred one is to just use string on Windows.
Right.
Yes.
STR.
Works great.
STR instead of bytes.
Yeah.
And in fact, it works fine on POSIX as well.
We've implemented on that side the conversion for file system stuff to be perfectly round trip.
So even if there's characters in paths that, you know, if you converted to text would be corrupt and it would throw exceptions, we actually preserve those and they'll pass back in.
So there's a little bit of a performance impact.
But...
It'd be better to be slow and right than fast and wrong.
Absolutely.
Nice.
And that's a super easy fix, just like use string.
Well, it's never quite as easy as just use string.
But where it gets real interesting is if you're doing things like reading in a list of files of the file system and writing it out to another file, because you're in control of that encoding.
So Python has not and probably will not change the default encoding of a file.
So, you know, you open a file to write text to it.
What is the default encoding?
The default on...
The default is the system locale, typically.
Okay.
Which for most non-Windows users these days is UTF-8.
Yeah.
And for every Windows user is whatever the legacy encoding is.
And this is a backwards compatibility thing.
We would love to change it to be UTF-8 by default.
But now you can't read in the file that you wrote with the previous version of Python.
And that...
Yeah, it's tricky.
That's just seems...
That's a hard sell.
It's very disruptive.
Very disruptive.
And concerning, like, what do you mean my file is corrupted?
Yeah.
Yeah, that won't feel good.
Yeah, and so even opening a file to write to, if you want it in UTF-8, then you should just specify that.
I always put UTF-8.
I wasn't sure what I'd get if I don't put that, though.
Yeah.
You will get...
It's not entirely random.
Yeah, but it's not entirely the same, always.
It's not a complete encoding.
Okay.
So there will be characters that can't be written out in that.
All right.
Well, let's maybe round this out with one more false assumption here.
We're sitting here looking at my very fancy Surface Book Pro.
No, I mean MacBook Pro.
And I'm a library developer.
And maybe I can't test on Windows.
Like, I'm sympathetic.
Yeah.
Like, half of my users are Windows developers.
But I can't verify whether my library works or not.
Yeah.
And I get this one.
Like, it's very easy to...
Or it's not very easy to get a Windows setup, necessarily, that it's very hard to switch kind of the platform you're used to to another one just for the sake of being able to address all of your users.
But at the same time, that's not...
That's like kind of drawing the line too close.
And it's like, you know, I'm aware of a problem.
And I'm aware that I need to solve it.
And I think of one solution and that's too hard.
And so I stop thinking about it.
Yeah, yeah.
That's hard.
So no.
And that's kind of what I see happen occasionally here.
And it just, you know, it makes me, you know, just choke up a little bit because I'm like, that's just bad and lazy.
Yeah, and so close.
And we have so many better options these days.
And it's really saying, thanks, but you're not welcome here to like half the users.
Absolutely.
Yeah.
And I could get it 10 years ago.
Because 10 years ago, we didn't have GitHub.
Or if we did have GitHub, we didn't have the reach of GitHub like we do now.
Right.
Or Azure Pipelines or all the CI.
Azure Pipelines.
Like I have GitHub Actions.
We didn't have all of these things where you can either set up to do it automatically and not need to own the machine yourself.
And we didn't have the reach to be able to say, hey, I need help with this.
Can someone come and help me test on Windows?
Because that's how it always happened, essentially.
Honestly, I think the hardest one to, if it's not you, the hardest one to test for is Mac.
Yeah.
Right?
I test none of my stuff on Mac.
That's not quite true.
But I do it all through CI.
Yeah, exactly.
But it's tougher to get CI for Mac.
It is.
Yeah.
It is.
But Windows and Linux are pretty easy to get that.
They're pretty easy.
And Azure Pipelines and GitHub Actions both have Windows, Mac, and Linux.
And I think at this point, they have multiple choices for all of those.
Okay.
So you can do like Mojave versus Catalina.
I think Windows 7 versus 10 or something.
I don't think we're offering Windows 7 as an option on any of those.
You don't want to encourage that?
The builds actually run on Windows Server.
Not even Windows Client.
So you do get a choice between Windows Server 2016 and 2019.
And choice of like the Visual Studio version, which is primarily, you know, people should
just be on the latest for the most part.
Python stuff is not that involved in the build tool set to really need to, you know, I must
stay on the old one anymore.
We made sure that Python works with future builds as well.
So you can build for old versions of Python with newer tools now.
Yeah.
So that's cool.
So the options and the opportunities there is really good.
And they're all free.
Like it doesn't cost anything to just put on your page.
I'm looking for someone to help with Windows maintenance.
And it doesn't cost anything for an open source project to be on GitHub Actions.
Right.
And people are probably excited if they're working on Windows.
Like, oh, this is a really easy way for me to contribute to this project.
Yeah.
Right.
Like all I got to do is sort of like run the test and just try a few things out.
You'll get more contributors because you're not telling them you have to switch to Linux
to contribute to my project because you've got the CI running on Linux as well.
Right.
So it opens up your pool of contributors and it helps with releases.
One of the biggest problems we see every time we release an update to Python.
So Python 3.8 came out and we're seeing this happen a bit is packages don't have wheels
ready.
They don't have builds that like they're not actually ready for Python 3.8.
And once you've got a CI setup going, which is almost automatic.
Yeah.
It's almost automatic.
As soon as the CI service has that version of Python on there or has a way to get it sooner
and, you know, we're working on making that happen faster, then it's very easy to just
spin another build and release that.
And all of your users are now successful at installing your package.
Good advice.
So that pretty much wraps it up.
You want to give us the quick summary?
The quick summary.
The checklist.
You had a checklist.
You don't have to remember all this.
Here's the checklist of what you got to do.
Yeah.
It annoys me when I see people holding their phones up at me while I'm speaking because
all of my slides build up.
Yeah.
And so like there'll be stuff on the slide that's bad and a big red line is about to appear
through it and someone's already taking a photo.
They're going to share it on social media now.
And I'm like, no, no, wait, wait, wait until it gets crossed out.
Yeah.
So I told everyone to wait for the checklist at the end of the talk because I did want to
make this really actionable and really easy for people to follow up.
So the things that I would recommend you check just before the next release of your project,
anytime you feel like it, does the dash M option work on it?
So if you've got a script entry point, can you also start your project running by typing
Python 3 dash M name of your project and document it.
Tell your users this is how you can use it.
Yeah.
Are you manipulating paths by hand anywhere?
Like, do you have any dot split instead of OS dot path dot split or path lib objects?
I like this recommendation because it's, it's just like you should do the thing that's easier
and safer and you'll be, you'll be in good shape.
Yeah.
Do I put configuration in weird places, which, you know, arbitrary paths for storing stuff.
It can make a mess, but it can't, you know, you can lose information and make things a
little harder to find.
Are you still using bytes for strings?
If you've gotten out of Python 2 and into Python 3, then there's no need to do that anymore.
That was the problem that we were trying to move people off.
So feel free to stop, you know, just use the string type.
The string type is very optimized for what it does.
And do you have, you know, continuous integration tools or collaborators on your project?
Like if it's just you on the project and the problem is that you are not representative
of your entire audience.
No one person can be.
Yeah, no matter who you are or what you do.
Yeah.
No matter who you are, there are people out there who are using your code.
Who are doing things differently from you.
And with continuous integration tools, GitHub Actions, Azure Pipelines, you can kind of have
automated systems that look like more of your users, but just welcoming more people in to
contribute and collaborate.
Even if it's just, hey, I'll email you when I'm about to do a release.
Can you run, you know, your tests on it?
And a lot more people are willing to do that than you think.
Yeah.
All right.
Well, it's all good advice.
And I definitely think the stats that you laid out are pretty interesting.
So thanks.
Yeah.
Not the world we often see around us, but it's the world as it is.
At least as good as the stats can measure from what we're using there.
Cool.
All right.
Well, before we wrap up the show, let me ask you the final two questions.
If you're going to write some Python code, what editor do you use?
I'm bouncing between editors all the time right now.
What's in the orbit that you're hitting?
I use Visual Studio until it annoys me.
Then I use Visual Studio code until it annoys me.
Then I use Notepad 2 until it annoys me.
Then I go back to Visual Studio and that's my code.
That's the three-body problem, the three-editor problem?
The three-editor problem.
Yeah.
Indeed.
And then notable PyPI package.
Oh.
What have you come across lately that's like, oh, this is pretty amazing?
Oh, I forgot this question was going to be here, so I hadn't thought about it.
Yeah.
See, this is like improv too.
On the spot.
Yeah.
What was I?
I was playing with something the other day that I really enjoyed.
While you're here thinking, I'll tell you about one I found recently that I thought was kind
of cool is HTTPX.
Oh, yes.
Okay.
I do like that one.
I like it because it's requests compatible, but it also does HTTP2 and async.
And then there's also some intermediate, simpler async parallelism built in it.
It's a cool one.
I've been helping promote that one.
It's in its early stages.
It is.
They're looking for contributors who are interested in the next big HTTP project.
So I'm excited about that one.
I guess I can't claim it.
Yeah, you claim it.
Go ahead.
I can claim it.
Okay.
We both like HTTPX.
Yeah, it's a good one.
Yeah.
It is early days and it could use some help, but I like it as well.
I think it's got promise.
Cool.
All right.
Well, Steve, final call to action.
People are working on their packages or working on their non-Windows machines.
What can they do to welcome the Windows people?
I think it's literally just that.
Like, welcome the Windows people.
You know, I gave a few simple things you can do to make them feel welcome, but it really just
is.
This also works on Windows, or if it doesn't, we want it to.
You know, please help.
Yeah, they got the checklist.
Yep.
All right.
Well, thanks for being here.
Great.
Thanks.
Bye.
This has been another episode of Talk Python to Me.
Our guest on this episode was Steve Dower, and it's been brought to you by Linode and
Brilliant.org.
Start your next Python project on Linode's state-of-the-art cloud service.
Just visit talkpython.fm/Linode, L-I-N-O-D-E.
You'll automatically get a $20 credit when you create a new account.
Brilliant.org encourages you to give the gift of critical thought and knowledge.
Visit talkpython.fm/brilliant and grab a gift subscription to help your loved ones
finish their day a little smarter this season.
Want to level up your Python?
If you're just getting started, try my Python Jumpstart by Building 10 Apps course.
Or if you're looking for something more advanced, check out our new Async course that digs into
all the different types of Async programming you can do in Python.
And of course, if you're interested in more than one of these, be sure to check out our
Everything Bundle.
It's like a subscription that never expires.
Be sure to subscribe to the show.
Open your favorite podcatcher and search for Python.
We should be right at the top.
You can also find the iTunes feed at /itunes, the Google Play feed at /play,
and the direct RSS feed at /rss on talkpython.fm.
This is your host, Michael Kennedy.
Thanks so much for listening.
I really appreciate it.
Now get out there and write some Python code.
I'll see you next time.