← Back to Show Notes

Transcript: Coverage.py - Ned Batchelder

Hello, and welcome to another episode of Django Chat, a podcast on the Django Web Framework.

I'm Will Vincent, joined by Carlton Gibson. Hello, Carlton.

Hello, Will.

Hi, Carlton. This week, we're joined by Ned Batchelder. So, Ned, welcome to the show.

So, we're going to talk a lot about testing, but also your career in Python and Django

coverage and all sorts of things. So, I'm really happy you could come on.

Thanks.

Someone we've wanted to have on for a long time now.

So thank you for making the time.

Sure.

I think we've been exchanging emails about this possibility for a while.

I think from the beginning.

I mean, the short list I had when we started this was you were on it.

Nice.

Wow.

I'm honored.

I'm honored to be early on the list and late on the recording.

You'll notice how practiced we are now.

All of that.

That's right.

It's very smooth.

Yes.

So you are, as a brief intro, so you don't have to say it yourself, you're a pillar of the Boston

Python community. You run coverage.py. You've given lots of talks at PyCons here. You've been

most recently at edX. I think everyone, most people in the Boston Python community know who

you are, and many of the people at PyCons know who you are. But for those listening who perhaps

don't, how do you describe yourself these days in terms of your background in the community?

Yeah, that's a good question. I often say I'm deeply embedded in the Python community.

You touched on Boston Python. So I'm here in Boston, Will, as you are. Or at least last I

heard, who knows what has happened in the 18 months of the lockdown. People seem to

move all over the place. But yeah, so I've been organizing the Boston Python user group for

over a decade I guess now. You mentioned PyCon. I have done a lot of PyCon talks but with the

pandemic and a few missed PyCons it's actually been a while since I've been to a PyCon and I

haven't done any of the virtual PyCons so I need to get back into that. But I have been maintaining

coverage.py for a very long time and as well as some other much less interesting side projects

and i work at edX as a day job which is open source project built on Django and i work on

the open source team at edX so i my whole life is open source python pretty much so you um i think

we to be more specific we both live in Brookline because i saw your your mapping project um and i

i was i thought i saw you and your son like two years ago walking along the riverway um but i

didn't want to interrupt you and um you have this very cool mapping project i was looking at on your

site which we'll have a link to um and so i think i have a pretty good idea where you live but i live

in brookline as well um that's right so i've been during the pandemic my exercise of choice has been

walking because it keeps me apart from people and i can do it from home and my son was at home with

me and he needed to walk too and to keep it interesting i've been trying to walk on new

streets every time and i've done now i think 302 walks from the house to the house and only two of

them have missed getting any new streets so it's been a fun nerdy way to get exercise so this is

this is reminiscent of kant's seven bridges of coningsburg problem yes but the topology is much

much worse and and we don't have time to get into all of the nerdy details that go through my head

when planning walks and kicking myself for having missed a street I could have walked on and all of

that stuff. Right. Okay. And you put it, I saw an image go past this week, I think. I didn't know

about this project. And then you've blogged about it on your site. That's right. There've been two

blog posts, well, three blog posts technically about it so far. But yeah, when I completed my

300th walk, I did another kind of visualization about how hard it is to get to new streets on

walks 201 through 300, because you have to walk over all of the old streets you've already walked

on to get to the new streets and etc etc and do you end up going ever further from home because

well yes both because i'm getting more fit so i can do a six and a half mile walk and not collapse

but also if i want to get to a new street i have to walk farther because i've already walked on

all the streets within the five mile radius so or the two and a half mile radius i guess um so yeah

It's been a lot of fun.

You mentioned it keeps you away from people.

Would you say that's part of a programmer personality type thing there?

Yeah, it sits well with my personality.

I don't mind the social distancing.

Well, that's a beautiful thing to do during COVID.

I'm jealous.

I was stuck here with an infant the whole time.

That's right.

And I've walked on streets during these walks that are within 50 yards of my house that I never had a reason to visit before.

So it is eye-opening.

Well, that's great.

So Python and Django, maybe I could just ask, so you have a long history with Django.

I think I've seen you say back to 2006.

I'm curious if you could talk about that and how you've seen the project develop since

that's pretty early.

That is early.

So actually, my earliest touchpoint with Django was actually part of Boston Python.

So in, I think, November of 2005, Boston Python, as one of their events, said, hey,

let's do sort of a shootout of some web frameworks and different people

volunteered for different frameworks.

I actually got turbo gears as the thing to try out and someone else got this

other thing, that new thing called Django to try out.

And we built some app,

we chose an app and we each built the same app and compared.

But shortly after that, in January of 2006,

I actually got a new job working for a startup called Tableau, T-A-B-B-L-O,

not the database tool.

Not the billion-dollar one.

Not the billion-dollar database tool,

the photo-sharing and storytelling website

that was eventually purchased

and then disappeared by Hewlett-Packard.

But that was all built in Django and Python.

And the reason I got the job

is that the founder of the company

had asked around in Boston,

like, how can I find some Python expertise?

And that eventually led him to me,

and we had a coffee, and the rest is history.

And that was on Django 0.91 in 2006.

And actually, my first week on the job, I had given three weeks notice at the old job

instead of two weeks.

And so through bad planning, my first week on the job was a week that my boss and the

founder of the startup was going to be on the other side of the country for a business

trip.

But Monday morning, I showed up in the office and he said, can you build some ACL stuff?

We need some access controls on this app we're building.

see you later and i spent the week digging into django and hacking around and building acls and

he showed up like friday afternoon and i showed him what i was built and you know we were both

happy with each other from then on so it was kind of a trial by fire but it worked out but that's

like the dream first week no yeah that's the perfect do some programming we're not going to

talk to you in some ways that yeah it was great i mean and it was the size the size of the startup

was I think three engineers including me and the founder and so there was just a lot of heads down

time just hacking on stuff there was not a lot of overhead or or difficulty um organizationally so

that was great it was very early on um I remember we had one problem with our home page that it was

it was doing a 9009 queries to build a home page or something and the reason was that if you if you

built, if you got a related object and then asked the related object for the parent, it would do a

new query to get the parent, even though the parent is how you got to the object in the first

place. And so I submitted a patch to Django that would just hold on to that object for later so

that we only needed a hundred queries or something. Like it was just one of those early on in the ORM,

you know, not, there hadn't been that much optimization done. So there was a lot of low

hanging fruit. And so early days you could, you could dig into those kinds of things and make

those kind of patches the great thing about Django now in some ways is there isn't that low

hanging fruit because it's so mature but in those days there was still a lot of work that needed to

be done to bring it up to speed yeah no select related or any of those you know conveniences for

I don't even remember if select related was an option at the time yeah I mean no class-based

views either you had to roll your own functions but listen so from my point of view class-based

views are still sort of mysterious and new and confusing and almost a poster child for what's

wrong with multiple inheritance but yeah definitely we don't have to get into that i'm sure if i

know no this is a podcast on jango like the whole point is so we're going to touch on this theme a

bunch i imagine but i tend to start do a thing once and then keep doing that thing for a very

long time and and not consider new things and the difference between function-based views and

class-based views fits neatly into that into that narrative i know how to write a function view as a

view and class-based views to me still seem weird so you're a bit like so you you fire up a blank

you know a blank pi file views.pi and you you need to write a view you're going to write a

function-based view that's that's my go-to yeah and i mean so since those early days of like

writing, spending a week writing access controls, I haven't done that much hardcore direct Django

development. So in some ways it's, you know, it's really moved on without me. And I've,

that's one of the challenges, you know, being a long time adopter of technology can sometimes

mean that you're an expert in the way that technology was 15 years ago. And you're stuck

because you've just been spending your time doing something else rather than keeping up with all the

amazing work that jango's been putting out so like i mean don't even talk to me about async

will was asking me earlier on about something how do i organize a i know where do i put my

settings files or something and i described a little file system layout to him and he's like

oh old school yeah probably yeah i know it's hard i mean people call me old school now but

yeah you were describing a you know dash running manage.py with dash dash settings and i said you

know you don't because you used to and you can still do it but you used to have multiple settings

files you'd have like a base and local production test and i would say these days you can use

environment variables so you have one file and then you swap in with the environment variables

but still works for carlton so you know all the time i still you know i still specify my settings

on the command line because like who knows where they might be otherwise you know even if it's one

far it's still i think what saves me is i'm constantly teaching beginners so i feel like i'm

obligated to find out if there's a better way whereas for my own stuff um i mean it's painful

it's like what's the point like i know what i want to build i just want to build it you know

it's sort of like installing python if you like you know we have our everyone has a different way

to do it unless you though actually i do want to say though like with running boston python

unusually you get a lot of exposure to a wide spectrum i mean both you mean because you have

talks and there's project nights, you get total beginners and then you get postdocs at science

places. So I want to just broadly ask you about that because you probably see more of a spectrum

than I do, whereas most people are in their little lane with work, what's in front of them.

Yeah, it's interesting. I mean, so you mentioned teaching beginners. The great thing about teaching

beginners is you don't have to bring them up to speed from the way things were in 2006, right?

You can, you can just pretend that the timeline starts now, like now we do it like this and,

and the old stuff doesn't matter, right?

Carlton and I are, are burdened with all that luggage.

So we, we will probably carry some of that around and, and we may touch on another recent

thing, which was me redoing my website, my personal website as an actual Django project,

which, you know, full disclosure, I think I have seven or eight different settings files

with different names of like base

and that server name and et cetera, et cetera.

And I know there's a better way to do it,

but I also know that if I go and look

for the better way to do it,

I'm going to be presented, you know,

in classic Python style

with a dozen different options

hacked together by a dozen different people,

each of whom thinks their way is the best.

And it's hard to sort it all out

and et cetera, et cetera.

Again, one of the nice things about Django

is the out of the box,

like Django will tell you how to do it

kind of mentality,

which is a rare Island in the chaos of the Python world,

where we love the fact that people can hack together something and get it out

there and people will start using it.

But that makes for a lot of competition among all these solutions that can be

really overwhelming for, for beginners or not even beginners,

but people for whom it's not their, their passion. Like I don't,

I don't want to make settings files. I want to make a website.

So please just tell me how to make my settings file so I can get on with the

thing I'm trying to do.

Right. But it's not JavaScript, right? I mean,

because I feel that, but then whenever I, it's not JavaScript, I'm always like, wow,

compared to JavaScript, Python is gloriously. Yeah. The problem with JavaScript is that they

don't, they don't, and I shouldn't talk trash about JavaScript, but my impression of the JavaScript

world is that every, every time I dip in there, which is about once a year, there seems to be

a new way to do things that is the right way to do things. So they haven't, they haven't embraced

the idea that there are many right ways to do things. They've sort of embraced the idea that

there is always a right way to do things, but it's different every single year. And, and that's just

as, that's almost more difficult to keep up with because now it's not just like, oh, I chose A and

you chose B. It's, I'm doing it right. And you're doing it wrong because you're still doing it last

year's way. That's the way it feels to me, at least. Maybe if I were more embedded in the

javascript world it would it wouldn't feel quite so foreign to me but you you asked me about boston

python and the beginners and it is true boston python has a wide range of people attending

you mentioned talks and project nights we've actually slowed down quite a bit during the

lockdown we haven't had a presentation night in a while one of the interesting things about running

a geographically based meetup during a pandemic is that all everything goes virtual and then all

sorts of people who live nowhere near you start showing up to your events and that's okay i guess

i'm not i'm not sure like what's the word boston mean in boston python if everything's on zoom now

i don't know um san francisco one too has had a number i mean i think that's the other large one

that i'm aware of um and they've had a couple new york is very big i guess you're not as active

right exactly yeah that's right i think they put a lot of their energy into pygotham which is their

annual um you know pycon like thing i think that's right um so yeah boston python we do get a lot of

beginners it's interesting i we don't we don't get that much discussion about from sort of django

beginners we get a lot of python beginners yeah and a lot of data beginners yeah well there is

that i'm not sure there is a django group which isn't as large um but i i mean i agree i for a

a while i went i tried to go to a number of the um boston python ones and almost always saw you there

which is a good i was like man i don't know if i should go all the time and yet you found the time

um but it's a lot of i mean a lot of grad students or it's you know or people getting a graduate

degree in whatever and realize they want to you know script something and so python so yeah not

much of a web focus um exactly right um and we've been doing the thing we've been doing in boston

Python during the lockdown, the new thing we've been doing is weekly office hours. So Mondays at

noon, we just get on Zoom for an hour. And that's one of those things that we couldn't have done in

person because who's going to travel for an hour long thing at lunchtime? But it's easy to do

weekly and there's no prep for it. You just show up and it's like people just start talking about

whatever and maybe someone knows the answer or wants to talk about it and you talk. So that's

been very easy you all are saints to do that i feel maybe it's just because i get a lot of emails

from people which i do respond to everyone eventually but i feel like i couldn't do that

it would drive me nuts but i wish i could see that on the flip side i i do get emails from

people and i have every intention of replying to them and then they're six months old and i just

have to declare bankruptcy well you know it's it's important just because someone emails you

doesn't mean you're obligated to respond right no i know and but i i mean i want to and then

it didn't i mean that's that's the open source dilemma right you can't you know no one is owed

your attention but you get into it because you want to give them attention and how do you how

do you strike that balance and feel good about it and still make progress on the things you want to

do and stuff like that so i mean do you have there's a good question do you have wisdom on

I mean, like you've experienced Open Source Contributor, what would you say?

I'd go back to Will's point, which is that you are not obligated.

It is very easy when you put a project out there.

So as Will mentioned in the introduction, I'm the maintainer of Coverage.py, which is the coverage measurement tool for Python.

6.0, congrats, by the way.

That was yesterday.

6.0 came out.

Yep.

It was actually, well, there's a funny story about that.

I was being kept awake in an Airbnb in Brooklyn by a next-door neighbor who was having an electronic dance party until about 2 in the morning.

See, that's why you can't leave Boston.

You've got to stay, you know, shuts down at 9.

And while I couldn't go to sleep, I figured, well, I might as well shove out a release of coverage.py.

I meant to do it to coincide with 3.10 anyway.

And if I do it in the middle of the weekend, then maybe it won't crash too many Travis jobs the way major releases often do.

So I did it then.

So, yeah, so coverage.py, right?

So it's a big project in the sense that lots of people use it because there really isn't any competition for coverage measurement in the Python world.

Most people don't even realize that the standard library has a coverage measurement module in it called trace.py.

They just come and get a third-party module called coverage.py, which I maintain.

But as a result of that, there's a lot of issues that get written that I can't debug because they tend to be about esoteric execution environments.

Like, oh, my tensorflow something or other didn't get coverage measured.

And I'm like, I only understood half of those words.

And I don't have the time to go and figure that out.

so it sits there. It's very easy to feel like, well, I put this out in the world, so I need to

make it work. And if it doesn't work, then that's me being a bad person, not fixing it. And you have

to get past that feeling. You have to allow yourself to take time off or just turn away

from it for a while. There are months where I'm just not interested to work on Coverage.py,

So I just don't, and occasionally it'll feel like,

well, maybe I'm never going to get back to it

and maybe I'm just done with it.

And then something comes up and an interesting bug

or a release and I was like, oh, Coverage.py,

that's a cool thing.

I'll do some stuff on it, you know, it'll,

and if it didn't come back, all right, then it wouldn't,

you know, maybe there'll be a whole year

where it never comes back to me and that'll be it.

I don't know.

I see Carlton nodding.

I mean, you two are both uniquely in this bucket.

I mean, because Carlton, aside from Django, has a number of projects that he maintains over many years as well.

The big one is that I'm working to maintain at the moment is the channels project.

And what you talked about esoteric execution environments, it's exactly that.

Someone will post a bug and it'll be like, you know, an Nginx config and a few lines of some logging file, you know, and it's like, I'm sorry, I don't even know where to begin to respond to this question.

and so I've been trying to click move to discussion for those um because then it keeps the which it's

it's a new thing and it's like well it's not it's not like I just want to click close right but I

can't answer this it's not really an issue so maybe if I move it to discussion it keeps the issues

less interesting because one of the one of the sort of demotivators for me is when the you know

the issues are piling up and it's like oh I feel a pressure and it's like oh do you know what I

haven't got the emotional space to look even look at the repo whereas if i can if i can move those

issues over to discussions those unaddressable ones over discussion then maybe someone else

finds it searching and they're like oh i had this problem and i did this and that does happen

but then the issues can be like oh actually there's an addressable you know code problem

that's identifiable that's one thing i don't mind so the coverage.py repo i think has 200

open issues right now going back years i'm okay with that whatever um some people say you should

close them if you're not going to fix them the author can close it if they want to close it they

can close it um you know i think the signals are pretty clear in that repo your issue might not get

looked at um and so um one thing that has been great is that people maybe are getting better

at making reproducible test cases.

A few times I've gotten a Docker image

with the bug report.

Like here is the Docker image showing it happening.

And I'm like, great.

I know I can, now I can see it.

Because, you know, too often you get people saying,

look, you know, it failed like this.

Can you give me a reproducible case?

Well, here's a link to my Jenkins job that failed.

I don't, how many times, you know,

how far in do I have to click

before I can even maybe find the error message

you're talking about?

You know, if you can't put work into this,

why am I putting work into this?

So if you're listeners out there,

when you write a bug,

make it really, really reproducible, right?

Write the instructions for that art school friend of yours

who doesn't know how to use computers

and you are going to be doing the maintainer a huge favor.

That's my advice for everyone else.

You do yourself a favor as well

because the maintainer will run it

and then they'll get to the break point

and they'll be like, oh, okay, I'll click that.

You a few times.

Oh, that's my code.

Oh, why is that?

you know, you've got a chance.

And I understand that the TensorFlow people,

they don't know anything about how coverage works, right?

And I don't know anything about how TensorFlow works.

So we have to meet in the middle somehow.

That's fine.

I'm willing to dig into it.

It's interesting to dig into it.

There was a bug report about PonyORM,

which is one of these tools that they take Python code.

I think it's the PonyORM.

You write a query in Python code, and then they rewrite that Python code.

And so when your query is running, it's not actually your code running.

It's a rewritten version of your code running.

So when you try to do coverage measurement, coverage doesn't think your code is running

because your code isn't running.

It's been moved over into a parallel universe.

And that was very interesting to see.

I think that was the Pony ORM.

Yeah, it's called the smartest Python ORM.

Okay.

so i have a pull request against pony rm to make that a little bit clearer to people and they

haven't bothered to merge it yet even though it's really simple but there you go turn around

is fair play i guess right it's perhaps not reproducible you'll see um can i ask about so

you mentioned that python has its own internal sort of coverage testing tool has there been any

talk of... So we have this in the Django community where there's third-party packages and

Django is kept deliberately quite small. You only pull in things when you really need to.

Has there been any talk of pulling coverage into Python? I mean, I know that PSF has fellows and

stuff. I mean, it's pretty much a standard tool for anyone I know who does Python professionally.

Yeah, there hasn't been. So there's two things you might have meant by that. One is pull it

into the standard library and the other is move it under the PSF organization.

I guess I meant both, just as a question.

Right, either.

Yeah, so there hasn't been any discussion of either of them.

These days, I think Python is doing the right thing by being very reluctant to put things in the standard library

under the theory that third-party packages can evolve more frequently

and will keep the bloat down on the Python releases.

And it's just better to have things decoupled than to have everything piled into the box.

That, you know, we should all get better at installing and using third-party packages rather than hoping everything's going to go into the standard library.

And the PSF thing, I think that moving—so the two projects that I know off the top of my head that are under the PSF organization on GitHub are Requests and Black.

And I'm not quite sure—I don't know, that one always struck me as an odd thing.

I'm not sure why the PSF, which doesn't even own the Python repo, why it would own third-party package repos.

I don't know the story on Black.

I mean, on requests, it was because the maintainer was stepping away and there was some other stuff.

So I think it wanted to keep it going.

I'm not sure about Black.

But I know they have someone.

Sorry, go ahead.

Black was started by Lukasz Lankov, right?

So he's well in place there in the PSF and very involved.

He's hardly walking away from it.

So I don't quite know what it means when something is under the PSF organization.

Because it's not the PSF that's maintaining it.

Right.

I suppose it just means maybe a fun...

Well, yeah.

We always, I mean, we, Django, look to the PSF as sort of a big brother-sister in terms of size on these things.

Because many of the same issues around.

Yep.

organizing. Yeah. And edX is going through a similar transition right now as well. So

we often look to the PSF for how to do things. For instance, the PSF has

PEPS, Python Enhancement Proposals. Open edX has OAPs, Open edX Proposals, I guess we call them.

Not quite the same acronym. But so no, the moving coverage.py hasn't been suggested. And maybe

that's just because i keep maintaining it enough probably i mean everything's fine i guess right

it's not a squeaky wheel so it's not a squeaky wheel right i mean it's it's interesting maintaining

coverage.py because um i get involved with new python releases because coverage is intimately

aware of how different python releases run the trace function to tell to indicate what lines

got run and which didn't.

And 3.10, there's two reasons why I coordinated the Coverage 6 release with the 3.10 release.

Mark Hammond was doing a lot of work in 3.10 to fix, quote, fix how the trace function

traced things.

There were lots of weird edge cases, and he was doing a lot of work to fix that.

And when he fixed it, coverage.py would break because coverage.py was used to the old broken way that things were getting traced.

And so I think I wrote, I think, 10 different bug reports against Python 3.10 during its alpha phase saying it looks like this now.

Is this what you meant?

And about half of them were, yes, it's what I meant.

And about half of them were like, oh, no, that's not what I meant.

And so we were kind of going back 50-50, you know, does coverage have to change now or does Python have to change now?

And we finally got that all straightened out, I think, by the time of at least beta 2, maybe even beta 1.

So I was really happy to be able to push that out there.

But the other thing that coverage.py had to do for 3.10 is that 3.10 now has the match case syntax for doing pattern matching.

And that is a change in execution and, ironically, a change in syntax highlighting, which is something that coverage.py does along the way, too.

So there were a few, it was a very involved release

to get Coverage.py synced up with 3.10.

That's cool.

I mean, the new syntax in 3.10 is quite cool.

In Django, we don't get to use it for years

because obviously we're still on 3.6.

Right, exactly.

We don't get to use the new match case for quite a long time yet.

Yeah, I totally understand.

There was a time when Coverage.py would run on everything

from Python 2.3 up to, I think, 3.4 at the time

or something like that coverage six is mostly called six because i dropped python to support

so now i can use f strings for instance so we're on three six plus now as well i mean what's your

policy following the um because so python 3.5 was end of life last um end of last year and 3.6 is

going to be end of life this december i think and so what's your policy about dropping the support

No, with the new annual release cycle.

I tend to be very, very accommodating.

I know some people are like,

oh, Python 2's out of support on January 1st, 2020.

I am pushing my new version that drops Python 2

on January 2nd.

And I'm doing it, you know, for the good of everybody

because everybody should move up and et cetera, et cetera.

And my feeling is, look, I'm building this tool

so that people can use it.

And if keeping Python 2 support isn't a pain,

then, you know, why not just keep it?

Coverage 6, really what happened was that there was a different change in coverage

that felt like it was going to need a major version bump because it changed the behavior.

Coverage 5 and before would often accidentally measure third-party packages

that you'd installed in your site packages.

And in Coverage 6, we made a change that it was cleverer about where the code was coming from,

and it would automatically exclude things that had been installed

where third-party packages go.

And that's great, but some people said,

you know, actually that kind of broke my coverage

and I have to go in and change my configuration.

And so that felt like that should be a major version bump.

And since I was doing a major version bump

and it's been 18 months since Python 2 went away,

I figured I might as well, you know,

let's clean this up now and drop Python 2.

Folks can still pin to the old version.

And they can pin to 5.5 if they want.

Yeah, that's always the consolation is,

You know, you're not, by dropping support, you're not dropping anyone using your code because they can just keep using whatever code they were using.

I mean, super.

So there was an article in the news this week, you know, the tech news about, what was it, that coverage itself isn't a good marker of the test base.

And what they dug into was that it's the number of tests that help, like, you know, coverage is handy.

And I remember asking you a question on Twitter about this a few months ago about is there a way of sort of marking which tests are meant to cover what?

Because I might have a few Selenium tests, which are kind of big end-to-end ones.

And just by running those, I get quite a high coverage number.

Yeah, exactly.

So there's enough to riff on.

I guess I'd ask, well, what's your thought on that and how coverage works, you know, and how you build a quality suite?

And that is a tricky problem because, for instance, if even if you write one test and then run your project on coverage, you're probably going to get like 35% coverage just because all of your import statements will have run and all of your definition statements will have run.

And all of that gets measured.

And it doesn't mean you're one third tested yet.

And by the way, depending on what you do in your asserts, you might literally not be testing.

You might be running lots of code and not testing any of it.

right so um i didn't i didn't exactly read i think i saw that headline go by about the coverage

uh problem i didn't go and read the article um but your point is a good one that you can write

a test which exercises lots of code but can't actually assess the results of all that code and

if you had a way of marking a test saying that when i run this test i don't want you to count

the coverage or only count the coverage on this part of it yeah um and that there have been a few

ideas about that in the coverage um issue tracker none of which we've we've implemented the the big

i keep saying we but it's really just me um you and your alternate person that's right

yeah um i i code up whatever my rice krispies tell me to um

the big thing in coverage five was that you we the package can tell you um for each line of code

which tests ran that's amazing cover that line which kind of gets at that same issue right so

you can take a look at the coverage report and you can see oh that line was actually only run by

the integration test for instance it was that coverage that changing coverage five which

prompted my question was it could i yeah i somehow work this backwards such that i could say that i'm

writing this test and it's for that function and right and one of the things that's that's that

keeps me interested in coverage is those new kinds of ideas like that's a whole other interesting

question like what can i say about a test that could tell coverage to focus more accurately on

what that test is doing like some people will say well it should only measure the coverage of the

immediate functions it's called, it calls, but it shouldn't measure the coverage of any function

that those functions call. But that doesn't feel right. That's too crude a measure. And I don't

know if anyone's going to want to put the work in to say, well, for this test, only measure the

functions in that module. And then for that test, and you've got a thousand tests, you're not going

to go and decorate a thousand tests. So what's the right balance there between the effort from

the developer to say what they know and what they want about the coverage. And then how do you say

that in a way that coverage can make use of? That's a very interesting thing to me. And that

might be the next big thing, right? So coverage five had a lot of big changes. We switched to

SQLite and we put in the context measurements so you could say which lines were measured by which

tests. Coverage six had a lot to do with fixing the tracing with Python 3.10. What's next? I don't

I don't know, what's the big feature for Coverage 7?

Maybe it's something like that.

But I want to make sure that it's something

that people will actually get benefit out of.

you know you we can we can invent esoteric strange features and if no one uses them then

what was the point so yeah it's it's good to be guided by the questions people ask on the issue

tracker about doing these sorts of things yeah i mean so the flip side kind of question was that

so say i'm doing i've got these nice unit tests which are targeted specifically just to their one

function and then i realize i need to refactor and what i actually then need is an integration test

around the sort of the outside and i kind of need to napalm all those nice unit i mean what's your

thought when you face a challenge like that like how do you address that that kind of issue i mean

it's a lot of work unit tests unit tests by their design are tied to what the units do and so moving

the units around is going to require moving the unit tests in some way either you know getting

rid of half of them or writing 50 more of them or changing what they all expect and it's a lot of

work and and you know some people some people take the attitude like i'm not going to bother

with unit tests what matters is whether the application works as a whole and i'm just going

to write a bunch of big integration tests and what are the chances that a big problem will get

through those maybe it's a good trade-off of benefit versus effort it's hard to know and by

the way, so I should say, though, for contexts, coverage can tell you which tests ran which

lines of code, but you can also do things like run your integration tests and say mark all of

that coverage as integration and run the unit tests separately and mark all of that coverage

as unit. And then every line of code will either say integration or unit or both, right? So you

can decide sort of how coarse you want it to be. The problem with marking every test on every line

is if you've got a thousand tests

and you're going to have lines

that are covered by 200 tests,

there's no point getting a list

of the names of 200 tests for a line.

That's just, that's too much information.

I went and looked at my own coverage,

Coverage's own coverage HTML reports

and they're a single file

can have like a two megabyte HTML file result

because every line's got dozens of test names

annotated onto it

and it's just, it's not worth it.

So, I mean, a way of aggregating

that information right clump it up at a bigger level that's not a level that

coverage can intuit by itself but it gives you the controls where you can you can indicate those

things when you run the tests so that you get the information you want so just um the thought that

came up while you were talking about people arguing for integration tests there's a line i saw um a

few tests mostly integration something i can't remember the exact line but it was that kind of

idea is don't write too many tests keep them mostly integration i think that's riffing on the

the food yeah the pollen yeah right eat less mostly plants we'll swing over to edx in a minute

but like maintaining a big code base like that like thinking about how um how how you maintain

your tests and manage testing and manage the evolution of the code i think that's a really

interesting thing and i wanted to just pull out some of your thoughts on that i mean unless you

say more though please well i mean to switch it over to edx so so it's a edx is open edx the code

base is a very large project. I mean, the edX organization on GitHub has 300 repos.

There's probably at least a million and a half lines of code. The main repo is called edX

Platform, and it's a giant Django project. So I think it's probably got about 400,000 lines of

code right now, and a lot of tests. The tricky thing about me talking about the technology is

that i've been mostly working on community issues at edX for a long time so my my hands on the bits

of Django are it's pretty few and far between um but you know edX does struggle with the the bulk

of tests we we have pretty good coverage um so we've got really a pretty extensive test suite

and we're constantly uh rejiggering the sharding of tests across uh github action suites so that

We can keep the total wall time of running the tests to a reasonable limit.

I think right now it's about half an hour to run them all.

But it's – and there's been cycles of we have too many tests.

These aren't telling us enough.

Let's just get rid of these, which, I mean, to be perfectly honest, I was – I felt a visceral shock at the idea of just delete tests.

But the fact is that if they aren't telling you anything and they do take a long time, and especially these in particular were the sort of front end tests that tend to be kind of flaky, where not only are they not giving you any value, but they're taking up your time with false alarms.

So it was the right thing to do is to delete those tests.

And it's hard to strike the right balance because, you know, developers, maybe like many people, but especially developers, tend to be very susceptible to gamification.

You know, oh, there's a metric there.

There's a needle that moves that way.

I want to move it all the way that way.

And so, you know, I'm one of the main purveyors of one of those needles, right?

Coverage measurement.

What's your percentage?

You're not at 100% yet.

You know, you've got to get to 100%.

And that's a lot of work that may not provide much benefit.

So trying to strike a balance rather than just being the best or the last or the first or whatever is really hard.

I don't know if hopefully your team is as familiar with this, but Adam Johnson,

who's on the Django security team, among other things, has a whole book called Speed Up Your

Django Tests, which is, they should look at it. If they're not, it's very well suited to

a large organization and just, I mean, Carlton, we both read it. It's just so many things that

if you're on a big code base, it's like, oh yeah, that helps, that helps, that helps, that helps.

like um he's got a chapter on profiling that's worth it just for the chapter on profiling it's

just amazing i'll have to take a look at that make sure people know yeah we'll put a link um

in the show notes one of our one of our challenges at x is that we have we use something like 150

different third-party packages um to build upon and we try to stay on the latest you know we try

to stay on supported Django releases. We're in the middle right now of moving to Django 3.2 from 2.2.

But it's hard to move. I mean, aside from the question of what do we have to do to our code

to make it work on Django 3.2, we have to go and look at 150 third-party packages and see,

are they running on 3.2? And many of them are not because these packages, you know, they get stale.

And then we have to decide, can we get rid of that package? Can we live with it the way it is?

Do we have to fork that package?

And actually, one of our engineering leads here at edX, the name is Jeremy Bowman.

He's doing a whole talk at the upcoming DjangoCon about how we manage that and how we're trying to actually be proactive in the community to push out what we've learned about other people's packages and getting them onto Django 3.2 so that we can get onto Django 3.2.

So he's doing some interesting work, you know, pushing the envelope forward on how an entire community, not just a large million line project can move to Django 3.2, but how an entire community of third party packages can move forward onto Django 3.2.

Yeah, that's, yeah, I mean, it's difficult because you're maintaining a, you know, so I've just recently bumped AppConf, which I know edX depends on too.

And the only bump was to add the Trove classifiers for 3.2 and 4.0.

Like, but it's still, it's still like, you know, do it, clean up the, you know, clean up the last few issues, make sure, you know, update the packet.

It's still, you know, it's a session to do and it needs doing.

And okay, for AppConf, it's once every couple of years, do a release, it's fine.

But if your package needs actual updates, then it's all the more.

Right.

And for us, it's hard to look at a third-party package and decide, oh, is this just a missing

metadata or is it actually not going to work on 3.2?

A question I did want to ask you, Ned, about with testing.

I mean, I think we're all engineers.

We all value it.

Managers don't always.

You've worked in a lot of organizations.

What is your advice for an engineer who is trying to sell taking the time to testing to a manager who may or may not be technical and may not see the value in it?

That's a good question.

So to go back to that job I started on Django, the ideal job where the boss left for a week, that was the same boss who said that the way we're going to test our code is we're going to push it to production and people are going to tweet at us.

Maybe it wasn't tweeting at the time.

We're doing it live.

Yeah, we're doing it live.

And actually, that Bill O'Reilly clip of doing it live was a popular meme around the office.

Absolutely.

And so one thing that happened there was that they were talking about, you know, we're going to ship in a month.

And I was looking at the software and I thought, this is not going to be ready in a month.

But how do I convince them of that?

And what I did is I brought in, I said, we should do some usability testing.

And I got some friends to come in and be the subjects in the usability tests.

And I ran the usability tests.

And I didn't know much about running usability tests.

But, you know, I knew enough to sort of pull the wool over those guys' eyes on the usability tests.

And, you know, I said, look, this guy is sitting down to use the app you said we're going to ship in a month.

Are we ready?

And they're like, okay, I can see it.

We're not ready.

So if the manager is not convinced that testing is worthwhile, keep an eye on the production outages.

and try to convince them to do a root cause analysis

and have the analysis come up with

what is probably the answer,

which is if we'd known that X and Y and Z earlier,

we could have prevented this.

The edX engineering culture is great that way.

We do RCAs all the time and it's a blameless culture.

And I don't know if I've ever heard someone say,

let's just build the feature and get it out there

And then we can write the tests later.

You know, we just have to get the feature done in time.

You know, those sorts of ill-advised trade-offs that you can sometimes hear pointy-haired bosses making.

And that just rots the morale of the engineers, too.

I mean, because I came into technology through the business end.

And I sometimes talk to MBAs who go and be product managers.

And I try to tell them the story of, well, when you go and manage a team of engineers and you're not an engineer, it's very easy.

there's a new product that your boss says, you know, get it done in two weeks, your engineers

say it'll take four weeks, and you crack the whip and find a way to motivate them to get done in

two weeks. And you think, wow, I just got to crack the whip on these lazy engineers. And the engineers

think, well, this person doesn't know anything, doesn't value testing, the code smells, the tech

that accumulates. And so both sides lose, even though the manager thinks they win. Right. And so

So, you know, having things like, my advice is generally like, because the issue is you want to, when you're in charge of managing the team, like that's the onus is on you.

You want to have an output or an outlet for that.

So I would often recommend saying you need to have like a bug day every month, every couple of weeks, so that the engineers have to prioritize it.

Because every bug is important to an engineer.

But like, how do you, when you're not technical, figure out which bug really matters?

You say, okay, I'm, you know, moving heaven and earth to give you the time and we'll celebrate it and get a gong or something, but you need to prioritize the bugs.

And then you're not just saying no all the time.

You're saying, okay, yes, at this date, and then we'll, and that sort of doesn't solve the problem, but that helps morale a lot.

And it can also sometimes be effective versus, you know, every bug that comes up is an important time off and we'll help you with that.

Right.

Yeah, and giving the engineers some measure of autonomy over some part of their effort is a really good thing to do.

And by the way, the startup that I'm talking about, he was not a pointy-haired boss.

I like to think of it as sort of a healthy debate over the costs and benefits of alternate approaches.

And we shipped a good product, I think.

Like I said, we got acquired by Hewlett Packard.

It's not around anymore.

Yeah. Well, it's like 100% test coverage, right? I mean, it's a goal. The truth is it's somewhere south of that, but the question is where.

Right. Exactly. Exactly. Yeah. By the way, when we got hired by Hewlett Packard, they looked at us and they said, oh, this Django Python thing, how quickly can you port it to Java?

Luckily, those people went away and we never heard from them again. But there was way more craziness after the acquisition by Hewlett Packard than before.

Yes. I think that's something that from the outside, perhaps it seems that large corporations are more stable on the individual level. And most of my experience is the opposite. So we're coming a little bit up on time. Are there any topics that we haven't asked you about or things you want to mention while you're talking to the Django community?

um well so the django coverage plugin yeah is a thing um and uh it's interesting so so the the

cool thing about uh django is it's got these templates and templates aren't meant to have

logic in them but they can have a little bit of logic in them you've got if statements and loops

and things um and there's a plugin called the django coverage plugin that will tell you which

aspects which parts which lines i guess of your templates have been used in your tests and which

have not. And it's an interesting project in and of itself, because when I first wrote it,

I took the strategy of, I don't need to stick to public interfaces. I can use whatever I want

that I find inside Django, and that's fine because it's on me, and I'm taking responsibility for

that. And one of the problems with the 6.0 release of coverage is that I heard from at least two

different people who said 6.0 broke my thing. And I looked at it like, yeah, your thing was using

private stuff that I didn't tell you to use. It's not my fault. I don't have to do anything about

that. You're welcome. You just say you're welcome. It was free. On the flip side, Django coverage

plugin does use internal stuff from Django. But like I said, I knew going in, that's what I was

doing. And when it doesn't work anymore, because Django has shifted, I update Django coverage

plugin to do a different thing and i have a testing strategy where every every week on sunday

it runs with the latest tip of django and if it breaks i will hear about it and i can update it

quickly before it becomes a problem ironically that test run this week only told me about how

coverage 6 broke it and not how django had broken it but you know that's that's what tests are for

to tell you this stuff broke the universe changed and your stuff doesn't work anymore so well the

template engine doesn't change very often but there's a bit of work going on at the moment to

optimize you know various bits you know make it a bit bit more performant and so maybe you'll have

some work i understand that you you might be surprised to hear that inside coverage.py is

its own template engine partly because it was just fun to write and partly because i didn't want to

have any third-party dependencies in coverage.py but i wanted to make nice html pages yeah great

well we'll definitely link to that anything anything else well i just i don't know if we're

going to talk about it much but i wanted to talk to you about cog which is uh one of your other

little projects which you claimed at the beginning your other projects aren't as interesting but cog

is an amazing little code generator that so yeah so quickly cog cog started when i was working at

a startup that was doing mostly c++ code and we had the need to have a sql schema and python and

C++ code that matched. And I wanted a way to generate the two from something. And the something

was going to be Python. And I tried using Cheetah, if you remember that templating engine, but that

was for text and not for code. So it was difficult. And so instead I came up with this thing called

cog, which is basically a way to have a text file in which you could embed bits of Python and it

would run through the text file and execute the Python. And whatever the Python generated would

go would replace the python in the output and it worked great for that for the c making c plus plus

and sql and i actually use it to make my pycon talks so i author my pycon talks in a giant html

file using a javascript based slide package and there's bits of python in the presentation that

generate parts of the slides so when i want you know a diagram or a table that's easier to generate

with code then by hand I put in the Python code and it generates that stuff.

So it lives on in kind of a much

different environment and everyone's and it is it's one of those packages that i hardly ever do

anything with but about once a year i hear from someone who's using it for something or wants to

make a change and so it's got kind of this tiny but dedicated following so yeah that's i guess i

had forgotten about cog that's that may be my second most successful side project it's just

super like i don't know i've used it for generating like um javascript clients from you know okay

there you go um that's that's similar to its original purpose in life yeah and it's like

this is you know whenever i find myself writing like really boilerplate so i'm just repeating

myself here yeah exactly you know reach for like cogs are just an awesome little tool so i wanted

to thank you thank you for that sure i think that's like levels like they say that you know

developers want to do a blog so you end up building your own static site generator and

this is like you doing that for talks so i respect that exactly i'm constantly on side sides of sides

of sides projects to make nicer looking diagrams in my blog posts on my django hosted self-written

django side project site etc yeah no but that's great that's what you you know because from that

comes coverage.py and who knows what else right if you lose that sense of play that's right yes

It's very helpful to have a side project where either you can do it exactly right because you can't in your day job or because your day job makes you do it exactly right in your side project, you can do it wrong.

Like, just having that outlet for whichever thing.

That's right.

Testing.

I don't need that.

Branches.

Everything is master.

Like, let's go.

Yeah, exactly.

Screw it.

That's, like, my site.

Branches.

My personal site.

Not mine.

site here because we we let you slip this by then but you're rewriting that and that was

what was the what was the old you're rewriting that as a straight dango site now right well so

it's more complicated than that it so my my personal site started in 2002 as a bunch of

python code that generated html that i would ftp up to so you did have a static site generator

it wasn't well originally yes this is pre-freeze right was it flask a flask freeze i think right

There's a Flask Freeze way you could do it.

It wasn't, well, there wasn't a web.

I forget what it was originally.

It was all XSLT and yeah.

Okay, but don't laugh

because it's still all XSLT.

Yeah, that's what I wanted to ask

because it's still the same thing.

It's still XSLT.

So it started as just like,

let's use XSLT and generate a pile of HTML,

FTP it up there.

And then at some point,

I switched it to being a Django site

that I would use a static site generator

with locally to generate a pile of HTML that I would FTP up to the site and to do comments that

had PHP code in there too. And there was some interesting Django middleware that would execute

PHP along the way for local testing or something like that. Yeah, it got really wacky. And then

this summer, my hosting provider said, we're kicking you off. They were getting bought and

And they said they could transfer my site and then they said they couldn't transfer

my site.

So you got to find a new host.

And so I went looking for, so I thought, fine, I'll just do a real Django site.

I made one little stop on, maybe I can just move the site as it is to a new host, but

the old site was PHP five and the new host was PHP seven.

And I definitely didn't want to invest any time in understanding how to upgrade PHP.

So I bit the bullet and I made it a real Django site.

It's really hosted on a digital DreamHost.

Sorry, DreamHost.

And so I had to reimplement the whole comment system, which was cool.

And now I can do better things with the comments and et cetera, et cetera.

But it's still very wacky.

So I still generate a bunch.

I import a lot of XML files into a SQLite database.

The SQLite databases are synced up to the server where the Django site will use XSLT to convert the XML into HTML and serve it.

So all sorts of wrong decisions, but it works.

But like 10 years of, you know, just bolting on a new bit.

Yeah, 20, 20 years.

It'll be 20 years in spring.

But now I can do cool things.

If I have images, I can auto-convert them to WebP and serve them as WebP from then on.

So the first hit does the convert, and then everyone else gets a better image, and I can

just do JPEGs locally.

So, you know, cool stuff.

Love it.

Maybe it's the last question to take us out.

So edX, I think this is public, has just been a non-profit that's been acquired by a for-profit

company.

I'm just curious what you can say about that, and how do you envision that changing your

role at all. Yeah. So this is a huge topic. But I mean, honestly, I pretty much mostly,

I know what's public. Yeah. Not much more than that. You know, people, so my role at edX has

been sort of the face of Open edX within edX. And then outside of edX, my role has been sort of the

face of Open edX from edX. So I think of myself sometimes, some people think that I'm like the

big brains behind Open edX or something. I have called myself the sidelines mascot for Open edX,

like I'm the guy in the suit dancing around as hard as I can to get everyone excited.

So when the announcement was made that 2U, an ed tech company, was going to acquire

at edX, I think that was at the end of June, people were getting in touch with me like,

you know, did you organize this? And I was like, I, I found out about it when you found out about

it. You know, when the news went public, that's when I knew. Yeah. Sometimes you're last to know

when you're on the inside. Yeah, exactly. So yeah, 2U is acquiring edX, but edX is a non-profit

and a for-profit company cannot acquire a non-profit company, or at least, I don't know

the legality, but what's actually happening is that there is going to be a new non-profit formed,

which will get all of the proceeds from the sale because you can't create a nonprofit to further education

and then sell it to a profit company and then me keep the money.

I don't get any of the proceeds of the acquisition because it was a nonprofit.

The money that went into the nonprofit has to continue the goal of the nonprofit.

So there's going to be a new nonprofit who continues that goal of education, furthering education.

And most of edX is going to go to you.

There will be people who work for the new nonprofit.

We don't know who those people are.

We don't know who's going to run the nonprofit.

We don't even know exactly when this is all going to happen.

It's under legal review by, I guess, the Attorney General of Massachusetts.

But it's going to be an interesting time.

So one of the challenges of edX and Open edX is that, I mean, and this is a classic problem

with any Django project is that you set out to build a platform,

but mostly what you're building is an application, right?

So like Django apps, oh, I'm going to have a blog app in my project.

And your blog app is never really just a blog app, right?

I mean, it's not general enough to be used by other people.

It's always got connections to the rest of the project.

And you hard-coded the name of it in there

because it was just too much trouble to make it a setting,

the right way. And you don't know what the API should be. Yeah. Yeah. Okay. So, and, you know,

Open edX is no different, right? So way back in 2012, you know, edX was building a site to serve

education and it was a Django site. And the goal was always to open source it so other people could

use it. But, you know, mostly it was just edX that we offered to other people to use. And over time,

we've gotten better about making it more of a platform and more generalizable.

But all along the way, we were deploying from master, and we deploy multiple times a day from

master today to edX.org. And that's, you know, the business that pays my salary. So it's very

important that we keep it running. Meanwhile, we also want to get contributions from people

into that open source repo. But how do we manage that risk? Right? They're not running a site that

has 30 million, 40 million, I don't know the exact count now, 50 million learners right now.

So they're not dealing with the kinds of scale we're dealing with. They don't know what our

roadmap is. So up until now, the contribution process has been very tightly controlled by edX.

Every change has to be reviewed by edX, roughly. We're opening it up a bit now, but for the most

part. Now that there's going to be a separate nonprofit that's going to own Open edX, separate

from the edX company that's running the edX.org website, what's the new contribution model

going to be?

What's the flow going to be?

How do we keep code moving at high velocity and keep the business stable under two separate

legal entities, one of whom is going to want, for the most part, to increase contribution

and one of whom, for the most part, is going to want to keep the business stable?

So that's a whole new open source dynamic that we're going to have to navigate.

So it's a very interesting time.

It was when your colleagues came on, you know, a year or so ago and talked through the OpenExit.

I went and checked it out and downloaded and tried to get up and running, but it wasn't easy to get up and running as a new contributor, as a new, like, you know, I know my way around Django, but it was like, well, bang on, this is tricky.

Yeah, it's big.

It's big.

And, you know, like I said, for the most part, edX engineers are focused on how can we make edX.org a little bit better today, not how can we make it easier for someone else to run another site that also does education.

Like, no one's opposed to that goal.

It's just probably the fourth or fifth goal in their list, and they're not being measured on that goal.

So it's very easy for it to lag.

I think that's I mean, I've I have heard that something of a similar dynamic is is off is even the case with, say, React, which is us within Facebook.

But it's the engineers there want to do that.

And Facebook itself sort of does it to humor them, but doesn't really care.

And so from the outside, it's like, well, Google or Facebook or Microsoft supports this open source package.

And really, it's probably a handful of people on the inside fighting, you know, they're getting paid by those companies.

But, you know, their boss isn't saying, nice job on React, release.

You know, it's like, okay, when you're done with everything else, you can maybe do that if it helps us hire people.

Yeah, and that's one of the things we're constantly, I mean, for eight years now, we've been trying to find good projects that we can compare ourselves to.

In other words, you know, the problems we have, are there other projects that have those problems?

How are they solving them?

Can we use those solutions too?

and there's always differences between the projects that make it not quite a direct map

and so it's hard to find analogs but actually that the the example of react coming out of facebook

actually was a recent one that we discussed i don't know how we'd actually get to the bottom

of that like how do we get into the cubicles at facebook to see what their actual you know

goals and measurements are and how do they support it maybe we should just go ask i don't know

I don't know.

But it's fascinating to – I mean, it's one of the tricks of open source is that it's not – there's no one way to do it.

And there's sort of the classic way, you know, just do it like Red Hat does it.

Well, Red Hat doesn't deploy to master multiple times a day.

Well, just do it like WordPress does it.

Well, that's a little different.

So, you know, it's interesting to work in open source and have to sort of rethink it from first principles to make it work for everyone, right?

edX loves open source as a way of expanding our engineering capacity, right?

Instead of having, I don't know what it is, 100, 150 engineers at edX, we could have 800 engineers among all of the people using open edX.

But we only get those 800 engineers if we can coordinate their contributions in a way

and open up the channels so that the contributions can flow.

And that means we have to tell those 800 engineers how to get started, like Carlton said.

We have to tell them, well, what are we interested in?

Where are we headed?

What's the roadmap?

And edX works like most companies.

They're the edX employees, and we all talk to each other.

But how do we talk beyond ourselves so that we can get those 800 people?

That's the big challenge.

And we're entering a whole new phase of that with this split of the acquisition and the new nonprofit.

I mean, it's a really good example.

If you want, you know, someone was asking on Twitter just today about, you know, what are examples of big Django sites?

Well, Open edX is a really good repo.

There's a lot going on there.

The problem with people, people want those examples because they want to know how to do it well.

And it's easy to find large projects and it's easy to find good projects.

Finding good large projects is really hard because the large projects have been around

for a long time.

And so they've just acquired lots of, first, they've got the archaeological layers of how

best to do it, right?

So way down at the bottom, you've got the function views, and then maybe we've got some

class-based views.

And the settings files, like we said, have been through their evolution, but they've

also just accumulated the tech debt and the cruft from having, you know, 100 people work

on it for eight years.

And it's just hard to keep everything with one voice and best practices spread across

a million lines of code. But isn't that what being an expert in coding feels like, is that you still

feel the same? It's just that people ask you and you realize there's no solution, so you just have

to pick one as an expert. That's how I feel. When people ask me something, I'm like, I don't know.

But then I ask around and Carlton doesn't know, Jeff doesn't know, a couple of other people,

Adam doesn't know. It's like, it's unknowable or there's no best practice because I just checked.

Yeah, exactly.

Well, and sometimes we've got a joke

among architects at edX

that it's always the same answer.

The answer is, it depends.

That's the tagline for our podcast.

We haven't said it yet.

We always, we try really hard not to slip it in.

Right.

But even like beginners come in saying,

well, what's the best way for me to install Python

and get it ready for my project?

Well, it depends.

Are you doing scientific work?

Conda.

Are you comfortable with the command line?

Well, you might like virtual env wrapper.

But otherwise, why don't you just go into PyCharm and pick new project?

You know, it depends.

These things are complicated.

Right.

And that's the kind of thing that a newcomer, they just want to work.

Right.

And that's not just because they're a newcomer.

It's because it's the part of the thing they're not interested in, right?

I'm not a newcomer.

I would love to not have to think about virtual env wrapper and just have it be solved for me.

It seems like about once every six months, I have to revisit how I get Python installed

on my computer and how I get virtual

in those versions of Python

and blah blah blah. Yeah, as we wrap

up, I think Python has gotten

better in that, you know,

A, just use Docker. B,

if you just need one version, you can just

go grab the official installer. That works

fine. And then if you need multiple versions

like a regular person, you can use PyEnv and

you know, I guess Poetry if you want to get fancy.

But that third case,

hopefully you, it's not

your first time installing Python if you need to have multiple

versions to work on stuff.

Yeah.

Yeah, but you just described the better way. And I think you had three conditionals

along that path. Well, it depends. Yeah, it depends on what they need. I mean, I think

it depends. I mean, so I've been thinking about this for my Django books, because I have a section

on, you know, how do you get to Django? It's like, well, I got to slog through Python. And I have

switched away from Homebrew on Mac and just the python.org installer actually, I think works quite

well. And, you know, yeah, there's all these things it doesn't do. Like, how do you switch

python versions it's like well there's a whole universe of thought on that but yeah we're exactly

doing clean greenfield stuff and so it's you know django 3.2 and python 3.3.10 soon and

don't have to worry about it yep well yep anyway thank you so much for taking the time to come on

i know we've gone a little over but i appreciate we had a lot of questions around testing and edX

and again you were one of the very first people we wanted to have on this podcast so i appreciate

you taking the time. So now the whole podcast is done. You can just, you can just, this is the,

the series finale. Yeah. It's like coverage six, you know, we'll take 18 months off and

now this is, this is a lot of fun. I always, I always enjoy doing these and it's great to

have a chance to have a longer discussion. I know we tweeted each other and maybe even see each

other in IRC or discord sometimes, but, uh, having an actual discussion with paragraphs and replies

and thoughtfulness is great.

Yeah.

And I mean, I sort of,

the goal is to lose people.

Like I have passive people who are like,

oh, coding, you have a podcast.

Like let's go listen.

And they get five, you know,

PhDs and something else.

You get five minutes in there.

Like you lost me.

I was like, good,

because I'm not trying to appease you.

That's right.

You're not the audience.

Yeah, that's right.

If you are interested in the podcast,

DjangoChat.com,

ChatDjango on Twitter.

And we'll see you all next time.

Bye-bye.

Join us next time.

Bye-bye.