diff options
author | Victor Stinner <vstinner@redhat.com> | 2019-05-23 03:45:09 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-23 03:45:09 +0200 |
commit | bc2aa816620c5e02ad8e94d8514b7e8f3f551ca1 (patch) | |
tree | bf5c847dda365eab94373bc06262d2092dd9077e /Lib/_pyio.py | |
parent | bpo-36721: Add --embed option to python-config (GH-13500) (diff) | |
download | cpython-bc2aa816620c5e02ad8e94d8514b7e8f3f551ca1.tar.gz cpython-bc2aa816620c5e02ad8e94d8514b7e8f3f551ca1.tar.bz2 cpython-bc2aa816620c5e02ad8e94d8514b7e8f3f551ca1.zip |
bpo-18748: _pyio.IOBase emits unraisable exception (GH-13512)
In development (-X dev) mode and in a debug build, IOBase finalizer
of the _pyio module now logs the exception if the close() method
fails. The exception is ignored silently by default in release build.
test_io: test_error_through_destructor() now uses
support.catch_unraisable_exception() rather than capturing stderr.
Diffstat (limited to 'Lib/_pyio.py')
-rw-r--r-- | Lib/_pyio.py | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/Lib/_pyio.py b/Lib/_pyio.py index af2ce30c278..be5e4266daf 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -33,6 +33,10 @@ DEFAULT_BUFFER_SIZE = 8 * 1024 # bytes # Rebind for compatibility BlockingIOError = BlockingIOError +# Does io.IOBase finalizer log the exception if the close() method fails? +# The exception is ignored silently by default in release build. +_IOBASE_EMITS_UNRAISABLE = (hasattr(sys, "gettotalrefcount") or sys.flags.dev_mode) + def open(file, mode="r", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None): @@ -378,15 +382,18 @@ class IOBase(metaclass=abc.ABCMeta): def __del__(self): """Destructor. Calls close().""" - # The try/except block is in case this is called at program - # exit time, when it's possible that globals have already been - # deleted, and then the close() call might fail. Since - # there's nothing we can do about such failures and they annoy - # the end users, we suppress the traceback. - try: + if _IOBASE_EMITS_UNRAISABLE: self.close() - except: - pass + else: + # The try/except block is in case this is called at program + # exit time, when it's possible that globals have already been + # deleted, and then the close() call might fail. Since + # there's nothing we can do about such failures and they annoy + # the end users, we suppress the traceback. + try: + self.close() + except: + pass ### Inquiries ### |