bpo-43680: _pyio.open() becomes a static method (GH-25354)

The Python _pyio.open() function becomes a static method to behave as
io.open() built-in function: don't become a bound method when stored
as a class variable. It becomes possible since static methods are now
callable in Python 3.10. Moreover, _pyio.OpenWrapper becomes a simple
alias to _pyio.open.

init_set_builtins_open() now sets builtins.open to io.open, rather
than setting it to io.OpenWrapper, since OpenWrapper is now an alias
to open in the io and _pyio modules.
This commit is contained in:
Victor Stinner 2021-04-12 10:44:53 +02:00 committed by GitHub
parent 9825bdfbd5
commit 77d668b122
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 18 additions and 14 deletions

View File

@ -63,6 +63,13 @@ def text_encoding(encoding, stacklevel=2):
return encoding return encoding
# Wrapper for builtins.open
#
# Trick so that open() won't become a bound method when stored
# as a class variable (as dbm.dumb does).
#
# See init_set_builtins_open() in Python/pylifecycle.c.
@staticmethod
def open(file, mode="r", buffering=-1, encoding=None, errors=None, def open(file, mode="r", buffering=-1, encoding=None, errors=None,
newline=None, closefd=True, opener=None): newline=None, closefd=True, opener=None):
@ -313,18 +320,9 @@ class DocDescriptor:
"errors=None, newline=None, closefd=True)\n\n" + "errors=None, newline=None, closefd=True)\n\n" +
open.__doc__) open.__doc__)
class OpenWrapper:
"""Wrapper for builtins.open
Trick so that open won't become a bound method when stored # bpo-43680: Alias to open() kept for backward compatibility
as a class variable (as dbm.dumb does). OpenWrapper = open
See initstdio() in Python/pylifecycle.c.
"""
__doc__ = DocDescriptor()
def __new__(cls, *args, **kwargs):
return open(*args, **kwargs)
# In normal operation, both `UnsupportedOperation`s should be bound to the # In normal operation, both `UnsupportedOperation`s should be bound to the

View File

@ -0,0 +1,6 @@
The Python :func:`_pyio.open` function becomes a static method to behave as
:func:`io.open` built-in function: don't become a bound method when stored as a
class variable. It becomes possible since static methods are now callable in
Python 3.10. Moreover, :func:`_pyio.OpenWrapper` becomes a simple alias to
:func:`_pyio.open`.
Patch by Victor Stinner.

View File

@ -2241,7 +2241,7 @@ error:
return NULL; return NULL;
} }
/* Set builtins.open to io.OpenWrapper */ /* Set builtins.open to io.open */
static PyStatus static PyStatus
init_set_builtins_open(void) init_set_builtins_open(void)
{ {
@ -2257,7 +2257,7 @@ init_set_builtins_open(void)
goto error; goto error;
} }
if (!(wrapper = PyObject_GetAttrString(iomod, "OpenWrapper"))) { if (!(wrapper = PyObject_GetAttrString(iomod, "open"))) {
goto error; goto error;
} }
@ -2279,7 +2279,7 @@ done:
} }
/* Initialize sys.stdin, stdout, stderr and builtins.open */ /* Create sys.stdin, sys.stdout and sys.stderr */
static PyStatus static PyStatus
init_sys_streams(PyThreadState *tstate) init_sys_streams(PyThreadState *tstate)
{ {