diff options
author | Victor Stinner <vstinner@python.org> | 2021-04-14 01:24:33 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-14 01:24:33 (GMT) |
commit | 3bc694d5f3d4eb2e5d2f0b83e498b19662845d4e (patch) | |
tree | 43e6d321001603933495058eedce97d43641f02f | |
parent | 11159d2c9d6616497ef4cc62953a5c3cc8454afb (diff) | |
download | cpython-3bc694d5f3d4eb2e5d2f0b83e498b19662845d4e.zip cpython-3bc694d5f3d4eb2e5d2f0b83e498b19662845d4e.tar.gz cpython-3bc694d5f3d4eb2e5d2f0b83e498b19662845d4e.tar.bz2 |
bpo-43680: Deprecate io.OpenWrapper (GH-25357)
Deprecate io.OpenWrapper and _pyio.OpenWrapper: use io.open and
_pyio.open instead. 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().
-rw-r--r-- | Lib/_pyio.py | 26 | ||||
-rw-r--r-- | Lib/io.py | 17 | ||||
-rw-r--r-- | Lib/test/test_io.py | 10 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2021-04-12-11-20-34.bpo-43680.SR0Epv.rst | 6 |
4 files changed, 44 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 @@ -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(): diff --git a/Misc/NEWS.d/next/Library/2021-04-12-11-20-34.bpo-43680.SR0Epv.rst b/Misc/NEWS.d/next/Library/2021-04-12-11-20-34.bpo-43680.SR0Epv.rst new file mode 100644 index 0000000..e4ddb96 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-04-12-11-20-34.bpo-43680.SR0Epv.rst @@ -0,0 +1,6 @@ +Deprecate io.OpenWrapper and _pyio.OpenWrapper: use io.open and _pyio.open +instead. 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(). |