PEP 594, take 2: Removing dead batteries from the standard library

This is also mentioned in the PEP itself: PEP 594 – Removing dead batteries from the standard library | peps.python.org

Yes, thanks! I’m clearly just going blind. I’m sure I read straight
past that several times over the last year and completely forgot it
was in there, then later failed to even expect something so specific
would be covered within the text of the PEP itself.

Anyway, to wrap it up, this does seem to satisfy pip’s use case for
the cgi module quite nicely.

Should a reference to those be added to the Replacement column of Table 1?

There’s also @jmr’s legacy-cgi · PyPI fork (see upthread).

PEPs, once accepted, are historical documents. I would rather not keep updating that table to list alternatives as that’s potentially unbounded.

2 Likes

Questions about the fate of/a replacement for cgi.parse_headers() (and several other other cgi utility functions) seem to have been by a large margin the most asked-about item deprecated by this PEP on various threads. While the PEP contain a good chunk of useful information that helps address this, it is evidently not that easy to find deep in the body text, particularly for the important case of users coming from the cgi module docs, which (unlike the PEP, as you note) is the canonical, up to date documentation once the PEP is accepted.

Right now, the only mention in the docs of the deprecation, much less potential replacements, is just a note to see the PEP for details, with the link pointing to the top level of such. Therefore, users are going to be scrolling through the PEP to find more information and what they should do about it/replace it with, and the first thing they will come across mentioning cgi is the table, which indicates there is no replacement, nor does it link to the cgi section several pages further down containing that information.

Therefore, the docs should directly link to the relevant sections in the PEP and any stdlib alternatives, and the PEP table should link the respective subsections for accessible navigation. I’ve opened issue python/cpython#92611 and PR python/cpython#92612 to do the former.

If there are lots of people asking about deprecated modules / APIs,
this is a good indication to reconsider the deprecation.

1 Like

As discussed above, what people are overwhelmingly asking about are not the module itself, but replacements for a handful of small utility functions, some undocumented, that are part of CGI, and have drop-in or close to drop-in replacements as described in the PEP, can be replaced 1:1 by simply switching to the aforementioned legacy-cgi forward-port, or can even just be copied into one’s code.

An alternative might be to keep a “stub” cgi module around that only provides that handful of utility functions. They might be implemented by calling the recommended replacements. This would keep a lot of code working, and stem the tide of questions, without incurring much maintenance. We’ve done things like this before, I recall the string module. We can be flexible.

—Guido

8 Likes

We can change that by adding individual deprecation notes for the functionality in the docs as listed in the PEP.

I personally haven’t seen more beyond the initial discussions.

I don’t think we need to roll back, just update the docs. Nearly all of the utility functions can be done with the stdlib already, they just aren’t documented in the cgi module directly. They are in the PEP, I just didn’t think to copy the helpful pointers as this is just one of 21 modules I had to get done for b1. :sweat_smile:

4 Likes

Just to be clear, I didn’t mean to imply that there was a particularly large volume of people asking about these utility functions, but rather of the PEP 594 questions I did see, a high proportion of them were just people asking what to replace those utility functions with, and were happily answered by the section helpfully included in the PEP.

You mean linking the sections directly and mentioning/linking any stdlib replacements, like my PR currently does? Or are you suggesting going further (as mentioned as a possibility in the issue) and actually reproducing more details of the full sections in the docs?

I’d be in favor of adding a bit more information on/links to replacements than my PR currently conservatively does to the note, though I don’t want to overload it with detail given its positioning and keep it at least somewhat consistent. For CGI at least (which is a bit of a special case since the replacements span several stdlib modules, and are for utility functions rather than the module itself), we could add that as a dedicated section near the top of its docs. But ultimately, I can implement whatever we decide here.

:+1: With my current PR, we link the section directly from the deprecation notice (like we do for the others), but I can also add it as a section in the cgi docs if you think that would be helpful, so it can be maintained there.

The latter. For instance, for cgi.parse(), add an explicit deprecation there that says, “See urllib.parse.parse_qs as a replacement.” And I am only thinking about this for cgi since the research was already done as part of the PEP discussion by various folks.

It could also be a whole block at the top, but at least by doing it per feature that has a replacement you will get the suggestion if someone deep-linked into the docs.

1 Like

Ah, that makes a lot more sense, thanks—I really should have thought of suggesting that instead; I don’t know why I didn’t. I’ve updated the PR to incorporate that.

1 Like

Yes, I am also in a similar situation. Most modern network switches still use telnet for some service control and usually, you must control it from devices where you can’t easily install side packages.
Even if telnetlib is not ideal but it works well, and I can’t see a real good alternative.
Will be possible to make such lib as a separate pkg/fork? I am not sure but current Python license.

1 Like

@brettcannon @tiran
After the relevant Git commits happen, could you please add references to them into the PEP 594?

  • Commit(s) removing the dead batteries in Python 3.13.
  • Last commit in 3.12 before the branch 3.12 is deleted. (i.e. the latest official revision of the dead batteries)

I think these references could be important for historical purposes. Probably it would be a good idea to mention in the PEP that the references will be added.

The PSF license allows for forks. Only requirement is you keep the license with the code.

All deprecations have already occurred if that what you mean by “relevant git commits”.

I don’t know if I see how the commits would be useful in the PEP. Git will record the code changes and removals, so you can query git for the relevant commits. Otherwise I feel like recording every individual commit is mostly busy work for those doing the changes.

2 Likes

Yeah, and you can just git checkout the 3.12.x Git tags to get the latest revisions of the files (which really should be the same since at least the 3.11.0 release when they were deprecated, since typically deprecated modules don’t accept further non-critical changes), and use Git filter-repo if you want to preserve the history. Once they are removed, you can also search for the pull request that removed the files for the relevant module(s) to get the last commit before that, or for the commit itself, among other methods. Most of the work is pulling out the code and maintaining it, not finding the commit.

1 Like

I’m a bit sad to see telnetlib go. It is very useful for ad-hoc tasks.

Earlier I needed it, because I was in a minimal container in a cluster with no network tooling and only the Python runtime.

It is also very popular in the CTF-community where you often have to make a TCP connection to some service and challenge the program at the other end programatically. The read_until and interact are especially powerful.

Of course all of this can be done with plain sockets, but that is rather tedious.

1 Like

Yeah, I have a project which is an RFC-compliant Telnet server and
so needs a proper Telnet client implementation for regression
testing protocol-level option handling (which is proving to be a
pain to reimplement from scratch with simple sockets). I briefly
considered using telnetlib3 · PyPI as a
replacement for that purpose, but it too actually relies on
telnetlib from the standard library so that doesn’t solve anything
(and its development seems to have ceased around 18 months ago, so
I’m not all that hopeful it will be updated either).

At this point, I’m leaning toward using subprocess interaction to
orchestrate a more standard Telnet client executable, which is a bit
of a shame because my regression testing times will probably
increase by an order of magnitude.

1 Like

telnetlib is a single file with a very friendly license. Feel free to just copy it and integrate it into whatever project you like.

4 Likes

It could also be uploaded as a distribution package to PyPI, at which point all you would need to do is list/install it as a run time requirement for Python >=3.13, and it would work exactly as if it was in the standard library.

3 Likes