diff --git a/Lib/pickletools.py b/Lib/pickletools.py index b4b28405302..c050fc526ae 100644 --- a/Lib/pickletools.py +++ b/Lib/pickletools.py @@ -1760,11 +1760,12 @@ def assure_pickle_consistency(verbose=False): print("skipping %r: it doesn't look like an opcode name" % name) continue picklecode = getattr(pickle, name) - if not isinstance(picklecode, str) or len(picklecode) != 1: + if not isinstance(picklecode, bytes) or len(picklecode) != 1: if verbose: print(("skipping %r: value %r doesn't look like a pickle " "code" % (name, picklecode))) continue + picklecode = picklecode.decode("latin-1") if picklecode in copy: if verbose: print("checking name %r w/ code %r for consistency" % ( diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index aa9b66dff28..934d50edc7b 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -251,12 +251,12 @@ class ExceptionTests(unittest.TestCase): 'print_file_and_line' : None, 'msg' : 'msgStr', 'filename' : None, 'lineno' : None, 'offset' : None}), (UnicodeError, (), {'message' : '', 'args' : (),}), - (UnicodeEncodeError, ('ascii', 'a', 0, 1, 'ordinal not in range'), + (UnicodeEncodeError, (str8('ascii'), 'a', 0, 1, str8('ordinal not in range')), {'message' : '', 'args' : ('ascii', 'a', 0, 1, 'ordinal not in range'), 'encoding' : 'ascii', 'object' : 'a', 'start' : 0, 'reason' : 'ordinal not in range'}), - (UnicodeDecodeError, ('ascii', '\xff', 0, 1, 'ordinal not in range'), + (UnicodeDecodeError, (str8('ascii'), b'\xff', 0, 1, str8('ordinal not in range')), {'message' : '', 'args' : ('ascii', '\xff', 0, 1, 'ordinal not in range'), 'encoding' : 'ascii', 'object' : '\xff', @@ -278,6 +278,7 @@ class ExceptionTests(unittest.TestCase): for exc, args, expected in exceptionList: try: + print("exc=%r, args=%r" % (exc, args)) raise exc(*args) except BaseException as e: if type(e) is not exc: @@ -297,7 +298,9 @@ class ExceptionTests(unittest.TestCase): if p is None: continue # cPickle not found -- skip it for protocol in range(p.HIGHEST_PROTOCOL + 1): - new = p.loads(p.dumps(e, protocol)) + ##print("p=%s, protocol=%s, e=%r" % (p.__name__, protocol, e)) + s = p.dumps(e, protocol) + new = p.loads(s) for checkArgName in expected: got = repr(getattr(new, checkArgName)) want = repr(expected[checkArgName]) diff --git a/Modules/cPickle.c b/Modules/cPickle.c index 9e3f8d18b53..00641d83e82 100644 --- a/Modules/cPickle.c +++ b/Modules/cPickle.c @@ -1335,7 +1335,8 @@ save_unicode(Picklerobject *self, PyObject *args, int doput) if (!( repr = PyUnicode_AsUTF8String(args))) return -1; - if ((size = PyString_Size(repr)) < 0) + assert(PyBytes_Check(repr)); + if ((size = PyBytes_Size(repr)) < 0) goto err; if (size > INT_MAX) return -1; /* string too large */ @@ -1354,7 +1355,7 @@ save_unicode(Picklerobject *self, PyObject *args, int doput) PDATA_APPEND(self->file, repr, -1); } else { - if (self->write_func(self, PyString_AS_STRING(repr), + if (self->write_func(self, PyBytes_AS_STRING(repr), size) < 0) goto err; } @@ -5275,8 +5276,11 @@ cpm_loads(PyObject *self, PyObject *args) PyObject *ob, *file = 0, *res = NULL; Unpicklerobject *unpickler = 0; - if (!( PyArg_ParseTuple(args, "S:loads", &ob))) - goto finally; + if (!( PyArg_ParseTuple(args, "S:loads", &ob))) { + PyErr_Clear(); + if (!PyArg_ParseTuple(args, "Y:loads", &ob)) + goto finally; + } if (!( file = PycStringIO->NewInput(ob))) goto finally; diff --git a/Python/getargs.c b/Python/getargs.c index 8331a18965a..0f6f21b7df4 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -1099,6 +1099,15 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, return converterr("string", arg, msgbuf, bufsize); break; } + + case 'Y': { /* bytes object */ + PyObject **p = va_arg(*p_va, PyObject **); + if (PyBytes_Check(arg)) + *p = arg; + else + return converterr("bytes", arg, msgbuf, bufsize); + break; + } case 'U': { /* Unicode object */ PyObject **p = va_arg(*p_va, PyObject **); @@ -1640,6 +1649,7 @@ skipitem(const char **p_format, va_list *p_va, int flags) /* object codes */ case 'S': /* string object */ + case 'Y': /* string object */ case 'U': /* unicode string object */ { (void) va_arg(*p_va, PyObject **);