WEBVTT

00:00:00.001 --> 00:00:05.200
Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to your earbuds.

00:00:05.200 --> 00:00:10.620
This is episode 39, recorded August 14th, 2017.

00:00:10.620 --> 00:00:18.280
I'm Brian Okken, and again, Michael is on vacation, and we have a guest host, and this week we have Mahmoud Hashemi.

00:00:18.280 --> 00:00:19.740
Hey, Mahmoud.

00:00:19.740 --> 00:00:20.200
Hi there.

00:00:20.200 --> 00:00:22.520
Great to be here.

00:00:22.520 --> 00:00:27.460
Yeah, you've been on Testing Code, and you've been on Talk Python a couple times.

00:00:27.460 --> 00:00:28.960
Yeah, a couple of my faves, for sure.

00:00:28.960 --> 00:00:34.760
Yeah, well, when I was looking up Talk Python, I noticed that you were on episode 4 in 54.

00:00:34.760 --> 00:00:41.940
Yeah, and I don't know, when Guido was on, you know, Michael was kind enough to ask my question, and I did like a panel thing.

00:00:41.940 --> 00:00:46.780
I don't know, I guess, yeah, it's been really nice to have repeat appearances.

00:00:46.780 --> 00:00:49.380
People recognize me by my voice now.

00:00:49.380 --> 00:00:52.660
It's kind of strange, but like, I'm very appreciative at the same time.

00:00:52.660 --> 00:00:53.340
That's good.

00:00:53.340 --> 00:00:54.140
That's great.

00:00:54.140 --> 00:00:56.560
And so, thanks a lot for helping to do this today.

00:00:56.560 --> 00:00:59.220
Yeah, hopefully I can do Michael Wright taking his spot here.

00:00:59.220 --> 00:01:00.580
Well, let's just jump right in.

00:01:00.580 --> 00:01:02.320
I'm really excited about your first topic.

00:01:02.320 --> 00:01:02.800
Oh, sure.

00:01:02.980 --> 00:01:04.000
So, let's see.

00:01:04.000 --> 00:01:08.800
First up, I mean, one thing that's been on my radar, I'm not sure if you guys talk about this before.

00:01:08.800 --> 00:01:12.680
Like, sometimes I'm listening to Python bytes, and it's a little bit garbled or something.

00:01:12.680 --> 00:01:14.700
Have you guys tried calling decode?

00:01:14.960 --> 00:01:17.740
I'm kind of curious, like, why it's not Python stirs.

00:01:17.740 --> 00:01:22.800
But one thing that's been on my radar is the new PyPI.

00:01:22.800 --> 00:01:32.820
So, if you haven't been on Distutils, SIG, you may have not seen that there's actually a new PyPI, pypi.org.

00:01:32.820 --> 00:01:37.420
And this is going to be the Python package index going forward.

00:01:37.600 --> 00:01:40.200
So, this is what we've been calling Warehouse before.

00:01:40.200 --> 00:01:40.840
Is that right?

00:01:40.840 --> 00:01:45.300
So, Warehouse is the software that runs PyPI, you know?

00:01:45.300 --> 00:01:45.540
Okay.

00:01:45.940 --> 00:01:48.600
And so, yeah, it's a package index.

00:01:48.600 --> 00:01:52.140
It's going to be where all of your wheels and SDISTs live.

00:01:52.140 --> 00:01:55.500
And there's basically a lot of development that's happening here.

00:01:55.500 --> 00:01:59.740
My friend Donald Stuffed is doing an amazing job with his team.

00:01:59.740 --> 00:02:05.080
Basically, yeah, we're up to 114,598 projects at the moment.

00:02:05.080 --> 00:02:12.120
This even lists the number of files, almost a million files with 230,000 users.

00:02:12.220 --> 00:02:15.980
And so, yeah, I would definitely check out this pypi.org for yourself.

00:02:15.980 --> 00:02:21.140
But for the most part, I wanted to talk about how they're deprecating the old PyPI.

00:02:21.140 --> 00:02:26.800
So, pypi.python.org is now basically just a read-only interface.

00:02:26.800 --> 00:02:33.020
And if you've tried to upload a package recently, then you may have seen an error, HTTP 4.10,

00:02:33.020 --> 00:02:37.940
which is like a 4.04, but this is 4.10 gone, meaning it was here, but now it's gone.

00:02:38.240 --> 00:02:42.480
And so, yeah, you basically make sure to use a new version of setup tools,

00:02:42.480 --> 00:02:45.000
and it'll automatically start using the new one.

00:02:45.000 --> 00:02:48.960
As long as your configs don't state otherwise, you might have to update a config.

00:02:48.960 --> 00:02:52.440
But this is a tremendous leap forward in a lot of ways.

00:02:52.440 --> 00:02:55.460
And they need some help doing it too, you know?

00:02:55.460 --> 00:02:57.140
So, it's all open source on GitHub.

00:02:57.140 --> 00:02:58.500
There are issues.

00:02:58.500 --> 00:02:59.960
I'm working on one right now.

00:02:59.960 --> 00:03:02.900
Yeah, it's got a lot of cool features.

00:03:02.900 --> 00:03:04.100
Have you taken a look, Brian?

00:03:04.100 --> 00:03:05.500
I've looked around a little bit.

00:03:05.500 --> 00:03:09.980
Now, one of the things I've noticed, like right off the bat, is it says up at the top,

00:03:09.980 --> 00:03:11.500
there's a big red bar that says...

00:03:11.500 --> 00:03:12.480
I know, it's kind of scary.

00:03:12.480 --> 00:03:12.980
Yeah.

00:03:12.980 --> 00:03:16.740
So, do you know, I'm guessing eventually at some point they'll,

00:03:16.740 --> 00:03:20.820
the other interface will just redirect to here, or is there...

00:03:20.820 --> 00:03:22.920
I mean, you know, cool URLs don't change.

00:03:22.920 --> 00:03:27.500
Personally, in my view, I'd like it if they just kept it up and put the red bar over there,

00:03:27.500 --> 00:03:31.140
that this is a, you know, archive version of PyPI.

00:03:31.440 --> 00:03:34.280
But for now, all those URLs are still working.

00:03:34.280 --> 00:03:39.880
And if you ask me, pypi.org has been in use for so long, because actually, if you've paid

00:03:39.880 --> 00:03:44.500
close attention, a lot of your downloads, pip is downloading from the new one.

00:03:44.500 --> 00:03:45.000
Oh, okay.

00:03:45.000 --> 00:03:47.280
So, yeah, it's been in production a long time.

00:03:47.280 --> 00:03:51.540
In fact, they just hit, I think, a petabyte a month in bandwidth downloads.

00:03:52.000 --> 00:03:57.080
So, yeah, just for a sense of the cost there, I think it's like in the tens of thousands,

00:03:57.080 --> 00:04:00.840
like 30, 40,000 a month to host PyPI.

00:04:00.840 --> 00:04:04.980
And that's kindly donated by the Fastly CDN.

00:04:04.980 --> 00:04:10.640
Should they stop feeling so generous, you know, we got to support our community somehow.

00:04:10.640 --> 00:04:13.140
So, there is a donate button here.

00:04:13.180 --> 00:04:18.580
But I think that right now, what they need most is sort of like people to work on cool

00:04:18.580 --> 00:04:24.520
features, like one that I saw has been working on that I'm very excited for, not strictly PyPI.org,

00:04:24.520 --> 00:04:27.280
but same team, the Python Packaging Authority.

00:04:27.280 --> 00:04:31.540
They are working on making a dependency graph between all packages.

00:04:31.540 --> 00:04:37.760
So, if you've ever wondered what depends on what ahead of time, then this would enable that.

00:04:37.760 --> 00:04:39.160
So, yeah.

00:04:39.460 --> 00:04:40.600
How do I start working on it?

00:04:40.600 --> 00:04:42.240
Do I go to the GitHub page?

00:04:42.240 --> 00:04:42.600
Yeah.

00:04:42.600 --> 00:04:48.560
So, I think it's github.com forward slash PyPA or I think it might be forward slash warehouse.

00:04:48.560 --> 00:04:49.000
Yeah.

00:04:49.000 --> 00:04:49.360
Okay.

00:04:49.360 --> 00:04:55.140
So, and, you know, Donald has been very candid about like, you know, the areas that need

00:04:55.140 --> 00:04:57.660
development and he's been working very hard.

00:04:57.660 --> 00:05:02.260
He's at Amazon now and he spends some time working on stuff there.

00:05:02.260 --> 00:05:04.720
Oh, one last thing, like distutils, right?

00:05:04.720 --> 00:05:10.960
So, so they still, there's an email list called distutils-sig, which stands for special interest

00:05:10.960 --> 00:05:11.320
group.

00:05:11.320 --> 00:05:16.840
And so, distutils-sig, you can just go join the listserv and you can read the archive and

00:05:16.840 --> 00:05:18.040
see the conversations they're having.

00:05:18.040 --> 00:05:20.960
If you care about packaging, you're probably already on there.

00:05:20.960 --> 00:05:23.480
But if you aren't, definitely subscribe.

00:05:23.480 --> 00:05:24.640
Oh, I didn't know about it.

00:05:24.640 --> 00:05:25.000
Yeah.

00:05:25.000 --> 00:05:28.300
So, we'll try to drop a link in the show notes for that.

00:05:28.300 --> 00:05:29.960
So, okay.

00:05:30.060 --> 00:05:31.600
Well, that's, that's really cool.

00:05:31.600 --> 00:05:33.580
Pretty good for first topic, you know, I don't know.

00:05:33.580 --> 00:05:35.180
Yeah, definitely.

00:05:35.180 --> 00:05:41.620
And I, and the one, one thing I want to add is I know that Donald has been vocal before about

00:05:41.620 --> 00:05:43.680
how awful the previous code was.

00:05:43.680 --> 00:05:44.260
Yeah.

00:05:44.260 --> 00:05:46.580
I mean, it's, it's pretty old code, right?

00:05:46.580 --> 00:05:47.580
Like, I don't even know.

00:05:47.580 --> 00:05:50.820
I, it may not predate WSGI, but it's pretty old.

00:05:50.820 --> 00:05:52.100
You've looked at the new code.

00:05:52.100 --> 00:05:52.900
I've looked at the new code.

00:05:52.900 --> 00:05:54.720
I can talk about the new code if we got a second.

00:05:54.720 --> 00:05:55.940
So, I've, I've looked at it.

00:05:55.940 --> 00:05:56.620
I've used it.

00:05:56.620 --> 00:05:58.420
It's got 100% coverage.

00:05:58.740 --> 00:06:00.540
It's got a lot of CI stuff set up.

00:06:00.540 --> 00:06:01.740
It uses Docker.

00:06:01.740 --> 00:06:07.740
I had a little bit of trouble, like, you know, with the make-based approach to running the

00:06:07.740 --> 00:06:09.080
thing, but it's pretty complex.

00:06:09.080 --> 00:06:12.000
Like, it runs, I think, an elastic search and all this stuff.

00:06:12.000 --> 00:06:14.060
So, basically, yeah, you just.

00:06:14.060 --> 00:06:17.940
People shouldn't be afraid to help out just because they've heard bad things about the

00:06:17.940 --> 00:06:18.320
old code.

00:06:18.320 --> 00:06:21.320
No, the new code is, it's pretty idiomatic, I think.

00:06:21.320 --> 00:06:26.620
And, you know, if you're familiar with SQLAlchemy, and I think it uses also maybe like

00:06:26.620 --> 00:06:28.080
Pyramid, I think.

00:06:28.360 --> 00:06:31.040
And it looks like the tests are in pytest, too.

00:06:31.040 --> 00:06:36.720
Yeah, the test is definitely in pytest, which is, frankly, the only way I've heard and have

00:06:36.720 --> 00:06:38.120
also found myself.

00:06:38.120 --> 00:06:40.280
So, yeah, it's been good.

00:06:40.280 --> 00:06:44.100
Oh, I could talk about this for a long time, but let's move on to the next topic.

00:06:44.100 --> 00:06:44.600
Absolutely.

00:06:44.820 --> 00:06:47.540
So, one of the things I just read about this yesterday.

00:06:47.540 --> 00:06:54.440
There's a, I read about it on Make, I think it's the Make website, but it's CircuitPython

00:06:54.440 --> 00:06:59.540
is now going to be, is supported by a whole bunch of Adafruit hardware.

00:06:59.700 --> 00:07:03.500
It's great news for hardware hackers and also tinkerers like myself.

00:07:03.500 --> 00:07:06.280
And so, we'll put a link in the show notes to the Make article.

00:07:06.280 --> 00:07:12.520
But there's also, so I had heard Adafruit announced CircuitPython in January.

00:07:12.520 --> 00:07:16.680
And it's a, it's an open source, it's based on MicroPython.

00:07:16.680 --> 00:07:21.540
So, CircuitPython is also open source, but it's, so I'm not quite sure how they differ.

00:07:22.080 --> 00:07:25.560
But they've added some things to make it easier to control hardware.

00:07:25.560 --> 00:07:35.740
And they already had, like, two devices, Metro M0 and Feather M0 express versions that support

00:07:35.740 --> 00:07:37.220
CircuitPython right off the bat.

00:07:37.220 --> 00:07:41.280
And they're, I guess they're working on a Circuit Playground Express.

00:07:41.280 --> 00:07:43.500
All of these look like really fun things.

00:07:43.500 --> 00:07:49.480
But the thing that really caught my attention was Gemma M0 that was announced at the end of

00:07:49.480 --> 00:07:49.860
July.

00:07:50.300 --> 00:07:52.600
And this thing is, like, the size of a quarter.

00:07:52.600 --> 00:07:58.000
It's a little small thing that you can make wearable software projects with, like LEDs and

00:07:58.000 --> 00:07:58.300
whatever.

00:07:58.300 --> 00:08:02.300
And you just plug it in into your computer.

00:08:02.300 --> 00:08:04.640
And you instantly, it's like an extra drive.

00:08:04.640 --> 00:08:09.960
You can see a main.py and it just, you can just start programming Python right away.

00:08:09.960 --> 00:08:10.440
Yeah, right.

00:08:10.440 --> 00:08:13.800
So, basically, it just, like, it sort of functions kind of like a USB drive.

00:08:13.800 --> 00:08:16.080
And there's a single main entry point in there.

00:08:16.080 --> 00:08:17.400
And you can just modify it.

00:08:17.400 --> 00:08:20.200
And then, you know, you don't need to install anything.

00:08:20.200 --> 00:08:21.800
Or anything like that.

00:08:21.800 --> 00:08:22.960
Yeah, there's no loading.

00:08:22.960 --> 00:08:24.980
Apparently, it does support Arduino.

00:08:24.980 --> 00:08:28.520
But you don't, like, right off the bat, you don't have to install anything.

00:08:28.520 --> 00:08:29.660
You can just start programming.

00:08:29.660 --> 00:08:32.720
And these are, they, right now, they're currently out of stock.

00:08:32.720 --> 00:08:35.480
But I'm sure they get new stuff in pretty quick.

00:08:35.480 --> 00:08:39.480
But they're, it's under 10 bucks to start programming some wearable programming.

00:08:39.700 --> 00:08:41.540
So, I definitely have to get one of these.

00:08:41.540 --> 00:08:41.780
Yeah.

00:08:41.780 --> 00:08:43.720
I can't wait to start wearing some running Python.

00:08:43.720 --> 00:08:45.880
That'd be taking it to the next level.

00:08:45.880 --> 00:08:51.220
And I'm also going to link to what I thought was great was they realized that, I mean, they

00:08:51.220 --> 00:08:55.100
are encouraging people to use Python if they can for programming hardware.

00:08:55.380 --> 00:08:58.760
But they realized that a lot of people are new to the Python community.

00:08:58.760 --> 00:09:04.320
So, there's a page called Creating and Sharing Circuit Python, a Circuit Python library.

00:09:05.060 --> 00:09:09.840
And it's got a whole bunch of great links, like, basically just telling people what, what

00:09:09.840 --> 00:09:15.300
we, when we call it, say library, we mean a package or a module with a setup file and doing

00:09:15.300 --> 00:09:15.880
it all right.

00:09:15.880 --> 00:09:20.220
And there's little intros to GitHub and Read the Docs and Travis.

00:09:20.220 --> 00:09:24.440
So, is it like, when you say package or module, is this their own format?

00:09:24.440 --> 00:09:27.180
Or is this like Python packages, wheels, that sort of thing?

00:09:27.180 --> 00:09:28.620
Yeah, it's just Python stuff.

00:09:28.620 --> 00:09:32.560
But it's just really quick tutorials to get people up to speed fast.

00:09:32.560 --> 00:09:32.900
Sure.

00:09:33.080 --> 00:09:36.740
So, it's like sort of a full, it's got like an end-to-end thing.

00:09:36.740 --> 00:09:39.620
It doesn't just send you left and right to other sites.

00:09:39.620 --> 00:09:40.400
Yeah, right.

00:09:40.400 --> 00:09:42.100
It's really telling you everything.

00:09:42.100 --> 00:09:43.760
And it's, they're pretty condensed.

00:09:43.760 --> 00:09:47.580
Actually, they're pretty good job condensing all that information.

00:09:47.580 --> 00:09:51.080
Yeah, you don't need the whole context and history of Python packaging.

00:09:51.080 --> 00:09:55.100
It's been, we've come a long way since, you know, eggs and that sort of stuff.

00:09:55.100 --> 00:09:55.440
Yeah.

00:09:55.440 --> 00:10:02.680
And then one of the things that is kind of interesting is they have a concept of bundles.

00:10:02.680 --> 00:10:10.340
And really, all the bundle is, is a bunch of installable Python packages that are zipped up into a bundle.

00:10:10.340 --> 00:10:11.440
Hmm, sure.

00:10:11.440 --> 00:10:18.400
We normally don't really care about that because on a larger computer, it's not that big of a deal.

00:10:18.580 --> 00:10:22.920
But these little tiny devices, you still have to care about how big it is.

00:10:22.920 --> 00:10:28.560
So, you're only, you might want to get everything that somebody cool has made, but you don't need it all.

00:10:28.560 --> 00:10:32.280
You just need like the little part that, you know, blinks the LED for you or whatever.

00:10:32.280 --> 00:10:32.600
Sure.

00:10:32.700 --> 00:10:34.240
So, it sort of freezes it all together.

00:10:34.240 --> 00:10:34.700
Yeah.

00:10:34.700 --> 00:10:36.440
These embedded applications are interesting.

00:10:36.440 --> 00:10:39.820
So, now that, so I maintain this one library called hyperlink.

00:10:39.820 --> 00:10:43.340
And I guess it's pretty widely used because twisted depends on it.

00:10:43.340 --> 00:10:47.960
And so, I've gotten some interesting feedback of a few things.

00:10:47.960 --> 00:10:49.620
Like one code review I just went through.

00:10:49.620 --> 00:10:51.160
I promise this is related.

00:10:51.640 --> 00:10:55.820
Basically, I'm using pytest and I'm writing my assert statements.

00:10:55.820 --> 00:10:59.600
And, you know, I love that pytest rewriting with the great error messages and so forth.

00:10:59.600 --> 00:11:05.320
But I got a comment on my code review that these tests are not runnable in an embedded environment

00:11:05.320 --> 00:11:10.260
because they will run with dash OO, which elides all of those assert statements.

00:11:10.260 --> 00:11:15.420
And I'm like, well, you're kind of running the tests wrong if you're not using pytest.

00:11:15.420 --> 00:11:19.240
But in these embedded environments, I don't know, maybe the convention is different.

00:11:20.020 --> 00:11:22.520
So, when you get yours, definitely like test it out.

00:11:22.520 --> 00:11:30.300
Maybe you'll have to put a little caveat on your pytest recommendation if that's not what we can do on hardware.

00:11:30.300 --> 00:11:30.760
I don't know.

00:11:30.760 --> 00:11:31.600
Oh, that's interesting.

00:11:31.600 --> 00:11:32.660
Yeah.

00:11:32.660 --> 00:11:34.660
Yeah, I'll definitely have to check that out.

00:11:34.660 --> 00:11:38.140
So, I don't want the hardware people to not buy my book.

00:11:38.140 --> 00:11:38.860
That would be terrible.

00:11:38.860 --> 00:11:40.000
Well, that's the thing.

00:11:40.000 --> 00:11:47.480
With something like hyperlink, which is for URLs, I'm like 99.9% sure it's going to run exactly the same everywhere.

00:11:48.060 --> 00:11:52.780
So, I'm confident that if it runs on my machine, it runs on Travis CI, it runs on CodeVayer or whatever.

00:11:52.780 --> 00:11:55.500
It's going to AppVayer, I think.

00:11:55.500 --> 00:11:56.580
It'll be fine.

00:11:56.580 --> 00:12:01.760
But at the same time, hardware people can be sticklers, as I'm sure you know.

00:12:01.760 --> 00:12:03.940
So, I respect that.

00:12:03.940 --> 00:12:04.580
I respect that.

00:12:04.580 --> 00:12:04.760
Cool.

00:12:04.760 --> 00:12:05.820
Yeah, neat.

00:12:06.400 --> 00:12:08.340
Well, what do we got next, Mahmoud?

00:12:08.340 --> 00:12:08.820
Oh, right.

00:12:08.820 --> 00:12:09.600
It's back to me.

00:12:09.600 --> 00:12:10.540
So, I don't know.

00:12:10.540 --> 00:12:18.280
I mean, so I spend a lot of my time pretty deep into development of all sorts of infrastructural sorts.

00:12:18.840 --> 00:12:24.100
And I find myself subscribed to Python Dev, Python Ideas, Distutils SIG.

00:12:24.100 --> 00:12:27.960
And, you know, you can't read everything there and still have a life.

00:12:27.960 --> 00:12:30.020
So, only a few things catch my eye.

00:12:30.020 --> 00:12:34.900
But this one in particular caught my eye because my friend Hinek has this great library called Adders.

00:12:34.900 --> 00:12:43.600
If you haven't heard of it, my other friend Glyph has a whole blog post that tells you why you have to use this library, ATTRS.

00:12:43.600 --> 00:12:50.360
And it's basically class decorators that make writing high-level classes very easy.

00:12:50.360 --> 00:12:55.840
So, it sort of derives from this sort of tradition of name tuples, right?

00:12:55.840 --> 00:13:03.320
Raymond Hedinger had this great idea to make name tuples, which let us define a class-like structured thing within just one line.

00:13:03.860 --> 00:13:09.260
But the problem with name tuples is that if you want to add methods to it, then you have to inherit from it.

00:13:09.260 --> 00:13:10.960
And they're immutable by default.

00:13:10.960 --> 00:13:17.780
And they don't really, even though they generate a __init__() for you, they don't do a whole heck of a lot of validation.

00:13:17.780 --> 00:13:23.800
So, Adders comes along, fixes all these things, adds a bunch of other cool functionality, and does it with class decorators.

00:13:23.800 --> 00:13:27.800
It doesn't pollute your final object with anything you don't want, right?

00:13:27.800 --> 00:13:29.800
It doesn't, because you don't inherit from anything.

00:13:29.800 --> 00:13:31.680
So, you just inherit from object.

00:13:31.920 --> 00:13:38.080
After Glyph's post took off or something, the core Python devs sat up, took some notice of this, and said,

00:13:38.080 --> 00:13:42.740
maybe we have been neglecting a higher-level interface for quickly defining classes.

00:13:42.740 --> 00:13:47.720
You know, you just want to have four or five fields all sort of batched together.

00:13:48.280 --> 00:13:52.980
And you don't want to have a lot of functions that everywhere have to define 15 arguments.

00:13:52.980 --> 00:13:59.320
So, like, how can we quickly, in a nice, concise, Pythonic way, define a Python class?

00:13:59.960 --> 00:14:13.460
And they came up with this new thing, which is still, I guess, kind of, this is what I mean, like, I don't know if this is a little bit too deep underground, but there's this kind of, there's this GitHub that Eric V. Smith, who is a Python core dev, has called Data Classes.

00:14:13.980 --> 00:14:23.960
And the issues of this have been really interesting to watch because Hynek and a bunch of core devs have been kind of debating, like, hey, should we just use attrs?

00:14:23.960 --> 00:14:27.400
If attrs is getting so popular, should it just be part of the core Python?

00:14:28.400 --> 00:14:30.160
And, you know, people seem to like it.

00:14:30.160 --> 00:14:33.600
Why make something that's so close to it that sort of thing?

00:14:33.600 --> 00:14:40.440
There's sort of a draft PEP inside of the Data Classes repo, and there's some examples of how it's used.

00:14:40.440 --> 00:14:43.140
Has some semantic differences, has some syntactic differences.

00:14:43.140 --> 00:14:45.940
I think that it's pretty interesting to watch.

00:14:45.940 --> 00:14:50.620
And, in fact, they seem to be encouraging more experimentation in this area.

00:14:50.620 --> 00:14:55.420
Even though I like attrs, they seem to want even more options, at least from themselves.

00:14:56.120 --> 00:14:57.360
So, I don't know.

00:14:57.360 --> 00:14:58.940
I had a good time reading the issues.

00:14:58.940 --> 00:15:00.340
Maybe other people enjoy it too.

00:15:00.340 --> 00:15:00.600
Yeah.

00:15:00.600 --> 00:15:03.300
So, is this, it's similar to attrs then?

00:15:03.300 --> 00:15:03.560
Yeah.

00:15:03.560 --> 00:15:05.440
It's pretty similar to attrs.

00:15:05.440 --> 00:15:11.240
There are, the differences are sort of fine enough that you have to kind of look closely.

00:15:11.240 --> 00:15:18.120
Basically, I think that what it is, is like, there's actually an issue called, why not just attrs?

00:15:18.120 --> 00:15:26.000
And they sort of explain that they want to use, like, the new, I think, type hint syntax type stuff.

00:15:26.000 --> 00:15:26.340
Okay.

00:15:26.340 --> 00:15:27.500
So, yeah.

00:15:27.500 --> 00:15:42.100
Other people, like, kind of said that, hey, maybe, like, naming-wise, data classes is a little bit clearer than attrs, because someone who is a new Python programmer doesn't know that adder is an attribute or something like that.

00:15:42.100 --> 00:15:42.820
That's true.

00:15:42.820 --> 00:15:45.440
So, it has some syntactic differences, yeah.

00:15:45.440 --> 00:15:48.280
And there are some big names in this discussion.

00:15:48.280 --> 00:15:49.280
There are, there are.

00:15:49.280 --> 00:15:50.120
So, that's what I mean.

00:15:50.120 --> 00:15:52.660
It's sort of like the inner circle, right?

00:15:52.660 --> 00:15:56.080
This is kind of like the sort of stuff that I have to follow.

00:15:56.080 --> 00:15:56.940
Oh, that's awesome.

00:15:56.940 --> 00:15:58.240
To be on the edge here.

00:15:58.240 --> 00:16:00.500
And it happens kind of behind the scenes.

00:16:00.500 --> 00:16:05.840
But I really do encourage people to join these email lists if you want to see the action happening.

00:16:05.840 --> 00:16:07.680
You know, you don't have to be a spectator.

00:16:07.680 --> 00:16:12.800
Or you don't have to sit maybe in the nosebleed section of the arena on open source, right?

00:16:12.840 --> 00:16:16.820
You can get up close on the, on, like, you know, get the, get the front row seats.

00:16:16.820 --> 00:16:18.600
And before you know it, you'll actually get involved.

00:16:18.600 --> 00:16:19.220
It'll be fun.

00:16:19.220 --> 00:16:20.180
Yeah, that's great.

00:16:20.180 --> 00:16:21.320
Oh, thanks for bringing that up.

00:16:21.320 --> 00:16:21.740
That's cool.

00:16:21.740 --> 00:16:28.800
Well, speaking of trying to get involved, unless you've had your head under a rock, data science is a thing.

00:16:28.800 --> 00:16:31.200
Is it, really?

00:16:31.200 --> 00:16:37.280
It isn't something that I have to do, use on a daily basis, but it's definitely something I want to pay attention to.

00:16:37.960 --> 00:16:44.220
And I ran across, there's a lot of books and tutorials that are huge because it's a huge topic.

00:16:44.220 --> 00:16:48.980
And I ran across a article called Pandas in a Nutshell.

00:16:48.980 --> 00:16:53.940
And it's, I like it because it's a, it's a Jupyter Notebook style post.

00:16:53.940 --> 00:16:55.620
So you can just see the code working.

00:16:55.620 --> 00:17:01.260
And it's mostly tutorial by example with, it's just a little bit of extra code for explanation.

00:17:01.260 --> 00:17:05.780
And the big part of it is really just talking about a couple of data structures.

00:17:05.780 --> 00:17:11.740
It's just talking about the series data structure, which is a one-dimensional array with indices.

00:17:11.740 --> 00:17:14.180
So just kind of like a vector.

00:17:14.180 --> 00:17:17.960
And then the data frame, which is like a two-dimensional array.

00:17:18.700 --> 00:17:36.000
And all the sort of common things that you need to do with it, like specifying a custom index or adding, combining two series or with matrix stuff, adding columns, adding a column that's based on another column.

00:17:36.000 --> 00:17:40.560
Then this sort of stuff sort of seems like Excel, like working on a spreadsheet.

00:17:40.740 --> 00:17:46.360
I think for a lot of people, like that is the natural next step, you know, when they want to get into programming.

00:17:46.360 --> 00:17:54.220
It's either going to be doing visual or is it like, you know, basic script of some sort inside of Excel or, you know, maybe move into Python.

00:17:54.460 --> 00:18:10.960
Yeah, and I guess that's one of the things I like about this little nutshell article is that it's, if somebody is already doing some things in spreadsheets and they want to switch to working with pandas, this might be a pretty good stepping point to try to get things going.

00:18:10.960 --> 00:18:19.900
And it's actually something I'm going to grab some of the concepts in here to try to deal with some of the large amounts of data that I deal with on a daily basis as well.

00:18:19.900 --> 00:18:20.920
Oh, for sure.

00:18:20.920 --> 00:18:23.880
So I haven't used, and I bring this up because I'm just starting.

00:18:23.880 --> 00:18:27.180
I'm trying to use pandas on a daily basis now.

00:18:27.180 --> 00:18:30.400
And it is, like, I've actually faced a lot of the same challenges.

00:18:30.400 --> 00:18:37.200
It's just because it's Python doesn't mean that it, you know, doesn't require some sort of kind of paradigm shift in your thought.

00:18:37.740 --> 00:18:43.720
It's like thinking about data frames is very different than thinking about lists in Python or dictionaries in Python.

00:18:43.720 --> 00:18:48.440
It's somewhere between Python and, like, full-blown relational databases.

00:18:48.440 --> 00:18:58.780
And so you do have to change the way you think how to approach a problem, especially if you want to get some performance out of the thing, because it has all this great broadcasting logic that it can perform.

00:18:58.780 --> 00:19:02.400
But it's not going to work if you just iterate over it in four loops.

00:19:02.400 --> 00:19:13.360
Yeah, and I guess that's where the data frames and series stuff comes in is because you want to do some computation on everything and or, you know, searching on stuff.

00:19:13.360 --> 00:19:19.780
So it's kind of like a combination of a database and an in-memory database and something else.

00:19:19.780 --> 00:19:23.740
Where I work, some of our data scientists are, you know, coming from an R background.

00:19:24.080 --> 00:19:27.240
And the data frame is based on R construct, I believe.

00:19:27.240 --> 00:19:30.340
So they, you know, find it quite natural.

00:19:30.340 --> 00:19:33.340
And the Python is what they sort of struggle with.

00:19:33.340 --> 00:19:34.480
And they come to me for that.

00:19:34.480 --> 00:19:38.240
But a Python person would want to ramp up on the data frame itself.

00:19:38.240 --> 00:19:41.460
And so this notebook seems like a great option to do that quickly.

00:19:41.460 --> 00:19:41.740
Yeah.

00:19:41.740 --> 00:19:43.480
So that's just a quickie.

00:19:43.480 --> 00:19:45.260
So that's it.

00:19:45.260 --> 00:19:46.280
Your last topic.

00:19:46.420 --> 00:19:47.340
Oh, already.

00:19:47.340 --> 00:19:54.520
So, yeah, basically, just yesterday I was at this conference, PyBay 2017.

00:19:54.520 --> 00:19:58.320
It's sort of the Bay Area, Silicon Valley, regional Python conference.

00:19:58.320 --> 00:19:59.720
Only the second annual one.

00:19:59.720 --> 00:20:02.760
There's, it's surprising how long it took to spin up here.

00:20:02.760 --> 00:20:05.480
Meanwhile, PyOhio has been going for who knows how long.

00:20:05.480 --> 00:20:08.120
So anyways, but it was a great conference.

00:20:08.120 --> 00:20:11.960
Almost 500 developers, pretty good turnout.

00:20:12.380 --> 00:20:17.980
And a lot of great topics covered the, I gave a packaging talk.

00:20:17.980 --> 00:20:24.800
But the thing I'm going to talk about today is actually the opening panel was on static typing.

00:20:24.800 --> 00:20:27.880
And it was quite an interesting mix.

00:20:27.880 --> 00:20:30.120
They had, first of all, it was very international.

00:20:30.120 --> 00:20:33.960
They had people from Germany, Russia, Poland, USA, and Netherlands.

00:20:33.960 --> 00:20:38.360
It seems like Europeans are big fans of static typing for whatever reason.

00:20:38.360 --> 00:20:39.340
Guido included.

00:20:39.980 --> 00:20:47.520
So, yeah, they had people from, I think, let's see, PyCharm, University of California, Berkeley.

00:20:47.520 --> 00:20:52.360
Then also Quora, Google, and I think another guy too.

00:20:52.360 --> 00:20:58.220
So it was a really nice cross-section of the industry and also the world.

00:20:58.220 --> 00:21:02.020
And they just talked about the state of static typing.

00:21:02.160 --> 00:21:06.880
So right now, just to bring you up to date, I'm not sure how recently you covered this stuff on the podcast.

00:21:06.880 --> 00:21:12.740
But there are currently three or four static type checkers.

00:21:12.740 --> 00:21:17.240
So in Python 3, you can specify your types however you'd like.

00:21:17.240 --> 00:21:23.180
Built into the language, it's not going to do a lot of complaining in case types don't match.

00:21:23.180 --> 00:21:25.800
First of all, at runtime, nothing is checked.

00:21:26.300 --> 00:21:30.240
So if you want to check it, it would be at a compile time step.

00:21:30.240 --> 00:21:33.300
The annotations are still there at runtime.

00:21:33.300 --> 00:21:40.200
And then you have a static type checker, the most popular of which is mypy, run over that and check it.

00:21:40.200 --> 00:21:44.100
Kind of like a linter or any other, I mean, static analysis tool.

00:21:44.920 --> 00:21:48.120
And so there are other ones too, though.

00:21:48.120 --> 00:21:54.060
Google has one that is not super well documented, but they use it internally.

00:21:54.060 --> 00:22:00.420
Then PyCharm has this functionality as well, which is also kind of built from scratch.

00:22:00.420 --> 00:22:05.760
And they made a pretty good case why you would want one built into PyCharm,

00:22:05.760 --> 00:22:08.800
which is that basically it can do incremental checking.

00:22:08.800 --> 00:22:13.940
So while you're still writing, it can do sort of partial checks, maybe a little bit better than mypy.

00:22:13.940 --> 00:22:14.720
Oh, right.

00:22:14.720 --> 00:22:18.940
The last person on the panel, Ukash Langa from Facebook.

00:22:18.940 --> 00:22:20.300
He also comes to my meetup.

00:22:20.300 --> 00:22:23.280
Anyways, so yeah, he's very opinionated about types.

00:22:23.280 --> 00:22:24.220
We'll get to that in a second.

00:22:24.220 --> 00:22:27.140
One that wasn't talked about was PyLint.

00:22:27.140 --> 00:22:28.600
So I was actually blown away.

00:22:28.600 --> 00:22:34.240
I updated my Emacs config recently, and I sort of integrated some more linting stuff.

00:22:34.240 --> 00:22:38.760
And the default PyLint these days can do an amazing amount of inference.

00:22:38.760 --> 00:22:41.460
It'll tell you you have the wrong number of arguments.

00:22:41.460 --> 00:22:45.160
It'll tell you that, like, oh, this default doesn't match that type.

00:22:45.160 --> 00:22:54.620
It'll do so many different things, in addition to its standard, very opinionated idea of how many arguments a function should even have and that sort of thing.

00:22:55.280 --> 00:22:59.480
Anyways, so those are our four sort of type inference engines.

00:22:59.480 --> 00:23:01.980
And they all are slightly different.

00:23:01.980 --> 00:23:04.640
But everyone seemed to get along pretty well on stage.

00:23:04.640 --> 00:23:14.800
And they talked about, you know, potentially in the future actually merging these things and making a PEP that would allow them to all sort of comply together, maybe even turn into a single project.

00:23:15.500 --> 00:23:17.420
So that was really nice to see.

00:23:17.420 --> 00:23:24.180
And one of the most interesting questions was basically from the audience.

00:23:24.180 --> 00:23:28.840
They said, like, well, what is the real point behind the static typing?

00:23:28.840 --> 00:23:31.180
Like, what is the biggest benefit that you see?

00:23:31.180 --> 00:23:33.440
And there was a little bit of divergence on this, right?

00:23:33.440 --> 00:23:41.100
Some people like it for the strictness of it all, being, you know, kind of the dictator of your own code base or whatever, right?

00:23:41.100 --> 00:23:48.700
But everyone else seemed to be pretty much on the same page that this is for human readability.

00:23:48.700 --> 00:23:54.840
This is a sort of documentation that can then be checked automatically at a rather large scale.

00:23:54.840 --> 00:23:59.340
So it's attached to the function, but it's more than just a doc test.

00:23:59.340 --> 00:24:10.520
And so the interesting side effect of this is that they, even though they all work on static typing stuff, they have a pretty nuanced view of how much static typing you should apply.

00:24:10.520 --> 00:24:17.500
So they say that, like, you know, maybe a list of a certain type, right?

00:24:17.500 --> 00:24:21.920
But actually defining, say, a completely recursive type is, one, not supported.

00:24:22.120 --> 00:24:28.680
And two, maybe not even that desirable because you don't want your function signatures to get super, super complex.

00:24:28.680 --> 00:24:40.800
So, yeah, I mean, it was interesting that they thought the human side of this was the most important part as opposed to, say, like a Haskell programmer or something where they want the mathematical correctness of it all.

00:24:40.800 --> 00:24:47.340
It's also interesting that there's, I would have liked to listen to the discussion of how much you should use of it.

00:24:47.340 --> 00:24:48.040
Well, it was at LinkedIn.

00:24:48.040 --> 00:24:49.460
I think that they recorded it.

00:24:49.460 --> 00:24:50.640
It should go up pretty soon.

00:24:50.860 --> 00:24:56.480
Yeah, I'll definitely, you know, it was only a couple of days ago, but once the video is available, I'll maybe send it to you.

00:24:56.480 --> 00:24:57.560
You can add it to the show notes.

00:24:57.560 --> 00:24:58.020
Yeah.

00:24:58.020 --> 00:25:01.440
Some interesting side effects of this, by the way, like some things to consider.

00:25:01.440 --> 00:25:06.840
So Cython does not support the new Python type syntax.

00:25:06.840 --> 00:25:19.220
So even though all these guys are kind of on the same page and buddy-buddy, like, you know, for us, people who really like Cython and have used it to achieve a lot of performance and type correctness to some degree, are a little bit out of luck at the moment.

00:25:19.220 --> 00:25:24.620
There, I think that people are working on making a pull request to it or something that would support, add support for this.

00:25:24.620 --> 00:25:27.000
But it's such a big change to the syntax.

00:25:27.000 --> 00:25:42.740
And Cython has its own type syntax, which is less focused on semantic types as this is, and more focused on being in line with C types, which allows you to have more compact memory, memory-like usage.

00:25:42.960 --> 00:25:48.500
And the people on the panel were actually pretty clear that the static types advantage is not in performance.

00:25:48.500 --> 00:25:59.340
So a project like PyPy, which actually can use types to achieve higher performance, they find that the JIT is faster without taking hints from the user in the code.

00:25:59.340 --> 00:26:00.700
So it just disregards this stuff.

00:26:00.700 --> 00:26:01.280
Oh, interesting.

00:26:01.280 --> 00:26:01.520
Yeah.

00:26:01.520 --> 00:26:03.640
Because the JIT has the actual types.

00:26:03.640 --> 00:26:06.280
So just a real quick thought experiment.

00:26:06.280 --> 00:26:10.540
Like, imagine that I say, I'm going to pass you a list of integers.

00:26:10.860 --> 00:26:13.180
That list is three integers long.

00:26:13.180 --> 00:26:13.520
Okay.

00:26:13.520 --> 00:26:14.480
I can just check them.

00:26:14.480 --> 00:26:15.340
One, two, three.

00:26:15.340 --> 00:26:16.060
All integers.

00:26:16.060 --> 00:26:16.700
Good to go.

00:26:16.700 --> 00:26:17.380
No type error.

00:26:17.380 --> 00:26:18.060
Right.

00:26:18.060 --> 00:26:25.780
But if I pass you a list of 20,000 integers, right, every time I pass that to you, I have to check that every single one is an integer.

00:26:25.780 --> 00:26:27.900
Otherwise, like, you know, I want to have a type error.

00:26:27.900 --> 00:26:35.920
That sort of thing is going a little bit against the spirit of Python and being like sort of practical and duck typey and whatnot.

00:26:36.220 --> 00:26:44.000
So a friend of mine from Intel, you know, was sitting next to me and he was saying how we call he came to Python so he wouldn't have to type everything.

00:26:44.000 --> 00:26:46.120
But thankfully, you don't have to type everything.

00:26:46.120 --> 00:26:57.840
Like the standard library itself, for instance, is all the type definitions for that are available in this joint type shed repo that all of these static type people sort of built together.

00:26:58.000 --> 00:26:59.880
And I'll link to that in the show notes for sure.

00:26:59.880 --> 00:27:00.180
Yeah.

00:27:00.180 --> 00:27:11.180
My favorite use so far that I've come across for my own work is putting type hints in interface areas like an API module to that.

00:27:11.180 --> 00:27:12.780
That's how you interact with the package.

00:27:12.780 --> 00:27:14.940
So those are great places for type hints.

00:27:14.940 --> 00:27:15.640
Oh, for sure.

00:27:15.640 --> 00:27:20.340
And so wait, are you saying that so there is this old thing like they're trying to get rid of it.

00:27:20.340 --> 00:27:23.420
Basically, Python has these sort of stub files, these interface files.

00:27:23.540 --> 00:27:26.100
Some people call them the header files for Python.

00:27:26.100 --> 00:27:28.220
Like I think it's a .py file.

00:27:28.220 --> 00:27:28.500
Okay.

00:27:28.500 --> 00:27:29.540
.py.

00:27:29.540 --> 00:27:42.380
I was just thinking like I've got a package that has a whole bunch of internal code, but it has like an API module that you should people interact with from the outside world.

00:27:42.800 --> 00:27:50.160
That's a great place for pretty much any interfaces that are not you that's going to use it, that somebody else is going to use it.

00:27:50.160 --> 00:27:52.880
Those are great places to put type hints if it matters.

00:27:52.880 --> 00:27:53.520
Oh, definitely.

00:27:53.520 --> 00:27:53.960
Definitely.

00:27:53.960 --> 00:27:55.200
Cool.

00:27:55.200 --> 00:27:56.600
But I'm pretty new to it too.

00:27:56.600 --> 00:27:58.160
So thanks for bringing that up.

00:27:58.160 --> 00:27:58.960
That was very interesting.

00:27:58.960 --> 00:27:59.240
Yeah.

00:27:59.240 --> 00:27:59.460
Yeah.

00:27:59.460 --> 00:28:02.860
And I mean, I think that they're still changing this stuff quite a bit, right?

00:28:03.040 --> 00:28:05.800
So I, you know, early adopters go nuts.

00:28:05.800 --> 00:28:13.180
But for the rest of us that like a little bit more boring technologies, you know, I'm going to go ahead and let the auto inference engine of Pilot figure things out for me.

00:28:13.180 --> 00:28:16.000
I'm not going to, you know, jump on the bandwagon so quickly.

00:28:16.000 --> 00:28:17.860
And I'm glad you brought Pilot up.

00:28:17.860 --> 00:28:21.880
I've been sort of dismissing it because I've been using FlightGate.

00:28:22.220 --> 00:28:24.460
But I'll have to take a look at Pilot again.

00:28:24.460 --> 00:28:24.760
Oh, yeah.

00:28:24.760 --> 00:28:27.740
They've definitely ramped up development on that again.

00:28:27.740 --> 00:28:30.220
I mean, you have to, for me anyways, right?

00:28:30.220 --> 00:28:35.460
I just blacklist a lot of the errors because I kind of don't agree with every single thing that they test for.

00:28:35.460 --> 00:28:37.400
But they make it pretty easy to do.

00:28:37.400 --> 00:28:38.720
You just change it in an I and I file.

00:28:38.720 --> 00:28:39.280
No big deal.

00:28:39.280 --> 00:28:46.320
Last topic, again, comes back to me finally getting my head out of thinking about pytest 24 hours a day.

00:28:47.440 --> 00:28:55.320
And one of the things I want to start looking at is some of the web frameworks like Django and Flask.

00:28:55.320 --> 00:28:57.220
I haven't played with them much personally.

00:28:57.220 --> 00:29:01.140
And there's a bunch of personal projects and work projects I'd like to do with them.

00:29:01.140 --> 00:29:07.360
And also quite a few people that listen to testing code are web people.

00:29:07.360 --> 00:29:12.600
And so just to kind of get more understanding of that, I'm trying to learn more frameworks.

00:29:12.600 --> 00:29:18.940
And one of the things that I've had a hard time getting my head around is ORMs or object relational mappers.

00:29:18.940 --> 00:29:26.120
So luckily I ran across an article on Fullstack Python, which is Matt Makai's site.

00:29:26.120 --> 00:29:26.780
Amazing site.

00:29:26.780 --> 00:29:27.060
Yeah.

00:29:27.060 --> 00:29:30.560
And basically it's Fullstack Python.

00:29:30.560 --> 00:29:34.740
I don't remember what it's called, but I think it's just object relational mappers.

00:29:35.600 --> 00:29:38.540
And it goes through what they are.

00:29:38.540 --> 00:29:50.380
So a norm is some code that automates the transfer of data from your internal Python objects and classes to database tables.

00:29:50.380 --> 00:29:55.540
And they're useful so that you can write Python code instead of writing SQL queries.

00:29:56.440 --> 00:30:01.400
And he talks about that and then also talks about why you need them and some downsides.

00:30:01.400 --> 00:30:03.200
And yeah.

00:30:03.200 --> 00:30:05.240
So the downsides actually were interesting.

00:30:05.240 --> 00:30:09.080
I didn't think that anybody would talk about what's wrong with using ORMs.

00:30:09.080 --> 00:30:09.400
Yeah.

00:30:09.400 --> 00:30:13.260
I mean, realistically, there are some definite engineering trade-offs.

00:30:13.260 --> 00:30:13.880
So what did he say?

00:30:13.880 --> 00:30:22.520
Well, he said, well, a few things are impedance mismatch, which coming from electrical world, I was like impedance mismatch.

00:30:22.520 --> 00:30:25.060
So that's like 50 ohms to 75 ohms, right?

00:30:25.060 --> 00:30:25.340
Yeah.

00:30:25.340 --> 00:30:25.560
Yeah.

00:30:25.560 --> 00:30:36.820
But it's basically the way a developer is using the objects is different from how, can be different from how the data is stored and joined in the tables in your database.

00:30:36.820 --> 00:30:44.820
And especially if you've set up the tables in a way that's not like, it's contradictory to how it's being used all the time.

00:30:44.820 --> 00:30:50.020
It might be slow and you can maybe reshaping your data might speed that up.

00:30:50.880 --> 00:30:53.080
And then potential for reduced performance.

00:30:53.080 --> 00:30:55.220
And this isn't surprising to me.

00:30:55.220 --> 00:30:59.280
If you stick some code in the middle, it's not free.

00:30:59.280 --> 00:31:00.160
It's got to run.

00:31:00.160 --> 00:31:09.000
And then also shifting complexity from database to the application code, which this is something that I didn't quite understand right off the bat.

00:31:09.080 --> 00:31:10.700
But if you think about it, it's not too bad.

00:31:10.700 --> 00:31:21.020
But there's databases are complex thing pieces of software that have things like stored procedures, stored procedures and a whole bunch of fancy join math and stuff.

00:31:21.020 --> 00:31:21.340
Right.

00:31:21.340 --> 00:31:21.640
Right.

00:31:21.640 --> 00:31:24.340
That might not be supported by an ORM.

00:31:24.540 --> 00:31:29.360
So you're going to, you have to, if you had to do that stuff, you have to do it in your application instead.

00:31:29.360 --> 00:31:36.900
So it's, it's using, using a database in a simpler way, but that complexity has to go somewhere and it'll go in your application code.

00:31:36.900 --> 00:31:37.100
Yeah.

00:31:37.100 --> 00:31:37.700
Almost certainly.

00:31:37.920 --> 00:31:46.580
But I mean, until you get like database specialists, then, you know, it makes it a little bit easier for you as, you know, a sole developer, for instance.

00:31:46.580 --> 00:31:47.100
Yeah.

00:31:47.200 --> 00:31:53.360
So I punted at first and used a document databases because I didn't have to think about ORMs right off the bat.

00:31:53.360 --> 00:31:57.660
But, but I mean, so, so, but the thing is that an ORM, like he's correct.

00:31:57.660 --> 00:32:05.480
Like a database is definitely a very advanced, complex tool, but a lot of that advances in complexity you retain even when using an ORM.

00:32:05.480 --> 00:32:12.320
For instance, a lot of document databases don't have great transaction models, don't have great, you know, sort of multi-version concurrency models.

00:32:13.100 --> 00:32:27.780
And, you know, so when they put all that work into Postgres or even like MariaDB or something like that, you can, just by using an ORM, it seems almost as simple as a document database, but you get that operational, you know, feature.

00:32:27.780 --> 00:32:28.060
Yeah.

00:32:28.060 --> 00:32:39.260
I'd definitely heard of SQLAlchemy or SQLAlchemy, but I hadn't heard of a couple of the others that he listed here, PeeWee and Pony and SQL Object.

00:32:39.260 --> 00:32:41.140
Have you used any of these?

00:32:41.320 --> 00:32:47.200
Yeah, so SQLAlchemy is definitely my go-to and I'll talk about why in a second.

00:32:47.200 --> 00:32:53.200
But yeah, I mean, I've used Django's ORM because I did the Django tutorial and that's one of the first things they teach you.

00:32:53.200 --> 00:33:00.040
Django has a serviceable ORM, but there are some issues with it that SQLAlchemy actually does a much better job with.

00:33:00.040 --> 00:33:02.620
And I have used PeeWee, in fact.

00:33:02.620 --> 00:33:03.440
I like PeeWee.

00:33:03.440 --> 00:33:05.800
It's sort of like a simplified version of Django.

00:33:06.140 --> 00:33:12.620
In my opinion, it basically says like, look, if you're not going to be SQLAlchemy, then, you know, you can just be plain simple.

00:33:13.340 --> 00:33:15.260
And it does a pretty good job.

00:33:15.260 --> 00:33:24.020
But these days, SQLAlchemy has gotten so good that, you know, I just reach for that every single time I'm going to work with a relational database in Python.

00:33:24.020 --> 00:33:24.460
Okay.

00:33:24.660 --> 00:33:35.240
So one thing that SQLAlchemy has is that it sort of has this working copy of all the models and they end up being kind of like singletons within a given process space.

00:33:35.780 --> 00:33:45.660
So with Django, you can actually get two copies of the same thing from the database within the same request or the same process.

00:33:45.660 --> 00:33:51.500
And that means that basically concurrently somewhere else in your program, it could change something, save it.

00:33:51.500 --> 00:34:00.000
And then when you change it in your request handler you're actually trying to work on, that will overwrite the previous change.

00:34:00.000 --> 00:34:09.460
You know, like if you change column A in one thread and column B in another thread, whichever thread saves first is going to overwrite the other unchanged value.

00:34:09.460 --> 00:34:15.300
So there's a setting that's off by default, I think, in Django called atomic requests.

00:34:15.300 --> 00:34:18.620
And you have to enable that to prevent that sort of situation.

00:34:18.620 --> 00:34:19.880
But Django is not alone in this.

00:34:19.880 --> 00:34:23.960
I think that Rails, at least for a very long time, did the same thing.

00:34:23.960 --> 00:34:26.800
And Django, of course, is sort of Python's response to Ruby on Rails.

00:34:26.800 --> 00:34:28.600
So, yeah.

00:34:28.600 --> 00:34:31.600
Does SQLAlchemy not have this problem?

00:34:31.600 --> 00:34:36.740
So SQLAlchemy doesn't have this problem because basically, yeah, you only get one copy of that thing in your system.

00:34:36.740 --> 00:34:44.920
It has this sort of local index of primary key to the object version of that row that you're representing, for instance.

00:34:44.920 --> 00:34:45.600
Okay.

00:34:45.600 --> 00:34:46.620
So, yeah.

00:34:46.620 --> 00:34:46.640
So, yeah.

00:34:46.640 --> 00:34:51.760
SQLAlchemy sort of has, it adds a lot of machinery, makes SQLAlchemy a little bit more complex.

00:34:51.760 --> 00:34:56.780
But I had a friend who I think spent days tracking down this issue with Django.

00:34:56.780 --> 00:34:59.220
And SQLAlchemy never would have happened.

00:34:59.220 --> 00:35:01.820
So you pay some upfront costs with setup with SQLAlchemy.

00:35:01.940 --> 00:35:03.460
But I think it's definitely worth it.

00:35:03.460 --> 00:35:12.900
When it comes to this sort of ORM thing, though, like if I can provide some general advice, ORMs are sort of the tools of applications.

00:35:13.500 --> 00:35:21.780
And if you want to see, if you want to form a real opinion on object relational mappers, you should look at and compare applications.

00:35:21.780 --> 00:35:28.460
So I spent a fair amount of time reading Reddit source code, which does, I think, use SQLAlchemy.

00:35:28.460 --> 00:35:31.260
And it uses it without the declarative object mapper.

00:35:31.260 --> 00:35:36.660
It uses it with the sort of legacy or lower level SQLAlchemy tools.

00:35:36.840 --> 00:35:41.320
But you still get a real sense for where they use an ORM and where they don't.

00:35:41.320 --> 00:35:45.860
And SQLAlchemy actually makes it very easy to pass through normal SQL text.

00:35:45.860 --> 00:35:47.900
That's another thing I really like about it.

00:35:47.900 --> 00:35:51.800
It understands that ORMs are an abstraction that's useful 90% of the time.

00:35:51.800 --> 00:35:58.220
And for that last 10%, you really want the full power of the driver or the database itself.

00:35:58.220 --> 00:35:59.160
Okay, cool.

00:35:59.160 --> 00:36:02.940
I don't have any opinion on these extra couple links that I put in here.

00:36:02.940 --> 00:36:07.620
Matt has some dedicated pages for SQLAlchemy and PeeWee.

00:36:07.620 --> 00:36:15.620
And one of the things I like about Matt's site anyway, the Fullstack Python, is he gives his opinion and information when he has it.

00:36:15.620 --> 00:36:22.360
And when somebody else has already explained it well enough or better, he just links to their stuff and says, go read that.

00:36:22.360 --> 00:36:23.020
Yeah, absolutely.

00:36:23.020 --> 00:36:24.920
No, I mean, he's a real team player in that regard.

00:36:24.920 --> 00:36:27.680
But I also, I just got to, you know, give a shout out to him.

00:36:27.780 --> 00:36:30.540
Like he so consistently adds to the site.

00:36:30.540 --> 00:36:34.600
It's become such a tremendous resource for someone who wants to develop an application.

00:36:34.600 --> 00:36:39.620
I'm sure that listeners of this podcast are, for the most part, like already aware of it.

00:36:39.620 --> 00:36:41.120
But yeah, definitely check it out.

00:36:41.120 --> 00:36:41.500
Definitely.

00:36:41.500 --> 00:36:44.620
Well, that's all of our topics so far.

00:36:44.620 --> 00:36:50.580
We didn't address what you're up to lately other than helping out with podcasts.

00:36:51.880 --> 00:36:53.440
Yeah, no, it's funny.

00:36:53.440 --> 00:36:59.600
I'm also like prepping for another podcast as well, but partially examined life, I guess.

00:36:59.600 --> 00:37:02.620
But basically, yeah, what am I up to lately?

00:37:02.620 --> 00:37:07.360
Well, I had a talk at PiBay and because it was based on a blog post, I thought it'd be easy to put together slides.

00:37:07.360 --> 00:37:09.760
Now, it still took like just full disclosure.

00:37:09.760 --> 00:37:14.320
It took like another 40, 50 hours to make slides from that blog post.

00:37:14.320 --> 00:37:15.560
But it seemed really well received.

00:37:15.560 --> 00:37:17.360
And so I'm very relieved right now.

00:37:17.360 --> 00:37:22.420
I got some nice life events coming through, parents coming to town, keeping me real busy.

00:37:22.420 --> 00:37:27.780
I also am working on this hyperlink library, like I mentioned earlier, URLs in Python.

00:37:27.780 --> 00:37:31.120
And it's used by Twisted and some other big projects.

00:37:31.120 --> 00:37:40.300
So fixing bugs in there is always kind of contentious, which is why I got a lot of support for people who work on things like setup tools, which is even more widely used.

00:37:41.000 --> 00:37:44.600
So then beyond this, let's see.

00:37:44.600 --> 00:37:46.000
Yeah, writing blog posts.

00:37:46.000 --> 00:37:49.260
I got I think my draft count is up to like 100 now.

00:37:49.260 --> 00:37:53.160
But yeah, maybe more conferences, more talks.

00:37:53.160 --> 00:37:56.640
I don't know why I keep signing up for these things, but it's great meeting people out there.

00:37:56.640 --> 00:38:01.000
People out there should really look into PiBay and regional conferences, meetups.

00:38:01.000 --> 00:38:07.900
Oh, well, I run a meetup to the Peninsula meetup, the hottest new meetup in the Bay Area, Silicon Valley.

00:38:08.520 --> 00:38:12.620
And so, yeah, like, yeah, yeah, we were a pun.

00:38:12.620 --> 00:38:14.340
Hey, this is programming, man.

00:38:14.340 --> 00:38:16.180
It's all about the terrible puns.

00:38:16.180 --> 00:38:19.640
So we but yeah, Peninsula.

00:38:19.640 --> 00:38:23.180
Yeah, I think we even have the site now, Peninsula dot org.

00:38:23.180 --> 00:38:25.400
And, you know, we're on Twitter and so forth.

00:38:25.400 --> 00:38:27.180
I do my best to record the talks.

00:38:27.520 --> 00:38:35.520
But for people who want to break into this type of, you know, speaking and that sort of thing, just look at look no further than your local meetup.

00:38:35.520 --> 00:38:35.820
Right.

00:38:35.820 --> 00:38:38.660
Go make a 15 minute, 30 minute talk.

00:38:38.660 --> 00:38:39.920
See how it goes.

00:38:39.920 --> 00:38:41.020
Iterate on it.

00:38:41.020 --> 00:38:41.260
Right.

00:38:41.260 --> 00:38:43.160
Have a brown bag at your company.

00:38:43.160 --> 00:38:44.680
Just keep iterating on it.

00:38:44.680 --> 00:38:46.260
And, you know, something will stick.

00:38:46.260 --> 00:38:50.240
And then you can submit it to something like PyCon or whatever.

00:38:50.240 --> 00:38:51.240
That's a great idea.

00:38:51.240 --> 00:38:57.380
I think a lot of people think that you could you just have to work really hard on a talk and give it once and then it's done.

00:38:57.380 --> 00:38:59.340
But a lot of people give them several times.

00:38:59.340 --> 00:38:59.620
Yeah.

00:38:59.660 --> 00:39:03.180
And also, like if there's not a meetup in your area, just maybe start one.

00:39:03.180 --> 00:39:05.700
Python programmers are literally everywhere.

00:39:05.700 --> 00:39:16.260
So we like, you know, even though there's a South Bay Python meetup, which is sort of like more towards Sunnyvale, like kind of south of Mountain View area.

00:39:16.260 --> 00:39:20.540
And there's this SF Python meetup, which is up in San Francisco.

00:39:20.540 --> 00:39:22.420
We put one right in the middle.

00:39:22.420 --> 00:39:27.000
I guess California traffic is bad enough that we sort of have a captive audience, literally.

00:39:27.440 --> 00:39:32.360
But we'll get like, you know, I think when Guido came, there were almost 100 people at the meetup.

00:39:32.360 --> 00:39:34.060
And normally we get like 50.

00:39:34.060 --> 00:39:38.100
But it's great because everyone can socialize and something a little bit more intimate.

00:39:38.100 --> 00:39:40.920
It's a little bit less stressful when you're trying to give the talk yourself, too.

00:39:40.920 --> 00:39:41.220
Yeah.

00:39:41.220 --> 00:39:45.600
So it wouldn't be a Python Bytes episode if I didn't plug my book.

00:39:45.600 --> 00:39:46.120
By all means.

00:39:46.120 --> 00:39:52.520
So one of the things I want to bring up is the Python testing with pytest has a nice discussion forum.

00:39:52.520 --> 00:39:56.540
It's kind of built into what Pragmatic offers for all the books.

00:39:57.120 --> 00:40:02.680
But if you ever ask a question on there, it pings me and emails me and says there's a question.

00:40:02.680 --> 00:40:05.020
Just this morning, I answered a question.

00:40:05.020 --> 00:40:08.860
Somebody got on and said that they were actually...

00:40:08.860 --> 00:40:09.720
I love this.

00:40:09.720 --> 00:40:13.700
They said that the book is helping them understand testing better.

00:40:13.700 --> 00:40:16.040
And I love comments like that.

00:40:16.040 --> 00:40:20.240
But he had a question about Monkey Patch versus Mock.

00:40:20.240 --> 00:40:23.420
And I'm not going to get into it too much here.

00:40:23.420 --> 00:40:24.900
But I did reply to him.

00:40:24.900 --> 00:40:27.500
And it's all up there for everybody else to read, too.

00:40:27.500 --> 00:40:29.680
So I'll have a link in the show notes to that.

00:40:29.680 --> 00:40:30.580
That's great.

00:40:30.580 --> 00:40:31.380
Yeah.

00:40:31.380 --> 00:40:32.800
Those sorts of comments really keep you going.

00:40:32.800 --> 00:40:36.500
I wish that my O'Reilly thing had had such a discussion forum.

00:40:36.500 --> 00:40:38.080
Instead, I have to...

00:40:38.080 --> 00:40:40.140
I got my feedback through reviews for a while.

00:40:40.140 --> 00:40:42.040
Oh, yeah.

00:40:42.040 --> 00:40:42.400
Yeah.

00:40:42.400 --> 00:40:43.720
I mean, emails, too.

00:40:43.720 --> 00:40:44.460
People email.

00:40:44.460 --> 00:40:45.320
And I appreciate it.

00:40:45.320 --> 00:40:45.480
Yeah.

00:40:45.480 --> 00:40:46.720
I get them from all over the place.

00:40:46.720 --> 00:40:48.500
I get it through the discussion forum.

00:40:48.500 --> 00:40:50.260
I get it from Twitter.

00:40:50.260 --> 00:40:51.080
And from...

00:40:51.080 --> 00:40:52.080
We've got a Slack channel.

00:40:52.080 --> 00:40:55.440
So people come and tell me what's wrong in the Slack.

00:40:55.440 --> 00:40:55.840
So...

00:40:55.840 --> 00:40:56.020
Yeah.

00:40:56.120 --> 00:40:56.440
Definitely.

00:40:56.440 --> 00:40:57.260
I don't know.

00:40:57.260 --> 00:40:58.640
For just like sort of chatting here, right?

00:40:58.640 --> 00:41:06.440
I've been really into like Riot.im, which is a Python-based open source Slack sort of thing.

00:41:06.440 --> 00:41:09.600
And there's also Zulip, which is just everywhere these days.

00:41:09.600 --> 00:41:10.820
They're doing an amazing job.

00:41:10.820 --> 00:41:12.360
So what's the first one, Riot?

00:41:12.360 --> 00:41:12.680
Yeah.

00:41:12.680 --> 00:41:16.880
So Riot.im, and it runs a sort of protocol called Matrix.

00:41:16.880 --> 00:41:20.780
And it's a very, very large thing.

00:41:20.780 --> 00:41:25.200
It's basically like you can have end-to-end encrypted chats with people who are on it.

00:41:25.420 --> 00:41:28.020
But I use it because it's an IRC bridge.

00:41:28.020 --> 00:41:33.320
Like I said, if you want to be sort of in this inner circle, see the goings-ons, IRC is still

00:41:33.320 --> 00:41:34.220
very much alive.

00:41:34.220 --> 00:41:39.040
So you've got your list serves and IRC and so forth.

00:41:39.040 --> 00:41:43.360
And Riot makes that pretty easy to get into.

00:41:43.360 --> 00:41:46.900
You know, there's a free node bridge and you just join a free node thing and you can look

00:41:46.900 --> 00:41:51.440
at IRC through your browser while having end-to-end encrypted chats with your other friends.

00:41:51.440 --> 00:41:55.400
It also has a like sort of peer-to-peer video chat that works really, really well.

00:41:55.400 --> 00:41:59.520
Because it's just the WebRTC open source protocol.

00:41:59.520 --> 00:42:00.940
Works great in Firefox.

00:42:00.940 --> 00:42:03.460
Well, I'm going to cut you off because we're right.

00:42:03.460 --> 00:42:04.800
But oh, wait.

00:42:04.800 --> 00:42:05.520
Yeah, we're way long.

00:42:05.520 --> 00:42:06.400
Anyways, that's great.

00:42:06.400 --> 00:42:08.880
Also, I think this is an awesome topic.

00:42:08.880 --> 00:42:15.300
I think that you should come on to Test and Code and we can talk about IRC and communication

00:42:15.300 --> 00:42:15.780
channels.

00:42:15.780 --> 00:42:16.480
That'd be fun.

00:42:16.480 --> 00:42:17.540
That's actually a great idea.

00:42:17.540 --> 00:42:18.420
Yeah, for sure.

00:42:18.640 --> 00:42:22.760
I'm always like coming up short with topics when the, when the, but yeah, here we are

00:42:22.760 --> 00:42:23.300
just chatting.

00:42:23.300 --> 00:42:23.720
That's great.

00:42:23.720 --> 00:42:24.460
That's a great idea.

00:42:24.460 --> 00:42:26.460
Again, thank you so much for coming on.

00:42:26.460 --> 00:42:28.900
I love having new voices on, on here.

00:42:28.900 --> 00:42:30.560
And it's been my pleasure.

00:42:30.560 --> 00:42:31.620
And thank Michael.

00:42:31.620 --> 00:42:33.520
You know, when he gets back, I'll send him an email.

00:42:33.520 --> 00:42:34.300
This has been great.

00:42:34.440 --> 00:42:34.640
Yeah.

00:42:34.640 --> 00:42:36.200
And we'll keep in touch.

00:42:36.200 --> 00:42:40.020
Thank you for listening to Python Bytes.

00:42:40.020 --> 00:42:43.400
Follow the show on Twitter via at Python Bytes.

00:42:43.400 --> 00:42:46.920
That's Python Bytes as in B-Y-T-E-S.

00:42:46.920 --> 00:42:51.020
Get the full show notes, including links at pythonbytes.fm.

00:42:51.020 --> 00:42:56.420
If you have a news story you'd like featured, visit pythonbytes.fm and send it our way.

00:42:56.420 --> 00:42:58.860
We're always on the lookout for sharing something cool.

00:42:58.860 --> 00:43:02.900
This is Brian Okken on behalf of myself and Michael Kennedy.

00:43:03.160 --> 00:43:06.420
Thank you for listening and sharing this podcast with your friends and colleagues.

