Transcript:
Hello, and welcome to another video In this video. Were going to be talking about pth files in Python and what they do. Um, to be honest. You probably won’t need them. For most things, um, but I figured I’d describe how they work anyway. Um, so to get started. I’m going to make a virtual environment and we’re going to start from there to look at how path files work. Uh, so the the first bit of information about path files is they are automatically run. Run, we’ll talk about the rules for how they get run in a bit, but they’re automatically run by the site module in Python. The site module basically parses pth files and performs side effects based on what they do and it will parse those only inside of site directories. So in a virtual environment, there’s a site directory in VM Lib. Well, it depends on your platform on windows. It’ll be in a different one. But the site packages directory is the one where I care about, and I believe modern versions of virtualenv actually ship with two different. Um, pth files. This might actually be from setup tools and we’ll actually look at the contents of these in a little bit, but I wanted to talk about how they function first. So there are two modes of path files. The first mode is the append things to systop path. Or is it prepend? I don’t remember, it’s either append or prepend, Um, and thing to Syspath. Um, this is well. Actually, I guess first off It ignores comments so you can have comments in there. So one ignore comments and comments Start with an octothorpe. The second is if it starts with an import line if it starts with imports, so things like python imports, it will exact that line, so this means that you can basically take a pth file and turn it into arbitrary code execution at Python. Start it if you want to. Otherwise, it will add that thing to system path, so otherwise add the thingsystempath and these pth files will have a number of lines in them. Let’s actually look at this one here. Yeah, so you can see here that it does import os this triggers. The pth behavior that this line should be treated as a as a line to be executed. And then anything after this so often you’ll see this hack where there’s an import, and then there’s a semicolon. And then there’s one line of a bunch of code in this case. It looks like it does. Var setup tools use disutils. It grabs an enabled flag here, and then it triggers an import. Uh, yeah, so that’s that’s how this particular one works, so it it’s looking for a particular environment variable and then if that’s available, it will import this disk. Util’s, hack and run this function on it. Um, you’ll note that a lot of these look really, really hacky. And that’s kind of. Because most of what pth enables is is hacky workarounds for stuff and this runs at the start of the interpreter. So if we were to write our own path file. VM flip python 3.8 site packages. Uh, me, dot pth. And let’s just say we did import OS and then print startup. Start up like that. Uh, so now when I run this python interpreter in this particular virtual environment, you’ll see well it, actually. Oh, that’s weird. Why did I get run twice? I actually don’t know why it got run twice. That’s weird, huh? Uh, is it because it’s interactive? No, just seems to run twice weird. Is that my prompt doing that? Nope, okay. Well, it’s running twice for some reason. I don’t quite know why, um, because I only put one pth file Weird. Maybe site is reloading in some particularly strange way. Uh, but anyway, because that line started with an import. Uh, if we look at this here because this line started with an import, it ran the rest of the code. Here, another trick that people often do because you know with one line of code. You’re kind of limited to one liners. Uh, what you can do is use exec and then pass a string into exec and then write multi-line code in there, so we did like exec, if true newline, um, print startup, uh, of course, we need single quotes because we’re nesting here, so this can be a way to work around the one line requirements here and again, like usually you don’t use exec in normal code either. So this is a piling another hack on another hack. Um, so you can see now. We still have that startup being printed here because we use exactly around there. So that’s the first mode If it starts with an import run the line, Uh, the second mode is to add something to system path. I’ve actually used this in the path or, in the past to make sure that a particular thing was installed. Um, this was before I knew about, like Editable, installs and Pip and like, and actually, the way Editable installs work is they use a pth file to reference a particular directory? Uh, but if I were to say, let’s say we make a directory here and we did. Vms Libs Python 3.8 sitepackagesmepth. And we’re going to add a path line, that’s. Uh, Temp explains why, and that will automatically make it end up on syspath. So now if we do import sys and look at systolpath, you’ll see that we have. Oh, and it does append. So when it adds to the syspath, it puts it at the end of it, So you’ll see that we have temp explains y on the end of there and so if I put modules in here, so let’s first show that. Yeah, let’s just add a module in y slash T5. Uh, you found me and if we take our pth file and delete this line and we run python3 and we do import t, you’ll see that that doesn’t work. Module is not found, But if we add temp explains y to our path here, we can suddenly import T and this is actually kind of how Editable installs work in python. I think I did a video about Editable installs so I will link that in the description. Um, if I didn’t, I’ll do one eventually, but and then it’ll be there eventually, but yeah. This is how this is! How edible installs work in python? So if I were to do Pip install dash e, I don’t know Pi upgrade, which is something in my in my home directory, you’ll see that inside Vmlib site packages, there should be an easyinstallpth and this includes a particular directory, which gets put onto syspath. So that way I can, you know, um, Import Pi upgrade, even though it’s not in my working directory, it happens to be upgradefile. It happens to be in that directory. That’s inside my home directory. But anyway, that is pth files. Um, I did want to show you one kind of sneaky thing that you can do with pth files or a sneaky thing. Oops, that I have done with Pth files and in order to demo that I’ve actually demoed this in other videos, so this isn’t exactly new, but we’re going to make a python 2 virtual environment and you’ll notice in Python 2 that if I try to make a file which prints an F string, something equals worlds printf another thing. If I run this with Python 2 there are no f strings in python 2 so you get a syntax here, but I made a terrible, terrible thing to then Activate Pip install future f strings. This is the package that I wrote and what future strings does is. It makes a little pth file, which does some magical stuff at startup such that. If you take this file and do Star Dash star dash coding future F strings, put the special little comment at the top of it and install this special little package now. Python 2 suddenly supports f strings, which is kind of neat and the way this works. Is my package installs this little? Oh, where is it? Oh, we need to be in Vienna too. We have two lib site packages. Uh, you’ll see there’s this AAA future f. Stringspath. Um, its names like this because there was a there was a, um, a proposal that path files would be run in order. I think they’re actually run an arbitrary order right now so, um. I was trying to make my thing load earlier than anything else. Um, but you’ll see that I have the same hack here where you know. I have an import statement at the beginning, and then I have an exact statement that tries to run some particular code here, and I’ll actually tab this out for you so you can see what is going on here. Oops, um, but it’s essentially trying to import future f strings. If that’s an import error, it will do nothing. Otherwise it will try and run this register function with this register function, does it? It installs a codec such that this source gets translated. Um, this is actually what the translated source looks like after future F strings has turned the F strings back into normal format calls. But anyway, that’s kind of an abusive pth, which is kind of cool. Uh, but anyway. Hopefully this was useful. If there are additional things, you would like me to explain. Leave a comment below or reach out to me on the various platforms. But thank you all for watching, and I will see you in the next one, you.