PEP: 594 Title: Removing dead batteries from the standard library
Author: Christian Heimes \<<christian@python.org>\> Discussions-To:
<https://discuss.python.org/t/pep-594-removing-dead-batteries-from-the-standard-library/1704>
Status: Draft Type: Standards Track Content-Type: text/x-rst Created:
20-May-2019 Post-History: 21-May-2019

Abstract
========

This PEP proposed a list of standard library modules to be removed from
the standard library. The modules are mostly historic data formats (e.g.
Commodore and SUN file formats), APIs and operating systems that have
been superseded a long time ago (e.g. Mac OS 9), or modules that have
security implications and better alternatives (e.g. password and login).

The PEP follows in the foot steps of other PEPS like
`3108`{.interpreted-text role="pep"}. The *Standard Library
Reorganization* proposal removed a bunch of modules from Python 3.0. In
2007, the PEP referred to maintenance burden as:

> \"Over the years, certain modules have become a heavy burden upon
> python-dev to maintain. In situations like this, it is better for the
> module to be given to the community to maintain to free python-dev to
> focus more on language support and other modules in the standard
> library that do not take up an undue amount of time and effort.\"

The withdrawn `206`{.interpreted-text role="pep"} from 2000 expresses
issues with the Python standard library unvarnished and fortright:

> \"\[\...\] the standard library modules aren\'t always the best
> choices for a job. Some library modules were quick hacks (e.g.
> `calendar`, `commands`), some were designed poorly and are now
> near-impossible to fix (`cgi`), and some have been rendered obsolete
> by other, more complete modules \[\...\].\"

Rationale
=========

Back in the early days of Python, the interpreter came with a large set
of useful modules. This was often referred to as \"batteries included\"
philosophy and was one of the cornerstones to Python\'s success story.
Users didn\'t have to figure out how to download and install separate
packages in order to write a simple web server or parse email.

Times have changed. The introduction of the cheese shop (PyPI),
setuptools, and later pip, it became simple and straightforward to
download and install packages. Nowadays Python has a rich and vibrant
ecosystem of third-party packages. It\'s pretty much standard to either
install packages from PyPI or use one of the many Python or Linux
distributions.

On the other hand, Python\'s standard library is piling up cruft,
unnecessary duplication of functionality, and dispensable features. This
is undesirable for several reasons.

-   Any additional module increases the maintenance cost for the Python
    core development team. The team has limited resources, reduced
    maintenance cost frees development time for other improvements.
-   Modules in the standard library are generally favored and seen as
    the de-facto solution for a problem. A majority of users only pick
    third-party modules to replace a stdlib module, when they have a
    compelling reason, e.g. `lxml` instead of `xml`. The removal of an
    unmaintained stdlib module increases the chances of a
    community-contributed module to become widely used.
-   A lean and mean standard library benefits platforms with limited
    resources like devices with just a few hundred kilobyte of storage
    (e.g. BBC Micro:bit). Python on mobile platforms like BeeWare or
    WebAssembly (e.g. pyodide) also benefit from reduced download size.

The modules in the PEP have been selected for deprecation because their
removal is either least controversial or most beneficial. For example,
least controversial are 30-year-old multimedia formats like the `sunau`
audio format, which was used on SPARC and NeXT workstations in the late
1980s. The `crypt` module has fundamental flaws that are better solved
outside the standard library.

This PEP also designates some modules as not scheduled for removal. Some
modules have been deprecated for several releases or seem unnecessary at
first glance. However it is beneficial to keep the modules in the
standard library, mostly for environments where installing a package
from PyPI is not an option. This can be corporate environments or
classrooms where external code is not permitted without legal approval.

-   The usage of FTP is declining, but some files are still provided
    over the FTP protocol or hosters offer FTP to upload content.
    Therefore `ftplib` is going to stay.
-   The `optparse` and `getopt` modules are widely used. They are mature
    modules with very low maintenance overhead.
-   According to David Beazley[^1] the `wave` module is easy to teach to
    kids and can make crazy sounds. Making a computer generate crazy
    sounds is powerful and highly motivating exercise for a
    nine-year-old aspiring developer. It\'s a fun battery to keep.

Deprecation schedule
====================

3.8
---

This PEP targets Python 3.8. Version 3.8.0 final is scheduled to be
released a few months before Python 2.7 will reach its end of lifetime.
We expect that Python 3.8 will be targeted by users that migrate to
Python 3 in 2019 and 2020. To reduce churn and to allow a smooth
transition from Python 2, Python 3.8 will neither raise
`DeprecationWarning` nor remove any modules that have been scheduled for
removal. Instead deprecated modules will just be *documented* as
deprecated. Optionally modules may emit a `PendingDeprecationWarning`.

All deprecated modules will also undergo a feature freeze. No additional
features should be added *unless* python-dev agrees that the deprecation
of the module is reverted and the code will not be removed. Bug should
still be fixed.

3.9
---

Starting with Python 3.9, deprecated modules will start issuing
`DeprecationWarning`. The [parser](#parser) module is removed and
potentially replaced with a new module.

All other deprecated modules are fully supported and will receive
security updates until Python 3.9 reaches its end-of-life. Python 3.9.0
will be released about 18 months after 3.8.0 (April 2021?) and most
likely be supported for five years after the release. The estimated EOL
of Python 3.9 is in 2026.

3.10
----

In 3.10 all deprecated modules will be removed from the CPython
repository together with tests, documentation, and autoconf rules.

PEP acceptance process
======================

3.8.0b1 is scheduled to be release shortly after the PEP is officially
submitted. Since it\'s improbable that the PEP will pass all stages of
the PEP process in time, I propose a two-step acceptance process that is
analogous to Python\'s two-release deprecation process.

The first *provisionally-accepted* phase targets Python 3.8.0b1. In the
first phase no code is changed or removed. Modules are only documented
as deprecated. The only exception is the [parser](#parser) module. It
has been documented as deprecated since Python 2.5 and is scheduled for
removal for 3.9 to make place for a more advanced parser.

The final decision, which modules will be removed and how the removed
code is preserved, can be delayed for another year.

Deprecated modules
==================

The modules are grouped as data encoding, multimedia, network, OS
interface, and misc modules. The majority of modules are for old data
formats or old APIs. Some others are rarely useful and have better
replacements on PyPI, e.g. Pillow for image processing or NumPy-based
projects to deal with audio processing.

  ------------------------------------------------------------------------------------------------------
  Module                  Deprecated   To be     Added in    Has            Replacement
                          in           removed               maintainer?    
  ----------------------- ------------ --------- ----------- -------------- ----------------------------
  aifc                    3.8 (3.0\*)  3.10      1993        **yes          \-
                                                             (inactive)**   

  asynchat                **3.6**      3.10      1999        **yes**        asyncio
                          (3.0\*)                                           

  asyncore                **3.6**      3.10      1999        **yes**        asyncio
                          (3.0\*)                                           

  audioop                 3.8 (3.0\*)  3.10      1992        **yes**        \-

  binhex                  3.8          3.10      1995        no             \-

  cgi                     3.8          3.10      1995        no             \-
                          (2.0\*\*)                                         

  cgitb                   3.8          3.10      1995        no             \-
                          (2.0\*\*)                                         

  chunk                   3.8          3.10      1999        no             \-

  crypt                   3.8          3.10      1994        **yes          legacycrypt, bcrypt,
                                                             (inactive)**   argon2cffi, hashlib, passlib

  email.message.Message   3.3          3.10      2001        yes            email.message.EmailMessage

  email.mime              3.3          3.10      2001        yes            email.contentmanager

  email.policy.Compat32   3.3          3.10      2011        yes            email.policy.EmailPolicy

  formatter               **3.4**      3.10      1995        no             \-

  fpectl                  **3.7**      **3.7**   1997        n/a            \-

  imghdr                  3.8          3.10      1992        no             filetype, puremagic,
                                                                            python-magic

  imp                     **3.4**      3.10      1990/1995   no             importlib

  macpath                 **3.7**      **3.8**   1990        n/a            \-

  msilib                  3.8          3.10      2006        no             \-

  nntplib                 3.8          3.10      1992        no             \-

  nis                     3.8 (3.0\*)  3.10      1992        no             \-

  ossaudiodev             3.8          3.10      2002        no             \-

  parser                  **2.5**      **3.9**   1993        **yes**        ast, lib2to3.pgen2

  pipes                   3.8          3.10      1992        no             subprocess

  smtpd                   **3.4.7**,   3.10      2001        **yes**        aiosmtpd
                          **3.5.4**                                         

  sndhdr                  3.8          3.10      1994        no             filetype, puremagic,
                                                                            python-magic

  spwd                    3.8          3.10      2005        no             python-pam, simplepam

  sunau                   3.8 (3.0\*)  3.10      1993        no             \-

  telnetlib               3.8 (3.0\*)  3.10      1997        no             telnetlib3, Exscript

  uu                      3.8          3.10      1994        no             \-

  xdrlib                  3.8          3.10      1992/1996   no             \-
  ------------------------------------------------------------------------------------------------------

  : Table 1: Proposed modules deprecations

Some module deprecations proposed by `3108`{.interpreted-text
role="pep"} for 3.0 and `206`{.interpreted-text role="pep"} for 2.0. The
*added in* column illustrates, when a module was originally designed and
added to the standard library. The *has maintainer* colum refers to the
[expert index](https://devguide.python.org/experts/), a list of domain
experts and maintainers in the DevGuide.

Data encoding modules
---------------------

### binhex

The [binhex](https://docs.python.org/3/library/binhex.html) module
encodes and decodes Apple Macintosh binhex4 data. It was originally
developed for TRS-80. In the 1980s and early 1990s it was used on
classic Mac OS 9 to encode binary email attachments.

Module type

:   pure Python

Deprecated in

:   3.8

To be removed in

:   3.10

Has a designated expert

:   no

Substitute

:   **none**

### uu and the uu encoding

The [uu](https://docs.python.org/3/library/uu.html) module provides
uuencode format, an old binary encoding format for email from 1980. The
uu format has been replaced by MIME. The uu codec is provided by the
`binascii` module. There\'s also `encodings/uu_codec.py` which is a
codec for the same encoding; it should also be deprecated.

Module type

:   pure Python

Deprecated in

:   3.8

To be removed in

:   3.10

Has a designated expert

:   no

Substitute

:   **none**

### xdrlib

The [xdrlib](https://docs.python.org/3/library/xdrlib.html) module
supports the Sun External Data Representation Standard. XDR is an old
binary serialization format from 1987. These days it\'s rarely used
outside specialized domains like NFS.

Module type

:   pure Python

Deprecated in

:   3.8

To be removed in

:   3.10

Has a designated expert

:   no

Substitute

:   **none**

Multimedia modules
------------------

### aifc

The [aifc](https://docs.python.org/3/library/aifc.html) module provides
support for reading and writing AIFF and AIFF-C files. The Audio
Interchange File Format is an old audio format from 1988 based on Amiga
IFF. It was most commonly used on the Apple Macintosh. These days only
few specialized application use AIFF.

A user disclosed[^2] that the post production film industry makes heavy
use of the AIFC file format. The usage of the `aifc` module in closed
source and internal software was unknown prior to the first posting of
this PEP. This may be a compelling argument to keep the `aifc` module in
the standard library. The file format is stable and the module does not
require much maintenance. The strategic benefits for Python may outmatch
the burden.

Module type

:   pure Python (depends on some functions from [audioop](#audioop) C
    extension)

Deprecated in

:   3.8

To be removed in

:   3.10

Has a designated expert

:   yes, but expert is currently inactive.

Substitute

:   **none**

### audioop

The [audioop](https://docs.python.org/3/library/audioop.html) module
contains helper functions to manipulate raw audio data and adaptive
differential pulse-code modulated audio data. The module is implemented
in C without any additional dependencies. The [aifc](#aifc),
[sunau](#sunau), and [wave](#wave) modules depend on [audioop](#audioop)
for some operations.

The byteswap operation in the `wave` module can be substituted with
little extra work. In case `aifc` is not deprecated as well, a reduced
version of the `audioop` module is converted into a private
implementation detail, e.g. `_audioop` with `byteswap`, `alaw2lin`,
`ulaw2lin`, `lin2alaw`, `lin2ulaw`, and `lin2adpcm`.

Module type

:   C extension

Deprecated in

:   3.8

To be removed in

:   3.10

Has a designated expert

:   yes

Substitute

:   **none**

### chunk

The [chunk](https://docs.python.org/3/library/chunk.html) module
provides support for reading and writing Electronic Arts\' Interchange
File Format. IFF is an old audio file format originally introduced for
Commodore and Amiga. The format is no longer relevant.

Module type

:   pure Python

Deprecated in

:   3.8

To be removed in

:   3.10

Has a designated expert

:   no

Substitute

:   **none**

### imghdr

The [imghdr](https://docs.python.org/3/library/imghdr.html) module is a
simple tool to guess the image file format from the first 32 bytes of a
file or buffer. It supports only a limited number of formats and neither
returns resolution nor color depth.

Module type

:   pure Python

Deprecated in

:   3.8

To be removed in

:   3.10

Has a designated expert

:   no

Substitute

:   [puremagic](https://pypi.org/project/puremagic/),
    [filetype](https://pypi.org/project/filetype/),
    [python-magic](https://pypi.org/project/python-magic/)

### ossaudiodev

The [ossaudiodev](https://docs.python.org/3/library/ossaudiodev.html)
module provides support for Open Sound System, an interface to sound
playback and capture devices. OSS was initially free software, but later
support for newer sound devices and improvements were proprietary. Linux
community abandoned OSS in favor of ALSA[^3]. Some operation systems
like OpenBSD and NetBSD provide an incomplete[^4] emulation of OSS.

To best of my knowledge, FreeBSD is the only widespread operating system
that uses Open Sound System as of today. The `ossaudiodev` hasn\'t seen
any improvements or new features since 2003. All commits since 2003 are
project-wide code cleanups and a couple of bug fixes. It would be
beneficial for both FreeBSD community and core development, if the
module would be maintained and distributed by people that care for it
and use it.

The standard library used to have more audio-related modules. The other
audio device interface (`audiodev`, `linuxaudiodev`, `sunaudiodev`) were
removed in 2007 as part of the `3108`{.interpreted-text role="pep"}
stdlib re-organization.

Module type

:   C extension

Deprecated in

:   3.8

To be removed in

:   3.10

Has a designated expert

:   no

Substitute

:   **none**

### sndhdr

The [sndhdr](https://docs.python.org/3/library/sndhdr.html) module is
similar to the [imghdr](#imghdr) module but for audio formats. It
guesses file format, channels, frame rate, and sample widths from the
first 512 bytes of a file or buffer. The module only supports AU, AIFF,
HCOM, VOC, WAV, and other ancient formats.

Module type

:   pure Python (depends on [audioop](#audioop) C extension for some
    operations)

Deprecated in

:   3.8

To be removed in

:   3.10

Has a designated expert

:   no

Substitute

:   [puremagic](https://pypi.org/project/puremagic/),
    [filetype](https://pypi.org/project/filetype/),
    [python-magic](https://pypi.org/project/python-magic/)

### sunau

The [sunau](https://docs.python.org/3/library/sunhdr.html) module
provides support for Sun AU sound format. It\'s yet another old,
obsolete file format.

Module type

:   pure Python (depends on [audioop](#audioop) C extension for some
    operations)

Deprecated in

:   3.8

To be removed in

:   3.10

Has a designated expert

:   no

Substitute

:   **none**

Networking modules
------------------

### asynchat

The [asynchat](https://docs.python.org/3/library/asynchat.html) module
is built on top of [asyncore](#asyncore) and has been deprecated since
Python 3.6.

Module type

:   pure Python

Deprecated in

:   3.6

Removed in

:   3.10

Has a designated expert

:   yes

Substitute

:   asyncio

### asyncore

The [asyncore](https://docs.python.org/3/library/asyncore.html) module
was the first module for asynchronous socket service clients and
servers. It has been replaced by asyncio and is deprecated since Python
3.6.

The `asyncore` module is also used in stdlib tests. The tests for
`ftplib`, `logging`, `smptd`, `smtplib`, and `ssl` are partly based on
`asyncore`. These tests must be updated to use asyncio or threading.

Module type

:   pure Python

Deprecated in

:   3.6

Removed in

:   3.10

Has a designated expert

:   yes

Substitute

:   asyncio

### cgi

The [cgi](https://docs.python.org/3/library/cgi.html) module is a
support module for Common Gateway Interface (CGI) scripts. CGI is deemed
as inefficient because every incoming request is handled in a new
process. `206`{.interpreted-text role="pep"} considers the module as:

> \"\[\...\] designed poorly and are now near-impossible to fix (`cgi`)
> \[\...\]\"

Several people proposed to either keep the `cgi` module for features
like `cgi.parse_qs` or move `cgi.escape` to a different module. The
functions `cgi.parse_qs` and `cgi.parse_qsl` have been deprecated for a
while and are actually aliases for `urllib.parse.parse_qs` and
`urllib.parse.parse_qsl`. The function `cgi.quote` has been deprecated
in favor of `html.quote` with secure default values.

Module type

:   pure Python

Deprecated in

:   3.8 (originally proposed for 2.0 by `206`{.interpreted-text
    role="pep"})

To be removed in

:   3.10

Has a designated expert

:   no

Substitute

:   **none**

### cgitb

The [cgitb](https://docs.python.org/3/library/cgitb.html) module is a
helper for the `cgi` module for configurable tracebacks.

The `cgitb` module is not used by any major Python web framework
(Django, Pyramid, Plone, Flask, CherryPy, or Bottle). Only Paste uses it
in an optional debugging middleware.

Module type

:   pure Python

Deprecated in

:   3.8 (originally proposed for 2.0 by `206`{.interpreted-text
    role="pep"})

To be removed in

:   3.10

Has a designated expert

:   no

Substitute

:   **none**

### email (legacy API)

The [email](https://docs.python.org/3/library/email.html) package is a
library for managing email messages. The email package contains several
legacy modules, legacy functions, and legacy classes, that provide
backwards compatibility to Python 3.2 and 2.7:

> -   `email.message.Message` (replaced by `email.message.EmailMessage`)
> -   `email.mime` (replaced by `email.contentmanager`)
> -   `email.header` (replaced by dict-like API of `EmailMessage` class)
> -   `email.charset`
> -   `email.encoders` (replaced by `EmailMessage.set_content`)
> -   `email.utils` (new API performs parsing and formatting
>     automatically)
> -   `email.iterators`
> -   `email.policy.Compat32`

The classes `email.mime.audio.MIMEAudio` and
`email.mime.image.MIMEImage` depend on the `sndhdr` and `imghdr`
modules. In case the `email.mime` package is not removed, the
auto-detection of file formats must be deprecated and `_subtype`
argument a required argument.

Module type

:   pure Python

Deprecated in

:   3.8 (documented as legacy APIs since 3.3 or 3.4)

To be removed in

:   3.10

Has a designated expert

:   yes

Substitute

:   email (non-legacy APIs)

### smtpd

The [smtpd](https://docs.python.org/3/library/smtpd.html) module
provides a simple implementation of a SMTP mail server. The module
documentation marks the module as deprecated and recommends `aiosmtpd`
instead. The deprecation message was added in releases 3.4.7, 3.5.4, and
3.6.1.

Module type

:   pure Python

Deprecated in

:   **3.4.7**, **3.5.4**, **3.6.1**

To be removed in

:   3.10

Has a designated expert

:   yes

Substitute

:   aiosmtpd

### nntplib

The [nntplib](https://docs.python.org/3/library/nntplib.html) module
implements the client side of the Network News Transfer Protocol (nntp).
News groups used to be a dominant platform for online discussions. Over
the last two decades, news has been slowly but steadily replaced with
mailing lists and web-based discussion platforms. Twisted is also
[planning](https://twistedmatrix.com/trac/ticket/9405) to deprecate NNTP
support and [pynntp](https://github.com/greenbender/pynntp) hasn\'t seen
any activity since 2014. This is a good indicator that the public
interest in NNTP support is declining.

The `nntplib` tests have been the cause of additional work in the recent
past. Python only contains client side of NNTP. The tests connect to
external news server. The servers are sometimes unavailable, too slow,
or do not work correctly over IPv6. The situation causes flaky test runs
on buildbots.

Module type

:   pure Python

Deprecated in

:   3.8

To be removed in

:   3.10

Has a designated expert

:   no

Substitute

:   **none**

### telnetlib

The [telnetlib](https://docs.python.org/3/library/telnetlib.html) module
provides a Telnet class that implements the Telnet protocol.

Module type

:   pure Python

Deprecated in

:   3.8

To be removed in

:   3.10

Substitute

:   [telnetlib3](https://pypi.org/project/telnetlib3),
    [Exscript](https://pypi.org/project/Exscript/)

Operating system interface
--------------------------

### crypt

The [crypt](https://docs.python.org/3/library/crypt.html) module
implements password hashing based on the `crypt(3)` function from
`libcrypt` or `libxcrypt` on Unix-like platforms. The algorithms are
mostly old, of poor quality and insecure. Users are discouraged to use
them.

-   The module is not available on Windows. Cross-platform applications
    need an alternative implementation anyway.
-   Only DES encryption is guaranteed to be available. DES has an
    extremely limited key space of 2\*\*56.
-   MD5, salted SHA256, salted SHA512, and Blowfish are optional
    extensions. SSHA256 and SSHA512 are glibc extensions. Blowfish
    (bcrypt) is the only algorithm that is still secure. However it\'s
    in glibc and therefore not commonly available on Linux.
-   Depending on the platform, the `crypt` module is not thread safe.
    Only implementations with `crypt_r(3)` are thread safe.
-   The module was never useful to interact with system user and
    password databases. On BSD, macOS, and Linux, all user
    authentication and password modification operations must go through
    PAM (pluggable authentication module), see [spwd](#spwd)
    deprecation.

Module type

:   C extension + Python module

Deprecated in

:   3.8

To be removed in

:   3.10

Has a designated expert

:   yes, but expert is currently inactive.

Substitute

:   [legacycrypt](https://pypi.org/project/legacycrypt/) (ctypes
    wrapper), [bcrypt](https://pypi.org/project/bcrypt/),
    [passlib](https://pypi.org/project/passlib/),
    [argon2cffi](https://pypi.org/project/argon2-cffi/), hashlib module
    (PBKDF2, scrypt)

### macpath

The [macpath](https://docs.python.org/3/library/macpath.html) module
provides Mac OS 9 implementation of `os.path` routines. Mac OS 9 is no
longer supported.

Module type

:   pure Python

Deprecated in

:   3.7

Removed in

:   3.8

Has a designated expert

:   n/a

Substitute

:   **none**

### nis

The [nis](https://docs.python.org/3/library/nis.html) module provides
NIS/YP support. Network Information Service / Yellow Pages is an old and
deprecated directory service protocol developed by Sun Microsystems.
It\'s designed successor NIS+ from 1992 never took off. For a long time,
libc\'s Name Service Switch, LDAP, and Kerberos/GSSAPI are considered a
more powerful and more secure replacement of NIS.

Module type

:   C extension

Deprecated in

:   3.8

To be removed in

:   3.10

Has a designated expert

:   no

Substitute

:   **none**

### spwd

The [spwd](https://docs.python.org/3/library/spwd.html) module provides
direct access to Unix shadow password database using non-standard APIs.

In general it\'s a bad idea to use spwd. It circumvents system security
policies, does not use the PAM stack, and is only compatible with local
user accounts, because it ignores NSS. The use of the `spwd` module for
access control must be considered a *security bug*, as it bypasses
PAM\'s access control.

Further more the `spwd` module uses the
[shadow(3)](http://man7.org/linux/man-pages/man3/shadow.3.html) APIs.
Functions like `getspnam(3)` access the `/etc/shadow` file directly.
This is dangerous and even forbidden for confined services on systems
with a security engine like SELinux or AppArmor.

Module type

:   C extension

Deprecated in

:   3.8

To be removed in

:   3.10

Has a designated expert

:   no

Substitute

:   [python-pam](https://pypi.org/project/python-pam/),
    [simpleplam](https://pypi.org/project/simplepam/)

Misc modules
------------

### formatter

The [formatter](https://docs.python.org/3/library/formatter.html) module
is an old text formatting module which has been deprecated since Python
3.4.

Module type

:   pure Python

Deprecated in

:   3.4

To be removed in

:   3.10

Has a designated expert

:   no

Substitute

:   *n/a*

### imp

The [imp](https://docs.python.org/3/library/imp.html) module is the
predecessor of the
[importlib](https://docs.python.org/3/library/importlib.html) module.
Most functions have been deprecated since Python 3.3 and the module
since Python 3.4.

Module type

:   C extension

Deprecated in

:   3.4

To be removed in

:   3.10

Has a designated expert

:   yes, experts have deprecated the module

Substitute

:   importlib

### msilib

The [msilib](https://docs.python.org/3/library/msilib.html) package is a
Windows-only package. It supports the creation of Microsoft Installers
(MSI). The package also exposes additional APIs to create cabinet files
(CAB). The module is used to facilitate distutils to create MSI
installers with the `bdist_msi` command. In the past it was used to
create CPython\'s official Windows installer, too.

Microsoft is slowly moving away from MSI in favor of Windows 10 Apps
(AppX) as new deployment model[^5].

Module type

:   C extension + Python code

Deprecated in

:   3.8

To be removed in

:   3.10

Has a designated expert

:   no

Substitute

:   **none**

### parser

The [parser](https://docs.python.org/3/library/parser.html) module
provides an interface to Python's internal parser and bytecode compiler.
The stdlib has superior ways to interact with the parse tree. From
Python 2.5 onward, it\'s much more convenient to cut in at the Abstract
Syntax Tree (AST) generation and compilation stage.

The `parser` module causes additional work. It\'s C code that must be
kept in sync with any change to Python\'s grammar and internal parser.
Pablo wants to remove the parser module and promote lib2to3\'s pgen2
instead [^6].

Most importantly the presence of the `parser` module makes it harder to
switch to something more powerful than a LL(1) parser[^7]. Since the
`parser` module is documented as deprecated since Python 2.5 and a new
parsing technology is planned for 3.9, the `parser` module is scheduled
for removal in 3.9.

Module type

:   C extension

Deprecated in

:   3.8, documented as deprecated since **2.5**

To be removed in

:   **3.9**

Has a designated expert

:   yes, experts have deprecated the module.

Substitute

:   ast, lib2to3.pgen2

### pipes

The [pipes](https://docs.python.org/3/library/pipes.html) module
provides helpers to pipe the input of one command into the output of
another command. The module is built on top of `os.popen`. Users are
encouraged to use the subprocess module instead.

Module type

:   pure Python

Deprecated in

:   3.8

To be removed in

:   3.10

Has a designated expert

:   no

Substitute

:   subprocess module

Removed modules
===============

fpectl
------

The [fpectl](https://docs.python.org/3.6/library/fpectl.html) module was
never built by default, its usage was discouraged and considered
dangerous. It also required a configure flag that caused an ABI
incompatibility. The module was removed in 3.7 by Nathaniel J. Smith in
[bpo-29137](https://bugs.python.org/issue29137).

Module type

:   C extension + CAPI

Deprecated in

:   3.7

Removed in

:   3.7

Has a designated expert

:   n/a

Substitute

:   **none**

Modules to keep
===============

Some modules were originally proposed for deprecation.

  -----------------------------------------------------------------------
  Module            Deprecated in     Replacement
  ----------------- ----------------- -----------------------------------
  colorsys          \-                colormath, colour, colorspacious,
                                      Pillow

  fileinput         \-                argparse

  getopt            \-                argparse, optparse

  lib2to3           \-                

  optparse          **3.2**           argparse

  wave              \-                
  -----------------------------------------------------------------------

  : Table 2: Withdrawn deprecations

colorsys
--------

The [colorsys](https://docs.python.org/3/library/colorsys.html) module
defines color conversion functions between RGB, YIQ, HSL, and HSV
coordinate systems.

Walter Dörwald, Petr Viktorin, and others requested to keep `colorsys`.
The module is useful to convert CSS colors between coordinate systems.
The implementation is simple, mature, and does not impose maintenance
overhead on core development.

The PyPI packages `colormath`, `colour`, and `colorspacious` provide
more and advanced features. The Pillow library is better suited to
transform images between color systems.

Module type

:   pure Python

Has a designated expert

:   no

Substitute

:   [colormath](https://pypi.org/project/colormath/),
    [colour](https://pypi.org/project/colour/)
    [colorspacious](https://pypi.org/project/colorspacious/),
    [Pillow](https://pypi.org/project/Pillow/)

fileinput
---------

The [fileinput](https://docs.python.org/3/library/fileinput.html) module
implements helpers to iterate over a list of files from `sys.argv`. The
module predates the `optparser` and `argparser` modules. The same
functionality can be implemented with the `argparser` module.

Several core developers expressed their interest to keep the module in
the standard library, as it is handy for quick scripts.

Module type

:   pure Python

Has a designated expert

:   no

lib2to3
-------

The [lib2to3](https://docs.python.org/3/library/2to3.html) package
provides the `2to3` command to transpile Python 2 code to Python 3 code.

The package is useful for other tasks besides porting code from Python 2
to 3. For example [Black]() uses it for code reformatting.

Module type

:   pure Python

Has a designated expert

:   no

getopt
------

The [getopt](https://docs.python.org/3/library/getopt.html) module
mimics C\'s `getopt()` option parser.

Although users are encouraged to use `argparse` instead, the `getopt`
module is still widely used. The module is small, simple, and handy for
C developers to write simple Python scripts.

Module type

:   pure Python

Has a designated expert

:   no

Substitute

:   argparse

optparse
--------

The [optparse](https://docs.python.org/3/library/optparse.html) module
is the predecessor of the `argparse` module.

Although it has been deprecated for many years, it\'s still too widely
used to remove it.

Module type

:   pure Python

Deprecated in

:   3.2

Has a designated expert

:   yes

Substitute

:   argparse

wave
----

The [wave](https://docs.python.org/3/library/wave.html) module provides
support for the WAV sound format.

The module is not deprecated, because The WAV format is still relevant
these days. The `wave` module is also used in education, e.g. to show
kids how to make noise with a computer.

The module uses one simple function from the [audioop](#audioop) module
to perform byte swapping between little and big endian formats. Before
24 bit WAV support was added, byte swap used to be implemented with the
`array` module. To remove `wave`\'s dependency on `audioop`, the byte
swap function could be either be moved to another module (e.g.
`operator`) or the `array` module could gain support for 24-bit (3-byte)
arrays.

Module type

:   pure Python (depends on *byteswap* from [audioop](#audioop) C
    extension)

Has a designated expert

:   no

Future maintenance of removed modules
=====================================

The main goal of the PEP is to reduce the burden and workload on the
Python core developer team. Therefore removed modules will not be
maintained by the core team as separate PyPI packages. However the
removed code, tests and documentation may be moved into a new Git
repository, so community members have a place from which they can pick
up and fork code.

A first draft of a [legacylib](https://github.com/tiran/legacylib)
repository is available on my private GitHub account. The modules could
be made available on PyPI. The Python core team will not publish or
maintain the packages. It is my hope that members of the Python
community will adopt, maintain, and perhaps improve the deprecated
modules.

It\'s my hope that some of the deprecated modules will be picked up and
adopted by users that actually care about them. For example `colorsys`
and `imghdr` are useful modules, but have limited feature set. A fork of
`imghdr` can add new features and support for more image formats,
without being constrained by Python\'s release cycle.

Most of the modules are in pure Python and can be easily packaged. Some
depend on a simple C module, e.g. [audioop](#audioop) and
[crypt](#crypt). Since [audioop](#audioop) does not depend on any
external libraries, it can be shipped as binary wheels with some effort.
Other C modules can be replaced with `ctypes` or `cffi`. For example I
created [legacycrypt](), which provides a full implementation of
`crypt`. It is implemented on top of a ctypes wrapper around `libxcrypt`
and `libcrypt` instead of a C extension like the original `_crypt`
module.

Discussions
===========

-   Elana Hashman and Nick Coghlan suggested to keep the `getopt`
    module.
-   Berker Peksag proposed to deprecate and removed `msilib`.
-   Brett Cannon recommended to delay active deprecation warnings and
    removal of modules like `imp` until Python 3.10. Version 3.8 will be
    released shortly before Python 2 reaches end-of-life. A delay
    reduced churn for users that migrate from Python 2 to 3.8.
-   Brett also came up with the idea to keep `lib2to3`. The package is
    useful for other purposes, e.g.
    [Black](https://pypi.org/project/black/) uses it to reformat Python
    code.
-   At one point, distutils was mentioned in the same sentence as this
    PEP. To avoid lengthy discussion and delay of the PEP, I decided
    against dealing with distutils. Deprecation of the distutils package
    will be handled by another PEP.
-   Multiple people (Gregory P. Smith, David Beazley, Nick Coghlan,
    \...) convinced me to keep the [wave](#wave) module.[^8]
-   Gregory P. Smith proposed to deprecate [nntplib](#nntplib).[^9]
-   Andrew Svetlov mentioned the `socketserver` module is questionable.
    However it\'s used to implement `http.server` and `xmlrpc.server`.
    The stdlib doesn\'t have a replacement for the servers, yet.

Update history
==============

Update 1
--------

-   Deprecate [parser](#parser) module
-   Keep [fileinput](#fileinput) module
-   Elaborate why `crypt` and `spwd` are dangerous and bad
-   Improve sections for [cgitb](#cgitb), [colorsys](#colorsys),
    [nntplib](#nntplib), and [smtpd](#smtpd) modules
-   The [colorsys](#colorsys), `crypt`, [imghdr](#imghdr),
    [sndhdr](#sndhdr), and `spwd` sections now list suitable
    substitutions
-   Mention that `socketserver` is going to stay for `http.server` and
    `xmlrpc.server`
-   The future maintenance section now states that the deprecated
    modules may be adopted by Python community members

Update 2
--------

-   Keep `colorsys` module
-   Add experts
-   Redirect discussions to discuss.python.org
-   Deprecate [telnetlib](#telnetlib)
-   Deprecate compat32 policy of email package
-   Add creation year to overview table
-   Mention `206`{.interpreted-text role="pep"} and
    `3108`{.interpreted-text role="pep"}
-   Update sections for `aifc`, `audioop`, `cgi`, and `wave`.

References
==========

Copyright
=========

This document has been placed in the public domain.

#### 

> Local Variables: mode: indented-text indent-tabs-mode: nil
> sentence-end-double-space: t fill-column: 70 coding: utf-8 End:

[^1]: <https://twitter.com/dabeaz/status/1130278844479545351>

[^2]: <https://mail.python.org/pipermail/python-dev/2019-May/157634.html>

[^3]: <https://en.wikipedia.org/wiki/Open_Sound_System#Free,_proprietary,_free>

[^4]: <https://man.openbsd.org/ossaudio>

[^5]: <https://blogs.msmvps.com/installsite/blog/2015/05/03/the-future-of-windows-installer-msi-in-the-light-of-windows-10-and-the-universal-windows-platform/>

[^6]: <https://mail.python.org/pipermail/python-dev/2019-May/157464.html>

[^7]: <https://discuss.python.org/t/switch-pythons-parsing-tech-to-something-more-powerful-than-ll-1/379>

[^8]: <https://twitter.com/ChristianHeimes/status/1130257799475335169>

[^9]: <https://twitter.com/ChristianHeimes/status/1130257799475335169>
