summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/hashlib.rst4
-rw-r--r--Lib/_pyio.py12
-rw-r--r--Lib/modulefinder.py1
-rw-r--r--Lib/test/test_bytes.py6
-rw-r--r--Lib/test/test_io.py28
-rw-r--r--Lib/test/test_modulefinder.py15
-rw-r--r--Misc/ACKS4
-rw-r--r--Misc/NEWS8
-rw-r--r--Modules/_ctypes/callproc.c2
-rw-r--r--Modules/_decimal/_decimal.c2
-rw-r--r--Modules/_decimal/libmpdec/basearith.h7
-rw-r--r--Modules/_decimal/libmpdec/constants.h7
-rw-r--r--Modules/_decimal/libmpdec/convolute.h9
-rw-r--r--Modules/_decimal/libmpdec/crt.h7
-rw-r--r--Modules/_decimal/libmpdec/difradix2.h7
-rw-r--r--Modules/_decimal/libmpdec/fnt.h7
-rw-r--r--Modules/_decimal/libmpdec/fourstep.h7
-rw-r--r--Modules/_decimal/libmpdec/memory.h7
-rw-r--r--Modules/_decimal/libmpdec/mpdecimal.c14
-rw-r--r--Modules/_decimal/libmpdec/mpdecimal.h21
-rw-r--r--Modules/_decimal/libmpdec/numbertheory.h7
-rw-r--r--Modules/_decimal/libmpdec/sixstep.h7
-rw-r--r--Modules/_decimal/libmpdec/transpose.h7
-rw-r--r--Modules/_io/bufferedio.c26
-rw-r--r--Modules/_io/textio.c24
-rw-r--r--Objects/bytesobject.c33
26 files changed, 246 insertions, 33 deletions
diff --git a/Doc/library/hashlib.rst b/Doc/library/hashlib.rst
index bc8ab2c..929d41b 100644
--- a/Doc/library/hashlib.rst
+++ b/Doc/library/hashlib.rst
@@ -40,12 +40,12 @@ concatenation of the data fed to it so far using the :meth:`digest` or
.. note::
- For better multithreading performance, the Python GIL is released for
+ For better multithreading performance, the Python :term:`GIL` is released for
strings of more than 2047 bytes at object creation or on update.
.. note::
- Feeding string objects is to :meth:`update` is not supported, as hashes work
+ Feeding string objects into :meth:`update` is not supported, as hashes work
on bytes, not on characters.
.. index:: single: OpenSSL; (use in module hashlib)
diff --git a/Lib/_pyio.py b/Lib/_pyio.py
index fa77ec1..9cbb364 100644
--- a/Lib/_pyio.py
+++ b/Lib/_pyio.py
@@ -346,8 +346,10 @@ class IOBase(metaclass=abc.ABCMeta):
This method has no effect if the file is already closed.
"""
if not self.__closed:
- self.flush()
- self.__closed = True
+ try:
+ self.flush()
+ finally:
+ self.__closed = True
def __del__(self):
"""Destructor. Calls close()."""
@@ -1584,8 +1586,10 @@ class TextIOWrapper(TextIOBase):
def close(self):
if self.buffer is not None and not self.closed:
- self.flush()
- self.buffer.close()
+ try:
+ self.flush()
+ finally:
+ self.buffer.close()
@property
def closed(self):
diff --git a/Lib/modulefinder.py b/Lib/modulefinder.py
index 683e305..f90a432 100644
--- a/Lib/modulefinder.py
+++ b/Lib/modulefinder.py
@@ -2,6 +2,7 @@
import dis
import imp
+import importlib.machinery
import marshal
import os
import sys
diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py
index fe6e939..f88c242 100644
--- a/Lib/test/test_bytes.py
+++ b/Lib/test/test_bytes.py
@@ -701,6 +701,12 @@ class BytesTest(BaseBytesTest):
def __bytes__(self):
return None
self.assertRaises(TypeError, bytes, A())
+ class A:
+ def __bytes__(self):
+ return b'a'
+ def __index__(self):
+ return 42
+ self.assertEqual(bytes(A()), b'a')
# Test PyBytes_FromFormat()
def test_from_format(self):
diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py
index 555ad74..6931e0a 100644
--- a/Lib/test/test_io.py
+++ b/Lib/test/test_io.py
@@ -603,6 +603,7 @@ class IOTest(unittest.TestCase):
raise IOError()
f.flush = bad_flush
self.assertRaises(IOError, f.close) # exception not swallowed
+ self.assertTrue(f.closed)
def test_multi_close(self):
f = self.open(support.TESTFN, "wb", buffering=0)
@@ -780,6 +781,22 @@ class CommonBufferedTests:
raw.flush = bad_flush
b = self.tp(raw)
self.assertRaises(IOError, b.close) # exception not swallowed
+ self.assertTrue(b.closed)
+
+ def test_close_error_on_close(self):
+ raw = self.MockRawIO()
+ def bad_flush():
+ raise IOError('flush')
+ def bad_close():
+ raise IOError('close')
+ raw.close = bad_close
+ b = self.tp(raw)
+ b.flush = bad_flush
+ with self.assertRaises(IOError) as err: # exception not swallowed
+ b.close()
+ self.assertEqual(err.exception.args, ('close',))
+ self.assertEqual(err.exception.__context__.args, ('flush',))
+ self.assertFalse(b.closed)
def test_multi_close(self):
raw = self.MockRawIO()
@@ -1296,6 +1313,16 @@ class BufferedWriterTest(unittest.TestCase, CommonBufferedTests):
with self.assertRaises(TypeError):
self.tp(self.MockRawIO(), 8, 12)
+ def test_write_error_on_close(self):
+ raw = self.MockRawIO()
+ def bad_write(b):
+ raise IOError()
+ raw.write = bad_write
+ b = self.tp(raw)
+ b.write(b'spam')
+ self.assertRaises(IOError, b.close) # exception not swallowed
+ self.assertTrue(b.closed)
+
class CBufferedWriterTest(BufferedWriterTest, SizeofTest):
tp = io.BufferedWriter
@@ -2465,6 +2492,7 @@ class TextIOWrapperTest(unittest.TestCase):
raise IOError()
txt.flush = bad_flush
self.assertRaises(IOError, txt.close) # exception not swallowed
+ self.assertTrue(txt.closed)
def test_multi_close(self):
txt = self.TextIOWrapper(self.BytesIO(self.testdata), encoding="ascii")
diff --git a/Lib/test/test_modulefinder.py b/Lib/test/test_modulefinder.py
index c5fc320..53ea232 100644
--- a/Lib/test/test_modulefinder.py
+++ b/Lib/test/test_modulefinder.py
@@ -196,6 +196,18 @@ a/module.py
from . import bar
"""]
+relative_import_test_4 = [
+ "a.module",
+ ["a", "a.module"],
+ [],
+ [],
+ """\
+a/__init__.py
+ def foo(): pass
+a/module.py
+ from . import *
+"""]
+
def open_file(path):
dirname = os.path.dirname(path)
@@ -273,6 +285,9 @@ class ModuleFinderTest(unittest.TestCase):
def test_relative_imports_3(self):
self._do_test(relative_import_test_3)
+ def test_relative_imports_4(self):
+ self._do_test(relative_import_test_4)
+
def test_main():
support.run_unittest(ModuleFinderTest)
diff --git a/Misc/ACKS b/Misc/ACKS
index a5351b3..e4d1783 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -894,15 +894,13 @@ Dan Parisien
William Park
Harri Pasanen
Gaël Pasgrimaud
-Berker Peksag
-Bo Peng
-Joe Peterson
Randy Pausch
Samuele Pedroni
Justin Peel
Marcel van der Peijl
Berker Peksag
Steven Pemberton
+Bo Peng
Santiago Peresón
George Peristerakis
Mathieu Perreault
diff --git a/Misc/NEWS b/Misc/NEWS
index 7ba832e..97e24fa 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,12 @@ What's New in Python 3.3.1?
Core and Builtins
-----------------
+- Issue #16597: In buffered and text IO, call close() on the underlying stream
+ if invoking flush() fails.
+
+- Issue #16722: In the bytes() constructor, try to call __bytes__ on the
+ argument before __index__.
+
- Issue #16602: When a weakref's target was part of a long deallocation
chain, the object could remain reachable through its weakref even though
its refcount had dropped to zero.
@@ -108,6 +114,8 @@ Core and Builtins
Library
-------
+- Issue #16752: Add a missing import to modulefinder. Patch by Berker Peksag.
+
- Issue #16646: ftplib.FTP.makeport() might lose socket error details.
(patch by Serhiy Storchaka)
diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c
index 09320cf..e940ec7 100644
--- a/Modules/_ctypes/callproc.c
+++ b/Modules/_ctypes/callproc.c
@@ -817,11 +817,11 @@ static int _call_function_pointer(int flags,
space[0] = errno;
errno = temp;
}
- Py_XDECREF(error_object);
#ifdef WITH_THREAD
if ((flags & FUNCFLAG_PYTHONAPI) == 0)
Py_BLOCK_THREADS
#endif
+ Py_XDECREF(error_object);
#ifdef MS_WIN32
#ifndef DONT_USE_SEH
if (dwExceptionCode) {
diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c
index 4fb9998..4dc9087 100644
--- a/Modules/_decimal/_decimal.c
+++ b/Modules/_decimal/_decimal.c
@@ -3484,7 +3484,7 @@ PyDec_Round(PyObject *dec, PyObject *args)
}
}
-PyObject *DecimalTuple = NULL;
+static PyObject *DecimalTuple = NULL;
/* Return the DecimalTuple representation of a PyDecObject. */
static PyObject *
PyDec_AsTuple(PyObject *dec, PyObject *dummy UNUSED)
diff --git a/Modules/_decimal/libmpdec/basearith.h b/Modules/_decimal/libmpdec/basearith.h
index 5004b2c..114cef3 100644
--- a/Modules/_decimal/libmpdec/basearith.h
+++ b/Modules/_decimal/libmpdec/basearith.h
@@ -35,6 +35,10 @@
#include "typearith.h"
+/* Internal header file: all symbols have local scope in the DSO */
+MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
+
+
mpd_uint_t _mpd_baseadd(mpd_uint_t *w, const mpd_uint_t *u, const mpd_uint_t *v,
mpd_size_t m, mpd_size_t n);
void _mpd_baseaddto(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n);
@@ -209,6 +213,9 @@ _mpd_isallnine(const mpd_uint_t *data, mpd_ssize_t len)
}
+MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */
+
+
#endif /* BASEARITH_H */
diff --git a/Modules/_decimal/libmpdec/constants.h b/Modules/_decimal/libmpdec/constants.h
index 2d63d7e..13df920 100644
--- a/Modules/_decimal/libmpdec/constants.h
+++ b/Modules/_decimal/libmpdec/constants.h
@@ -33,6 +33,10 @@
#include "mpdecimal.h"
+/* Internal header file: all symbols have local scope in the DSO */
+MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
+
+
/* choice of optimized functions */
#if defined(CONFIG_64)
/* x64 */
@@ -77,6 +81,9 @@ extern const mpd_uint_t LH_P1P2;
extern const mpd_uint_t UH_P1P2;
+MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */
+
+
#endif /* CONSTANTS_H */
diff --git a/Modules/_decimal/libmpdec/convolute.h b/Modules/_decimal/libmpdec/convolute.h
index 2f8d6d8..c35ed46 100644
--- a/Modules/_decimal/libmpdec/convolute.h
+++ b/Modules/_decimal/libmpdec/convolute.h
@@ -33,11 +33,18 @@
#include "mpdecimal.h"
#include <stdio.h>
-#define SIX_STEP_THRESHOLD 4096
+/* Internal header file: all symbols have local scope in the DSO */
+MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
+
+
+#define SIX_STEP_THRESHOLD 4096
int fnt_convolute(mpd_uint_t *c1, mpd_uint_t *c2, mpd_size_t n, int modnum);
int fnt_autoconvolute(mpd_uint_t *c1, mpd_size_t n, int modnum);
+MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */
+
+
#endif
diff --git a/Modules/_decimal/libmpdec/crt.h b/Modules/_decimal/libmpdec/crt.h
index 0e03e5d..8909232 100644
--- a/Modules/_decimal/libmpdec/crt.h
+++ b/Modules/_decimal/libmpdec/crt.h
@@ -34,7 +34,14 @@
#include <stdio.h>
+/* Internal header file: all symbols have local scope in the DSO */
+MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
+
+
void crt3(mpd_uint_t *x1, mpd_uint_t *x2, mpd_uint_t *x3, mpd_size_t nmemb);
+MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */
+
+
#endif
diff --git a/Modules/_decimal/libmpdec/difradix2.h b/Modules/_decimal/libmpdec/difradix2.h
index 759442a..81aa598 100644
--- a/Modules/_decimal/libmpdec/difradix2.h
+++ b/Modules/_decimal/libmpdec/difradix2.h
@@ -35,7 +35,14 @@
#include "numbertheory.h"
+/* Internal header file: all symbols have local scope in the DSO */
+MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
+
+
void fnt_dif2(mpd_uint_t a[], mpd_size_t n, struct fnt_params *tparams);
+MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */
+
+
#endif
diff --git a/Modules/_decimal/libmpdec/fnt.h b/Modules/_decimal/libmpdec/fnt.h
index 2d701b6..1f302cc 100644
--- a/Modules/_decimal/libmpdec/fnt.h
+++ b/Modules/_decimal/libmpdec/fnt.h
@@ -34,9 +34,16 @@
#include <stdio.h>
+/* Internal header file: all symbols have local scope in the DSO */
+MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
+
+
int std_fnt(mpd_uint_t a[], mpd_size_t n, int modnum);
int std_inv_fnt(mpd_uint_t a[], mpd_size_t n, int modnum);
+MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */
+
+
#endif
diff --git a/Modules/_decimal/libmpdec/fourstep.h b/Modules/_decimal/libmpdec/fourstep.h
index 61d9d6a..593f27d 100644
--- a/Modules/_decimal/libmpdec/fourstep.h
+++ b/Modules/_decimal/libmpdec/fourstep.h
@@ -34,8 +34,15 @@
#include <stdio.h>
+/* Internal header file: all symbols have local scope in the DSO */
+MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
+
+
int four_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum);
int inv_four_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum);
+MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */
+
+
#endif
diff --git a/Modules/_decimal/libmpdec/memory.h b/Modules/_decimal/libmpdec/memory.h
index b3a4a56..7e73c13 100644
--- a/Modules/_decimal/libmpdec/memory.h
+++ b/Modules/_decimal/libmpdec/memory.h
@@ -33,11 +33,18 @@
#include "mpdecimal.h"
+/* Internal header file: all symbols have local scope in the DSO */
+MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
+
+
int mpd_switch_to_dyn(mpd_t *result, mpd_ssize_t size, uint32_t *status);
int mpd_switch_to_dyn_zero(mpd_t *result, mpd_ssize_t size, uint32_t *status);
int mpd_realloc_dyn(mpd_t *result, mpd_ssize_t size, uint32_t *status);
+MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */
+
+
#endif
diff --git a/Modules/_decimal/libmpdec/mpdecimal.c b/Modules/_decimal/libmpdec/mpdecimal.c
index 05f7628..6633fb6 100644
--- a/Modules/_decimal/libmpdec/mpdecimal.c
+++ b/Modules/_decimal/libmpdec/mpdecimal.c
@@ -107,7 +107,7 @@ static inline void _mpd_qpow_uint(mpd_t *result, const mpd_t *base,
mpd_uint_t exp, uint8_t resultsign,
const mpd_context_t *ctx, uint32_t *status);
-mpd_uint_t mpd_qsshiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n);
+static mpd_uint_t mpd_qsshiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n);
/******************************************************************************/
@@ -2301,7 +2301,7 @@ _mpd_get_rnd(const mpd_uint_t *data, mpd_ssize_t len, int use_msd)
* It is the caller's responsibility to ensure that the coefficient is big
* enough. The function cannot fail.
*/
-mpd_uint_t
+static mpd_uint_t
mpd_qsshiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n)
{
mpd_uint_t rnd;
@@ -5123,7 +5123,7 @@ _karatsuba_rec(mpd_uint_t *c, const mpd_uint_t *a, const mpd_uint_t *b,
* to the result or NULL in case of failure (malloc error).
* Conditions: ulen >= vlen, ulen >= 4
*/
-mpd_uint_t *
+static mpd_uint_t *
_mpd_kmul(const mpd_uint_t *u, const mpd_uint_t *v,
mpd_size_t ulen, mpd_size_t vlen,
mpd_size_t *rsize)
@@ -5208,7 +5208,7 @@ _mpd_set_control87(unsigned short cw)
}
#endif
-unsigned int
+static unsigned int
mpd_set_fenv(void)
{
unsigned int cw;
@@ -5228,7 +5228,7 @@ mpd_set_fenv(void)
return cw;
}
-void
+static void
mpd_restore_fenv(unsigned int cw)
{
#ifdef _MSC_VER
@@ -5246,7 +5246,7 @@ mpd_restore_fenv(unsigned int cw)
* Multiply u and v, using the fast number theoretic transform. Returns
* a pointer to the result or NULL in case of failure (malloc error).
*/
-mpd_uint_t *
+static mpd_uint_t *
_mpd_fntmul(const mpd_uint_t *u, const mpd_uint_t *v,
mpd_size_t ulen, mpd_size_t vlen,
mpd_size_t *rsize)
@@ -5432,7 +5432,7 @@ _karatsuba_rec_fnt(mpd_uint_t *c, const mpd_uint_t *a, const mpd_uint_t *b,
* base case. Returns a pointer to the result or NULL in case of failure
* (malloc error). Conditions: ulen >= vlen, ulen >= 4.
*/
-mpd_uint_t *
+static mpd_uint_t *
_mpd_kmul_fnt(const mpd_uint_t *u, const mpd_uint_t *v,
mpd_size_t ulen, mpd_size_t vlen,
mpd_size_t *rsize)
diff --git a/Modules/_decimal/libmpdec/mpdecimal.h b/Modules/_decimal/libmpdec/mpdecimal.h
index d131c71..b7d4ff7 100644
--- a/Modules/_decimal/libmpdec/mpdecimal.h
+++ b/Modules/_decimal/libmpdec/mpdecimal.h
@@ -51,6 +51,9 @@ extern "C" {
#ifndef UNUSED
#define UNUSED
#endif
+ #define MPD_PRAGMA(x)
+ #define MPD_HIDE_SYMBOLS_START
+ #define MPD_HIDE_SYMBOLS_END
#define EXTINLINE extern inline
#else
#ifdef HAVE_STDINT_H
@@ -67,10 +70,25 @@ extern "C" {
#else
#define UNUSED
#endif
+ #if (defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)) && \
+ defined(__GNUC__) && __GNUC__ >= 4 && !defined(__INTEL_COMPILER)
+ #define MPD_PRAGMA(x) _Pragma(x)
+ #define MPD_HIDE_SYMBOLS_START "GCC visibility push(hidden)"
+ #define MPD_HIDE_SYMBOLS_END "GCC visibility pop"
+ #else
+ #define MPD_PRAGMA(x)
+ #define MPD_HIDE_SYMBOLS_START
+ #define MPD_HIDE_SYMBOLS_END
+ #endif
#define EXTINLINE
#endif
+/* This header file is internal for the purpose of building _decimal.so.
+ * All symbols should have local scope in the DSO. */
+MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
+
+
#if !defined(LEGACY_COMPILER)
#if !defined(UINT64_MAX)
/* The following #error is just a warning. If the compiler indeed does
@@ -789,6 +807,9 @@ int mpd_resize(mpd_t *result, mpd_ssize_t size, mpd_context_t *ctx);
int mpd_resize_zero(mpd_t *result, mpd_ssize_t size, mpd_context_t *ctx);
+MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */
+
+
#ifdef __cplusplus
} /* END extern "C" */
#endif
diff --git a/Modules/_decimal/libmpdec/numbertheory.h b/Modules/_decimal/libmpdec/numbertheory.h
index f54d11d..1092254 100644
--- a/Modules/_decimal/libmpdec/numbertheory.h
+++ b/Modules/_decimal/libmpdec/numbertheory.h
@@ -34,6 +34,10 @@
#include "mpdecimal.h"
+/* Internal header file: all symbols have local scope in the DSO */
+MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
+
+
/* transform parameters */
struct fnt_params {
int modnum;
@@ -66,6 +70,9 @@ std_setmodulus(int modnum, mpd_uint_t *umod)
#endif
+MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */
+
+
#endif
diff --git a/Modules/_decimal/libmpdec/sixstep.h b/Modules/_decimal/libmpdec/sixstep.h
index 4d251df..0467007 100644
--- a/Modules/_decimal/libmpdec/sixstep.h
+++ b/Modules/_decimal/libmpdec/sixstep.h
@@ -34,8 +34,15 @@
#include <stdio.h>
+/* Internal header file: all symbols have local scope in the DSO */
+MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
+
+
int six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum);
int inv_six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum);
+MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */
+
+
#endif
diff --git a/Modules/_decimal/libmpdec/transpose.h b/Modules/_decimal/libmpdec/transpose.h
index dd0aec6..7e349ee 100644
--- a/Modules/_decimal/libmpdec/transpose.h
+++ b/Modules/_decimal/libmpdec/transpose.h
@@ -34,6 +34,10 @@
#include <stdio.h>
+/* Internal header file: all symbols have local scope in the DSO */
+MPD_PRAGMA(MPD_HIDE_SYMBOLS_START)
+
+
enum {FORWARD_CYCLE, BACKWARD_CYCLE};
@@ -52,4 +56,7 @@ static inline void pointerswap(mpd_uint_t **a, mpd_uint_t **b)
}
+MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */
+
+
#endif
diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c
index 334734b..b077f34 100644
--- a/Modules/_io/bufferedio.c
+++ b/Modules/_io/bufferedio.c
@@ -484,7 +484,7 @@ buffered_closed_get(buffered *self, void *context)
static PyObject *
buffered_close(buffered *self, PyObject *args)
{
- PyObject *res = NULL;
+ PyObject *res = NULL, *exc = NULL, *val, *tb;
int r;
CHECK_INITIALIZED(self)
@@ -512,13 +512,29 @@ buffered_close(buffered *self, PyObject *args)
res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
if (!ENTER_BUFFERED(self))
return NULL;
- if (res == NULL) {
- goto end;
- }
- Py_XDECREF(res);
+ if (res == NULL)
+ PyErr_Fetch(&exc, &val, &tb);
+ else
+ Py_DECREF(res);
res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
+ if (exc != NULL) {
+ if (res != NULL) {
+ Py_CLEAR(res);
+ PyErr_Restore(exc, val, tb);
+ }
+ else {
+ PyObject *val2;
+ Py_DECREF(exc);
+ Py_XDECREF(tb);
+ PyErr_Fetch(&exc, &val2, &tb);
+ PyErr_NormalizeException(&exc, &val2, &tb);
+ PyException_SetContext(val2, val);
+ PyErr_Restore(exc, val2, tb);
+ }
+ }
+
end:
LEAVE_BUFFERED(self)
return res;
diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c
index 96434a8..83437d6 100644
--- a/Modules/_io/textio.c
+++ b/Modules/_io/textio.c
@@ -2554,6 +2554,7 @@ textiowrapper_close(textio *self, PyObject *args)
Py_RETURN_NONE; /* stream already closed */
}
else {
+ PyObject *exc = NULL, *val, *tb;
if (self->deallocating) {
res = _PyObject_CallMethodId(self->buffer, &PyId__dealloc_warn, "O", self);
if (res)
@@ -2562,13 +2563,28 @@ textiowrapper_close(textio *self, PyObject *args)
PyErr_Clear();
}
res = _PyObject_CallMethodId((PyObject *)self, &PyId_flush, NULL);
- if (res == NULL) {
- return NULL;
- }
+ if (res == NULL)
+ PyErr_Fetch(&exc, &val, &tb);
else
Py_DECREF(res);
- return _PyObject_CallMethodId(self->buffer, &PyId_close, NULL);
+ res = _PyObject_CallMethodId(self->buffer, &PyId_close, NULL);
+ if (exc != NULL) {
+ if (res != NULL) {
+ Py_CLEAR(res);
+ PyErr_Restore(exc, val, tb);
+ }
+ else {
+ PyObject *val2;
+ Py_DECREF(exc);
+ Py_XDECREF(tb);
+ PyErr_Fetch(&exc, &val2, &tb);
+ PyErr_NormalizeException(&exc, &val2, &tb);
+ PyException_SetContext(val2, val);
+ PyErr_Restore(exc, val2, tb);
+ }
+ }
+ return res;
}
}
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c
index bf9259f..52db15d 100644
--- a/Objects/bytesobject.c
+++ b/Objects/bytesobject.c
@@ -2505,8 +2505,10 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
const char *encoding = NULL;
const char *errors = NULL;
PyObject *new = NULL;
+ PyObject *func;
Py_ssize_t size;
static char *kwlist[] = {"source", "encoding", "errors", 0};
+ _Py_IDENTIFIER(__bytes__);
if (type != &PyBytes_Type)
return str_subtype_new(type, args, kwds);
@@ -2536,6 +2538,28 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
assert(PyBytes_Check(new));
return new;
}
+
+ /* We'd like to call PyObject_Bytes here, but we need to check for an
+ integer argument before deferring to PyBytes_FromObject, something
+ PyObject_Bytes doesn't do. */
+ func = _PyObject_LookupSpecial(x, &PyId___bytes__);
+ if (func != NULL) {
+ new = PyObject_CallFunctionObjArgs(func, NULL);
+ Py_DECREF(func);
+ if (new == NULL)
+ return NULL;
+ if (!PyBytes_Check(new)) {
+ PyErr_Format(PyExc_TypeError,
+ "__bytes__ returned non-bytes (type %.200s)",
+ Py_TYPE(new)->tp_name);
+ Py_DECREF(new);
+ return NULL;
+ }
+ return new;
+ }
+ else if (PyErr_Occurred())
+ return NULL;
+
/* Is it an integer? */
size = PyNumber_AsSsize_t(x, PyExc_OverflowError);
if (size == -1 && PyErr_Occurred()) {
@@ -2549,12 +2573,10 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
}
else {
new = PyBytes_FromStringAndSize(NULL, size);
- if (new == NULL) {
+ if (new == NULL)
return NULL;
- }
- if (size > 0) {
+ if (size > 0)
memset(((PyBytesObject*)new)->ob_sval, 0, size);
- }
return new;
}
@@ -2564,7 +2586,8 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
"encoding or errors without a string argument");
return NULL;
}
- return PyObject_Bytes(x);
+
+ return PyBytes_FromObject(x);
}
PyObject *