We're sunsetting PodQuest on 2025-07-28. Thank you for your support!
Export Podcast Subscriptions
cover of episode #426 Committing to Formatted Markdown

#426 Committing to Formatted Markdown

2025/3/31
logo of podcast Python Bytes

Python Bytes

AI Deep Dive AI Chapters Transcript
People
B
Brian
Python 开发者和播客主持人,专注于测试和软件开发教育。
M
Michael
帮助医生和高收入专业人士管理财务的金融教育者和播客主持人。
Topics
Brian: 我推荐使用mdformat来格式化Markdown文件,它是一个功能强大的工具,可以帮助我们保持Markdown文件的风格一致性。它是一个Python项目,可以用来格式化Markdown文件,它遵循一定的风格指南,并支持插件系统来格式化代码块。它可以将下划线标题转换为#,##等标题,并对项目符号列表和有序列表进行标准化处理。虽然它将有序列表的编号都转换为1,但这可以提高代码的可读性,并减少git diff的次数。此外,它还支持插件系统,可以格式化各种编程语言的代码块。 Matthias Schöttle: (没有直接引语,但建议使用mdformat)

Deep Dive

Chapters
This chapter introduces MDFormat, a Python-based Markdown formatter. It discusses its features, including handling headings, lists, and code blocks, and compares its functionality with other tools like Blacken-Docs. The installation and use of MDFormat via Pipx, including its 'inject' function, are explained.
  • MDFormat is an opinionated Markdown formatter.
  • It's written in Python and can be installed via pipx.
  • It offers a plugin system for code block formatting.
  • Pipx inject adds packages to MDFormat's virtual environment.

Shownotes Transcript

Translations:
中文

Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to your earbuds. This is episode 426, recorded March 31st, 2021. I'm Michael Kennedy. And I'm Brian Ocken. And this episode is kindly brought to you by Posit Connect Cloud. Last time, Brian told you all about Posit Connect On-Prem, or your own cloud. And we'll talk about Posit Connect Cloud, a cool sibling offering, I guess.

If you are a social media person, you can find us on the social media things. You can find us on Mastodon and Blue Skies, the two main places we hang out. Those links are in the podcast player show notes right at the top. Also, YouTube, follow us on YouTube. There's the live link in the top that'll take you there. Please subscribe if you want to be part of the show. That happens.

Usually, right now, mod 7, every week, Monday at 10 a.m. Pacific time. Time zone changes, like daylight savings, screw that up a little bit for people. But anyway, that's when it is. We're going into summer, Brian. I don't know how consistent we're going to be, but we've been pretty good lately, right? Yeah. I think so. But we're people. We've switched if we need to. Yeah.

Exactly. And if you would like an artisanal handcrafted digest of an email form, we send a bunch of information that's not even in the show notes. And Brian sends that out to us, to all of us, including me every week. And I appreciate that, Brian. That's awesome. You know what else I appreciate? What? Our audience. When we say stuff, they're like, I know you said you don't know about a thing, but there are several things. Yeah. It's one of the benefits of having a podcast. Like last week,

You mentioned, what were you talking about? You were talking about... I was talking about something... Black and Docs. Yeah. Oh, no, no. It was Black and Docs. And it formatted all sorts of Markdown code blocks. Yeah. And I mentioned that it's cool to format the code blocks within Markdown files. But I kind of wanted an auto formatter for Markdown itself. Yeah.

And one of our listeners, Matthias, um, uh, got ahold of us and said, Hey, have you guys checked out? Um, let's see. Have you checked out MD format? So, uh,

MD format, so I did check it out this weekend. MD format is super cool, actually. I'm kind of in love with it. So it's just like any other RR format or you sort of, you can, and it's written in Python. I wasn't necessarily needing it to be written in Python, but it's kind of neat that it is. So you can check it out, see how it's implemented and open source.

But so after you install it, you run MD format on a file. So you just sort of run it. You can run it on a give it file names. You can give it a directory and it reformats your markdown. That's exactly what I wanted. But you have to kind of agree with its style because it is opinionated. And there is a warning that says, hey, we're going to we may change this. So if you really like the style that we're using right now, you might want to pin it.

which is a good idea. So the style, one of the things that I really wanted was the underline headings of Markdown with like you can have on this next line of a, you can write a heading and then on the next line you can write like three equal signs or more or three dashes and that means a heading or a subheading and I don't ever use that. I use the pound. Only animals use the three underscore. Yeah.

Well, I used to... I'm joking. Please don't write me. I'm joking. No, I often use the three lines for like the horizontal line. I do too. Yeah, I do too. Thank you. Anyway, so it switches it to the heading style I like. Bulleted lists, which are kind of cool. They alternate between dashes and asterisks because both of those work. But so like if you have embedded lists, it'll alternate. So it looks nice.

Um, but I mean, the output is all the same anyway, but it makes it look nice. And then, uh, there's standardization for ordered lists. However, this one tripped me up. I'm like, I get it. So what they do with ordered lists, if, if you have like one, two, and three, um, it converts them all to one.

And that seems weird and there's a reason around it. There's a reason is because it reduces the number of git diffs or when you change a version, if you move things around, the only thing that'll diff is the thing that you added or the thing you deleted, not all the numbering changes.

And that's nice. However, it's something I like to be able, it's less readable just right off the bat. So there is a flag. You can pass it, pass it dash dash number. And it doesn't do that. It just re or it just numbers them consecutively, which actually also kind of nice because if you move things around,

instead of having to go through and retype all those numbers, you can just do the empty format with number. So why would you put a 1, 4, 7, 2, 3, 5, 6,

Yeah. Well, I mean, you've done that. I'm sure like you're moving things around and now they're wrong. So I'm excited about that. If I was writing in plain and a completely unassisted text editor, I might write just one dot, one dot, one dot. And so you have the ability to reorder it. However, if you're using sort of tools that understand Markdown, when you hit enter, it will increment that like Typeora and Alphamore.

IA writers and others. Right. So it's going to number it automatically for you. And if you want to reorder it, then it's broken. And so this is really nice. I like it. Yeah. And then you could, of course, since it's a command line tool, there's probably a hook already written for a commit, like a pre-commit hook, but you could write your own easily or just use it or use it, put it in CI. Yeah.

So, uh, so I like, this is already enough and, and I'm, I'm going to use it right away just for this, but it doesn't stop there. You can also mark down, you can convert your code. So, um, you, it will handle, uh, um,

auto formatting your code blocks also and for that it has a plugin system because it doesn't know how you want it formatted so uh there's a plugin for black and one for rough and a bunch of others that you can um so there's a web one so you can like uh format your javascript or css or html within your so this is pretty cool that you can have all these different plugins to uh

convert your code blocks also. Anyway, I'm kind of in love with this. I like it a lot. That is very nice. Can you go back to the homepage of this thing? I want to point out something interesting here. Okay. Yeah, go to the top. So it says, here's how you install it. Pipx install MD format. You could easily do UV tool install MD format, right, Ryan? Yeah.

But see the inject, that inject, pipx inject, MD format, MD format dash GFM, I'm guessing GitHub Markdown format. What does inject do? Yes, I'm like, what is that? And so while we were talking, I did a little research and

And what it does is it will add additional packages, but to the same virtual environment, the dedicated virtual environment that PipX creates for the tool. So PipX will create a tool for MD format and then also install these other things. Now, we talked UV up so much and we're going to come back to it somewhat as well. But as far as I can tell, it doesn't have such a feature. You've got to create a virtual environment and then install it. Hmm.

You might be able to do a run dash dash with and make a really long complicated thing, but there's no clean. So how about that? Pip X for the win a little bit, which is not usually what we're saying. I like Pip X, but that's not normally what we say. Yeah, no. Cool.

All right. All right. On to the next, which is pre-commit UV. I told you that we're coming back to it. Here it is. So despite it having no description, it's in the GitHub repo, which I could probably use. The idea is...

to make, to bring the advantages of UV to pre-commit and get pre-commit hooks. So pre-commit is a project by Anthony Satili and the idea is it's like a multi-language runner happens to be written in Python but it's not about

about Python per se, that will run pre-commit hooks. So instead of saying, well, you want to use a pre-commit hook written in Rust, you've got to install and manage Rust and all that. You just kind of like do it its way. You just pre-commit it, right? Yeah. So that uses pip and it has all the bonuses, but also the drawbacks of using pip.

So you can pipx install pre-commit, and then here we are again, pipx inject pre-commit-uv. And so then when it does its thing to install and set up a new machine with the pre-commit hooks or update it or whatever, it's going to use uv, and they did a...

Oh, go back up a look for a second. There's the UV version, UV tool install pre-commit with. So that's like the inject. Yeah, I think that would do it. I think that's the way that you could probably pull that off. But I think...

You know, maybe that will do it. I thought you could only do that with run, but if you can do with in the install, then, you know, there you go. That's the UV way. Awesome. Okay, so we're learning stuff, but they're running a timed example of run one thing and then the other says run

I tried pre-commit install hooks. I don't know what the hooks were, but some set of hooks, install them with raw pre-commit and then pre-commit UV install hooks. And the difference here is with regular pre-commit, it took 54 seconds plus or minus eight around. With pre-commit UV, it took 41. However, that's the first time.

You do that on a machine that involves those dependencies, right? If you hit it again, like if pre-commit UV has to build something from source, it's going to be super cached again, right? Yeah. So I think, well, it does say 10 runs. Interesting. But I think it's doing it with like an isolated environment or something like that. Anyway.

If you're already using UV and you use pre-commit hooks, check it out. There's some configuration options you can pass with environment variables and so on. Nice. Once installed, it will use UV out of the box. However, you can disable that and then require you to run it with, I think, the dash command, the pre-commit, pre-dash-commit-UV. There you go. Cool. Cool, cool. You know what? Before we move on, I

I do want to tell people about our sponsor. So let me tell everyone about Posit and Posit Connect Cloud. So this episode is brought to you by the folks over at Posit. They're originally known for building RStudio and Shiny, and they've created a bunch of tools for the Python community. For example, Shiny for Python. I had Joe Chung on to talk about that.

and a whole bunch of infrastructure things for Team Python. So I want to tell you all about PositConnect Clouds.

Cloud, which is a cool cloud hosted, they manage it pass that manages your data science platform. So it simplifies deployment of data applications and documents. And it might be the most simple way to share your Python content as a data scientist. So all you do, three steps, you put your code into a public or private repo. And then if it's

private, you can give it access to your private repo, for example. It's public. Obviously, don't worry about it. Then you basically point PositConnect Cloud at that repo, and you click deploy. That's it. And it's off and running, and it'll clone your code repo, build your asset, and host it on an online URL that you can share. And best of all, it will update your app.

continuous delivery style. So if you push new stuff to the branch that you've told it to publish, it'll just go, ah, there's a new version of your data science thing. Let me update the one out on the cloud that you're sharing with people at your company or researchers or however you're sharing it. And any GitHub user can create a free PositConnect cloud account. So you don't have to do a trial or anything like that. You can just use it for free and try it out. And if you need fast updates,

lightweight way to share your data science content, try PositConnect Cloud. And as Brian told you last week, if you need these features, but you need them private, then you can try the on-prem version PositConnect. So if you work on a data science team where moving fast matters, you owe it to yourself and your organization to check out PositConnect Cloud. Visit pythonbytes.fm slash connect dash cloud. See if it's a good fit. It's pythonbytes.fm slash connect dash cloud. The link is in your podcast player show notes or

Right at the top, thank you, Deposit, for supporting Python Bytes. Yes, very much. Thank you. So now I'd like to talk about a couple of PEPs. So these are pretty quick topics, but there's some changes to the PEPs. So PEP 5, 7... No, I got that wrong.

PEP 758 is allow, accept and accept star expressions without parentheses. This was accepted as of looks like the 14th of March. And so looking through here and I kind of I

I guess I just like, I don't really think about it too much, but if you, if you have a try accept block and the accept can accept a lot, like you shouldn't have just accept with nothing. You should have accepted with which types of exceptions. That's right. You should put pass it there. Try accept pass is the best way. Try pass. Try it. Just skip the accept.

Anyway, so the if normally right now, if you have several exceptions that are allowed, you put them in parentheses. Now, this is just a small little language change that says you don't actually have to put the parentheses there or you won't in the future.

And I'm all for this. This is, this looks great. It seems like a slam dunk and I'm sure that's why I got it. One of the reasons why it got accepted is that just in the future in Python 3.14 and beyond, you won't need the parentheses. That's really it. Kind of nice. So, however, you know, so like four years from now, we can start using this if...

Because you'll, you know, once you stop supporting all other pythons below three point, you know, whatever, for packet. So for package maintainers, this is future news for normal humans. This is news for this year. So anyway. Yes.

Um, the, another pep that is not accepted yet. It's in draft form in, I just want to highlight it because I think it's a good idea is pep seven 81 make type checking type, make type checking a built in constant.

And this, the idea around this is I'm noticing as I'm using typing more is that occasionally I need to, like if you're gonna import something, like if I only import something just so that I can import the type, so that I can put the type of something, you know, the type of a class or a type of a return value or whatever in a function import or a function statement or whatever, a variable type,

I don't really need the type, the import for running. I just need it for type checking because that's to get the type. So there's, there's that, but it does cause some, uh, the M, but if you do that, the import, like, um, you know, is running all the time anyway. So, but you always have to, to say like, you know, from typing import type checking what to tell whether you're type checking or not.

It's just basically just saying that we, that we won't have to do this anymore. So instead of, oh, where's the, where's the actual spec? Yeah. So we'll have like, just have it be a constant is all. So anyway. Yeah, that's great. Part of a part of the built-ins, right? Just, you don't have to import it. You can just use it like you can print another. Yeah.

Yeah. Yeah. Like underscore Dunder type checking or something. So yeah. Anyway, I love it. I think we should have it. It'll be good. Oh, while, while I was here though, another thing I want to highlight is I was like looking around. I'm like, well, what else is there? And there's an index by category here at pepstoppython.org. And it's really kind of great. This is a really well put together web page about how to navigate peps. Cause there's a lot of peps, right?

So I was like, well, I'm currently looking for ones that have been accepted. So you can pop down and say accepted peps. And then you can look at what the version number, which, which they're, what version they're coming in or which they came in and stuff. So really nice, nicely done, easy to navigate website. So good job. Very nice. Anyway, that's it for that. I wonder if that's available in a structured data way. Is there like,

a JSON that represents some data or something. There is an API, but I don't know if it applies to that. I'm sure somebody will tell us. Yeah. Nine point chat GPT at that table and have it do it. Yeah, JSON metadata. Yes, indeed. All right. On my final item, Siri. Sorry, anybody's phone has started? I just pronounced the same, S-E-R-I-E. I guess that would be the same. Sorry.

So this is for people who are more terminal-like but need a better Git experience. So it's a rich Git commit graph in your terminal. So there's a little picture here.

open the image and look at it bigger, I suppose. But basically, it gives you the entire branch tree and something that you can navigate around and interact with, kind of like Rich, and lets you do things like search all branches over the commit log and browse through tags and all kinds of stuff. What do you think, Brian? I love this.

I mean, can you try it right away? Yes, I know. This looks so cool. It looks really cool. I totally want to start like, okay, that's cool. Now, it's written in Rust, so it's not a Python thing. It is a tool for Python people. Although I feel like we have a certain kinship with Rust people. It's not really...

written in Python, but that doesn't matter because you just type the command and you get better understanding of your Python and other code, right? Yeah. So, yeah, there's not a whole lot more to say about it. You can install it with Homebrew. You can install it via Cargo. Other ways, you can even build it from source. But, yeah, it's a pretty simple tool, but it's super nice. I'll have to check it out. Please be available on Windows.

Because that's where I really need it. Yeah, for work, right? Yeah. I imagine it is. I mean, Rust is pretty cross-platform. Rust and fingers. Remember to try it in Windows Terminal. Don't do it in cmd.exe. Don't push your luck. Windows Terminal? Yeah, it's like the much nicer. PowerShell? Yeah.

PowerShell is the thing that the shell that runs, but Windows Terminal is the app that hosts it and it has much better compatibility. Like for example, Rich works a lot better in Windows Terminal than it does in CMD and so on. Get it from the Microsoft apps

app store. How am I only learning about this now? It's really nice. It's real. And you can do like dropdowns and say, run this, this tab in PowerShell, run this one and get back from this one. And I don't know what you call DOS, whatever that is. I'll report back because I've spent my entire career pretending that I don't use a Windows machine at work, but yeah. Yeah. Yeah. You could even, I think open a particular tab as a Windows,

Windows subsystem for Linux and Voodoo type deal. So pretty cool. Nice. Okay. Tangent. Extras. We're on to our extras if you have extras. I have no extras today. Well, you're lucky that I do.

Oh, and before we jump on, Will, who I just released a TalkPython episode about high-performance algorithms, algorithms for high-performance terminal apps, and we talked a lot about this, says Windows Terminal will be the default in future Windows releases. Good times for terminal users and, in the case of Will, terminal framework builders, 2E builders. I wonder if you need term colors for Windows Terminal. So anyway, okay. I don't know.

I don't know, but let's see what else I have extra hours on. Okay, not the picture. So I wrote a blog post. I was just going to link to the place that I'm using, but I wrote a blog post called Sunsetting Search. And Brian, I used to use search so much. I've talked about Kagi and how much I love Kagi and all those things, right? A couple of years ago. And I was probably doing a couple thousand searches per month in there. Yeah. I looked last month across Microsoft.

My three computers that I use and my multiple browsers on each one and my phone and my iPad, I did 211 searches. How about that? You probably did more, but okay. Kaggy keeps track like in your account because they charge you by it. Oh, okay. So I went and looked at my Kaggy stats and said, you did 211. Why is it going down? Because I'm using AI to answer so many of these questions these days.

And so many with the pro chat GPT and stuff, it's just like, I could open up a bunch of tabs and do a research project myself, or I could, hey, go do some deep research on this and come back to me with references to where you found the answers.

summarize it. And anyway, I think it's, I just thought it was really wild. And so I am switching over to something called Startpage. Have you heard of Startpage? Yeah, I've been using it for the last couple months. I love it. Do you like it? Yeah, it doesn't have, I'm gonna sound like a, like an old guy or something. I like that it just gives me search results and doesn't give me AI results at the top. Yeah, yeah, yeah. It's really good. And I'm

I super love it. You can go and you don't even have to have an account. You can just basically set it up to not show all of its ad stuff somewhere. I don't know. I was fooling around with that. But I think it's great. It's basically private. Privacy preserving doesn't pass your information on along to Google, but it's basically the Google index. There's some places that say don't show the ad. Is it appearance, general? I don't know. Somewhere here. It says don't show all the marketing goo.

But if you go and search there, it will sort of disintermediate your Google searches, I guess. And it has like little visits privately, right? You can say if you do some kind of search, like how do I get out of here? Let's go back here. If I search for like Python podcast or something, it'll let you run it in like a little VM iframe that doesn't even let it know where you came from. It's pretty interesting, this thing.

I think it's pretty interesting. So it's using the Google index though. Yes. And the way that it funds itself is it also has ads. Yeah. However, notice I have no ads in mind because I run an ad blocker and it takes them out. So it's even better. See, I'm running it with ads and it's just not annoying to me. I'm like, I'm okay with that. Yeah, that's good. But because they're not tracking it, they're not tracking stuff. So yeah, I mostly hate the, the tracking and the retargeting and all that. Yeah. Yeah.

So yeah. Oh, good. One of the curious things I've got about this is I wonder, so I know that Google, that's sort of a tangent, but I know that Google like worsened their search like recent, I don't know, several years ago so that people would have to go through more pages. So they see more ads. Yes. Terrible. Uh,

I wonder if that's the case with the... Did they do that mucking about in the index so that StartPage is using the mucked up index? Probably. But it doesn't have as much of that...

immediate, like not so much of the answers. So if you did a search on straight Google, you get, and here's a whole bunch of videos and here's a bunch of like Q and a stuff we found. And like, that's half of it. And then you got the ads of which are a third of it. Then like way down at the bottom somewhere, you get a little bit of something to start. And I don't see any of that stuff there. Yeah. Or just the AI answer at the top. I think that, um,

A lot of that's killing a lot of ad revenue for actual or actually traffic to people that are actually writing about interesting stuff. I know, exactly. Kaggy does have a very interesting approach on whether to put the AI answer at the top. And that's if your search on Kaggy ends in a question mark, it'll put an AI answer.

if the same search without a question mark on the end goes there, there's no answer shown. Interesting. Yeah. I believe that start page does have an answer sort of thing, but you got to turn it on or something. I'm not sure. I feel like I've seen it, but anyway, since I'm not using search so much, I thought, well, let me search around and see what else I can find. And yeah, start page. It's interesting that you're,

that you're using that as well. Yeah. Um, yes, I think it gets, it just got turned on by me. I didn't think I found it. I think Vivaldi turned it on or something, but I don't know. Interesting. Okay. Yeah. I'm a fan, but all right. Cool. Yeah. Cool. Uh,

One final extra, Rhett Turnball, who's been on Talk Python to talk about building Mac apps with Python, sent us, so he knows something about building some frameworks and stuff. He says, remember I said, Brian, you can just uv-tool install rough and then you just have rough and don't have to put it into your requirements file or your uv-lock or wherever those things go. He says, good advice. However, you might want to actually put it in your virtual environment. That way it becomes part of your pinned database

dependencies so that people who are contributing to your project use the same version of rough if they don't already have that exact version and you don't get like flip flop of get changes because something changed about rough itself or the rules defaults or something. Yeah. Yeah. I totally agree. And that's one of the fun things that we have in talking about Python tools and everything for everybody is that the advice for solo developers is different than the advice of people that work on teams. So yeah.

Teams even being open source teams. Yeah, exactly. Exactly. All right. Shall we make a joke? Sure. Let's see how I did today. This one, I thought of you, Brian, when I wrote this, because I thought this is all about the C developers or even the C sharp or C plus plus. I'm sure there's some many other languages that have this, but C in particular came to mind. This has to do with a genie and this software developer like person comes along and he's

stumbles upon the golden genie-shaped little vase or whatever the heck it is, and rubs it as you do, out comes the genie. He says, I will grant you three wishes. Okay. But before you can, the genie interrupts. The rules are you can't wish for death or life or make people fall in love. And you can't wish for more wishes. That's usually the escape hatch. You have three wishes. Like first wish, I wish for a million wishes. Now let's start. Okay.

Can't do that. Can't wish for more. So I can wish for fewer wishes? Why would you wish for that? I think there's a bug in this cartoon, so I'm going to fix it. I wish to have negative one wishes. Fine. Granted. You have 4,295,967, sorry, 4,295,967,295 wishes left.

Stack them underflow. Yeah, it's an unsigned int they were storing it in. Yeah, I think you're right. It has a bug because the cartoon has zero and zero should be valid for any numbering system. Yes, it should, but minus one. Yeah.

And then if you go to the thread a little bit further down in here, there's a lot of pretty good comments. Almost no one caught that it needs to be negative. Like underflow, like zero doesn't underflow people. But someone pointed out, the hat pointed out, you need to upgrade the 64-bit genie. There's some kind of like animated crazier, crazy game with like lightning striking it. That's the 64-bit version. That's funny. It would just give you even more wishes if you underflowed that though.

Yeah, so do you remember the first time you heard, you probably don't, and I don't either, but early on learning these, like, the genie in the lamp stories, I was, like, thrown because, like, one, that didn't look like any lamp I had in my house. And why are you rubbing the lamp? That seems weird. Why would somebody do that? Yeah.

I guess it comes from a time when you've got more time on your hands. Well, no. Yeah. Well, it's also like it's an oil lamp. They look different. And also, it was probably brass. And now that I'm an antique dealer, yeah. You got to polish it or something, right? Yeah. Yeah. Exactly. I don't know that I own a single thing that's brass. I got a lot of crap around my house, but I don't know that any of them are brass. But who knows? Really? Yeah.

Anyway, I thought that was a pretty good joke. What do you think? It was good. I like it. Yeah. Yeah. As a C person, you have to approve. Except for the bug. Except for the bug. Except for the bug. They didn't test it. No, they certainly did not test it. We'll come back to that next week somehow, I'm sure. Yeah. All right. Well, thank you, Brian. Thank you, everyone, for listening. And see you all later.