Markdown and others

There is a real need in rich text support in the stdlib, whcih cannot be satisfied by third-party libraries.

First, pydoc. Currently it only supports plain preformatted text. There are two problems:

  • Text is preformatted. Most of it fits in 80 columns, but there are many outliers, and they look ugly. Free flow would be beneficial – you write docstring so it look nice in the source code, and user see tem nice on their output devise. But we should take into account code samples, enumeration lists, etc.
  • There is no standard way to hightlight parameter names. Different docstrings use different styles: 'param', `param', *param*, PARAM and even :class:`param` is somebody copied docstrings from the module docunentation without cleanup.

Second, argparse. Generated parts in the help output became colorised in recent versions, but user supplied descriptions are still plain text. We need several types of hightlighting, free flow with extemptions.

There are many ways of user-friendly text markup which would solve this problem.

  • Plain Old Documentation (POD) – used for documentation in Perl since ancient times.
  • BBCode. Simple, widely used on forums. Similar to simplified HTML, but with square brackets, supports several types of highlighing, enumeration lists, etc.
  • Markdown. Widely used on modern programming sites, like GitHub.
  • reStructuredText. Extensible, but more heavy than Markdown.

reStructuredText is too heavy for stdlib, and its markdown is more verbose that in other formats.

Markdown parser and renderer was first non-toy project I implemented with Claude. It’s problem is that it was not formally standartized. The original Markdown specification was very informal and vague, the original implementation had many quirks, so other implementations vary in they capability and interpretation of corner cases. The closest thing to standartization was CommonMark which is used as base on GitHub and several other large providers.

My implementation passes all 652 CommonMark conformancy tests. It consists of the parser which produces an AST, and a bunch of renderers: plain text, plain text with overstrike (like produced by man and pydoc fot highlighting in less), plain text with ANSI sequences, HTML, Markdown (almost 100% round-trip), reStructuredText. It has CLI. The code is quite large, it would be in top10 or top5 of the largest single-file stdlib module (I converted it to package for better managabelity). If comunity is interested of inclusion of it in the stdlib, I will write a PEP. Otherwise I am not interesting in concurring with other third-party implementations.

POD and BBCode are much simpler. I have prototype implementations of them too. Anyway, pydoc and argparse will have pluggable formatters, but we need at least one non-plaintext implementation in the stdlib.

15 Likes

I’m a bit lost at what you are saying, I’m just rewording what I think you are getting at.
Are you proposing to write a PEP to standardize/unify docstrings and using the markdown “language” to write a docstring?

1 Like

My impression is that the proposal is to add a markdown parser/renderer to the stdlib, and use it in other stdlib modules like pydoc and argparse.

I’m not against the idea, but do we have the resources to maintain and support a full-scale markdown library in the stdlib? I feel like far smaller proposals have been rejected with the argument “it’s too much extra code to maintain”…

3 Likes

There are already several such modules available on PyPI, for example marko, python-markdown, and mistune. Combined, they have around 195 million downloads per month, which is actually quite small compared with the top PyPI packages. I do not see a strong reason to add another implementation to the standard library, and there does not appear to be much demand specifically for a stdlib implementation.

Another issue is the specification. Markdown parsing is messy because Markdown is not a single, clearly defined format, as you noted. Different users want different specifications and extensions, so the standard library would need to choose one interpretation and maintain it indefinitely. That seems like a poor fit for the stdlib, especially when mature third-party implementations already exist.

argparse also already implements some Markdown-like formatting features: it uses backticks to render text in colour, as documented. More limited formatting support could be added where necessary without introducing and maintaining a complete Markdown parser in the standard library. I am not convinced that either argparse or pydoc needs a complete CommonMark parser.

4 Likes

Well, the opening post of the thread is specifically about offering a standardized way for users to format text in pydoc and argparse. Whatever is used for those necessarily needs to be in the stdlib, no?

4 Likes

See my following paragraphs.

I think it should be on PyPI first so that users can play around with it. When we’re sure that it’s solid and no changes need to be made, then it can be added to stdlib.

There are multiple on PyPI already. But a third-party package isn’t relevant to the use-case here: inside pydoc or argparse. Hence the first sentence of the OP.

But I think the real debate here is not “should there be a stdlib module” but actually “should python standardize on using markdown internally”. As far as I’m aware, that’s been rejected whenever it came up in the past.

2 Likes

My point is that if a markdown implementation is going to be in the stdlib, it would be good to put it on PyPI first.

I can personally attest to the quality of python-markdown as I’ve made good use of it. But like all Markdown parsers, its (default) output is HTML. I’m not sure how that ties in with pydoc/argparse.

Besides the fact that “put it on PyPI” is a cop-out that applies to just about anything, I don’t think it’s a good argument for this particular case; iterating on a PyPI module for something intended to be tightly coupled with the CPython standard library is going to be a huge headache that is almost certainly going to drain the motivation of anyone wanting to work on it.

I think it would make more sense to first add this as a private module for use in pydoc and argparse, and then, if people seem to like it, we can eventually consider making it public. Keeping it private allows us to iterate and change things while also letting power users experiment with it, similar to what we’ve been doing with _colorize.

What would convince you? I find Serhiy’s arguments compelling. I’m convinced that there’s a concrete need for this internally.

8 Likes

I would prefer standardized docstrings but for that we do need to first agree on a rich text format, so I’m +1 on something. I don’t really care which one makes it in but I do prefer markdown because of familiarity. Having used languages that picked one docstring format, I was blown away by how integrated docstrings can get with editors and tooling and I sorely miss that in Python.

2 Likes

I can promise to maintain it in the stdlib for the rest of my life if I can, like I have maintained many other parts of the stdlib over the past 14 years. That doesn’t look very promising considering that I could be killed or lost the rest of my sight next week.

4 Likes

@Stanfromireland, I already mentioned these objections in my post. This is why I started this discussion instead of just writing a PEP and submitting a PR.

There are more than several such modules available on PyPI. Some of them are very basic and only support conversion of a subset of Markdown to HTML, others can support multiple incompatible Markdown dialects. Most of them are focused on conversion to HTML, which is not useful to us. I have no desire to add yet one to the bunch. The only reason of creating a new implementation from scratch is for including it in the stdlib.

We can probably be satisfied with supporting a subset of Markdown, but what subset? And how to call it? Calling it “markdown” would be not fair, other names like “simplemark” or “minimark” already taken.

If not Markdown then what? Would POD or BBCodes be more acceptable? I am fine with any which would allow to fix the current mess in the docstrings.

Note that I propose to make docstring format configurable by module (plain text by default). Third-party modules could use third-party formatters. But we need at least one for use in the stdlib.

2 Likes

I agree that a private helper module for pydoc and argparse would be reasonable. My objection is to using a complete CommonMark implementation for that purpose.

Serhiy has two key arguments, the need for free-flowing text with exceptions for code and lists, and a consistent way to highlight inline elements such as parameter names. Both seem worth implementing, but they require only a small subset of Markdown-like syntax.

CommonMark is a long and complex specification, and, as Serhiy noted, the proposed implementation would be among the largest modules in the standard library. That seems disproportionate when argparse ultimately produces terminal text with ANSI styling. It cannot meaningfully use many CommonMark features, such as images, raw HTML, link targets, link-reference definitions, block quotes, (both Setext and ATX) headings of various depths, etc.

pydoc also supports HTML output, so it could benefit from a broader subset. However, more advanced API-documentation use cases are already served by existing tools such as pydoc-markdown and Sphinx’s autodoc. We have previously considered generating Python’s documentation from docstrings, but ultimately decided against it.

Its HTML interface is also currently fairly limited and does not appear to be widely used. According to the documentation statistics, the pydoc documentation receives roughly half as many views as the calendar documentation.

I would therefore be fine with a limited private formatting helper. argparse already supports inline code, and extending that with features such as emphasis, lists, and text wrapping seems reasonable. I am not yet convinced that our internal use case requires a complete CommonMark parser and several general-purpose renderers.

Personally, I never used reStructuredText. IMHO it’s really unpythonic. I rather prefer the Google style, or at least the numpy one. But these are specialized for docstrings, so they don’t fit argparse.

I feel BBCode more verbose than md. Furthermore, people that in 2026 still uses BBCode or POD are rare. Personally, this is the first time I’ve hard about POD :slight_smile:

Apart the cited mistune, that is rated as # 317 on clickhouse, there’s markdown-it-py, that’s #99 today. Not something that can be easily ignored as irrelevant IMHO :slight_smile:

About an implementation, md or not, I suppose that if it’s simple enough maybe it needs no maintainance at all, once well-established. The stdlib is full of code that’s really simple and it was practically unchanged by dozen of years.

Not an expert of md, but this claim for me is very strong. I suppose that every consideration should take this claim very seriously.

Just my 0.0.2beta cents.

With rST already in heavy use for Sphinx-based CPython documentation and docstrings for external rendering in things like API documentation, embedding a MD renderer instead of rST seems like it has potential to create fragmentation between markup styles used within the project.

A lot of the Python-based projects I personally work on also adopted rST years ago precisely for the purpose of staying consistent with the CPython community’s own choice.

5 Likes

I like the premise. Coming from a person who regularly wont have internet access to do their work, i rely on pydoc, a lot. In other words, I regularly keep a second terminal open just do pydoc str or pydoc pandas.DataFrame.query or whatever.

However, short of this becoming the de facto standard for how the stdlib will start writing docstrings (which means re-writing the current), I think the ship has sailed and do not believe there will be a lot of use for this. There’s already too many existing docstring standards that go against this for it to ever become wide spread I believe.

I don’t understand well the use case. If a docstring or an argparse argument help uses bold (ex: using **bold** Markdown syntax), should I expect bold formatting when reading the pydoc/argparse help in a terminal or if I read pydoc in a browser (HTML)?

What if the terminal cannot display bold, would I see **item** or item? Python can be inspected in various UI. For example, IDLE is able to display docstring. Should I expect IDLE to support bold as well?

Does it mean that obj.__doc__ can now contain formatting? Or should we add a new attribute which includes formatting?

Markdown has more features than bold! It supports headings, paragraphs, line breaks, blockquotes, lists, images, code, horizontal rule, URLs and email addresses, etc. What if an UI only supports some features? Would the impacted source text be rendered unformatted or be completely omitted?

Should we check if docstrings can be parsed without any error/warning when building Python? I suppose that we cannot migrate (reformat) the whole stdlib at once, so if we do so, it should be done incrementally.

7 Likes

A big selling point of markdown is that raw markdown is nearly as readable as rendered markdown. So if anything, it’s probably the best rich text format for dumber terminals or anything that doesn’t support rich text to the fullest. That’s to say, I think it’s completely acceptable if a piece of software shows me **item** because it doesn’t support markdown.

5 Likes