[Python-checkins] bpo-45085: Remove the binhex module (GH-28117)

ambv webhook-mailer at python.org
Thu Sep 2 06:10:21 EDT 2021


https://github.com/python/cpython/commit/a8066087054417885db0a2dbdce2ddb2ac498247
commit: a8066087054417885db0a2dbdce2ddb2ac498247
branch: main
author: Victor Stinner <vstinner at python.org>
committer: ambv <lukasz at langa.pl>
date: 2021-09-02T12:10:08+02:00
summary:

bpo-45085: Remove the binhex module (GH-28117)

The binhex module, deprecated in Python 3.9, is now removed. The
following binascii functions, deprecated in Python 3.9, are now also
removed:

* a2b_hqx(), b2a_hqx();
* rlecode_hqx(), rledecode_hqx().

The binascii.crc_hqx() function remains available.

files:
A Misc/NEWS.d/next/Library/2021-09-02-00-47-14.bpo-45085.mMnaDv.rst
D Doc/library/binhex.rst
D Lib/binhex.py
D Lib/test/test_binhex.py
M Doc/library/binascii.rst
M Doc/library/netdata.rst
M Doc/whatsnew/3.11.rst
M Lib/test/test_binascii.py
M Modules/binascii.c
M Modules/clinic/binascii.c.h
M PCbuild/lib.pyproj
M Python/stdlib_module_names.h

diff --git a/Doc/library/binascii.rst b/Doc/library/binascii.rst
index fd5df69e852dc..62d7efe34ab36 100644
--- a/Doc/library/binascii.rst
+++ b/Doc/library/binascii.rst
@@ -8,14 +8,13 @@
 .. index::
    module: uu
    module: base64
-   module: binhex
 
 --------------
 
 The :mod:`binascii` module contains a number of methods to convert between
 binary and various ASCII-encoded binary representations. Normally, you will not
-use these functions directly but use wrapper modules like :mod:`uu`,
-:mod:`base64`, or :mod:`binhex` instead. The :mod:`binascii` module contains
+use these functions directly but use wrapper modules like :mod:`uu` or
+:mod:`base64` instead. The :mod:`binascii` module contains
 low-level functions written in C for greater speed that are used by the
 higher-level modules.
 
@@ -98,45 +97,6 @@ The :mod:`binascii` module defines the following functions:
    stream.
 
 
-.. function:: a2b_hqx(string)
-
-   Convert binhex4 formatted ASCII data to binary, without doing RLE-decompression.
-   The string should contain a complete number of binary bytes, or (in case of the
-   last portion of the binhex4 data) have the remaining bits zero.
-
-   .. deprecated:: 3.9
-
-
-.. function:: rledecode_hqx(data)
-
-   Perform RLE-decompression on the data, as per the binhex4 standard. The
-   algorithm uses ``0x90`` after a byte as a repeat indicator, followed by a count.
-   A count of ``0`` specifies a byte value of ``0x90``. The routine returns the
-   decompressed data, unless data input data ends in an orphaned repeat indicator,
-   in which case the :exc:`Incomplete` exception is raised.
-
-   .. versionchanged:: 3.2
-      Accept only bytestring or bytearray objects as input.
-
-   .. deprecated:: 3.9
-
-
-.. function:: rlecode_hqx(data)
-
-   Perform binhex4 style RLE-compression on *data* and return the result.
-
-   .. deprecated:: 3.9
-
-
-.. function:: b2a_hqx(data)
-
-   Perform hexbin4 binary-to-ASCII translation and return the resulting string. The
-   argument should already be RLE-coded, and have a length divisible by 3 (except
-   possibly the last fragment).
-
-   .. deprecated:: 3.9
-
-
 .. function:: crc_hqx(data, value)
 
    Compute a 16-bit CRC value of *data*, starting with *value* as the
@@ -222,9 +182,6 @@ The :mod:`binascii` module defines the following functions:
       Support for RFC compliant base64-style encoding in base 16, 32, 64,
       and 85.
 
-   Module :mod:`binhex`
-      Support for the binhex format used on the Macintosh.
-
    Module :mod:`uu`
       Support for UU encoding used on Unix.
 
diff --git a/Doc/library/binhex.rst b/Doc/library/binhex.rst
deleted file mode 100644
index 7de6a663762f0..0000000000000
--- a/Doc/library/binhex.rst
+++ /dev/null
@@ -1,59 +0,0 @@
-:mod:`binhex` --- Encode and decode binhex4 files
-=================================================
-
-.. module:: binhex
-   :synopsis: Encode and decode files in binhex4 format.
-
-**Source code:** :source:`Lib/binhex.py`
-
-.. deprecated:: 3.9
-
---------------
-
-This module encodes and decodes files in binhex4 format, a format allowing
-representation of Macintosh files in ASCII. Only the data fork is handled.
-
-The :mod:`binhex` module defines the following functions:
-
-
-.. function:: binhex(input, output)
-
-   Convert a binary file with filename *input* to binhex file *output*. The
-   *output* parameter can either be a filename or a file-like object (any object
-   supporting a :meth:`write` and :meth:`close` method).
-
-
-.. function:: hexbin(input, output)
-
-   Decode a binhex file *input*. *input* may be a filename or a file-like object
-   supporting :meth:`read` and :meth:`close` methods. The resulting file is written
-   to a file named *output*, unless the argument is ``None`` in which case the
-   output filename is read from the binhex file.
-
-The following exception is also defined:
-
-
-.. exception:: Error
-
-   Exception raised when something can't be encoded using the binhex format (for
-   example, a filename is too long to fit in the filename field), or when input is
-   not properly encoded binhex data.
-
-
-.. seealso::
-
-   Module :mod:`binascii`
-      Support module containing ASCII-to-binary and binary-to-ASCII conversions.
-
-
-.. _binhex-notes:
-
-Notes
------
-
-There is an alternative, more powerful interface to the coder and decoder, see
-the source for details.
-
-If you code or decode textfiles on non-Macintosh platforms they will still use
-the old Macintosh newline convention (carriage-return as end of line).
-
diff --git a/Doc/library/netdata.rst b/Doc/library/netdata.rst
index e76280f2fe3f4..16f43a69d68b2 100644
--- a/Doc/library/netdata.rst
+++ b/Doc/library/netdata.rst
@@ -17,7 +17,6 @@ on the internet.
    mailbox.rst
    mimetypes.rst
    base64.rst
-   binhex.rst
    binascii.rst
    quopri.rst
    uu.rst
diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst
index 8f0f6f83c012a..7d42c840c4a19 100644
--- a/Doc/whatsnew/3.11.rst
+++ b/Doc/whatsnew/3.11.rst
@@ -235,9 +235,21 @@ sqlite3
 
 Removed
 =======
+
 * :class:`smtpd.MailmanProxy` is now removed as it is unusable without
   an external module, ``mailman``. (Contributed by Dong-hee Na in :issue:`35800`.)
 
+* The ``binhex`` module, deprecated in Python 3.9, is now removed.
+  The following :mod:`binascii` functions, deprecated in Python 3.9, are now
+  also removed:
+
+  * ``a2b_hqx()``, ``b2a_hqx()``;
+  * ``rlecode_hqx()``, ``rledecode_hqx()``.
+
+  The :func:`binascii.crc_hqx` function remains available.
+
+  (Contributed by Victor Stinner in :issue:`45085`.)
+
 
 Optimizations
 =============
diff --git a/Lib/binhex.py b/Lib/binhex.py
deleted file mode 100644
index ace5217d27139..0000000000000
--- a/Lib/binhex.py
+++ /dev/null
@@ -1,502 +0,0 @@
-"""Macintosh binhex compression/decompression.
-
-easy interface:
-binhex(inputfilename, outputfilename)
-hexbin(inputfilename, outputfilename)
-"""
-
-#
-# Jack Jansen, CWI, August 1995.
-#
-# The module is supposed to be as compatible as possible. Especially the
-# easy interface should work "as expected" on any platform.
-# XXXX Note: currently, textfiles appear in mac-form on all platforms.
-# We seem to lack a simple character-translate in python.
-# (we should probably use ISO-Latin-1 on all but the mac platform).
-# XXXX The simple routines are too simple: they expect to hold the complete
-# files in-core. Should be fixed.
-# XXXX It would be nice to handle AppleDouble format on unix
-# (for servers serving macs).
-# XXXX I don't understand what happens when you get 0x90 times the same byte on
-# input. The resulting code (xx 90 90) would appear to be interpreted as an
-# escaped *value* of 0x90. All coders I've seen appear to ignore this nicety...
-#
-import binascii
-import contextlib
-import io
-import os
-import struct
-import warnings
-
-warnings.warn('the binhex module is deprecated', DeprecationWarning,
-              stacklevel=2)
-
-
-__all__ = ["binhex","hexbin","Error"]
-
-class Error(Exception):
-    pass
-
-# States (what have we written)
-_DID_HEADER = 0
-_DID_DATA = 1
-
-# Various constants
-REASONABLY_LARGE = 32768  # Minimal amount we pass the rle-coder
-LINELEN = 64
-RUNCHAR = b"\x90"
-
-#
-# This code is no longer byte-order dependent
-
-
-class FInfo:
-    def __init__(self):
-        self.Type = '????'
-        self.Creator = '????'
-        self.Flags = 0
-
-def getfileinfo(name):
-    finfo = FInfo()
-    with io.open(name, 'rb') as fp:
-        # Quick check for textfile
-        data = fp.read(512)
-        if 0 not in data:
-            finfo.Type = 'TEXT'
-        fp.seek(0, 2)
-        dsize = fp.tell()
-    dir, file = os.path.split(name)
-    file = file.replace(':', '-', 1)
-    return file, finfo, dsize, 0
-
-class openrsrc:
-    def __init__(self, *args):
-        pass
-
-    def read(self, *args):
-        return b''
-
-    def write(self, *args):
-        pass
-
-    def close(self):
-        pass
-
-
-# DeprecationWarning is already emitted on "import binhex". There is no need
-# to repeat the warning at each call to deprecated binascii functions.
- at contextlib.contextmanager
-def _ignore_deprecation_warning():
-    with warnings.catch_warnings():
-        warnings.filterwarnings('ignore', '', DeprecationWarning)
-        yield
-
-
-class _Hqxcoderengine:
-    """Write data to the coder in 3-byte chunks"""
-
-    def __init__(self, ofp):
-        self.ofp = ofp
-        self.data = b''
-        self.hqxdata = b''
-        self.linelen = LINELEN - 1
-
-    def write(self, data):
-        self.data = self.data + data
-        datalen = len(self.data)
-        todo = (datalen // 3) * 3
-        data = self.data[:todo]
-        self.data = self.data[todo:]
-        if not data:
-            return
-        with _ignore_deprecation_warning():
-            self.hqxdata = self.hqxdata + binascii.b2a_hqx(data)
-        self._flush(0)
-
-    def _flush(self, force):
-        first = 0
-        while first <= len(self.hqxdata) - self.linelen:
-            last = first + self.linelen
-            self.ofp.write(self.hqxdata[first:last] + b'\r')
-            self.linelen = LINELEN
-            first = last
-        self.hqxdata = self.hqxdata[first:]
-        if force:
-            self.ofp.write(self.hqxdata + b':\r')
-
-    def close(self):
-        if self.data:
-            with _ignore_deprecation_warning():
-                self.hqxdata = self.hqxdata + binascii.b2a_hqx(self.data)
-        self._flush(1)
-        self.ofp.close()
-        del self.ofp
-
-class _Rlecoderengine:
-    """Write data to the RLE-coder in suitably large chunks"""
-
-    def __init__(self, ofp):
-        self.ofp = ofp
-        self.data = b''
-
-    def write(self, data):
-        self.data = self.data + data
-        if len(self.data) < REASONABLY_LARGE:
-            return
-        with _ignore_deprecation_warning():
-            rledata = binascii.rlecode_hqx(self.data)
-        self.ofp.write(rledata)
-        self.data = b''
-
-    def close(self):
-        if self.data:
-            with _ignore_deprecation_warning():
-                rledata = binascii.rlecode_hqx(self.data)
-            self.ofp.write(rledata)
-        self.ofp.close()
-        del self.ofp
-
-class BinHex:
-    def __init__(self, name_finfo_dlen_rlen, ofp):
-        name, finfo, dlen, rlen = name_finfo_dlen_rlen
-        close_on_error = False
-        if isinstance(ofp, str):
-            ofname = ofp
-            ofp = io.open(ofname, 'wb')
-            close_on_error = True
-        try:
-            ofp.write(b'(This file must be converted with BinHex 4.0)\r\r:')
-            hqxer = _Hqxcoderengine(ofp)
-            self.ofp = _Rlecoderengine(hqxer)
-            self.crc = 0
-            if finfo is None:
-                finfo = FInfo()
-            self.dlen = dlen
-            self.rlen = rlen
-            self._writeinfo(name, finfo)
-            self.state = _DID_HEADER
-        except:
-            if close_on_error:
-                ofp.close()
-            raise
-
-    def _writeinfo(self, name, finfo):
-        nl = len(name)
-        if nl > 63:
-            raise Error('Filename too long')
-        d = bytes([nl]) + name.encode("latin-1") + b'\0'
-        tp, cr = finfo.Type, finfo.Creator
-        if isinstance(tp, str):
-            tp = tp.encode("latin-1")
-        if isinstance(cr, str):
-            cr = cr.encode("latin-1")
-        d2 = tp + cr
-
-        # Force all structs to be packed with big-endian
-        d3 = struct.pack('>h', finfo.Flags)
-        d4 = struct.pack('>ii', self.dlen, self.rlen)
-        info = d + d2 + d3 + d4
-        self._write(info)
-        self._writecrc()
-
-    def _write(self, data):
-        self.crc = binascii.crc_hqx(data, self.crc)
-        self.ofp.write(data)
-
-    def _writecrc(self):
-        # XXXX Should this be here??
-        # self.crc = binascii.crc_hqx('\0\0', self.crc)
-        if self.crc < 0:
-            fmt = '>h'
-        else:
-            fmt = '>H'
-        self.ofp.write(struct.pack(fmt, self.crc))
-        self.crc = 0
-
-    def write(self, data):
-        if self.state != _DID_HEADER:
-            raise Error('Writing data at the wrong time')
-        self.dlen = self.dlen - len(data)
-        self._write(data)
-
-    def close_data(self):
-        if self.dlen != 0:
-            raise Error('Incorrect data size, diff=%r' % (self.rlen,))
-        self._writecrc()
-        self.state = _DID_DATA
-
-    def write_rsrc(self, data):
-        if self.state < _DID_DATA:
-            self.close_data()
-        if self.state != _DID_DATA:
-            raise Error('Writing resource data at the wrong time')
-        self.rlen = self.rlen - len(data)
-        self._write(data)
-
-    def close(self):
-        if self.state is None:
-            return
-        try:
-            if self.state < _DID_DATA:
-                self.close_data()
-            if self.state != _DID_DATA:
-                raise Error('Close at the wrong time')
-            if self.rlen != 0:
-                raise Error("Incorrect resource-datasize, diff=%r" % (self.rlen,))
-            self._writecrc()
-        finally:
-            self.state = None
-            ofp = self.ofp
-            del self.ofp
-            ofp.close()
-
-def binhex(inp, out):
-    """binhex(infilename, outfilename): create binhex-encoded copy of a file"""
-    finfo = getfileinfo(inp)
-    ofp = BinHex(finfo, out)
-
-    with io.open(inp, 'rb') as ifp:
-        # XXXX Do textfile translation on non-mac systems
-        while True:
-            d = ifp.read(128000)
-            if not d: break
-            ofp.write(d)
-        ofp.close_data()
-
-    ifp = openrsrc(inp, 'rb')
-    while True:
-        d = ifp.read(128000)
-        if not d: break
-        ofp.write_rsrc(d)
-    ofp.close()
-    ifp.close()
-
-class _Hqxdecoderengine:
-    """Read data via the decoder in 4-byte chunks"""
-
-    def __init__(self, ifp):
-        self.ifp = ifp
-        self.eof = 0
-
-    def read(self, totalwtd):
-        """Read at least wtd bytes (or until EOF)"""
-        decdata = b''
-        wtd = totalwtd
-        #
-        # The loop here is convoluted, since we don't really now how
-        # much to decode: there may be newlines in the incoming data.
-        while wtd > 0:
-            if self.eof: return decdata
-            wtd = ((wtd + 2) // 3) * 4
-            data = self.ifp.read(wtd)
-            #
-            # Next problem: there may not be a complete number of
-            # bytes in what we pass to a2b. Solve by yet another
-            # loop.
-            #
-            while True:
-                try:
-                    with _ignore_deprecation_warning():
-                        decdatacur, self.eof = binascii.a2b_hqx(data)
-                    break
-                except binascii.Incomplete:
-                    pass
-                newdata = self.ifp.read(1)
-                if not newdata:
-                    raise Error('Premature EOF on binhex file')
-                data = data + newdata
-            decdata = decdata + decdatacur
-            wtd = totalwtd - len(decdata)
-            if not decdata and not self.eof:
-                raise Error('Premature EOF on binhex file')
-        return decdata
-
-    def close(self):
-        self.ifp.close()
-
-class _Rledecoderengine:
-    """Read data via the RLE-coder"""
-
-    def __init__(self, ifp):
-        self.ifp = ifp
-        self.pre_buffer = b''
-        self.post_buffer = b''
-        self.eof = 0
-
-    def read(self, wtd):
-        if wtd > len(self.post_buffer):
-            self._fill(wtd - len(self.post_buffer))
-        rv = self.post_buffer[:wtd]
-        self.post_buffer = self.post_buffer[wtd:]
-        return rv
-
-    def _fill(self, wtd):
-        self.pre_buffer = self.pre_buffer + self.ifp.read(wtd + 4)
-        if self.ifp.eof:
-            with _ignore_deprecation_warning():
-                self.post_buffer = self.post_buffer + \
-                    binascii.rledecode_hqx(self.pre_buffer)
-            self.pre_buffer = b''
-            return
-
-        #
-        # Obfuscated code ahead. We have to take care that we don't
-        # end up with an orphaned RUNCHAR later on. So, we keep a couple
-        # of bytes in the buffer, depending on what the end of
-        # the buffer looks like:
-        # '\220\0\220' - Keep 3 bytes: repeated \220 (escaped as \220\0)
-        # '?\220' - Keep 2 bytes: repeated something-else
-        # '\220\0' - Escaped \220: Keep 2 bytes.
-        # '?\220?' - Complete repeat sequence: decode all
-        # otherwise: keep 1 byte.
-        #
-        mark = len(self.pre_buffer)
-        if self.pre_buffer[-3:] == RUNCHAR + b'\0' + RUNCHAR:
-            mark = mark - 3
-        elif self.pre_buffer[-1:] == RUNCHAR:
-            mark = mark - 2
-        elif self.pre_buffer[-2:] == RUNCHAR + b'\0':
-            mark = mark - 2
-        elif self.pre_buffer[-2:-1] == RUNCHAR:
-            pass # Decode all
-        else:
-            mark = mark - 1
-
-        with _ignore_deprecation_warning():
-            self.post_buffer = self.post_buffer + \
-                binascii.rledecode_hqx(self.pre_buffer[:mark])
-        self.pre_buffer = self.pre_buffer[mark:]
-
-    def close(self):
-        self.ifp.close()
-
-class HexBin:
-    def __init__(self, ifp):
-        if isinstance(ifp, str):
-            ifp = io.open(ifp, 'rb')
-        #
-        # Find initial colon.
-        #
-        while True:
-            ch = ifp.read(1)
-            if not ch:
-                raise Error("No binhex data found")
-            # Cater for \r\n terminated lines (which show up as \n\r, hence
-            # all lines start with \r)
-            if ch == b'\r':
-                continue
-            if ch == b':':
-                break
-
-        hqxifp = _Hqxdecoderengine(ifp)
-        self.ifp = _Rledecoderengine(hqxifp)
-        self.crc = 0
-        self._readheader()
-
-    def _read(self, len):
-        data = self.ifp.read(len)
-        self.crc = binascii.crc_hqx(data, self.crc)
-        return data
-
-    def _checkcrc(self):
-        filecrc = struct.unpack('>h', self.ifp.read(2))[0] & 0xffff
-        #self.crc = binascii.crc_hqx('\0\0', self.crc)
-        # XXXX Is this needed??
-        self.crc = self.crc & 0xffff
-        if filecrc != self.crc:
-            raise Error('CRC error, computed %x, read %x'
-                        % (self.crc, filecrc))
-        self.crc = 0
-
-    def _readheader(self):
-        len = self._read(1)
-        fname = self._read(ord(len))
-        rest = self._read(1 + 4 + 4 + 2 + 4 + 4)
-        self._checkcrc()
-
-        type = rest[1:5]
-        creator = rest[5:9]
-        flags = struct.unpack('>h', rest[9:11])[0]
-        self.dlen = struct.unpack('>l', rest[11:15])[0]
-        self.rlen = struct.unpack('>l', rest[15:19])[0]
-
-        self.FName = fname
-        self.FInfo = FInfo()
-        self.FInfo.Creator = creator
-        self.FInfo.Type = type
-        self.FInfo.Flags = flags
-
-        self.state = _DID_HEADER
-
-    def read(self, *n):
-        if self.state != _DID_HEADER:
-            raise Error('Read data at wrong time')
-        if n:
-            n = n[0]
-            n = min(n, self.dlen)
-        else:
-            n = self.dlen
-        rv = b''
-        while len(rv) < n:
-            rv = rv + self._read(n-len(rv))
-        self.dlen = self.dlen - n
-        return rv
-
-    def close_data(self):
-        if self.state != _DID_HEADER:
-            raise Error('close_data at wrong time')
-        if self.dlen:
-            dummy = self._read(self.dlen)
-        self._checkcrc()
-        self.state = _DID_DATA
-
-    def read_rsrc(self, *n):
-        if self.state == _DID_HEADER:
-            self.close_data()
-        if self.state != _DID_DATA:
-            raise Error('Read resource data at wrong time')
-        if n:
-            n = n[0]
-            n = min(n, self.rlen)
-        else:
-            n = self.rlen
-        self.rlen = self.rlen - n
-        return self._read(n)
-
-    def close(self):
-        if self.state is None:
-            return
-        try:
-            if self.rlen:
-                dummy = self.read_rsrc(self.rlen)
-            self._checkcrc()
-        finally:
-            self.state = None
-            self.ifp.close()
-
-def hexbin(inp, out):
-    """hexbin(infilename, outfilename) - Decode binhexed file"""
-    ifp = HexBin(inp)
-    finfo = ifp.FInfo
-    if not out:
-        out = ifp.FName
-
-    with io.open(out, 'wb') as ofp:
-        # XXXX Do translation on non-mac systems
-        while True:
-            d = ifp.read(128000)
-            if not d: break
-            ofp.write(d)
-    ifp.close_data()
-
-    d = ifp.read_rsrc(128000)
-    if d:
-        ofp = openrsrc(out, 'wb')
-        ofp.write(d)
-        while True:
-            d = ifp.read_rsrc(128000)
-            if not d: break
-            ofp.write(d)
-        ofp.close()
-
-    ifp.close()
diff --git a/Lib/test/test_binascii.py b/Lib/test/test_binascii.py
index da8f9d1f213f7..b5aa847b943e6 100644
--- a/Lib/test/test_binascii.py
+++ b/Lib/test/test_binascii.py
@@ -8,10 +8,10 @@
 
 
 # Note: "*_hex" functions are aliases for "(un)hexlify"
-b2a_functions = ['b2a_base64', 'b2a_hex', 'b2a_hqx', 'b2a_qp', 'b2a_uu',
-                 'hexlify', 'rlecode_hqx']
-a2b_functions = ['a2b_base64', 'a2b_hex', 'a2b_hqx', 'a2b_qp', 'a2b_uu',
-                 'unhexlify', 'rledecode_hqx']
+b2a_functions = ['b2a_base64', 'b2a_hex', 'b2a_qp', 'b2a_uu',
+                 'hexlify']
+a2b_functions = ['a2b_base64', 'a2b_hex', 'a2b_qp', 'a2b_uu',
+                 'unhexlify']
 all_functions = a2b_functions + b2a_functions + ['crc32', 'crc_hqx']
 
 
@@ -38,7 +38,6 @@ def test_functions(self):
             self.assertTrue(hasattr(getattr(binascii, name), '__call__'))
             self.assertRaises(TypeError, getattr(binascii, name))
 
-    @warnings_helper.ignore_warnings(category=DeprecationWarning)
     def test_returned_value(self):
         # Limit to the minimum of all limits (b2a_uu)
         MAX_ALL = 45
@@ -51,9 +50,6 @@ def test_returned_value(self):
                 res = a2b(self.type2test(a))
             except Exception as err:
                 self.fail("{}/{} conversion raises {!r}".format(fb, fa, err))
-            if fb == 'b2a_hqx':
-                # b2a_hqx returns a tuple
-                res, _ = res
             self.assertEqual(res, raw, "{}/{} conversion: "
                              "{!r} != {!r}".format(fb, fa, res, raw))
             self.assertIsInstance(res, bytes)
@@ -226,7 +222,6 @@ def test_uu(self):
         with self.assertRaises(TypeError):
             binascii.b2a_uu(b"", True)
 
-    @warnings_helper.ignore_warnings(category=DeprecationWarning)
     def test_crc_hqx(self):
         crc = binascii.crc_hqx(self.type2test(b"Test the CRC-32 of"), 0)
         crc = binascii.crc_hqx(self.type2test(b" this string."), crc)
@@ -246,32 +241,6 @@ def test_crc32(self):
 
         self.assertRaises(TypeError, binascii.crc32)
 
-    @warnings_helper.ignore_warnings(category=DeprecationWarning)
-    def test_hqx(self):
-        # Perform binhex4 style RLE-compression
-        # Then calculate the hexbin4 binary-to-ASCII translation
-        rle = binascii.rlecode_hqx(self.data)
-        a = binascii.b2a_hqx(self.type2test(rle))
-
-        b, _ = binascii.a2b_hqx(self.type2test(a))
-        res = binascii.rledecode_hqx(b)
-        self.assertEqual(res, self.rawdata)
-
-    @warnings_helper.ignore_warnings(category=DeprecationWarning)
-    def test_rle(self):
-        # test repetition with a repetition longer than the limit of 255
-        data = (b'a' * 100 + b'b' + b'c' * 300)
-
-        encoded = binascii.rlecode_hqx(data)
-        self.assertEqual(encoded,
-                         (b'a\x90d'      # 'a' * 100
-                          b'b'           # 'b'
-                          b'c\x90\xff'   # 'c' * 255
-                          b'c\x90-'))    # 'c' * 45
-
-        decoded = binascii.rledecode_hqx(encoded)
-        self.assertEqual(decoded, data)
-
     def test_hex(self):
         # test hexlification
         s = b'{s\005\000\000\000worldi\002\000\000\000s\005\000\000\000helloi\001\000\000\0000'
@@ -404,7 +373,6 @@ def test_qp(self):
         self.assertEqual(b2a_qp(type2test(b'a.\n')), b'a.\n')
         self.assertEqual(b2a_qp(type2test(b'.a')[:-1]), b'=2E')
 
-    @warnings_helper.ignore_warnings(category=DeprecationWarning)
     def test_empty_string(self):
         # A test for SF bug #1022953.  Make sure SystemError is not raised.
         empty = self.type2test(b'')
@@ -421,7 +389,7 @@ def test_empty_string(self):
 
     def test_unicode_b2a(self):
         # Unicode strings are not accepted by b2a_* functions.
-        for func in set(all_functions) - set(a2b_functions) | {'rledecode_hqx'}:
+        for func in set(all_functions) - set(a2b_functions):
             try:
                 self.assertRaises(TypeError, getattr(binascii, func), "test")
             except Exception as err:
@@ -429,15 +397,11 @@ def test_unicode_b2a(self):
         # crc_hqx needs 2 arguments
         self.assertRaises(TypeError, binascii.crc_hqx, "test", 0)
 
-    @warnings_helper.ignore_warnings(category=DeprecationWarning)
     def test_unicode_a2b(self):
         # Unicode strings are accepted by a2b_* functions.
         MAX_ALL = 45
         raw = self.rawdata[:MAX_ALL]
         for fa, fb in zip(a2b_functions, b2a_functions):
-            if fa == 'rledecode_hqx':
-                # Takes non-ASCII data
-                continue
             a2b = getattr(binascii, fa)
             b2a = getattr(binascii, fb)
             try:
@@ -447,10 +411,6 @@ def test_unicode_a2b(self):
                 res = a2b(a)
             except Exception as err:
                 self.fail("{}/{} conversion raises {!r}".format(fb, fa, err))
-            if fb == 'b2a_hqx':
-                # b2a_hqx returns a tuple
-                res, _ = res
-                binary_res, _ = binary_res
             self.assertEqual(res, raw, "{}/{} conversion: "
                              "{!r} != {!r}".format(fb, fa, res, raw))
             self.assertEqual(res, binary_res)
@@ -468,18 +428,6 @@ def test_b2a_base64_newline(self):
         self.assertEqual(binascii.b2a_base64(b, newline=False),
                          b'aGVsbG8=')
 
-    def test_deprecated_warnings(self):
-        with self.assertWarns(DeprecationWarning):
-            self.assertEqual(binascii.b2a_hqx(b'abc'), b'B@*M')
-        with self.assertWarns(DeprecationWarning):
-            self.assertEqual(binascii.a2b_hqx(b'B@*M'), (b'abc', 0))
-
-        with self.assertWarns(DeprecationWarning):
-            self.assertEqual(binascii.rlecode_hqx(b'a' * 10), b'a\x90\n')
-
-        with self.assertWarns(DeprecationWarning):
-            self.assertEqual(binascii.rledecode_hqx(b'a\x90\n'), b'a' * 10)
-
 
 class ArrayBinASCIITest(BinASCIITest):
     def type2test(self, s):
diff --git a/Lib/test/test_binhex.py b/Lib/test/test_binhex.py
deleted file mode 100644
index efc1654a6b710..0000000000000
--- a/Lib/test/test_binhex.py
+++ /dev/null
@@ -1,72 +0,0 @@
-"""Test script for the binhex C module
-
-   Uses the mechanism of the python binhex module
-   Based on an original test by Roger E. Masse.
-"""
-import unittest
-from test import support
-from test.support import import_helper
-from test.support import os_helper
-from test.support import warnings_helper
-
-
-with warnings_helper.check_warnings(('', DeprecationWarning)):
-    binhex = import_helper.import_fresh_module('binhex')
-
-
-class BinHexTestCase(unittest.TestCase):
-
-    def setUp(self):
-        # binhex supports only file names encodable to Latin1
-        self.fname1 = os_helper.TESTFN_ASCII + "1"
-        self.fname2 = os_helper.TESTFN_ASCII + "2"
-        self.fname3 = os_helper.TESTFN_ASCII + "very_long_filename__very_long_filename__very_long_filename__very_long_filename__"
-
-    def tearDown(self):
-        os_helper.unlink(self.fname1)
-        os_helper.unlink(self.fname2)
-        os_helper.unlink(self.fname3)
-
-    DATA = b'Jack is my hero'
-
-    def test_binhex(self):
-        with open(self.fname1, 'wb') as f:
-            f.write(self.DATA)
-
-        binhex.binhex(self.fname1, self.fname2)
-
-        binhex.hexbin(self.fname2, self.fname1)
-
-        with open(self.fname1, 'rb') as f:
-            finish = f.readline()
-
-        self.assertEqual(self.DATA, finish)
-
-    def test_binhex_error_on_long_filename(self):
-        """
-        The testcase fails if no exception is raised when a filename parameter provided to binhex.binhex()
-        is too long, or if the exception raised in binhex.binhex() is not an instance of binhex.Error.
-        """
-        f3 = open(self.fname3, 'wb')
-        f3.close()
-
-        self.assertRaises(binhex.Error, binhex.binhex, self.fname3, self.fname2)
-
-    def test_binhex_line_endings(self):
-        # bpo-29566: Ensure the line endings are those for macOS 9
-        with open(self.fname1, 'wb') as f:
-            f.write(self.DATA)
-
-        binhex.binhex(self.fname1, self.fname2)
-
-        with open(self.fname2, 'rb') as fp:
-            contents = fp.read()
-
-        self.assertNotIn(b'\n', contents)
-
-def test_main():
-    support.run_unittest(BinHexTestCase)
-
-
-if __name__ == "__main__":
-    test_main()
diff --git a/Misc/NEWS.d/next/Library/2021-09-02-00-47-14.bpo-45085.mMnaDv.rst b/Misc/NEWS.d/next/Library/2021-09-02-00-47-14.bpo-45085.mMnaDv.rst
new file mode 100644
index 0000000000000..22eada24f0f5a
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2021-09-02-00-47-14.bpo-45085.mMnaDv.rst
@@ -0,0 +1,10 @@
+The ``binhex`` module, deprecated in Python 3.9, is now removed. The
+following :mod:`binascii` functions, deprecated in Python 3.9, are now also
+removed:
+
+* ``a2b_hqx()``, ``b2a_hqx()``;
+* ``rlecode_hqx()``, ``rledecode_hqx()``.
+
+The :func:`binascii.crc_hqx` function remains available.
+
+Patch by Victor Stinner.
diff --git a/Modules/binascii.c b/Modules/binascii.c
index e80eb2af49cf7..db960dcdcb0b6 100644
--- a/Modules/binascii.c
+++ b/Modules/binascii.c
@@ -72,69 +72,6 @@ get_binascii_state(PyObject *module)
     return (binascii_state *)PyModule_GetState(module);
 }
 
-/*
-** hqx lookup table, ascii->binary.
-*/
-
-#define RUNCHAR 0x90
-
-#define DONE 0x7F
-#define SKIP 0x7E
-#define FAIL 0x7D
-
-static const unsigned char table_a2b_hqx[256] = {
-/*       ^@    ^A    ^B    ^C    ^D    ^E    ^F    ^G   */
-/* 0*/  FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-/*       \b    \t    \n    ^K    ^L    \r    ^N    ^O   */
-/* 1*/  FAIL, FAIL, SKIP, FAIL, FAIL, SKIP, FAIL, FAIL,
-/*       ^P    ^Q    ^R    ^S    ^T    ^U    ^V    ^W   */
-/* 2*/  FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-/*       ^X    ^Y    ^Z    ^[    ^\    ^]    ^^    ^_   */
-/* 3*/  FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-/*              !     "     #     $     %     &     '   */
-/* 4*/  FAIL, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
-/*        (     )     *     +     ,     -     .     /   */
-/* 5*/  0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, FAIL, FAIL,
-/*        0     1     2     3     4     5     6     7   */
-/* 6*/  0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, FAIL,
-/*        8     9     :     ;     <     =     >     ?   */
-/* 7*/  0x14, 0x15, DONE, FAIL, FAIL, FAIL, FAIL, FAIL,
-/*        @     A     B     C     D     E     F     G   */
-/* 8*/  0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
-/*        H     I     J     K     L     M     N     O   */
-/* 9*/  0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, FAIL,
-/*        P     Q     R     S     T     U     V     W   */
-/*10*/  0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, FAIL,
-/*        X     Y     Z     [     \     ]     ^     _   */
-/*11*/  0x2C, 0x2D, 0x2E, 0x2F, FAIL, FAIL, FAIL, FAIL,
-/*        `     a     b     c     d     e     f     g   */
-/*12*/  0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, FAIL,
-/*        h     i     j     k     l     m     n     o   */
-/*13*/  0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, FAIL, FAIL,
-/*        p     q     r     s     t     u     v     w   */
-/*14*/  0x3D, 0x3E, 0x3F, FAIL, FAIL, FAIL, FAIL, FAIL,
-/*        x     y     z     {     |     }     ~    ^?   */
-/*15*/  FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-/*16*/  FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-};
-
-static const unsigned char table_b2a_hqx[] =
-"!\"#$%&'()*+,-012345689 at ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr";
 
 static const unsigned char table_a2b_base64[] = {
     -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
@@ -165,7 +102,6 @@ static const unsigned char table_b2a_base64[] =
 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
 
-
 static const unsigned short crctab_hqx[256] = {
     0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
     0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
@@ -649,356 +585,6 @@ binascii_b2a_base64_impl(PyObject *module, Py_buffer *data, int newline)
     return _PyBytesWriter_Finish(&writer, ascii_data);
 }
 
-/*[clinic input]
-binascii.a2b_hqx
-
-    data: ascii_buffer
-    /
-
-Decode .hqx coding.
-[clinic start generated code]*/
-
-static PyObject *
-binascii_a2b_hqx_impl(PyObject *module, Py_buffer *data)
-/*[clinic end generated code: output=4d6d8c54d54ea1c1 input=0d914c680e0eed55]*/
-{
-    if (PyErr_WarnEx(PyExc_DeprecationWarning,
-                     "binascii.a2b_hqx() is deprecated", 1) < 0) {
-        return NULL;
-    }
-
-    const unsigned char *ascii_data;
-    unsigned char *bin_data;
-    int leftbits = 0;
-    unsigned char this_ch;
-    unsigned int leftchar = 0;
-    PyObject *res;
-    Py_ssize_t len;
-    int done = 0;
-    _PyBytesWriter writer;
-    binascii_state *state;
-
-    ascii_data = data->buf;
-    len = data->len;
-    _PyBytesWriter_Init(&writer);
-
-    assert(len >= 0);
-
-    if (len > PY_SSIZE_T_MAX - 2)
-        return PyErr_NoMemory();
-
-    /* Allocate a string that is too big (fixed later)
-       Add two to the initial length to prevent interning which
-       would preclude subsequent resizing.  */
-    bin_data = _PyBytesWriter_Alloc(&writer, len + 2);
-    if (bin_data == NULL)
-        return NULL;
-
-    for( ; len > 0 ; len--, ascii_data++ ) {
-        /* Get the byte and look it up */
-        this_ch = table_a2b_hqx[*ascii_data];
-        if ( this_ch == SKIP )
-            continue;
-        if ( this_ch == FAIL ) {
-            state = get_binascii_state(module);
-            if (state == NULL) {
-                return NULL;
-            }
-            PyErr_SetString(state->Error, "Illegal char");
-            _PyBytesWriter_Dealloc(&writer);
-            return NULL;
-        }
-        if ( this_ch == DONE ) {
-            /* The terminating colon */
-            done = 1;
-            break;
-        }
-
-        /* Shift it into the buffer and see if any bytes are ready */
-        leftchar = (leftchar << 6) | (this_ch);
-        leftbits += 6;
-        if ( leftbits >= 8 ) {
-            leftbits -= 8;
-            *bin_data++ = (leftchar >> leftbits) & 0xff;
-            leftchar &= ((1 << leftbits) - 1);
-        }
-    }
-
-    if ( leftbits && !done ) {
-        state = get_binascii_state(module);
-        if (state == NULL) {
-            return NULL;
-        }
-        PyErr_SetString(state->Incomplete,
-                        "String has incomplete number of bytes");
-        _PyBytesWriter_Dealloc(&writer);
-        return NULL;
-    }
-
-    res = _PyBytesWriter_Finish(&writer, bin_data);
-    if (res == NULL)
-        return NULL;
-    return Py_BuildValue("Ni", res, done);
-}
-
-
-/*[clinic input]
-binascii.rlecode_hqx
-
-    data: Py_buffer
-    /
-
-Binhex RLE-code binary data.
-[clinic start generated code]*/
-
-static PyObject *
-binascii_rlecode_hqx_impl(PyObject *module, Py_buffer *data)
-/*[clinic end generated code: output=393d79338f5f5629 input=e1f1712447a82b09]*/
-{
-    if (PyErr_WarnEx(PyExc_DeprecationWarning,
-                     "binascii.rlecode_hqx() is deprecated", 1) < 0) {
-        return NULL;
-    }
-
-    const unsigned char *in_data;
-    unsigned char *out_data;
-    unsigned char ch;
-    Py_ssize_t in, inend, len;
-    _PyBytesWriter writer;
-
-    _PyBytesWriter_Init(&writer);
-    in_data = data->buf;
-    len = data->len;
-
-    assert(len >= 0);
-
-    if (len > PY_SSIZE_T_MAX / 2 - 2)
-        return PyErr_NoMemory();
-
-    /* Worst case: output is twice as big as input (fixed later) */
-    out_data = _PyBytesWriter_Alloc(&writer, len * 2 + 2);
-    if (out_data == NULL)
-        return NULL;
-
-    for( in=0; in<len; in++) {
-        ch = in_data[in];
-        if ( ch == RUNCHAR ) {
-            /* RUNCHAR. Escape it. */
-            *out_data++ = RUNCHAR;
-            *out_data++ = 0;
-        } else {
-            /* Check how many following are the same */
-            for(inend=in+1;
-                inend<len && in_data[inend] == ch &&
-                    inend < in+255;
-                inend++) ;
-            if ( inend - in > 3 ) {
-                /* More than 3 in a row. Output RLE. */
-                *out_data++ = ch;
-                *out_data++ = RUNCHAR;
-                *out_data++ = (unsigned char) (inend-in);
-                in = inend-1;
-            } else {
-                /* Less than 3. Output the byte itself */
-                *out_data++ = ch;
-            }
-        }
-    }
-
-    return _PyBytesWriter_Finish(&writer, out_data);
-}
-
-
-/*[clinic input]
-binascii.b2a_hqx
-
-    data: Py_buffer
-    /
-
-Encode .hqx data.
-[clinic start generated code]*/
-
-static PyObject *
-binascii_b2a_hqx_impl(PyObject *module, Py_buffer *data)
-/*[clinic end generated code: output=d0aa5a704bc9f7de input=9596ebe019fe12ba]*/
-{
-    if (PyErr_WarnEx(PyExc_DeprecationWarning,
-                     "binascii.b2a_hqx() is deprecated", 1) < 0) {
-        return NULL;
-    }
-
-    unsigned char *ascii_data;
-    const unsigned char *bin_data;
-    int leftbits = 0;
-    unsigned char this_ch;
-    unsigned int leftchar = 0;
-    Py_ssize_t len;
-    _PyBytesWriter writer;
-
-    bin_data = data->buf;
-    len = data->len;
-    _PyBytesWriter_Init(&writer);
-
-    assert(len >= 0);
-
-    if (len > PY_SSIZE_T_MAX / 2 - 2)
-        return PyErr_NoMemory();
-
-    /* Allocate a buffer that is at least large enough */
-    ascii_data = _PyBytesWriter_Alloc(&writer, len * 2 + 2);
-    if (ascii_data == NULL)
-        return NULL;
-
-    for( ; len > 0 ; len--, bin_data++ ) {
-        /* Shift into our buffer, and output any 6bits ready */
-        leftchar = (leftchar << 8) | *bin_data;
-        leftbits += 8;
-        while ( leftbits >= 6 ) {
-            this_ch = (leftchar >> (leftbits-6)) & 0x3f;
-            leftbits -= 6;
-            *ascii_data++ = table_b2a_hqx[this_ch];
-        }
-    }
-    /* Output a possible runt byte */
-    if ( leftbits ) {
-        leftchar <<= (6-leftbits);
-        *ascii_data++ = table_b2a_hqx[leftchar & 0x3f];
-    }
-
-    return _PyBytesWriter_Finish(&writer, ascii_data);
-}
-
-
-/*[clinic input]
-binascii.rledecode_hqx
-
-    data: Py_buffer
-    /
-
-Decode hexbin RLE-coded string.
-[clinic start generated code]*/
-
-static PyObject *
-binascii_rledecode_hqx_impl(PyObject *module, Py_buffer *data)
-/*[clinic end generated code: output=9826619565de1c6c input=54cdd49fc014402c]*/
-{
-    if (PyErr_WarnEx(PyExc_DeprecationWarning,
-                     "binascii.rledecode_hqx() is deprecated", 1) < 0) {
-        return NULL;
-    }
-
-    const unsigned char *in_data;
-    unsigned char *out_data;
-    unsigned char in_byte, in_repeat;
-    Py_ssize_t in_len;
-    _PyBytesWriter writer;
-
-    in_data = data->buf;
-    in_len = data->len;
-    _PyBytesWriter_Init(&writer);
-    binascii_state *state;
-
-    assert(in_len >= 0);
-
-    /* Empty string is a special case */
-    if ( in_len == 0 )
-        return PyBytes_FromStringAndSize("", 0);
-    else if (in_len > PY_SSIZE_T_MAX / 2)
-        return PyErr_NoMemory();
-
-    /* Allocate a buffer of reasonable size. Resized when needed */
-    out_data = _PyBytesWriter_Alloc(&writer, in_len);
-    if (out_data == NULL)
-        return NULL;
-
-    /* Use overallocation */
-    writer.overallocate = 1;
-
-    /*
-    ** We need two macros here to get/put bytes and handle
-    ** end-of-buffer for input and output strings.
-    */
-#define INBYTE(b)                                                       \
-    do {                                                                \
-         if ( --in_len < 0 ) {                                          \
-           state = get_binascii_state(module);                          \
-           if (state == NULL) {                                         \
-               return NULL;                                             \
-           }                                                            \
-           PyErr_SetString(state->Incomplete, "");                      \
-           goto error;                                                  \
-         }                                                              \
-         b = *in_data++;                                                \
-    } while(0)
-
-    /*
-    ** Handle first byte separately (since we have to get angry
-    ** in case of an orphaned RLE code).
-    */
-    INBYTE(in_byte);
-
-    if (in_byte == RUNCHAR) {
-        INBYTE(in_repeat);
-        /* only 1 byte will be written, but 2 bytes were preallocated:
-           subtract 1 byte to prevent overallocation */
-        writer.min_size--;
-
-        if (in_repeat != 0) {
-            /* Note Error, not Incomplete (which is at the end
-            ** of the string only). This is a programmer error.
-            */
-            state = get_binascii_state(module);
-            if (state == NULL) {
-                return NULL;
-            }
-            PyErr_SetString(state->Error, "Orphaned RLE code at start");
-            goto error;
-        }
-        *out_data++ = RUNCHAR;
-    } else {
-        *out_data++ = in_byte;
-    }
-
-    while( in_len > 0 ) {
-        INBYTE(in_byte);
-
-        if (in_byte == RUNCHAR) {
-            INBYTE(in_repeat);
-            /* only 1 byte will be written, but 2 bytes were preallocated:
-               subtract 1 byte to prevent overallocation */
-            writer.min_size--;
-
-            if ( in_repeat == 0 ) {
-                /* Just an escaped RUNCHAR value */
-                *out_data++ = RUNCHAR;
-            } else {
-                /* Pick up value and output a sequence of it */
-                in_byte = out_data[-1];
-
-                /* enlarge the buffer if needed */
-                if (in_repeat > 1) {
-                    /* -1 because we already preallocated 1 byte */
-                    out_data = _PyBytesWriter_Prepare(&writer, out_data,
-                                                      in_repeat - 1);
-                    if (out_data == NULL)
-                        goto error;
-                }
-
-                while ( --in_repeat > 0 )
-                    *out_data++ = in_byte;
-            }
-        } else {
-            /* Normal byte */
-            *out_data++ = in_byte;
-        }
-    }
-    return _PyBytesWriter_Finish(&writer, out_data);
-
-error:
-    _PyBytesWriter_Dealloc(&writer);
-    return NULL;
-}
-
 
 /*[clinic input]
 binascii.crc_hqx
@@ -1629,14 +1215,10 @@ static struct PyMethodDef binascii_module_methods[] = {
     BINASCII_B2A_UU_METHODDEF
     BINASCII_A2B_BASE64_METHODDEF
     BINASCII_B2A_BASE64_METHODDEF
-    BINASCII_A2B_HQX_METHODDEF
-    BINASCII_B2A_HQX_METHODDEF
     BINASCII_A2B_HEX_METHODDEF
     BINASCII_B2A_HEX_METHODDEF
     BINASCII_HEXLIFY_METHODDEF
     BINASCII_UNHEXLIFY_METHODDEF
-    BINASCII_RLECODE_HQX_METHODDEF
-    BINASCII_RLEDECODE_HQX_METHODDEF
     BINASCII_CRC_HQX_METHODDEF
     BINASCII_CRC32_METHODDEF
     BINASCII_A2B_QP_METHODDEF
diff --git a/Modules/clinic/binascii.c.h b/Modules/clinic/binascii.c.h
index a9240046a5911..a0ca6d60ce969 100644
--- a/Modules/clinic/binascii.c.h
+++ b/Modules/clinic/binascii.c.h
@@ -191,145 +191,6 @@ binascii_b2a_base64(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P
     return return_value;
 }
 
-PyDoc_STRVAR(binascii_a2b_hqx__doc__,
-"a2b_hqx($module, data, /)\n"
-"--\n"
-"\n"
-"Decode .hqx coding.");
-
-#define BINASCII_A2B_HQX_METHODDEF    \
-    {"a2b_hqx", (PyCFunction)binascii_a2b_hqx, METH_O, binascii_a2b_hqx__doc__},
-
-static PyObject *
-binascii_a2b_hqx_impl(PyObject *module, Py_buffer *data);
-
-static PyObject *
-binascii_a2b_hqx(PyObject *module, PyObject *arg)
-{
-    PyObject *return_value = NULL;
-    Py_buffer data = {NULL, NULL};
-
-    if (!ascii_buffer_converter(arg, &data)) {
-        goto exit;
-    }
-    return_value = binascii_a2b_hqx_impl(module, &data);
-
-exit:
-    /* Cleanup for data */
-    if (data.obj)
-       PyBuffer_Release(&data);
-
-    return return_value;
-}
-
-PyDoc_STRVAR(binascii_rlecode_hqx__doc__,
-"rlecode_hqx($module, data, /)\n"
-"--\n"
-"\n"
-"Binhex RLE-code binary data.");
-
-#define BINASCII_RLECODE_HQX_METHODDEF    \
-    {"rlecode_hqx", (PyCFunction)binascii_rlecode_hqx, METH_O, binascii_rlecode_hqx__doc__},
-
-static PyObject *
-binascii_rlecode_hqx_impl(PyObject *module, Py_buffer *data);
-
-static PyObject *
-binascii_rlecode_hqx(PyObject *module, PyObject *arg)
-{
-    PyObject *return_value = NULL;
-    Py_buffer data = {NULL, NULL};
-
-    if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) {
-        goto exit;
-    }
-    if (!PyBuffer_IsContiguous(&data, 'C')) {
-        _PyArg_BadArgument("rlecode_hqx", "argument", "contiguous buffer", arg);
-        goto exit;
-    }
-    return_value = binascii_rlecode_hqx_impl(module, &data);
-
-exit:
-    /* Cleanup for data */
-    if (data.obj) {
-       PyBuffer_Release(&data);
-    }
-
-    return return_value;
-}
-
-PyDoc_STRVAR(binascii_b2a_hqx__doc__,
-"b2a_hqx($module, data, /)\n"
-"--\n"
-"\n"
-"Encode .hqx data.");
-
-#define BINASCII_B2A_HQX_METHODDEF    \
-    {"b2a_hqx", (PyCFunction)binascii_b2a_hqx, METH_O, binascii_b2a_hqx__doc__},
-
-static PyObject *
-binascii_b2a_hqx_impl(PyObject *module, Py_buffer *data);
-
-static PyObject *
-binascii_b2a_hqx(PyObject *module, PyObject *arg)
-{
-    PyObject *return_value = NULL;
-    Py_buffer data = {NULL, NULL};
-
-    if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) {
-        goto exit;
-    }
-    if (!PyBuffer_IsContiguous(&data, 'C')) {
-        _PyArg_BadArgument("b2a_hqx", "argument", "contiguous buffer", arg);
-        goto exit;
-    }
-    return_value = binascii_b2a_hqx_impl(module, &data);
-
-exit:
-    /* Cleanup for data */
-    if (data.obj) {
-       PyBuffer_Release(&data);
-    }
-
-    return return_value;
-}
-
-PyDoc_STRVAR(binascii_rledecode_hqx__doc__,
-"rledecode_hqx($module, data, /)\n"
-"--\n"
-"\n"
-"Decode hexbin RLE-coded string.");
-
-#define BINASCII_RLEDECODE_HQX_METHODDEF    \
-    {"rledecode_hqx", (PyCFunction)binascii_rledecode_hqx, METH_O, binascii_rledecode_hqx__doc__},
-
-static PyObject *
-binascii_rledecode_hqx_impl(PyObject *module, Py_buffer *data);
-
-static PyObject *
-binascii_rledecode_hqx(PyObject *module, PyObject *arg)
-{
-    PyObject *return_value = NULL;
-    Py_buffer data = {NULL, NULL};
-
-    if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) {
-        goto exit;
-    }
-    if (!PyBuffer_IsContiguous(&data, 'C')) {
-        _PyArg_BadArgument("rledecode_hqx", "argument", "contiguous buffer", arg);
-        goto exit;
-    }
-    return_value = binascii_rledecode_hqx_impl(module, &data);
-
-exit:
-    /* Cleanup for data */
-    if (data.obj) {
-       PyBuffer_Release(&data);
-    }
-
-    return return_value;
-}
-
 PyDoc_STRVAR(binascii_crc_hqx__doc__,
 "crc_hqx($module, data, crc, /)\n"
 "--\n"
@@ -767,4 +628,4 @@ binascii_b2a_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj
 
     return return_value;
 }
-/*[clinic end generated code: output=0f261ee49971f5ca input=a9049054013a1b77]*/
+/*[clinic end generated code: output=4162d08536697182 input=a9049054013a1b77]*/
diff --git a/PCbuild/lib.pyproj b/PCbuild/lib.pyproj
index eba4d7591568d..ded02b0d6a07f 100644
--- a/PCbuild/lib.pyproj
+++ b/PCbuild/lib.pyproj
@@ -53,7 +53,6 @@
     <Compile Include="asyncore.py" />
     <Compile Include="base64.py" />
     <Compile Include="bdb.py" />
-    <Compile Include="binhex.py" />
     <Compile Include="bisect.py" />
     <Compile Include="bz2.py" />
     <Compile Include="calendar.py" />
@@ -894,7 +893,6 @@
     <Compile Include="test\test_bigaddrspace.py" />
     <Compile Include="test\test_bigmem.py" />
     <Compile Include="test\test_binascii.py" />
-    <Compile Include="test\test_binhex.py" />
     <Compile Include="test\test_binop.py" />
     <Compile Include="test\test_bisect.py" />
     <Compile Include="test\test_bool.py" />
diff --git a/Python/stdlib_module_names.h b/Python/stdlib_module_names.h
index 2f75c2e54cd5e..1743292593f36 100644
--- a/Python/stdlib_module_names.h
+++ b/Python/stdlib_module_names.h
@@ -103,7 +103,6 @@ static const char* _Py_stdlib_module_names[] = {
 "base64",
 "bdb",
 "binascii",
-"binhex",
 "bisect",
 "builtins",
 "bz2",



More information about the Python-checkins mailing list