From: Serhiy Storchaka Date: Sat, 6 Aug 2016 20:29:29 +0000 (+0300) Subject: Issue #26754: Undocumented support of general bytes-like objects X-Git-Tag: v3.6.0a4~60 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=febc3320563bf597e186ebce75abdac2926ceeb6;p=python Issue #26754: Undocumented support of general bytes-like objects as path in compile() and similar functions is now deprecated. --- diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst index 7603fa1220..ca5b3e5e91 100644 --- a/Doc/whatsnew/3.6.rst +++ b/Doc/whatsnew/3.6.rst @@ -639,8 +639,9 @@ Deprecated features (Contributed by Serhiy Storchaka in :issue:`21708`.) * Undocumented support of general :term:`bytes-like objects ` - as paths in :mod:`os` functions is now deprecated. - (Contributed by Serhiy Storchaka in :issue:`25791`.) + as paths in :mod:`os` functions, :func:`compile` and similar functions is + now deprecated. + (Contributed by Serhiy Storchaka in :issue:`25791` and :issue:`26754`.) Deprecated Python behavior diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 824e843914..9638e6975a 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -473,10 +473,13 @@ if 1: self.assertEqual(d, {1: 2, 3: 4}) def test_compile_filename(self): - for filename in ('file.py', b'file.py', - bytearray(b'file.py'), memoryview(b'file.py')): + for filename in 'file.py', b'file.py': code = compile('pass', filename, 'exec') self.assertEqual(code.co_filename, 'file.py') + for filename in bytearray(b'file.py'), memoryview(b'file.py'): + with self.assertWarns(DeprecationWarning): + code = compile('pass', filename, 'exec') + self.assertEqual(code.co_filename, 'file.py') self.assertRaises(TypeError, compile, 'pass', list(b'file.py'), 'exec') @support.cpython_only diff --git a/Lib/test/test_parser.py b/Lib/test/test_parser.py index 1e7d331bc0..e2a42f9715 100644 --- a/Lib/test/test_parser.py +++ b/Lib/test/test_parser.py @@ -632,12 +632,18 @@ class CompileTestCase(unittest.TestCase): self.assertEqual(code.co_filename, '') code = st.compile() self.assertEqual(code.co_filename, '') - for filename in ('file.py', b'file.py', - bytearray(b'file.py'), memoryview(b'file.py')): + for filename in 'file.py', b'file.py': code = parser.compilest(st, filename) self.assertEqual(code.co_filename, 'file.py') code = st.compile(filename) self.assertEqual(code.co_filename, 'file.py') + for filename in bytearray(b'file.py'), memoryview(b'file.py'): + with self.assertWarns(DeprecationWarning): + code = parser.compilest(st, filename) + self.assertEqual(code.co_filename, 'file.py') + with self.assertWarns(DeprecationWarning): + code = st.compile(filename) + self.assertEqual(code.co_filename, 'file.py') self.assertRaises(TypeError, parser.compilest, st, list(b'file.py')) self.assertRaises(TypeError, st.compile, list(b'file.py')) diff --git a/Lib/test/test_symtable.py b/Lib/test/test_symtable.py index c5d7facfdb..bf99505623 100644 --- a/Lib/test/test_symtable.py +++ b/Lib/test/test_symtable.py @@ -158,9 +158,11 @@ class SymtableTest(unittest.TestCase): checkfilename("def f(x): foo)(") # parse-time checkfilename("def f(x): global x") # symtable-build-time symtable.symtable("pass", b"spam", "exec") - with self.assertRaises(TypeError): + with self.assertWarns(DeprecationWarning), \ + self.assertRaises(TypeError): symtable.symtable("pass", bytearray(b"spam"), "exec") - symtable.symtable("pass", memoryview(b"spam"), "exec") + with self.assertWarns(DeprecationWarning): + symtable.symtable("pass", memoryview(b"spam"), "exec") with self.assertRaises(TypeError): symtable.symtable("pass", list(b"spam"), "exec") diff --git a/Lib/test/test_zipimport.py b/Lib/test/test_zipimport.py index 20491cde7a..a2482d45a7 100644 --- a/Lib/test/test_zipimport.py +++ b/Lib/test/test_zipimport.py @@ -629,8 +629,10 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase): zipimport.zipimporter(filename) zipimport.zipimporter(os.fsencode(filename)) - zipimport.zipimporter(bytearray(os.fsencode(filename))) - zipimport.zipimporter(memoryview(os.fsencode(filename))) + with self.assertWarns(DeprecationWarning): + zipimport.zipimporter(bytearray(os.fsencode(filename))) + with self.assertWarns(DeprecationWarning): + zipimport.zipimporter(memoryview(os.fsencode(filename))) @support.requires_zlib diff --git a/Misc/NEWS b/Misc/NEWS index 03a8104a34..56c21cb8be 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -43,6 +43,9 @@ Core and Builtins Library ------- +- Issue #26754: Undocumented support of general bytes-like objects + as path in compile() and similar functions is now deprecated. + - Issue #26800: Undocumented support of general bytes-like objects as paths in os functions is now deprecated. diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 0932f35b76..2d31c700de 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -3837,7 +3837,13 @@ PyUnicode_FSDecoder(PyObject* arg, void* addr) output = arg; Py_INCREF(output); } - else if (PyObject_CheckBuffer(arg)) { + else if (PyBytes_Check(arg) || PyObject_CheckBuffer(arg)) { + if (!PyBytes_Check(arg) && + PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "path should be string or bytes, not %.200s", + Py_TYPE(arg)->tp_name)) { + return 0; + } arg = PyBytes_FromObject(arg); if (!arg) return 0; @@ -3846,11 +3852,6 @@ PyUnicode_FSDecoder(PyObject* arg, void* addr) Py_DECREF(arg); if (!output) return 0; - if (!PyUnicode_Check(output)) { - Py_DECREF(output); - PyErr_SetString(PyExc_TypeError, "decoder failed to return unicode"); - return 0; - } } else { PyErr_Format(PyExc_TypeError,