summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorBrett Cannon <brett@python.org>2022-04-05 19:05:48 (GMT)
committerGitHub <noreply@github.com>2022-04-05 19:05:48 (GMT)
commitc1d93b6411f975d67e43942f1a2745a22983c18c (patch)
treecccdd369da191fa03268967013d60369ab48fcdf /Lib
parent944f09adfcc59f54432ac2947cf95f3465d90e1e (diff)
downloadcpython-c1d93b6411f975d67e43942f1a2745a22983c18c.zip
cpython-c1d93b6411f975d67e43942f1a2745a22983c18c.tar.gz
cpython-c1d93b6411f975d67e43942f1a2745a22983c18c.tar.bz2
bpo-47061: deprecate the `aifc` module (GH-32134)
Co-authored-by: Christian Heimes <christian@python.org>
Diffstat (limited to 'Lib')
-rw-r--r--Lib/aifc.py4
-rw-r--r--Lib/sndhdr.py5
-rw-r--r--Lib/test/support/warnings_helper.py8
-rw-r--r--Lib/test/test___all__.py1
-rw-r--r--Lib/test/test_aifc.py7
-rw-r--r--Lib/test/test_pyclbr.py6
-rw-r--r--Lib/test/test_warnings/__init__.py40
-rw-r--r--Lib/warnings.py21
8 files changed, 86 insertions, 6 deletions
diff --git a/Lib/aifc.py b/Lib/aifc.py
index d50f258..b5eab92 100644
--- a/Lib/aifc.py
+++ b/Lib/aifc.py
@@ -140,6 +140,10 @@ import warnings
__all__ = ["Error", "open"]
+
+warnings._deprecated(__name__, remove=(3, 13))
+
+
class Error(Exception):
pass
diff --git a/Lib/sndhdr.py b/Lib/sndhdr.py
index 96595c6..a63b6fd 100644
--- a/Lib/sndhdr.py
+++ b/Lib/sndhdr.py
@@ -33,6 +33,7 @@ explicitly given directories.
__all__ = ['what', 'whathdr']
from collections import namedtuple
+import warnings
SndHeaders = namedtuple('SndHeaders',
'filetype framerate nchannels nframes sampwidth')
@@ -73,7 +74,9 @@ def whathdr(filename):
tests = []
def test_aifc(h, f):
- import aifc
+ with warnings.catch_warnings():
+ warnings.simplefilter('ignore', category=DeprecationWarning)
+ import aifc
if not h.startswith(b'FORM'):
return None
if h[8:12] == b'AIFC':
diff --git a/Lib/test/support/warnings_helper.py b/Lib/test/support/warnings_helper.py
index a024fbe..28e96f88 100644
--- a/Lib/test/support/warnings_helper.py
+++ b/Lib/test/support/warnings_helper.py
@@ -1,10 +1,18 @@
import contextlib
import functools
+import importlib
import re
import sys
import warnings
+def import_deprecated(name):
+ """Import *name* while suppressing DeprecationWarning."""
+ with warnings.catch_warnings():
+ warnings.simplefilter('ignore', category=DeprecationWarning)
+ return importlib.import_module(name)
+
+
def check_syntax_warning(testcase, statement, errtext='',
*, lineno=1, offset=None):
# Test also that a warning is emitted only once.
diff --git a/Lib/test/test___all__.py b/Lib/test/test___all__.py
index a1a3d89..1ec83cb 100644
--- a/Lib/test/test___all__.py
+++ b/Lib/test/test___all__.py
@@ -41,6 +41,7 @@ class AllTest(unittest.TestCase):
def check_all(self, modname):
names = {}
with warnings_helper.check_warnings(
+ (f".*{modname}", DeprecationWarning),
(".* (module|package)", DeprecationWarning),
(".* (module|package)", PendingDeprecationWarning),
("", ResourceWarning),
diff --git a/Lib/test/test_aifc.py b/Lib/test/test_aifc.py
index fb6da41..ad8a7ee 100644
--- a/Lib/test/test_aifc.py
+++ b/Lib/test/test_aifc.py
@@ -1,6 +1,6 @@
from test.support import findfile
from test.support.os_helper import TESTFN, unlink
-from test.support.warnings_helper import check_no_resource_warning
+from test.support.warnings_helper import check_no_resource_warning, import_deprecated
import unittest
from unittest import mock
from test import audiotests
@@ -8,7 +8,10 @@ from audioop import byteswap
import io
import sys
import struct
-import aifc
+
+
+aifc = import_deprecated("aifc")
+
class AifcTest(audiotests.AudioWriteTests,
audiotests.AudioTestsWithSourceFile):
diff --git a/Lib/test/test_pyclbr.py b/Lib/test/test_pyclbr.py
index 157c522..329acf0 100644
--- a/Lib/test/test_pyclbr.py
+++ b/Lib/test/test_pyclbr.py
@@ -216,12 +216,12 @@ class PyclbrTest(TestCase):
def test_others(self):
cm = self.checkModule
- # These were once about the 10 longest modules
+ # These were once some of the longest modules.
+ cm('aifc', ignore=('_aifc_params',)) # set with = in module
cm('random', ignore=('Random',)) # from _random import Random as CoreGenerator
cm('cgi', ignore=('log',)) # set with = in module
cm('pickle', ignore=('partial', 'PickleBuffer'))
- cm('aifc', ignore=('_aifc_params',)) # set with = in module
- cm('re._parser', ignore=('dump', 'groups', 'pos')) # from ._constants import *; property
+ cm('sre_parse', ignore=('dump', 'groups', 'pos')) # from sre_constants import *; property
cm(
'pdb',
# pyclbr does not handle elegantly `typing` or properties
diff --git a/Lib/test/test_warnings/__init__.py b/Lib/test/test_warnings/__init__.py
index 4b1b4e1..f7f9311 100644
--- a/Lib/test/test_warnings/__init__.py
+++ b/Lib/test/test_warnings/__init__.py
@@ -1219,7 +1219,47 @@ class PyEnvironmentVariableTests(EnvironmentVariableTests, unittest.TestCase):
module = py_warnings
+class _DeprecatedTest(BaseTest, unittest.TestCase):
+
+ """Test _deprecated()."""
+
+ module = original_warnings
+
+ def test_warning(self):
+ version = (3, 11, 0, "final", 0)
+ test = [(4, 12), (4, 11), (4, 0), (3, 12)]
+ for remove in test:
+ msg = rf".*test_warnings.*{remove[0]}\.{remove[1]}"
+ filter = msg, DeprecationWarning
+ with self.subTest(remove=remove):
+ with warnings_helper.check_warnings(filter, quiet=False):
+ self.module._deprecated("test_warnings", remove=remove,
+ _version=version)
+
+ version = (3, 11, 0, "alpha", 0)
+ msg = r".*test_warnings.*3\.11"
+ with warnings_helper.check_warnings((msg, DeprecationWarning), quiet=False):
+ self.module._deprecated("test_warnings", remove=(3, 11),
+ _version=version)
+
+ def test_RuntimeError(self):
+ version = (3, 11, 0, "final", 0)
+ test = [(2, 0), (2, 12), (3, 10)]
+ for remove in test:
+ with self.subTest(remove=remove):
+ with self.assertRaises(RuntimeError):
+ self.module._deprecated("test_warnings", remove=remove,
+ _version=version)
+ for level in ["beta", "candidate", "final"]:
+ version = (3, 11, 0, level, 0)
+ with self.subTest(releaselevel=level):
+ with self.assertRaises(RuntimeError):
+ self.module._deprecated("test_warnings", remove=(3, 11),
+ _version=version)
+
+
class BootstrapTest(unittest.TestCase):
+
def test_issue_8766(self):
# "import encodings" emits a warning whereas the warnings is not loaded
# or not completely loaded (warnings imports indirectly encodings by
diff --git a/Lib/warnings.py b/Lib/warnings.py
index 691ccdd..887ca6e 100644
--- a/Lib/warnings.py
+++ b/Lib/warnings.py
@@ -483,6 +483,27 @@ class catch_warnings(object):
self._module._showwarnmsg_impl = self._showwarnmsg_impl
+_DEPRECATED_MSG = "{name!r} is deprecated and slated for removal in Python {remove}"
+
+def _deprecated(name, message=_DEPRECATED_MSG, *, remove, _version=sys.version_info):
+ """Warn that *name* is deprecated or should be removed.
+
+ RuntimeError is raised if *remove* specifies a major/minor tuple older than
+ the current Python version or the same version but past the alpha.
+
+ The *message* argument is formatted with *name* and *remove* as a Python
+ version (e.g. "3.11").
+
+ """
+ remove_formatted = f"{remove[0]}.{remove[1]}"
+ if (_version[:2] > remove) or (_version[:2] == remove and _version[3] != "alpha"):
+ msg = f"{name!r} was slated for removal after Python {remove_formatted} alpha"
+ raise RuntimeError(msg)
+ else:
+ msg = message.format(name=name, remove=remove_formatted)
+ warn(msg, DeprecationWarning, stacklevel=3)
+
+
# Private utility function called by _PyErr_WarnUnawaitedCoroutine
def _warn_unawaited_coroutine(coro):
msg_lines = [