summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'Lib')
-rw-r--r--Lib/_pyio.py26
-rw-r--r--Lib/io.py17
-rw-r--r--Lib/test/test_io.py10
3 files changed, 38 insertions, 15 deletions
diff --git a/Lib/_pyio.py b/Lib/_pyio.py
index cb5a619..56e9a0c 100644
--- a/Lib/_pyio.py
+++ b/Lib/_pyio.py
@@ -311,18 +311,20 @@ except AttributeError:
open_code = _open_code_with_warning
-class DocDescriptor:
- """Helper for builtins.open.__doc__
- """
- def __get__(self, obj, typ=None):
- return (
- "open(file, mode='r', buffering=-1, encoding=None, "
- "errors=None, newline=None, closefd=True)\n\n" +
- open.__doc__)
-
-
-# bpo-43680: Alias to open() kept for backward compatibility
-OpenWrapper = open
+def __getattr__(name):
+ if name == "OpenWrapper":
+ # bpo-43680: Until Python 3.9, _pyio.open was not a static method and
+ # builtins.open was set to OpenWrapper to not become a bound method
+ # when set to a class variable. _io.open is a built-in function whereas
+ # _pyio.open is a Python function. In Python 3.10, _pyio.open() is now
+ # a static method, and builtins.open() is now io.open().
+ import warnings
+ warnings.warn('OpenWrapper is deprecated, use open instead',
+ DeprecationWarning, stacklevel=2)
+ global OpenWrapper
+ OpenWrapper = open
+ return OpenWrapper
+ raise AttributeError(name)
# In normal operation, both `UnsupportedOperation`s should be bound to the
diff --git a/Lib/io.py b/Lib/io.py
index 01f1df8..2a6140c 100644
--- a/Lib/io.py
+++ b/Lib/io.py
@@ -56,7 +56,22 @@ from _io import (DEFAULT_BUFFER_SIZE, BlockingIOError, UnsupportedOperation,
BufferedWriter, BufferedRWPair, BufferedRandom,
IncrementalNewlineDecoder, text_encoding, TextIOWrapper)
-OpenWrapper = _io.open # for compatibility with _pyio
+
+def __getattr__(name):
+ if name == "OpenWrapper":
+ # bpo-43680: Until Python 3.9, _pyio.open was not a static method and
+ # builtins.open was set to OpenWrapper to not become a bound method
+ # when set to a class variable. _io.open is a built-in function whereas
+ # _pyio.open is a Python function. In Python 3.10, _pyio.open() is now
+ # a static method, and builtins.open() is now io.open().
+ import warnings
+ warnings.warn('OpenWrapper is deprecated, use open instead',
+ DeprecationWarning, stacklevel=2)
+ global OpenWrapper
+ OpenWrapper = open
+ return OpenWrapper
+ raise AttributeError(name)
+
# Pretend this exception was created here.
UnsupportedOperation.__module__ = "io"
diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py
index 48a3cca..32c29ea 100644
--- a/Lib/test/test_io.py
+++ b/Lib/test/test_io.py
@@ -4283,6 +4283,14 @@ class MiscIOTest(unittest.TestCase):
self.assertTrue(
warnings[1].startswith(b"<string>:8: EncodingWarning: "))
+ @support.cpython_only
+ # Depending if OpenWrapper was already created or not, the warning is
+ # emitted or not. For example, the attribute is already created when this
+ # test is run multiple times.
+ @warnings_helper.ignore_warnings(category=DeprecationWarning)
+ def test_openwrapper(self):
+ self.assertIs(self.io.OpenWrapper, self.io.open)
+
class CMiscIOTest(MiscIOTest):
io = io
@@ -4598,8 +4606,6 @@ def load_tests(*args):
globs = globals()
c_io_ns.update((x.__name__, globs["C" + x.__name__]) for x in mocks)
py_io_ns.update((x.__name__, globs["Py" + x.__name__]) for x in mocks)
- # Avoid turning open into a bound method.
- py_io_ns["open"] = pyio.OpenWrapper
for test in tests:
if test.__name__.startswith("C"):
for name, obj in c_io_ns.items():