summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2023-05-25 14:25:27 (GMT)
committerGitHub <noreply@github.com>2023-05-25 14:25:27 (GMT)
commitdbc8216f4c00ea40b0c2d3ca487e5afeb4b0e0b1 (patch)
tree87054aa8f6853402fadad273a071839e88aaeced
parente4127eaa1ea9104be0a1d9d9e147d50ba88f59aa (diff)
downloadcpython-dbc8216f4c00ea40b0c2d3ca487e5afeb4b0e0b1.zip
cpython-dbc8216f4c00ea40b0c2d3ca487e5afeb4b0e0b1.tar.gz
cpython-dbc8216f4c00ea40b0c2d3ca487e5afeb4b0e0b1.tar.bz2
gh-104773: PEP 594: Remove the uu module (#104932)
Doc/license.rst: Keep the UUencode and UUdecode license since it's also used by the uu codec.
-rw-r--r--Doc/library/binascii.rst6
-rw-r--r--Doc/library/superseded.rst1
-rw-r--r--Doc/library/uu.rst72
-rw-r--r--Doc/license.rst2
-rw-r--r--Doc/whatsnew/3.11.rst2
-rw-r--r--Doc/whatsnew/3.12.rst2
-rw-r--r--Doc/whatsnew/3.13.rst4
-rw-r--r--Doc/whatsnew/3.7.rst2
-rw-r--r--Lib/test/test_uu.py287
-rw-r--r--Lib/uu.py216
-rw-r--r--Misc/NEWS.d/3.12.0b1.rst2
-rw-r--r--Misc/NEWS.d/next/Library/2023-05-25-15-54-02.gh-issue-104773.nW-5MI.rst2
-rw-r--r--Python/stdlib_module_names.h1
-rwxr-xr-xTools/wasm/wasm_assets.py2
14 files changed, 12 insertions, 589 deletions
diff --git a/Doc/library/binascii.rst b/Doc/library/binascii.rst
index 21960cb..e9f6f0e 100644
--- a/Doc/library/binascii.rst
+++ b/Doc/library/binascii.rst
@@ -6,14 +6,13 @@
representations.
.. index::
- pair: module; uu
pair: module; base64
--------------
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` or
+use these functions directly but use wrapper modules like
: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.
@@ -179,8 +178,5 @@ The :mod:`binascii` module defines the following functions:
Support for RFC compliant base64-style encoding in base 16, 32, 64,
and 85.
- Module :mod:`uu`
- Support for UU encoding used on Unix.
-
Module :mod:`quopri`
Support for quoted-printable encoding used in MIME email messages.
diff --git a/Doc/library/superseded.rst b/Doc/library/superseded.rst
index 284716e..7e05f0e 100644
--- a/Doc/library/superseded.rst
+++ b/Doc/library/superseded.rst
@@ -15,4 +15,3 @@ backwards compatibility. They have been superseded by other modules.
chunk.rst
imghdr.rst
optparse.rst
- uu.rst
diff --git a/Doc/library/uu.rst b/Doc/library/uu.rst
deleted file mode 100644
index 83c4aec..0000000
--- a/Doc/library/uu.rst
+++ /dev/null
@@ -1,72 +0,0 @@
-:mod:`uu` --- Encode and decode uuencode files
-==============================================
-
-.. module:: uu
- :synopsis: Encode and decode files in uuencode format.
- :deprecated:
-
-.. moduleauthor:: Lance Ellinghouse
-
-**Source code:** :source:`Lib/uu.py`
-
-.. deprecated-removed:: 3.11 3.13
- The :mod:`uu` module is deprecated
- (see :pep:`PEP 594 <594#uu-and-the-uu-encoding>` for details).
- :mod:`base64` is a modern alternative.
-
---------------
-
-This module encodes and decodes files in uuencode format, allowing arbitrary
-binary data to be transferred over ASCII-only connections. Wherever a file
-argument is expected, the methods accept a file-like object. For backwards
-compatibility, a string containing a pathname is also accepted, and the
-corresponding file will be opened for reading and writing; the pathname ``'-'``
-is understood to mean the standard input or output. However, this interface is
-deprecated; it's better for the caller to open the file itself, and be sure
-that, when required, the mode is ``'rb'`` or ``'wb'`` on Windows.
-
-.. index::
- single: Jansen, Jack
- single: Ellinghouse, Lance
-
-This code was contributed by Lance Ellinghouse, and modified by Jack Jansen.
-
-The :mod:`uu` module defines the following functions:
-
-
-.. function:: encode(in_file, out_file, name=None, mode=None, *, backtick=False)
-
- Uuencode file *in_file* into file *out_file*. The uuencoded file will have
- the header specifying *name* and *mode* as the defaults for the results of
- decoding the file. The default defaults are taken from *in_file*, or ``'-'``
- and ``0o666`` respectively. If *backtick* is true, zeros are represented by
- ``'`'`` instead of spaces.
-
- .. versionchanged:: 3.7
- Added the *backtick* parameter.
-
-
-.. function:: decode(in_file, out_file=None, mode=None, quiet=False)
-
- This call decodes uuencoded file *in_file* placing the result on file
- *out_file*. If *out_file* is a pathname, *mode* is used to set the permission
- bits if the file must be created. Defaults for *out_file* and *mode* are taken
- from the uuencode header. However, if the file specified in the header already
- exists, a :exc:`uu.Error` is raised.
-
- :func:`decode` may print a warning to standard error if the input was produced
- by an incorrect uuencoder and Python could recover from that error. Setting
- *quiet* to a true value silences this warning.
-
-
-.. exception:: Error()
-
- Subclass of :exc:`Exception`, this can be raised by :func:`uu.decode` under
- various situations, such as described above, but also including a badly
- formatted header, or truncated input file.
-
-
-.. seealso::
-
- Module :mod:`binascii`
- Support module containing ASCII-to-binary and binary-to-ASCII conversions.
diff --git a/Doc/license.rst b/Doc/license.rst
index 947a9b1..4b7113b 100644
--- a/Doc/license.rst
+++ b/Doc/license.rst
@@ -476,7 +476,7 @@ The :mod:`trace` module contains the following notice::
UUencode and UUdecode functions
-------------------------------
-The :mod:`uu` module contains the following notice::
+The ``uu`` codec contains the following notice::
Copyright 1994 by Lance Ellinghouse
Cathedral City, California Republic, United States of America.
diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst
index efff132..ece273c 100644
--- a/Doc/whatsnew/3.11.rst
+++ b/Doc/whatsnew/3.11.rst
@@ -1733,7 +1733,7 @@ Modules
+---------------------+---------------------+---------------------+---------------------+---------------------+
| :mod:`aifc` | :mod:`chunk` | :mod:`!msilib` | :mod:`!pipes` | :mod:`!telnetlib` |
+---------------------+---------------------+---------------------+---------------------+---------------------+
- | :mod:`audioop` | :mod:`!crypt` | :mod:`!nis` | :mod:`!sndhdr` | :mod:`uu` |
+ | :mod:`audioop` | :mod:`!crypt` | :mod:`!nis` | :mod:`!sndhdr` | :mod:`!uu` |
+---------------------+---------------------+---------------------+---------------------+---------------------+
| :mod:`!cgi` | :mod:`imghdr` | :mod:`!nntplib` | :mod:`!spwd` | :mod:`!xdrlib` |
+---------------------+---------------------+---------------------+---------------------+---------------------+
diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst
index f01cc27..7c18406 100644
--- a/Doc/whatsnew/3.12.rst
+++ b/Doc/whatsnew/3.12.rst
@@ -935,7 +935,7 @@ Modules (see :pep:`594`):
* :mod:`!spwd`
* :mod:`!sunau`
* :mod:`!telnetlib`
-* :mod:`uu`
+* :mod:`!uu`
* :mod:`!xdrlib`
APIs:
diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst
index f570e03..38526e1 100644
--- a/Doc/whatsnew/3.13.rst
+++ b/Doc/whatsnew/3.13.rst
@@ -217,6 +217,10 @@ Removed
(Contributed by Victor Stinner in :gh:`104773`.)
+* :pep:`594`: Remove the :mod:`!uu` module, deprecated in Python 3.11:
+ the :mod:`base64` module is a modern alternative.
+ (Contributed by Victor Stinner in :gh:`104773`.)
+
Porting to Python 3.13
======================
diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst
index 93915b2..fa89b7d 100644
--- a/Doc/whatsnew/3.7.rst
+++ b/Doc/whatsnew/3.7.rst
@@ -1547,7 +1547,7 @@ adding ``~`` to the set of characters that are never quoted by default.
uu
--
-The :func:`uu.encode` function now accepts an optional *backtick*
+The :func:`!uu.encode` function now accepts an optional *backtick*
keyword argument. When it's true, zeros are represented by ``'`'``
instead of spaces. (Contributed by Xiang Zhang in :issue:`30103`.)
diff --git a/Lib/test/test_uu.py b/Lib/test/test_uu.py
deleted file mode 100644
index a189d6b..0000000
--- a/Lib/test/test_uu.py
+++ /dev/null
@@ -1,287 +0,0 @@
-"""
-Tests for uu module.
-Nick Mathewson
-"""
-
-import unittest
-from test.support import os_helper, warnings_helper
-
-uu = warnings_helper.import_deprecated("uu")
-
-import os
-import stat
-import sys
-import io
-
-plaintext = b"The symbols on top of your keyboard are !@#$%^&*()_+|~\n"
-
-encodedtext = b"""\
-M5&AE('-Y;6)O;',@;VX@=&]P(&]F('EO=7(@:V5Y8F]A<F0@87)E("% (R0E
-*7B8J*"E?*WQ^"@ """
-
-# Stolen from io.py
-class FakeIO(io.TextIOWrapper):
- """Text I/O implementation using an in-memory buffer.
-
- Can be a used as a drop-in replacement for sys.stdin and sys.stdout.
- """
-
- # XXX This is really slow, but fully functional
-
- def __init__(self, initial_value="", encoding="utf-8",
- errors="strict", newline="\n"):
- super(FakeIO, self).__init__(io.BytesIO(),
- encoding=encoding,
- errors=errors,
- newline=newline)
- self._encoding = encoding
- self._errors = errors
- if initial_value:
- if not isinstance(initial_value, str):
- initial_value = str(initial_value)
- self.write(initial_value)
- self.seek(0)
-
- def getvalue(self):
- self.flush()
- return self.buffer.getvalue().decode(self._encoding, self._errors)
-
-
-def encodedtextwrapped(mode, filename, backtick=False):
- if backtick:
- res = (bytes("begin %03o %s\n" % (mode, filename), "ascii") +
- encodedtext.replace(b' ', b'`') + b"\n`\nend\n")
- else:
- res = (bytes("begin %03o %s\n" % (mode, filename), "ascii") +
- encodedtext + b"\n \nend\n")
- return res
-
-class UUTest(unittest.TestCase):
-
- def test_encode(self):
- inp = io.BytesIO(plaintext)
- out = io.BytesIO()
- uu.encode(inp, out, "t1")
- self.assertEqual(out.getvalue(), encodedtextwrapped(0o666, "t1"))
- inp = io.BytesIO(plaintext)
- out = io.BytesIO()
- uu.encode(inp, out, "t1", 0o644)
- self.assertEqual(out.getvalue(), encodedtextwrapped(0o644, "t1"))
- inp = io.BytesIO(plaintext)
- out = io.BytesIO()
- uu.encode(inp, out, "t1", backtick=True)
- self.assertEqual(out.getvalue(), encodedtextwrapped(0o666, "t1", True))
- with self.assertRaises(TypeError):
- uu.encode(inp, out, "t1", 0o644, True)
-
- @os_helper.skip_unless_working_chmod
- def test_decode(self):
- for backtick in True, False:
- inp = io.BytesIO(encodedtextwrapped(0o666, "t1", backtick=backtick))
- out = io.BytesIO()
- uu.decode(inp, out)
- self.assertEqual(out.getvalue(), plaintext)
- inp = io.BytesIO(
- b"UUencoded files may contain many lines,\n" +
- b"even some that have 'begin' in them.\n" +
- encodedtextwrapped(0o666, "t1", backtick=backtick)
- )
- out = io.BytesIO()
- uu.decode(inp, out)
- self.assertEqual(out.getvalue(), plaintext)
-
- def test_truncatedinput(self):
- inp = io.BytesIO(b"begin 644 t1\n" + encodedtext)
- out = io.BytesIO()
- try:
- uu.decode(inp, out)
- self.fail("No exception raised")
- except uu.Error as e:
- self.assertEqual(str(e), "Truncated input file")
-
- def test_missingbegin(self):
- inp = io.BytesIO(b"")
- out = io.BytesIO()
- try:
- uu.decode(inp, out)
- self.fail("No exception raised")
- except uu.Error as e:
- self.assertEqual(str(e), "No valid begin line found in input file")
-
- def test_garbage_padding(self):
- # Issue #22406
- encodedtext1 = (
- b"begin 644 file\n"
- # length 1; bits 001100 111111 111111 111111
- b"\x21\x2C\x5F\x5F\x5F\n"
- b"\x20\n"
- b"end\n"
- )
- encodedtext2 = (
- b"begin 644 file\n"
- # length 1; bits 001100 111111 111111 111111
- b"\x21\x2C\x5F\x5F\x5F\n"
- b"\x60\n"
- b"end\n"
- )
- plaintext = b"\x33" # 00110011
-
- for encodedtext in encodedtext1, encodedtext2:
- with self.subTest("uu.decode()"):
- inp = io.BytesIO(encodedtext)
- out = io.BytesIO()
- uu.decode(inp, out, quiet=True)
- self.assertEqual(out.getvalue(), plaintext)
-
- with self.subTest("uu_codec"):
- import codecs
- decoded = codecs.decode(encodedtext, "uu_codec")
- self.assertEqual(decoded, plaintext)
-
- def test_newlines_escaped(self):
- # Test newlines are escaped with uu.encode
- inp = io.BytesIO(plaintext)
- out = io.BytesIO()
- filename = "test.txt\n\roverflow.txt"
- safefilename = b"test.txt\\n\\roverflow.txt"
- uu.encode(inp, out, filename)
- self.assertIn(safefilename, out.getvalue())
-
- def test_no_directory_traversal(self):
- relative_bad = b"""\
-begin 644 ../../../../../../../../tmp/test1
-$86)C"@``
-`
-end
-"""
- with self.assertRaisesRegex(uu.Error, 'directory'):
- uu.decode(io.BytesIO(relative_bad))
- if os.altsep:
- relative_bad_bs = relative_bad.replace(b'/', b'\\')
- with self.assertRaisesRegex(uu.Error, 'directory'):
- uu.decode(io.BytesIO(relative_bad_bs))
-
- absolute_bad = b"""\
-begin 644 /tmp/test2
-$86)C"@``
-`
-end
-"""
- with self.assertRaisesRegex(uu.Error, 'directory'):
- uu.decode(io.BytesIO(absolute_bad))
- if os.altsep:
- absolute_bad_bs = absolute_bad.replace(b'/', b'\\')
- with self.assertRaisesRegex(uu.Error, 'directory'):
- uu.decode(io.BytesIO(absolute_bad_bs))
-
-
-class UUStdIOTest(unittest.TestCase):
-
- def setUp(self):
- self.stdin = sys.stdin
- self.stdout = sys.stdout
-
- def tearDown(self):
- sys.stdin = self.stdin
- sys.stdout = self.stdout
-
- def test_encode(self):
- sys.stdin = FakeIO(plaintext.decode("ascii"))
- sys.stdout = FakeIO()
- uu.encode("-", "-", "t1", 0o666)
- self.assertEqual(sys.stdout.getvalue(),
- encodedtextwrapped(0o666, "t1").decode("ascii"))
-
- def test_decode(self):
- sys.stdin = FakeIO(encodedtextwrapped(0o666, "t1").decode("ascii"))
- sys.stdout = FakeIO()
- uu.decode("-", "-")
- stdout = sys.stdout
- sys.stdout = self.stdout
- sys.stdin = self.stdin
- self.assertEqual(stdout.getvalue(), plaintext.decode("ascii"))
-
-class UUFileTest(unittest.TestCase):
-
- def setUp(self):
- # uu.encode() supports only ASCII file names
- self.tmpin = os_helper.TESTFN_ASCII + "i"
- self.tmpout = os_helper.TESTFN_ASCII + "o"
- self.addCleanup(os_helper.unlink, self.tmpin)
- self.addCleanup(os_helper.unlink, self.tmpout)
-
- def test_encode(self):
- with open(self.tmpin, 'wb') as fin:
- fin.write(plaintext)
-
- with open(self.tmpin, 'rb') as fin:
- with open(self.tmpout, 'wb') as fout:
- uu.encode(fin, fout, self.tmpin, mode=0o644)
-
- with open(self.tmpout, 'rb') as fout:
- s = fout.read()
- self.assertEqual(s, encodedtextwrapped(0o644, self.tmpin))
-
- # in_file and out_file as filenames
- uu.encode(self.tmpin, self.tmpout, self.tmpin, mode=0o644)
- with open(self.tmpout, 'rb') as fout:
- s = fout.read()
- self.assertEqual(s, encodedtextwrapped(0o644, self.tmpin))
-
- # decode() calls chmod()
- @os_helper.skip_unless_working_chmod
- def test_decode(self):
- with open(self.tmpin, 'wb') as f:
- f.write(encodedtextwrapped(0o644, self.tmpout))
-
- with open(self.tmpin, 'rb') as f:
- uu.decode(f)
-
- with open(self.tmpout, 'rb') as f:
- s = f.read()
- self.assertEqual(s, plaintext)
- # XXX is there an xp way to verify the mode?
-
- @os_helper.skip_unless_working_chmod
- def test_decode_filename(self):
- with open(self.tmpin, 'wb') as f:
- f.write(encodedtextwrapped(0o644, self.tmpout))
-
- uu.decode(self.tmpin)
-
- with open(self.tmpout, 'rb') as f:
- s = f.read()
- self.assertEqual(s, plaintext)
-
- @os_helper.skip_unless_working_chmod
- def test_decodetwice(self):
- # Verify that decode() will refuse to overwrite an existing file
- with open(self.tmpin, 'wb') as f:
- f.write(encodedtextwrapped(0o644, self.tmpout))
- with open(self.tmpin, 'rb') as f:
- uu.decode(f)
-
- with open(self.tmpin, 'rb') as f:
- self.assertRaises(uu.Error, uu.decode, f)
-
- @os_helper.skip_unless_working_chmod
- def test_decode_mode(self):
- # Verify that decode() will set the given mode for the out_file
- expected_mode = 0o444
- with open(self.tmpin, 'wb') as f:
- f.write(encodedtextwrapped(expected_mode, self.tmpout))
-
- # make file writable again, so it can be removed (Windows only)
- self.addCleanup(os.chmod, self.tmpout, expected_mode | stat.S_IWRITE)
-
- with open(self.tmpin, 'rb') as f:
- uu.decode(f)
-
- self.assertEqual(
- stat.S_IMODE(os.stat(self.tmpout).st_mode),
- expected_mode
- )
-
-
-if __name__=="__main__":
- unittest.main()
diff --git a/Lib/uu.py b/Lib/uu.py
deleted file mode 100644
index 26bb59a..0000000
--- a/Lib/uu.py
+++ /dev/null
@@ -1,216 +0,0 @@
-#! /usr/bin/env python3
-
-# Copyright 1994 by Lance Ellinghouse
-# Cathedral City, California Republic, United States of America.
-# All Rights Reserved
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose and without fee is hereby granted,
-# provided that the above copyright notice appear in all copies and that
-# both that copyright notice and this permission notice appear in
-# supporting documentation, and that the name of Lance Ellinghouse
-# not be used in advertising or publicity pertaining to distribution
-# of the software without specific, written prior permission.
-# LANCE ELLINGHOUSE DISCLAIMS ALL WARRANTIES WITH REGARD TO
-# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
-# FITNESS, IN NO EVENT SHALL LANCE ELLINGHOUSE CENTRUM BE LIABLE
-# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-#
-# Modified by Jack Jansen, CWI, July 1995:
-# - Use binascii module to do the actual line-by-line conversion
-# between ascii and binary. This results in a 1000-fold speedup. The C
-# version is still 5 times faster, though.
-# - Arguments more compliant with python standard
-
-"""Implementation of the UUencode and UUdecode functions.
-
-encode(in_file, out_file [,name, mode], *, backtick=False)
-decode(in_file [, out_file, mode, quiet])
-"""
-
-import binascii
-import os
-import sys
-import warnings
-
-warnings._deprecated(__name__, remove=(3, 13))
-
-__all__ = ["Error", "encode", "decode"]
-
-class Error(Exception):
- pass
-
-def encode(in_file, out_file, name=None, mode=None, *, backtick=False):
- """Uuencode file"""
- #
- # If in_file is a pathname open it and change defaults
- #
- opened_files = []
- try:
- if in_file == '-':
- in_file = sys.stdin.buffer
- elif isinstance(in_file, str):
- if name is None:
- name = os.path.basename(in_file)
- if mode is None:
- try:
- mode = os.stat(in_file).st_mode
- except AttributeError:
- pass
- in_file = open(in_file, 'rb')
- opened_files.append(in_file)
- #
- # Open out_file if it is a pathname
- #
- if out_file == '-':
- out_file = sys.stdout.buffer
- elif isinstance(out_file, str):
- out_file = open(out_file, 'wb')
- opened_files.append(out_file)
- #
- # Set defaults for name and mode
- #
- if name is None:
- name = '-'
- if mode is None:
- mode = 0o666
-
- #
- # Remove newline chars from name
- #
- name = name.replace('\n','\\n')
- name = name.replace('\r','\\r')
-
- #
- # Write the data
- #
- out_file.write(('begin %o %s\n' % ((mode & 0o777), name)).encode("ascii"))
- data = in_file.read(45)
- while len(data) > 0:
- out_file.write(binascii.b2a_uu(data, backtick=backtick))
- data = in_file.read(45)
- if backtick:
- out_file.write(b'`\nend\n')
- else:
- out_file.write(b' \nend\n')
- finally:
- for f in opened_files:
- f.close()
-
-
-def decode(in_file, out_file=None, mode=None, quiet=False):
- """Decode uuencoded file"""
- #
- # Open the input file, if needed.
- #
- opened_files = []
- if in_file == '-':
- in_file = sys.stdin.buffer
- elif isinstance(in_file, str):
- in_file = open(in_file, 'rb')
- opened_files.append(in_file)
-
- try:
- #
- # Read until a begin is encountered or we've exhausted the file
- #
- while True:
- hdr = in_file.readline()
- if not hdr:
- raise Error('No valid begin line found in input file')
- if not hdr.startswith(b'begin'):
- continue
- hdrfields = hdr.split(b' ', 2)
- if len(hdrfields) == 3 and hdrfields[0] == b'begin':
- try:
- int(hdrfields[1], 8)
- break
- except ValueError:
- pass
- if out_file is None:
- # If the filename isn't ASCII, what's up with that?!?
- out_file = hdrfields[2].rstrip(b' \t\r\n\f').decode("ascii")
- if os.path.exists(out_file):
- raise Error(f'Cannot overwrite existing file: {out_file}')
- if (out_file.startswith(os.sep) or
- f'..{os.sep}' in out_file or (
- os.altsep and
- (out_file.startswith(os.altsep) or
- f'..{os.altsep}' in out_file))
- ):
- raise Error(f'Refusing to write to {out_file} due to directory traversal')
- if mode is None:
- mode = int(hdrfields[1], 8)
- #
- # Open the output file
- #
- if out_file == '-':
- out_file = sys.stdout.buffer
- elif isinstance(out_file, str):
- fp = open(out_file, 'wb')
- os.chmod(out_file, mode)
- out_file = fp
- opened_files.append(out_file)
- #
- # Main decoding loop
- #
- s = in_file.readline()
- while s and s.strip(b' \t\r\n\f') != b'end':
- try:
- data = binascii.a2b_uu(s)
- except binascii.Error as v:
- # Workaround for broken uuencoders by /Fredrik Lundh
- nbytes = (((s[0]-32) & 63) * 4 + 5) // 3
- data = binascii.a2b_uu(s[:nbytes])
- if not quiet:
- sys.stderr.write("Warning: %s\n" % v)
- out_file.write(data)
- s = in_file.readline()
- if not s:
- raise Error('Truncated input file')
- finally:
- for f in opened_files:
- f.close()
-
-def test():
- """uuencode/uudecode main program"""
-
- import optparse
- parser = optparse.OptionParser(usage='usage: %prog [-d] [-t] [input [output]]')
- parser.add_option('-d', '--decode', dest='decode', help='Decode (instead of encode)?', default=False, action='store_true')
- parser.add_option('-t', '--text', dest='text', help='data is text, encoded format unix-compatible text?', default=False, action='store_true')
-
- (options, args) = parser.parse_args()
- if len(args) > 2:
- parser.error('incorrect number of arguments')
- sys.exit(1)
-
- # Use the binary streams underlying stdin/stdout
- input = sys.stdin.buffer
- output = sys.stdout.buffer
- if len(args) > 0:
- input = args[0]
- if len(args) > 1:
- output = args[1]
-
- if options.decode:
- if options.text:
- if isinstance(output, str):
- output = open(output, 'wb')
- else:
- print(sys.argv[0], ': cannot do -t to stdout')
- sys.exit(1)
- decode(input, output)
- else:
- if options.text:
- if isinstance(input, str):
- input = open(input, 'rb')
- else:
- print(sys.argv[0], ': cannot do -t from stdin')
- sys.exit(1)
- encode(input, output)
-
-if __name__ == '__main__':
- test()
diff --git a/Misc/NEWS.d/3.12.0b1.rst b/Misc/NEWS.d/3.12.0b1.rst
index a1ea082..96d76f8 100644
--- a/Misc/NEWS.d/3.12.0b1.rst
+++ b/Misc/NEWS.d/3.12.0b1.rst
@@ -4,7 +4,7 @@
.. release date: 2023-05-22
.. section: Security
-Fixed a security in flaw in :func:`uu.decode` that could allow for directory
+Fixed a security in flaw in :func:`!uu.decode` that could allow for directory
traversal based on the input if no ``out_file`` was specified.
..
diff --git a/Misc/NEWS.d/next/Library/2023-05-25-15-54-02.gh-issue-104773.nW-5MI.rst b/Misc/NEWS.d/next/Library/2023-05-25-15-54-02.gh-issue-104773.nW-5MI.rst
new file mode 100644
index 0000000..522e259
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-05-25-15-54-02.gh-issue-104773.nW-5MI.rst
@@ -0,0 +1,2 @@
+:pep:`594`: Remove the :mod:`!uu` module, deprecated in Python 3.11. Patch
+by Victor Stinner.
diff --git a/Python/stdlib_module_names.h b/Python/stdlib_module_names.h
index 00742b3..db574fe 100644
--- a/Python/stdlib_module_names.h
+++ b/Python/stdlib_module_names.h
@@ -268,7 +268,6 @@ static const char* _Py_stdlib_module_names[] = {
"unicodedata",
"unittest",
"urllib",
-"uu",
"uuid",
"venv",
"warnings",
diff --git a/Tools/wasm/wasm_assets.py b/Tools/wasm/wasm_assets.py
index 5e59ee7..2cf5ac5 100755
--- a/Tools/wasm/wasm_assets.py
+++ b/Tools/wasm/wasm_assets.py
@@ -41,8 +41,6 @@ OMIT_FILES = (
# package management
"ensurepip/",
"venv/",
- # deprecated
- "uu.py",
# other platforms
"_aix_support.py",
"_osx_support.py",