Brought to you by Michael and Brian - take a Talk Python course or get Brian's pytest book


Transcript #159: Brian's PR is merged, the src will flow

Return to episode page view on github
Recorded on Tuesday, Nov 26, 2019.

00:00 Hello and welcome to Python Bytes where we deliver Python news and headlines directly to your earbuds. This is episode 159 recorded November 26, 2019. I'm Brian Okken.

00:12 And I'm Michael Kennedy.

00:13 And this episode is brought to you by DigitalOcean. Thank you DigitalOcean. More about them later. Michael, what are we talking about right away?

00:19 about right away. You know, I'm a big fan of type annotations. And I don't know how I missed this one. I can't remember what I was reading. It was something we covered on a show recently. And it was talking about the final type annotation. I'm like, wait a minute, what there's a final as in with object oriented programming. You know, there's like abstract methods, virtual methods that can be overridden protected types. And some of those things appear in Python, abstract meta, for example, but others don't, but such is protected or internal.

00:49 Another thing that until very recently did not appear in Python is a final type saying this class cannot be overridden or this method cannot be overridden in a type hierarchy.

01:01 But now you can.

01:02 Oh cool.

01:03 And this is actually already in Python 3.8 if I'm reading this right.

01:06 So this is PEP 591.

01:10 Its status is accepted and its Python version is 3.8.

01:12 So I have not actually had a chance to test this out.

01:16 But yeah, it looks like it is part of it.

01:19 And you know, because it has to do with typing, of course, Gita Von Rossum is the BDFL delegate, which is kind of interesting.

01:27 He's his own delegate, in a sense, but now the steering council is there.

01:31 It's a little bit different.

01:32 But yeah, so he was part of this and it adds a final type.

01:35 So I can say this class cannot be derived from this method should not be overridden.

01:42 And those sound pretty straightforward, but as far as I can tell from the use cases they put in the pep, it's something that is very, very close to a constant value as well.

01:50 What do you mean?

01:51 So, one of the things I can do is I can put an @final decorator on a class, and then if I try to derive from it, the type decorator will give me an error saying you cannot inherit from final class, whatever, right?

02:03 Yeah.

02:04 If I put it on a method, and then I try to have a derive class that replaces that method effectively like implicitly overriding it.

02:11 I'll get an error that says cannot override final method foo.

02:14 Whatever, right?

02:15 It was first defined.

02:15 But I can also say that there's a variable called rate, which is final and it equals 3000.

02:22 And if I try to set it to another value, like rate equals 300, the type checker will give me an error say cannot assign to a final attribute.

02:29 - Okay.

02:30 - Or I can go to a class and I can put that on a field.

02:33 And if I try to change the field, like if I have a class called base and it has a default ID, if I say base.defaultId equals something other than what it was initially set to, error cannot override final attribute.

02:44 So the error doesn't say this is a constant value, you cannot do this, but it's like a constant.

02:48 >> Yeah, okay, that's nice.

02:51 >> It's interesting, right?

02:51 >> Well, I guess it totally makes sense because overriding, like deriving from a class or something is kind of similar.

02:59 >> Certainly changing the name, like the redefining the method in a base class is like replacing the name of it.

03:06 And so the implementation seems to just catch straight up attributes as well, just probably with not much extra work, if any.

03:15 Yeah, so this is all the stuff that I'm telling you.

03:18 This is all type checker magic.

03:20 This is not real, right?

03:23 This is not runtime behavior.

03:25 But I suspect that tooling like PyCharm, for example, if you tried to set that, it would turn it yellowish and say, warning, this is a problem here.

03:35 And already if your editor tells you not to do it, your continuous integration maybe checks these things.

03:40 I think you're in a pretty good place.

03:41 - And I think that more and more we're gonna see as the years come on, that people's workflow is just gonna include type checkers with their code, with large projects at least.

03:52 - Yeah, at least with large projects, I agree.

03:54 Cool, well, I'm pretty excited about this.

03:56 I was really surprised to see that was in 3.8, but I'm happy to spread the news about PEP 591.

04:02 How about you?

04:03 - We've got some numbers that are incrementing as well, huh?

04:05 - Yes, so Flit, have we talked about packaging?

04:09 - No, I don't think we have.

04:13 Enough, not enough.

04:14 Let's keep going.

04:15 - I'm almost positive we've covered Flit before.

04:17 - Yeah, we certainly discussed it, if not made it its own pure topic.

04:20 We've definitely talked about it.

04:21 - Right, so one of the beefs I had with Flit, which was just a minor thing.

04:26 So Flit makes it so easy so that you can, like super easy, so if you've got some code that you wanna share with somebody, just install flit and say flit init and essentially it does the right thing to create a package for you. You don't have to read up on setup tools or anything it just kind of works. Oh that's interesting it's like npm init sort of. Okay I don't know what that is but I'll believe you. That creates a good job of like an npm package yeah yeah. The news right now is flit 2 is here so when initially playing with flit I noticed a little a lot of quirks with it so you for instance you couldn't use a source directory to put your source code in it your package needed to be a top-level directory or just a module.

05:05 That was actually a pull request that I did to try to get the source directory added to flit.

05:11 And now it's in, so it's in too.

05:13 - But it also wouldn't... - Sweet. That's awesome.

05:15 Yeah. So when playing with it now also, it used to be that it really assumed you were going to be in a Git repository.

05:23 That's fine, except for when you're just playing with stuff.

05:25 Sometimes you're not. You're just trying...

05:28 Yeah, I want to just try this out.

05:29 I'm not committed yet to this even working.

05:31 Let's just see what happens, right?

05:32 - Right.

05:33 Flit now does work without, if you're not in a Git, it determines what files to include in a package with Git stuff, with what's in Git and what's not in Git.

05:43 And I don't know how it works when you're not in a Git repo, but right now it does work if you're just playing around, if you don't have anything checked in, it still works.

05:51 And that's pretty handy.

05:52 I mean, I definitely want everybody to use version control, but if you're just trying this out, you can now.

05:58 And it's really cool.

05:59 And there's a whole bunch of improvements.

06:00 We're just, I'm linking to the release notes and the history.

06:05 It's just sort of, if you've tried it before and were frustrated, try it again.

06:09 The caveats I'd like to say is this kind of a lightweight packaging system, it does not work for compiled code.

06:16 So it's not built yet to deal with compiled parts of it.

06:21 - Right, if I had like some Cython bits or something, doesn't deal with that.

06:25 - Doesn't, and then there's a couple other reasons why you might not wanna use this, but for I think the 80% case where people are just trying to share some Python code with each other, this is the way to go.

06:37 - Okay, that sounds super cool.

06:39 - Yeah, one of the other things that I love in the second version is your email address is optional now.

06:45 It used to be required, but you're not required to put an email address in PyPI, so why require it for these tools?

06:55 - Yeah, that makes a lot of sense.

06:56 - Yay, so now my big beef with the let not supporting source is I'm done with that beef.

07:01 - You know what, this is a super cool example as well, right?

07:04 Like it's one thing to just complain and say, you know what, this thing is crappy or it doesn't work the way I want or something.

07:12 It's another to say, and I'll help to make a difference, right?

07:16 So like the reason it supports it is your PR was merged in, right?

07:19 That's awesome.

07:20 - Yeah, and it also, it doesn't add any, I didn't add any flags, didn't add anything.

07:24 It's just within the init part of it.

07:27 It detects that your code is in a source directory and it just uses that.

07:31 - Yeah, super.

07:32 Nice work.

07:33 - You know what else is cool?

07:34 - DigitalOcean.

07:34 - DigitalOcean is very cool.

07:36 DigitalOcean is making Kubernetes easier with their DigitalOcean container registry and one-click apps.

07:44 After building your app into Docker containers, you'll often want to store container images in a centralized location called a container registry.

07:53 From there, you can pull images into a Kubernetes cluster or a VM, whether it's a development, testing, staging, or production environment.

08:02 While you can post your containers' images into the open internet freely using services like Docker Hub, clearly you don't want to do that with confidential software or your own private stuff.

08:14 So DigitalOcean introduced a new managed service called DigitalOcean Container Registry, and It's now available in early access mode.

08:24 So DigitalOcean Container Registry is simple, private, secure, and fast.

08:29 And you can get started using it by going to pythonbytes.fm/digitalocean.

08:34 - Cool.

08:35 I feel like this next item that I want us to talk about, I feel like we talked about it before, but I went back and I searched and I couldn't find anything about it.

08:42 So if we covered it like three years ago, we're gonna cover it again.

08:46 Nonetheless, it deserves to be covered because it's really cool.

08:49 comes to us from Andrew Simon and it's called pint. So how many cups is in a pint or do pints go into cups? Is there like how many gallons go in there and if I had to convert that to liters or milligrams like what would like I don't know all these questions are completely unknown to me without like some chart and a calculator or Google and I would suspect they are to a lot of folks.

09:12 mixing some form of units, even if they're in the same system, like meters and millimeters, can be tricky.

09:22 So this pint thing, its job is to basically apply units to numbers and calculations in Python.

09:30 Okay.

09:31 Okay, so I'm sure you took physics and in physics or maybe the chemistry, like your professor would tell you, you cannot just tell me the number is seven.

09:40 You have to say seven what?

09:41 You have to put units on this number or this number doesn't really tell us what the answer is or what we're working with, right?

09:49 And so Pint lets you do that.

09:50 It has all these different types of measurements.

09:53 It has like energy and like joules and it has distance and weight and all these different types of things, even wavelength.

10:01 It'll help you like convert wavelength types of measurements and stuff.

10:05 So if you've got some numbers you need to add together, Like for example, it's super easy to add two meters and five inches and get the right answer in the units that you want.

10:14 >> That's cool.

10:15 >> Yeah, super cool, right?

10:16 So I'm linking to basically a Python document that has a txt ending on GitHub.

10:23 So read that however you want when you get to it.

10:25 It's a little unformatted, but it shows you all the different units and types of units that you can work with, right?

10:31 It knows what a deci gram or a deci meter is and all those different types of things.

10:36 So I just want to share a quote that's on the homepage there that talks on the pint, read the docs.

10:42 So it talks about the Mars Climate Orbiter.

10:47 And it said the MCO has determined, this is an orbiter that went around Mars until it didn't go around Mars anymore and it hit Mars, I believe.

10:57 It met Mars in an unfortunate way.

10:59 It said the MCO Mission Investigation Board, MIB I'm guessing that's what that stands for, has determined the root cause for the loss of the MCO spacecraft was a failure to use metric units in the coding of the ground software file, Small Forces.

11:15 Used in trajectory models, specifically the thruster performance data in English units instead of metric units was used in the software application titled SM_Forces.

11:26 Hence, Orbiter Meet Planet.

11:29 So yeah, you know, this is not the type of code I write a lot, so it's not directly useful for me but I've studied science a bunch and it seems if it is the kind of code you write, it's very simple and very powerful.

11:41 - Yeah, one of the things I like about it is it's not that the unit's separate so that you can like look these up, it stores the values. It just has values with units associated with it and so you can pass them around and use them in other places and all the math operators work on it.

11:57 I mean, if you really want, I mean, you kind of have to know the units anyway, One other way to do that people often use is like suffixing variable names with what the units are, but then that's there's nothing telling the software that it has to comply with that.

12:14 It's just it's just convention at that point.

12:17 But so if you're especially with mission-critical stuff, I think this is a really great idea.

12:21 Absolutely.

12:22 So the way you would create like three meters is you would create an instance of a unit registry and then you just take the number three times meter.

12:30 Yeah.

12:31 And now it's a three meter quantity.

12:32 So they override what the multiplication thing means.

12:36 And yeah, it's pretty cool.

12:37 That's clear.

12:38 - You can add different units together, like meters and centimeters together, and it just works right.

12:43 And that's great.

12:43 - Yep.

12:44 Nice and simple.

12:45 Speaking of simple.

12:46 - I gotta say that the unit thing that you looked at, you were linked to, it has, I didn't know this, that yada is one times 10 to the 24th.

12:56 So yada, yada, yada is a really big number.

12:59 - I had no idea.

13:00 That's a huge number.

13:01 How interesting.

13:02 What a cool piece of trivia.

13:03 Yeah.

13:04 OK.

13:05 Speaking of a bunch of numbers and great things.

13:07 We're going to take a look at some pytest plugins.

13:11 So Jeff Triplett wrote an article called "8 Great pytest Plugins." And there is even some fun stuff for me.

13:18 I'll just list them quickly.

13:20 There's a couple that I'll highlight.

13:22 So pytest Sugar.

13:24 So sweet.

13:25 It's just a fun one that changes the output.

13:28 But it isn't just fun.

13:30 changes the output so it looks kind of nice. You get green check marks and stuff instead of the progress bar. But it also shows failing tests instantly instead of waiting to the end or something. So that's nice. It's cool.

13:43 pytest-cov hooks into the coverage so that you can, you know, more succinctly check your coverage on your code using pytest. I use that. It works great. The next one I want to, which I hadn't heard of before, is called pytest-picked and this is like a brilliant idea. So if you've ran your pytest code, you know, you think your stuff is good, but what this one does is you're working on your code and if you're using git, you've got modified and unstaged and uncommitted code within your repo. That's the stuff that probably the new bugs are in. So what pytest-picked does is it only it tests files that It runs tests that use the files that have been changed since your last commit.

14:30 That is super cool.

14:31 And it probably runs your test code that have been changed since your last commit.

14:37 But what I would love to see, and maybe it does this, you tell me if you know, is if it would look at the coverage data and it would rerun the tests that were covered by your tests, the files that were covered by your tests but then changed, it would rerun those tests that covered it.

14:53 Oh, did I get it wrong?

14:54 Does it just run?

14:55 I think it just straight up runs the files.

14:58 It's just like if your tests have changed.

15:02 Yeah, I'm pretty sure.

15:03 - It says the tagline is runs the test related to the unstaged files.

15:09 So, not sure.

15:11 - Yeah, yeah, not sure.

15:12 - I'll have to try that one out.

15:13 Report back.

15:14 - Yeah, we definitely gotta try it.

15:15 My first impression from looking at it is it runs the tests that were changed, not the code that was changed, covered by the test.

15:22 But yeah, we'll report back.

15:24 - Both of them are interesting.

15:26 - They're both very interesting, yes.

15:27 They're like already, I think it is a super cool idea and I love it.

15:31 If it does the second thing I said, then I'll love it even more.

15:34 - Yeah, okay.

15:36 The next one is pytest InstaFail.

15:38 Modifies the default output so that failures show up immediately.

15:43 Right now, if you run pytest, if you just run it with no options, you get a bunch of dots for all your passes.

15:48 You will see the F for the fails, but you don't get the output right away, like what the traceback is.

15:54 And so if you really want to like start debugging before your test suite is done, InstaFail might be the thing for you to show your failures right away, the details of your failures.

16:04 Now for people that really think that pytest is already giving you too much information, pytest TLDR is hilarious, but it's actually quite useful and it will kind of remove some of the stuff from the pytest output, some of the boilerplate that comes at the top and bottom also just kind of reduces the output it's kind of nice and this is by by Freakboy. Kenneth I'm gonna get this wrong. Keith Russell McGee. Yeah that's it.

16:30 Now next one is pytest XDist. A lot of people think of the XDist as the the way to run all your tests in parallel you can run them on multiple processors. The surprising thing is you can also run them on not just multiple processors but multiple instruments or multiple machines you can have them spawn into other computers to run tests, which is really cool. But you can also do things like loop on fail and just perpetually, you can just have this thing just keep running. So that's pretty cool.

17:02 That is cool. Just periodically just say, "Tried it, tried it, tried it," until it turns green.

17:07 Yeah, especially if you're actively working on a fix, why not just have that pop up whenever it's done.

17:12 Nice.

17:13 The last two are pytest Django and Django Test Plus are both things that will help you if you're testing Django, which is not surprising that this came from Jeff Triplett because he's a Django guy.

17:26 Yeah, very cool ones.

17:27 I like these.

17:28 Although, I feel like you cheated, Brian.

17:29 I mean, we're supposed to cover like six things each show and here you've covered eight.

17:33 Eight great pytest plugins.

17:34 Come on.

17:35 Who would do that?

17:36 You know, I told you I was a sucker for link bait articles.

17:39 So, listicles.

17:41 Yeah, for sure.

17:42 Well, the next one I have is 11 new web frameworks.

17:44 Oh, and you're giving me a bad time.

17:47 Not for long, though.

17:48 No, I think it's great.

17:49 It's cool to touch on a bunch of those little things real quickly.

17:52 Now people know that I do a bunch of web development and I'm a fan of web frameworks.

17:57 And for a long time we had kind of the mainstays, Blast, Django and so on.

18:03 But recently, and I feel like two things, both the type hints and the async capable ASGI servers, those two things have created just like a blossoming of all these different types because they're like, well, if we got to rewrite it so that it supports async and to wait, or if we're going to rewrite it so I can use type in, so like grab stuff out of the query string, let's just go crazy and create all these new frameworks and well, 11 new ones is what we get actually more than that.

18:29 Cause there's, there's some that are not listed.

18:30 Some we've spoken about some we haven't spoken about, but I've heard of and some I've not even heard of.

18:35 So it's pretty cool.

18:36 I'll just go down the list really quick.

18:38 One of the things that's interesting, if you look at a lot of these frameworks, a lot of them are flask inspired and like, you know, the, you create an app and then you do app.route to define it and stuff like that.

18:50 A lot of them have adopted the Flask API without actually being Flask or coming from Flask.

18:56 So anyway, so the number one is Sanic, which is a web server framework meant to go fast.

19:03 And this one is mostly focused around enabling async and await.

19:07 That's pretty cool.

19:08 Probably the most widely used, at least in terms of other projects, for the ASGI, the async type of frameworks is Starlet.

19:18 So Starlette is cool, comes from, I believe, Tom Christie and folks who are involved with the Django REST framework, and it's a lightweight ASGI framework, which is great for high-performance async and await services, and you can either use it as its own web framework, or it's interesting as a foundation.

19:36 For example, Responder is built to top it.

19:39 I believe FastAPI may be as well.

19:41 - Yeah, I think so.

19:42 - Yeah, so there's a bunch of things that are derived from it, that's pretty cool.

19:45 And both those first two are Flask-like.

19:48 On Masonite, I had Joseph from the Masonite team on Talk Python not long ago, and it's interesting.

19:54 This is not an async and await framework.

19:57 It's like a standard framework like Flask or Django, at least at the moment.

20:01 But what makes it unique is it has this command line tool that lets you do things to the project called craft.

20:08 So the craft CLI is like what makes this kind of unique.

20:12 That was a really good episode with that interview.

20:14 And I liked the example of somebody bringing in good ideas from other languages and helping out the Python community with that.

20:22 - Yeah, thanks, I agree.

20:23 It was definitely fun to talk to Joseph.

20:25 So for example, like with a lot of these projects, you create the project and then you're on your own, right?

20:31 So, okay, well, I use maybe cookie cutter or some other technique to create the project.

20:36 And now I've got to write every little bit.

20:38 But with Masonite, you can actually go and say, and now add this model or go add, you know, these other things and it'll continue to like let you evolve it using these sort of starter cookie cutter type things.

20:49 So it's cool.

20:50 FastAPI.

20:51 If I was building an API these days, I would definitely definitely look at this fast modern framework for building APIs with Python three six based on type hints.

21:01 That's cool.

21:02 Responder.

21:03 This is from Kenneth writes, it's based on starlet and its primary reason for existing to bring the niceties both from Flask and Falcon over into a single framework.

21:13 That's cool.

21:13 Molten, which is a minimal extensible fast framework for building HTTP APIs with Python.

21:21 And it's sort of magic.

21:23 One of its magic things is it can automatically validate requests according to schemas.

21:28 So you're building an API, it takes a JSON document.

21:31 It can validate that by saying, this is what this method takes.

21:34 It takes an integer and it has this thing in the JSON document and so on.

21:38 It's pretty cool.

21:39 Jupronto, another one of the async and await frameworks.

21:42 This one's based on UV loop and Pico HTTP parser, so it's super, super fast.

21:47 Basically, its foundation is all C.

21:49 Klein, have you ever heard of Klein?

21:51 No.

21:52 Me either, but apparently it's a micro framework for Python, and it's got an incredibly small API like Bottle or Flask.

22:01 Speaking of Flask, there's Cort.

22:03 This is the one that's closest to Flask because it is literally a superset of Flask.

22:07 so compatible it even takes like Flask extensions and just runs those.

22:11 But the difference here is it adds async and await to Flask.

22:15 So if you have a Flask app, you do a find and replace the word Flask with court, and now you can use async and await in Flask.

22:21 That's pretty cool.

22:21 That's cool.

22:22 Blacksheep, we talked a little bit about that.

22:24 This one is inspired by Flask in ASP.NET Core.

22:28 One of its bits of magic is it automatically supports binding request values into variables either by convention or type annotation.

22:37 So I could have a view method and it takes a username and it takes a product ID and I could put a little decorator that says the username comes from, I don't know, a cookie or something and the product ID comes from the query string and it'll automatically go and pull those all together and just pass them as arguments.

22:56 That's pretty cool.

22:57 And finally, wrap this up, is Cyclone.

23:01 Another one I have never heard of, but it's a framework that implements the Tornado API and the Twisted protocol to bridge Tornado's elegant API and Twisted's event loop, enabling a vast number of protocols.

23:14 So very, very cool.

23:14 - Yeah, so unlike my list, you should not use all of these at once.

23:19 - No, yeah, your list would be great if you try to use all these at once.

23:23 Yeah, you're just gonna mess things up.

23:24 It's not good.

23:25 Like pick one or maybe two.

23:26 Maybe if you have APIs and you've got a web framework, but you probably don't even need to do that.

23:31 just pick one.

23:32 Or you could end up with like crashes and exceptions.

23:35 All sorts of error messages.

23:36 - Yeah, and one of the things, there's an application I'm thinking of doing that I assumed I would, I don't want to do go crazy with the micro, micro architecture, what are those things called?

23:47 - Micro frameworks?

23:48 - Not the micro frameworks, but like the whole bunch of microservices, that's it.

23:53 - Oh yes.

23:54 - However, things like FastAPI and stuff make it so easy to write the API part that I am thinking about doing a two-level thing of doing a FastAPI and then a web interface based on that.

24:08 It's just two services.

24:10 - It seems totally reasonable, yeah.

24:11 It seems fine.

24:12 And with Nginx and stuff, you can put it under the same domain and just put proxies to different parts of your app based on /api or not /api.

24:21 Be really easy. - Oh, cool.

24:23 - So the deployment's really easy.

24:24 - Well, it's a good thing I have friends like you.

24:26 Yeah. - Yeah, that's right.

24:27 Happy to help.

24:28 Next up, I want to talk about exceptions.

24:31 Like I am exceptional and you're exceptional.

24:33 We're all exceptional.

24:35 - Everyone's special, we're all snowflakes.

24:37 - Yes, this is a nice article that just came out this November called "Raise Better Exceptions in Python." So this is just sort of a, I guess, kind of like a public service announcement.

24:49 Actually kind of a nice article though, about when you're raising exceptions, you know, you throw an assert in sometimes to be like, I should really never get here.

25:01 But exceptions are not really unexpected things.

25:04 They're, they should be, your software should handle it.

25:07 It's really bad if your software's not handling exceptions at the top level.

25:12 However, often exceptions will happen if like you're raising from a trial, you try some stuff, you grab a value error or something, and then you raise a more meaningful exception.

25:24 That's a pattern that's often used.

25:26 The article's really pointing at, just don't put like f-strings with value stuff within your, just all within one string as a value error or any sort of, don't just like try to bundle it all together.

25:41 The point is, most exceptions, unless you've mucked something up in the init, most exceptions take a unlimited number of parameters.

25:49 So if you want to raise an exception with a whole bunch of values for your exception handler to be able to introspect and use, just put them in more parameters in the list of the constructor to the exception.

26:03 - That's super cool.

26:04 And I honestly, I didn't know about this.

26:06 This is great because, so the example is, if I raise a value error and the message is, the value is too small, it's like, okay, great.

26:13 So now what?

26:14 Maybe you can't even get back to like what the value was because the way it got passed around or it wasn't in a variable.

26:21 So what can you like report on that value?

26:23 could you log the value, whatever, right?

26:25 But if you can just say, here's the message, comma, thing one, thing two, thing three, thing four, and it just appears in the exception.args later, and you can deal with it in your catch clause.

26:36 It's great.

26:37 - Right, and some people will realize that, but not realizing that you can put them as parameters, but realize that you want to know the value.

26:44 So they'll try to put the value in a string, but that depends on the repper function or the stir function being valid.

26:54 And maybe that's the thing that blew up in the first place.

26:57 So, yeah. - Exactly.

26:58 It's simple, but it's gonna be really handy.

27:01 Yeah, love it.

27:02 All right, well, that's it for our main items.

27:04 You got anything extra you wanna chat about quick?

27:06 - Yeah, I did.

27:07 It showed up on your list, but I'm gonna bring it up anyway.

27:10 - So I was reading around on realpython.com and I came across this thing.

27:15 I don't know, there was this guy who was being interviewed.

27:17 It said, "Python community interview with Brian Okken." - Yep, I did that thing.

27:23 - Awesome, that's cool.

27:23 Yeah, so if people want to learn more about you, they can go check out this interview on RealPython, right?

27:27 - One of my favorite questions and answers is the question of how did you get into testing?

27:33 And really, I never did.

27:36 I've always been a software engineer, so that was a fun question to answer.

27:39 - That's cool.

27:40 - Anything else?

27:41 - Yeah, I got two more things I want to talk about.

27:43 One of them comes from Brett Cannon, sort of.

27:46 It also had you appearing on this little list of mine that I've got.

27:51 So Brett Cannon put out a poll, and the poll said, "If you typically keep your virtual environment locally with your code, as I do, like so, at the top level of your project folder, what do you call it?

28:02 Is it venv?

28:04 Is it .env?

28:06 Is it .venv?

28:07 Is it something else?" And so on.

28:10 And that's pretty interesting.

28:11 You can see the polls straight up, no .venv is what came up the most, and that's what what I've migrated towards these days, mostly 'cause some of the tooling works better than the hidden ones or .env.

28:24 But you've got some replies in here and all sorts of stuff.

28:27 But the one that caught my eye the most, and I think maybe you commented on it, was from Brian here, as in Brian Skin.

28:35 And he said, "I actually use the ability "to change the prompt name." So normally when you activate that virtual environment, it would just say parenthesis V-E-N-V, and you're like, okay, super, so something, somewhere in my entire computer is different about Python, but which, right?

28:53 But if you do --prompt equals, you can give it a name so that when you activate it, it says, you know, like Python bytes web app, or whatever it is you want.

29:03 - Yeah, I always use that.

29:04 - You do?

29:05 That's cool.

29:06 - Yeah, because otherwise all my virtual environments are named V and V, and that's boring.

29:11 - That's quite boring.

29:11 So yeah, it's pretty cool, and you can even pair that with like the read command and then take that.

29:16 So when you create the virtual environment, you could set up a script that'll ask, what do you want your prompt to be called?

29:21 And then it'll just put it into the virtual environment.

29:24 So when it activates it, it converts it over to that, which is pretty cool.

29:26 - So my request is, I haven't actually requested this yet, but I would like it to be the name of the directory that the virtual environment is in, not the VENV one, but the parent directory.

29:38 - Yes, that would actually almost always be the right answer, wouldn't it?

29:41 - Yeah, it's usually my project name.

29:43 That's what I want to know.

29:45 So that's what I'd like.

29:46 And then Al Swigert said, I use VENV.

29:50 Al said he uses .VENV for the reason that you shouldn't muck with it.

29:56 It's just there, but you shouldn't change it.

29:59 And I'm frustrated that he's right.

30:01 And I think I'm going to try using it with a dot from now on, or for at least a little while and see what I think.

30:07 - Yeah, the reason I like not having the dot is that when I'm in the finder, If I go over there, I can see, okay, this one already has a virtual environment set up.

30:16 I haven't been on this project.

30:17 It was in GitHub.

30:18 It's been like six months.

30:19 I come back to it, like, do I need to create a virtual environment or is there already one here I just go activate?

30:24 - In Finder?

30:25 You can't see the dot files?

30:27 - No, it hides them.

30:28 That's hidden.

30:29 - Oh, I guess they use command line more than anything else.

30:31 - Yeah, yeah.

30:32 So if you want to see them in Finder, you have to go into the dot folder and then you can say open dot or open that folder and then it'll like be half a grade out in Finder.

30:40 But if you just browse to a project, you won't know whether or not it has a virtual environment if it's a dot something.

30:47 - Okay. - Anyway, it's not a huge benefit, but that's why I kind of stopped using the dot, which I had been before.

30:51 - So for the subset of people that are on Macs, but don't like a command line.

30:57 - I also like the command line, but I don't exclusively use it, right?

31:02 - Okay, okay.

31:03 - Yeah, anyway, this is a whole long discussion about this, and I thought it was actually pretty interesting, all the threads there.

31:09 - Yeah, pretty cool.

31:11 All right, last thing, I told you about a new course last time, right?

31:13 - Yeah.

31:14 - Well, since then, I wrote another course and recorded it, and I think this one's gonna be really fun for people as well.

31:19 I wanted to write a course for people who are team leads, who are decision makers at their company, and they're trying to decide, or they're working with their team to decide, like, should we adopt Python, or is Python the right thing for this project or not?

31:33 So I wrote a course called Python for Decision Makers and Business Leaders.

31:36 if you need ammunition to help sell Python in your organization, or if you want to know maybe when it's not the best choice.

31:45 This talks to all those things.

31:46 And it also looks at the job market and hiring developers and all kinds of random stuff that I think those groups would care about.

31:52 So anyway, another course is coming shortly.

31:54 - That's really cool.

31:55 - Yeah, thanks.

31:56 - I might want to do an alternate course of Python for indecisive cogs.

32:00 (laughing)

32:02 - You might want to work on the name.

32:04 It might not attract.

32:06 You know what, I am an indecisive cog.

32:08 I will--

32:09 (laughing)

32:10 - Maybe.

32:11 - Yeah, yeah, maybe, maybe.

32:11 Anyway, it was a lot of fun to put together, and it'll be out pretty soon.

32:15 - Okay, you got a joke for us?

32:17 - I got something for you.

32:18 You can tell me whether it's a joke.

32:19 So this comes to us from Daniel Pope.

32:21 He didn't send it in, I just found it on the internet, and it was his joke, so I'm gonna, at least it came through him, so I'm gonna share it.

32:27 This one is about farm implements.

32:29 - Okay. - Okay?

32:31 What is a tractor's least favorite programming language?

32:34 - I don't know, what?

32:35 - Rust.

32:36 (laughing)

32:38 That's bad, right?

32:39 - Definitely a groaner, yeah.

32:41 But that reminds me, so how do you tell when a joke is a bad joke?

32:46 When it's fully groan?

32:47 - Oh, that's a good one.

32:49 I like it.

32:50 - Thanks a lot.

32:51 - Yeah, yeah, thanks for being here, Brian, it was fun.

32:52 - Bye. - Yeah, bye.

32:53 - Thank you for listening to Python Bytes.

32:55 Follow the show on Twitter @pythonbytes.

32:58 That's Python Bytes as in B-Y-T-E-S.

33:01 And get the full show notes at pythonbytes.fm.

33:04 If you have a news item you want featured, just visit pythonbytes.fm and send it our way.

33:08 We're always on the lookout for sharing something cool.

33:11 This is Brian Okken, and on behalf of myself and Michael Kennedy, thank you for listening and sharing this podcast with your friends and colleagues.

Back to show page