Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to your earbuds.
This is episode 305, recorded October 10, 2022.
And I am Brian Okken.
I'm Michael Kennedy.
We got a whole bunch of stuff that's great.
We also want to thank Microsoft for Startups, Founders Hub, for sponsoring this episode.
We'll hear more about them later.
But do you want to start us off with something exciting?
Let's kick it off.
I have a theme this week, Brian.
Okay.
Before we get to it, if my voice sounds a little bit scratchy, I just want to apologize.
It's not that I'm sick.
It's that I was rocking out to the Scorpions last night.
They were here in Portland.
And even if they're 70, they still rock.
It was amazing.
I don't know how old they are, but they probably are up there.
I don't know.
Maybe being sick may have been a better excuse.
Yeah, maybe.
All right.
I do have a theme, though, for the week.
And let's kick it off with that theme.
This first one, both of these are recommendations.
The first one came to us from Matt Kramer.
Thank you for that.
And Jeff Glass, remember last time I said they announced PyScript?
That is Python compiled to WebAssembly running on top of PyIodide and Wasm browser, which is amazing.
So many cool things and so much potential there.
I pointed out that that was released and there were some breaking changes.
And it was like last minute that I got that.
So I just threw it in as an extra.
But now I had a chance to look at it.
So there's a bunch of changes.
And I just want to highlight some of the things for people.
So they're using semantic versioning.
And I don't fully understand this.
I guess it's just like month based.
Right.
So it's 2022.09.1.
That doesn't mean September 1st, though.
It was released on September 30th.
So about 11 days ago, 10 days ago.
And they just reiterate this project is undergoing lots of changes.
It's in its super early stages.
The calendar versioning doesn't really indicate that it's like 0.1 or whatever type of level.
But there's a lot of breaking changes.
So if you've worked with it before, just you want to read through this and figure out where things are going.
It doesn't look like anything's majorly broken and like you've got to rewrite a ton of stuff.
But it also, there are parts that will stop working, but they seem pretty easy to fix.
So first of all, like many Python programs, you need to express your dependencies.
You would do that through a pyproject.toml or requirements.txt.
Unless you're on the web or in the browser, then nope, you don't do that.
Instead, what you would do is you'd use this py-env section to express.
I depend on these packages, either just a URL to a wheel, a Python wheel,
or something that could be pip installed using micro pip.
That's gone.
It's now deprecated and will be taken away.
So now that's folded into the pyconfig section.
And there's a way to say packages are a list of packages.
And files that we're using is a list of paths.
And it's in these kind of places where you indicate what Python files you might write and import.
Because while you can write Python in HTML, just like JavaScript, you should do that very sparingly.
And you shouldn't just write your, you know, a thousand lines of Python, like inline.
That's not a great idea.
So you would link over to a set of Python files that you can run one of them and import others from that.
All right.
So pyenv going away, folded into pyconfig.
This is one of the things that's easy to fix.
But like I said, will stop working.
They've also changed the syntax of some events.
So you might have seen people on HTML elements like a paragraph or a div or a button.
It's a mouse over equals in some JavaScript function name, like a function call, either inline function or a function you've written.
In PyScript, there's a py dash event.
So there's a py dash mouse over and a py dash click type of thing.
And in here, you can just write arbitrary Python.
And unlike JavaScript, you can actually write arbitrary Python, multiline Python separated by semicolons.
Look at that.
Semicolons, they made it to Python.
You can write arbitrary Python.
It doesn't have to be a single function call.
Pretty cool, right?
It is pretty cool.
Python's starting to turn into JavaScript that is changing all the time.
Exactly.
Well, that's why the breaking changes.
No, just kidding.
That's the new project.
But don't let it become JavaScript.
I'm very excited that maybe it could supplant JavaScript to some degree.
There's some stuff about HTML escaping.
So you could do like print a string that will show up in the browser sometimes, or you can get it to go to the console.
But if you put like one is less than two, and that shows up in the browser, you know, that might get interpreted as an opening bracket instead of just a less than symbol.
All right.
So there's some fixes there, some stuff for logging.
The ability to run multiple runtimes.
So there's, when people usually do PyScript, they point at just a CDN version of PyScript, which points at a CDN version of Pyodide.
But you can, and easily can do, you can like download that, customize it, and put it in your static files and run it out of there.
You could possibly not even use Pyodide itself.
You could use, say, like MicroPython, potentially.
Or you could actually have maybe different versions of Pyodide running in different sections of your site, if you want it.
So different PyScript blocks, presumably even on the same page.
So a lot of flexibility about managing multiple runtimes.
Let's see a few other things.
There's also some major releases of Pyodide that's coming along.
And because it's built on top of Pyodide or runs on top of Pyodide, PyScript does, obviously the changes there are super important.
So some of the changes are that they broke, it used to be kind of like one huge namespace, and they broke that up into a bunch of pieces.
So you got to know about that.
But probably the most relevant for people is you used to have to do this thing where you would import from JavaScript some event and do like a proxy type thing to like hook.
An event, which wasn't terrible, but it was kind of like, well, are you still doing Python?
I don't know.
Right.
So they've written a bunch of event handlers or event sources in Pyodide FFI.wrappers.
So like add event listener, remove event listener, set timeout, set interval, clear interval.
And so now you can just import, say like add event listener, have a function, Python function, and then you just say add event listener on a tag on an event.
And here's your Python function.
That's awesome, right?
That is awesome.
Yeah.
So they've added these event handler sources that are straight Python and not interoperating with JavaScript more directly.
There's a bunch of things behind the scenes that will make it better, like that we don't necessarily as users care about.
But like in scripting is getting better.
They've got a whole testing scheme.
You might be interested in this, Brian, for your show.
They do integration tests with Pyright.
They do TypeScript tests because a lot of the interaction bits are in TypeScript.
And they do that with Jest.
And then Python, the Python code gets tested with pytest.
That's an interesting mix, huh?
I guess just point out, we said Pyright.
It's PlayWrite.
Yeah, I'm sorry.
I'm too much on the Py right now.
Yes, PlayWrite.
Thank you for keeping me honest.
Yeah.
But I'll do a famous pull request on them to try to get that pytest case all lowercase.
That'd be good.
Yeah, I'm not even going to use this project until I get fixed.
So some stuff on infrastructure.
There's new CI things that they're working on to make it better.
They're using type annotations.
And they're trying to synchronize TypeScript and PyScript type annotations to kind of keep the end-to-end across JavaScript, across Python accurate.
And a bunch of stuff that's coming, in particular, a lot of rethinking how async works, because JavaScript is already super asynchronous, but it just has one loop.
And if you hook your async Python into that, then is it really async?
It's a little bit complicated.
You can check out what they said there.
But otherwise, very exciting stuff.
And if you're doing PyScript, definitely check this out, because it's going to affect you.
Yeah, that's cool.
Well, let's give your voice a little bit of a break.
Yeah, I mean, too much Rocky Like a Hurricane stuff going on.
Yeah.
Well, I want to talk about decorators a little bit.
So I was actually on a – I sat in on a Boston, the Python Boston meetup group.
They're still – it's kind of neat.
They're still doing online, so it's not really Boston.
It's anybody can jump in and have fun there.
But we're talking about pytest, and Ned Batchelder was there and talking about coverage also.
And he was showing us some of the test code.
It was really fun, because he was showing us some of the test code within the coverage – the
test code that tests coverage by coverage.py.
And he was showing some things about using decorator shortcuts.
And then I was like, that's really cool.
I always forget to do that.
And so he wrote up this – I don't know if it's just for me, but he wrote up a blog post called decorator shortcuts.
And especially – I mean, I guess for a lot of stuff, we use decorators a lot in Python now.
And pytest also uses a lot of decorators.
Things like pytest mark parameterize or pytest mark skip or xfail.
Those are all decorators built in part of pytest.
And so the thing he wanted to show us is, like, as an example, he's got some tests that have to – that are either skipped or xfailed on certain Python versions.
So he's got a way to test a piece of code that only works on, say, like it doesn't work on PyPy.
Or it doesn't work on, like, Python 3.8 or before or something like that.
And so he has these fairly complex, like, version – like, xfail decorator sequences that he can take.
And instead of saying – and let's say he's actually filed – maybe there's an issue.
And he's actually filed an issue against PyPy, for instance.
But his tests are still failing.
He had an example where instead of just this whole big xfail blob with the environment – checking the environment version,
and having a reason and a link to the defect, he just shortcutted that to just, like, a single variable name or single name that says xfail PyPy3749 as an example.
Just a single thing.
And then when you're using it, instead of this whole big blob, you can just write at xfail.
Instead of, like, xfail – instead of saying, like, pytestMark xfail, you can have this specific xfail.
And then you get the reason printout and everything.
That's very clever.
Yeah.
Especially – I like it for this is there's – we were talking about how we don't like to leave xfails in for a long time.
But sometimes you're dependent on a different piece of software that you're not one of the maintainers.
In which case, what do you do with the failing test?
One of the things you can do is you can xfail it and link it to a defect report so you can keep watch of it.
But, yeah, having a way to just mark different tests with the same thing is pretty cool.
And then this really kind of relates to really a lot of things.
There's a lot of places where we use long, complex decorators that you can just assign to a variable and then use it later.
Yeah.
To put this decorator on a test function, you have to have – you specify a whole bunch of conditionals around the version.
And then the reason is a big, long string.
And if that's affecting 10 tests, you put that on 10 tests, it's all over the place.
You know, one of the things that you hear from people sometimes is like, well, I don't like unit testing because it's hard to maintain.
And I find that when people say that a lot, they kind of go into like this sort of – this mode where when they're writing test code,
they forget about things like trying to isolate change to one place.
And you would never write the same code 10 times in a real part of your app.
Why should you write it 10 times duplicate in a test?
Right?
Well, it's hard to maintain.
Well, it'd be hard to maintain if you did that in your regular code too.
Just – you don't do it there, so don't do it here.
And this is a cool technique to accomplish that, yeah.
Yeah, definitely.
And this is – this part of it isn't – it's also great because it's consistent.
It keeps – it'd be terrible if you were, you know, referencing this issue in three different places,
but only sometimes including the link and, you know, having some consistency is good.
So –
Absolutely.
And there was some concerns.
Larry Hastings put up a concern about possibly not doing this for code that can – that is – that generates a single-use object,
like iterator or something like that.
But just don't do that.
But Larry has a workaround.
If you – you can do it a different way if you have something that acts like that.
I see.
Interesting.
Yeah.
There's a lot of turtles all the way down, like decorators of functions that return functions.
And so what we do is wrap that in a function to alleviate the – capture the closure.
Yeah.
It's fun.
But anyway.
Cool.
Excellent stuff.
Yeah.
Next up, our sponsor.
Yeah.
We have a sponsor.
Our sponsor this week is Microsoft for Startups, Founders Hub.
So Microsoft for Startups, Founders Hub provides all founders at any stage with free resources to help solve startup challenges.
The platform provides technology benefits, access to expert guidance and skilled resources, mentorship, networking connections, and a whole bunch more.
And unlike others in the industry, Microsoft for Startup, Founders Hub does not require the startup to be investor-backed or third-party validated or able to relocate to San Francisco for a short time.
So Founders Hub is truly open to all.
So what do you get?
You get free access to GitHub and Microsoft Cloud with the ability to unlock credits over time.
They've also partnered with other companies like OpenAI to provide services and discounts.
And Microsoft, through the Microsoft for Startup Founders Hub, becoming a founder is no longer about who you know.
You'll have access to their mentorship network, giving you access to a pool of hundreds of mentors across a range of disciplines, across areas like idea validation, fundraising, management, coaching, sales, marketing, maybe even testing.
Who knows?
You'll be able to book a one-on-one meeting with the mentors, many of whom are former founders themselves.
So make your ideas a reality today with the critical support you'll get from Microsoft for Startups Founders Hub.
And to join or just check it out, visit pythonbytes.fm/foundershub 2022.
The link is in the show notes.
And I know you can find this stuff on your own with Google or something.
But if you go through our link, it helps them know that you heard about them here.
So thanks.
Yeah.
Thanks, Microsoft, for supporting the show.
Brian, before we move on, audience feedback from Henry Schreiner.
For that exact example, talking about pytest and decorators, I'm not fond of making the test directory importable unless I have to.
A mark might be better.
What do you think?
A mark might be better.
I mean, they are marks.
So the marks are decorators.
Yeah.
Okay.
Cool.
What is next?
Another continuation of my theme here.
So Mark Madsen sent over a recommendation to talk about this.
Unrelated to the previous announcement, only in timing or origin.
So Panel, people probably have heard of HoloViz.
And Panel is related to that project.
It's an open source Python library.
It tells us you create custom interactive web apps and dashboards by connecting widgets, plots, images.
So people have heard of Streamlit.
They've heard of H2O Wave.
They've heard of Plotly Dash.
It's like in that category, right?
So you can put together a lot of interactive fun pieces.
So for example, here, if you go to the main website for Panel, you can see that there's like this graph.
As you hover over it, it's very interactive.
But you also have widgets to let you reevaluate how you compare all these things and just play with it live.
Right?
Kind of like it's a notebook, but it's not.
That's neat, right?
Yeah.
So traditionally, this has run in Jupyter Notebooks.
Or you can run it on like the Flask backend type of thing.
You can host it on your own stroker.
The news is not that.
This has been around for a while.
The news is that Panel now comes to Wasm via Pyodide and has PyScript integration.
That's pretty awesome.
That is pretty cool.
So in order to host it before, you have to either have a running notebook server or you had to set up your own separate web server and maintain that thing.
And all that goes with.
And now you can just put a little py-config in there.
And boom, when they interact with your data and they run it, it just happens client side.
No servers needed.
So let's talk about some of the things here.
You can automatically convert Panel applications to a Pyodide version.
A couple of flavors.
Reasons I'll explain in a minute.
Or you can convert to a PyScript-based app, which is pretty epic.
So you could embed a panel inside your Sphinx documentation just to some HTML, which is pretty nuts.
So there's this convert command, panel space convert on the CLI.
And you can tell it the two format from your regular panel code to convert it to a Pyodide.
This one is good if you want to have a single HTML file that you say, here's my HTML file.
Off it goes.
It's just no dependencies.
And then it runs there.
That's not as good as creating a Pyodide worker, which creates a JavaScript and HTML file that you've got to serve over more of a server.
Or you can even output a PyScript version where you can write additional PyScript code.
It's pretty epic.
And here you can see a little example.
This looks like standard XGBoost SKLearn code right here.
It does all its things.
Except for the end, you just say pn.column.
And here's your output right there.
And you put your little pipeline you created and maybe a head of a data frame to show up.
And there it goes.
So in order to run this, you would say panel convert the script to a Pyodide worker.
Output Pyodide.
Then you just run a server locally so that you can get to it.
You can pull in the JavaScript, open it up, and you get something that looks like this.
That's super interactive.
There you have machine learning in the browser.
That simple.
That's pretty cool.
The browser's JavaScript will take over the world.
It'll get smart and then take off.
So a couple of cool tips and tricks they recommend is you can do --auto reload.
So if you make changes to the file, it'll auto reload the browser.
So just as you edit, you can also add a panel dot convert --watch.
So if the source files change, it'll regenerate the script.
And then the script will get reloaded.
So you can chain those together, I believe.
But then there's a section on formats that actually describes what is the point of the different outputs,
like Pyodide versus Pyodide worker.
So the worker one says it generates an HTML file and JavaScript that runs better.
This is the most in a separate thread.
This is the most performing option, but it has to be running out of a server instead of just a file.
Worth noting here, PyScript generates an HTML file leveraging PyScript, produces standalone HTML files containing pyenv and PyScript tags with the dependencies.
It's basically a PyScript variant of the Pyodide one.
Well, guess what?
This might need a little update coming soon.
Py-DNV is not there anymore, so they can check that out.
I'm sure they're on top of it.
Yeah.
Final thing to note here that's pretty dope is progressive web apps.
So this comes with a --PWA option, which turns your, I'm pretty sure this is going to require the Pyodide worker variant,
because you need these worker things for progressive web apps.
But this means that you can install your app into, say, an iPad or install it like a desktop app and run it with cached offline data.
So, for example, let's see if I go to YouTube here.
I signed in.
No.
Good.
So, like, in Vivaldi, I can right-click on this, and it'll say install YouTube there.
So if you did that option for your panel app, you could right-click and say install panel.
And you might think, oh, well, that's silly.
Like, who cares about that?
Let's see if this let me do it, though, here.
Oh, this is live.
If you go to a lot of these, I just need some video.
I don't really care where it is.
A lot of these, you can come in and actually click download.
I guess you've got to be signed in, but if you have, like, a premium account or whatever, you can click download.
And that's only possible for YouTube installed as a PWA.
Because I think a lot of people feel like, oh, it just gives me an icon on my homepage.
But, like, there's actually different behaviors.
So you can get, like, offline videos on the PWA YouTube, whereas the web one, you can't.
And so on.
So anyway, that's the kind of benefits you would get if you would do your panels at PWA, which is just a command line option.
Interesting.
Cool.
Anyway, people check it out if they're interested in building dashboards, they're interested in PyScript and running in the browser using WebAssembly.
Here's a pretty awesome option.
Thanks, Mark, for sending this in.
Yeah, thanks a lot.
Did you know that Python 3.11 is coming right up?
It's got to be soon.
It's October.
There's not that much October left.
Yeah, but it was 3.8 when we got the walrus operator.
Do you realize it's been that long?
It seems like the walrus operator is still new.
But that's a long time, yeah.
Yeah, so...
It's like an adolescent walrus now, not even a baby walrus.
Yeah, exactly.
So I think it's time for people to embrace the walrus.
And so one of the things you can do is you can install Marco Gorelli's auto walrus, and it'll convert your code for you in places where you really should have used the walrus operator.
So, and this is good if you're supporting 3.8 and above.
And golly, I hope you're already up to 3.9 or 3.10 by now.
So there's this auto walrus.
I checked it out.
It's pretty simple.
It can run as a pre-commit hook, too, which is nice.
But you can run it on the command line, which that's what I did when I tried it.
You pip install auto-walrus.
So it's one word, but with a dash in the middle.
And then you have this application.
You can run it on a file.
And like we said, you can run it as a pre-commit hook as well, and it'll run on everything.
But you can...
And it just converts stuff.
So if you have things like...
Here's a simple example of n equals 10.
And then if n is greater than 3, do something.
And that converts...
The auto walrus will convert that to the walrus operator of if, you know, n colon equal 10 is greater than 3.
And I kind of like this being separate from other tools because some people just honestly haven't been...
Haven't came on board with this already.
You know, embrace the walrus sort of thing.
But it's a fun way to just try it out on your code and do a diff.
Get diff and see what it changed.
And maybe you like it.
Maybe it's a thing to do as a group code review thing to just talk to your team and find out if you want to change it this way or not.
Yeah.
And then this reminded me of something.
I'm like, we had something like this before, right?
And back in episode 82...
Wow.
That was in 2018.
We talked about Anthony Satili's Pi upgrade.
So...
And that's...
It's been a while.
So that's like four years ago.
So I went and took a look again.
And I would like people to try to check out Pi upgrade too.
Because there's a whole...
It's moved on.
So it's not just...
We recommended Pi upgrade for things like upgrading from two to three sort of thing.
Was that back in the controversial legacy Python days?
Yeah.
So there's...
And there's always times to go and revisit old scripts and old applications that you're still maintaining.
And going, well, we don't really want to support the old Python.
But our code server looks like the old Python.
So let's take a look at some of this stuff.
And it'll do things like, you know, the set literal.
Some of the old things of...
And doing comprehensions for you.
And better...
Comprehensions are cleaner looking.
And then...
But there's also like different print styles.
But one of the things I wanted to point out is if you go to the readme, you got to scroll all the way down.
Or at least halfway down.
And you get things like the 3.6 plus.
So there's these plus options.
So you can say if you're running 3.6 or above, run that.
But you also want to do...
Like let's just go all the way down to like 3.7 plus.
And there was a kind of a new way to run subprocess, for instance.
But you're...
I mean...
And it just finds some of these things and just changes it for you.
So it's kind of cool.
Some of the things you may not have remembered.
The 3.8 plus the LRU cache.
You used to have to do the LRU cache and call it as a function for your decorator.
But now you don't have to do the PRINs.
So just some cleanup like that.
It's just nice.
I try to run this every once in a while.
And yeah, I guess public service announcement for this cool little project.
That is a cool project.
And going through this huge long readme and looking at like as it gets later and later in Python
versions, it's kind of like a...
Here are just a bunch of examples of how Python has changed over the last few years.
Yeah.
Ooh, neat.
It has like 604 type rewrites.
It'll rewrite the union operator to the bar operator.
That's in 3.10 plus.
That's nice.
Yeah.
Well, we got 3.11 plus coming soon.
Yeah.
That'll be fun.
Awesome.
Well, that's our items, right?
Got any extras?
You know, I was going to have an extra, but I'm going to save that for later.
So no, I don't.
Do you have any extras?
No extras.
But I have a joke.
I do a quick follow-up to this though.
This is a hint of what's coming next week.
I'm going to talk.
I think it's next week.
I'm going to cover this.
Refurb.
Have you seen Refurb?
I don't think so.
Refurb is a similar one that like will go through and give you recommendations of here's
the most modern way to do your thing.
So like if you said, you know, if value is in bracket XYZ, it's like, you know, it's a
little less efficient than like why make a mutable list when you could make it a tuple.
It's a little more efficient just to create the tuple.
So if value is in parenthesis, it'll suggest you change a parenthesis or suggest using some
path lib operations instead of with open operations.
Like instead of a context manager with open, do a bunch of stuff.
You can just do path of thing dot read text.
You don't need to do the context manager.
Just bam, there it is.
A bunch of cool stuff like that.
So anyway, that one more.
And then also Flint.
I've talked about Flint.
I love Flint.
Super straightforward.
It brings one of the most beloved things you can do for upgrading your Python is convert
all your variations of string formatting to f-strings just across a whole directory of
Python files.
Cool.
A lot of different things to be running together, but are you ready for our joke?
I am.
You had the comment about bring back the walrus or something.
I feel like that could be a cool t-shirt, right?
Yeah.
Yeah, absolutely.
So I came across this place a little while ago.
I don't have any particular one to recommend here, but this place that has like funny, geeky
t-shirts.
So I thought I'd just pull a couple of these up and see what you think about them.
So some of them are good.
I like the first one, the Mordor.
The Mordor fun run.
One does not simply walk into Middle Earth.
You have some for our data science friends out there.
It has a graph of two things that are very similar.
One is shark attacks.
The other is ice cream cone sales.
And it says correlation does not imply causation.
Apparently ice cream sales and shark attacks are closely correlated because it's warm.
You go in the water.
It probably doesn't cause shark attacks.
It might.
If you are more into math, you have the distance raptor divided by time raptor is the velociraptor.
But there's some really good programming ones in here as well.
Like this one, for example, check this out.
Go outside.
The graphics are amazing.
And the picture of the shirt is like a super low bit rate, like graphics.
Here's a good one.
Some lab person pouring like beakers of clearly poisonous green stuff.
It says, forget lab safety.
I want superpowers.
Oh, boy.
What about the, what do you think of this one, Brian?
Here, the forecast for Alderaan.
So remember, Alderaan is the home of Princess Leia that was blown up by the Death Star and Star Wars.
And it says five day forecast, Alderaan.
Monday, 72 and cloudy.
Tuesday, 74.
Wednesday, 15,000 degrees.
No Thursday or Friday.
It's kind of mean, but it's also kind of awesome.
Yeah.
Those are good.
Yeah.
This is me.
We see if I can find one more, one more programming one.
Oh, yeah.
Let's see.
Here's some good ones.
One, it has a floppy disk.
It says, kids today have no idea what this is.
And then this one here, Brian, this is the last one.
It's somebody holding a CD going into a drive.
And it just says, never forget.
Never forget the CDs.
Yeah.
CD drive.
I still love that old joke of a person calls into IT help desk and says, I need some help because my cup holder's broken.
Yeah.
I just went in and spilled this drink all over me.
Come on, man.
You guys got to get a safe fix.
Yeah.
So you could spend a lot of time on this page.
I'm not necessarily suggesting you get a shirt here or anything, but it's pretty awesome.
Well, it makes me miss ThinkGeek.
ThinkGeek should have never folded.
But we have other people coming up with good humorous shirts.
So that's good.
Yeah.
Houston, we have dibs.
Putting a flag on the moon.
Dibs on the moon.
Got it.
So a more serious, a couple quick follow-up here.
Marco Garelli, from the project that you talked about, the Auto Auris, says, yeah, I love Pi Upgrade.
And Will McGugan.
Hey, guys.
We could use the Pi Upgrade because Rich is dropping support for 3.6.
So just clean it up.
Yeah.
And then I want to follow up with the first thing I was talking about, about the decorators.
So Henry Schreiner said, oh, I think I got the wrong one.
But for that example, I'm not fond of making the test directory importable unless I have to.
A mark might be better.
And I guess I brushed that off too quickly.
If I were to put a bunch of these, like if I had a project-wide decorators that I wanted to use, I don't know what the best way to do that would be.
It might be a non-test file that I would import.
I'll have to play with it.
So thanks for Henry for bringing that up.
I'm not quite sure how to deal with that problem.
Indeed.
All right.
Well, should we call it a week?
Let's call it.
All right.
Thanks everybody for showing up.
We'll talk to you next week.