diff options
author | INADA Naoki <methane@users.noreply.github.com> | 2016-02-14 17:08:13 +0900 |
---|---|---|
committer | INADA Naoki <methane@users.noreply.github.com> | 2016-02-14 17:08:13 +0900 |
commit | f895517995754ce9bb758a77ea3db9ac7e6262c9 (patch) | |
tree | 66c3c4472ac6530cb861cab553d045dc716fd082 | |
parent | 82b31215079bc47bd4d5a8f3c18d83ac73c8221b (diff) | |
parent | b2a8ce6cbdbef80d1a89d02fa483f56862cf1efa (diff) | |
download | msgpack-python-f895517995754ce9bb758a77ea3db9ac7e6262c9.tar.gz |
Merge pull request #172 from methane/palaviv-msgpack-exceptions
Organize Exceptions
-rw-r--r-- | msgpack/_packer.pyx | 24 | ||||
-rw-r--r-- | msgpack/_unpacker.pyx | 47 | ||||
-rw-r--r-- | msgpack/exceptions.py | 22 | ||||
-rw-r--r-- | msgpack/fallback.py | 51 | ||||
-rw-r--r-- | test/test_limits.py | 23 |
5 files changed, 93 insertions, 74 deletions
diff --git a/msgpack/_packer.pyx b/msgpack/_packer.pyx index b19d462..e923895 100644 --- a/msgpack/_packer.pyx +++ b/msgpack/_packer.pyx @@ -6,7 +6,7 @@ from libc.stdlib cimport * from libc.string cimport * from libc.limits cimport * -from msgpack.exceptions import PackValueError +from msgpack.exceptions import PackValueError, PackOverflowError from msgpack import ExtType @@ -166,7 +166,7 @@ cdef class Packer(object): default_used = True continue else: - raise + raise PackOverflowError("Integer value out of range") elif PyInt_CheckExact(o) if strict_types else PyInt_Check(o): longval = o ret = msgpack_pack_long(&self.pk, longval) @@ -180,7 +180,7 @@ cdef class Packer(object): elif PyBytes_CheckExact(o) if strict_types else PyBytes_Check(o): L = len(o) if L > (2**32)-1: - raise ValueError("bytes is too large") + raise PackValueError("bytes is too large") rawval = o ret = msgpack_pack_bin(&self.pk, L) if ret == 0: @@ -191,7 +191,7 @@ cdef class Packer(object): o = PyUnicode_AsEncodedString(o, self.encoding, self.unicode_errors) L = len(o) if L > (2**32)-1: - raise ValueError("unicode string is too large") + raise PackValueError("unicode string is too large") rawval = o ret = msgpack_pack_raw(&self.pk, L) if ret == 0: @@ -200,7 +200,7 @@ cdef class Packer(object): d = <dict>o L = len(d) if L > (2**32)-1: - raise ValueError("dict is too large") + raise PackValueError("dict is too large") ret = msgpack_pack_map(&self.pk, L) if ret == 0: for k, v in d.iteritems(): @@ -211,7 +211,7 @@ cdef class Packer(object): elif not strict_types and PyDict_Check(o): L = len(o) if L > (2**32)-1: - raise ValueError("dict is too large") + raise PackValueError("dict is too large") ret = msgpack_pack_map(&self.pk, L) if ret == 0: for k, v in o.items(): @@ -225,13 +225,13 @@ cdef class Packer(object): rawval = o.data L = len(o.data) if L > (2**32)-1: - raise ValueError("EXT data is too large") + raise PackValueError("EXT data is too large") ret = msgpack_pack_ext(&self.pk, longval, L) ret = msgpack_pack_raw_body(&self.pk, rawval, L) elif PyList_CheckExact(o) if strict_types else (PyTuple_Check(o) or PyList_Check(o)): L = len(o) if L > (2**32)-1: - raise ValueError("list is too large") + raise PackValueError("list is too large") ret = msgpack_pack_array(&self.pk, L) if ret == 0: for v in o: @@ -239,11 +239,11 @@ cdef class Packer(object): if ret != 0: break elif PyMemoryView_Check(o): if PyObject_GetBuffer(o, &view, PyBUF_SIMPLE) != 0: - raise ValueError("could not get buffer for memoryview") + raise PackValueError("could not get buffer for memoryview") L = view.len if L > (2**32)-1: PyBuffer_Release(&view); - raise ValueError("memoryview is too large") + raise PackValueError("memoryview is too large") ret = msgpack_pack_bin(&self.pk, L) if ret == 0: ret = msgpack_pack_raw_body(&self.pk, <char*>view.buf, L) @@ -274,7 +274,7 @@ cdef class Packer(object): def pack_array_header(self, size_t size): if size > (2**32-1): - raise ValueError + raise PackValueError cdef int ret = msgpack_pack_array(&self.pk, size) if ret == -1: raise MemoryError @@ -287,7 +287,7 @@ cdef class Packer(object): def pack_map_header(self, size_t size): if size > (2**32-1): - raise ValueError + raise PackValueError cdef int ret = msgpack_pack_map(&self.pk, size) if ret == -1: raise MemoryError diff --git a/msgpack/_unpacker.pyx b/msgpack/_unpacker.pyx index 1aefc64..0443505 100644 --- a/msgpack/_unpacker.pyx +++ b/msgpack/_unpacker.pyx @@ -11,11 +11,11 @@ from libc.string cimport * from libc.limits cimport * from msgpack.exceptions import ( - BufferFull, - OutOfData, - UnpackValueError, - ExtraData, - ) + BufferFull, + OutOfData, + UnpackValueError, + ExtraData, +) from msgpack import ExtType @@ -397,24 +397,27 @@ cdef class Unpacker(object): else: raise OutOfData("No more data to unpack.") - ret = execute(&self.ctx, self.buf, self.buf_tail, &self.buf_head) - if write_bytes is not None: - write_bytes(PyBytes_FromStringAndSize(self.buf + prev_head, self.buf_head - prev_head)) - - if ret == 1: - obj = unpack_data(&self.ctx) - unpack_init(&self.ctx) - return obj - elif ret == 0: - if self.file_like is not None: - self.read_from_file() - continue - if iter: - raise StopIteration("No more data to unpack.") + try: + ret = execute(&self.ctx, self.buf, self.buf_tail, &self.buf_head) + if write_bytes is not None: + write_bytes(PyBytes_FromStringAndSize(self.buf + prev_head, self.buf_head - prev_head)) + + if ret == 1: + obj = unpack_data(&self.ctx) + unpack_init(&self.ctx) + return obj + elif ret == 0: + if self.file_like is not None: + self.read_from_file() + continue + if iter: + raise StopIteration("No more data to unpack.") + else: + raise OutOfData("No more data to unpack.") else: - raise OutOfData("No more data to unpack.") - else: - raise ValueError("Unpack failed: error = %d" % (ret,)) + raise UnpackValueError("Unpack failed: error = %d" % (ret,)) + except ValueError as e: + raise UnpackValueError(e) def read_bytes(self, Py_ssize_t nbytes): """Read a specified number of raw bytes from the stream""" diff --git a/msgpack/exceptions.py b/msgpack/exceptions.py index f7678f1..9766881 100644 --- a/msgpack/exceptions.py +++ b/msgpack/exceptions.py @@ -1,5 +1,5 @@ class UnpackException(Exception): - pass + """Deprecated. Use Exception instead to catch all exception during unpacking.""" class BufferFull(UnpackException): @@ -11,10 +11,10 @@ class OutOfData(UnpackException): class UnpackValueError(UnpackException, ValueError): - pass + """Deprecated. Use ValueError instead.""" -class ExtraData(ValueError): +class ExtraData(UnpackValueError): def __init__(self, unpacked, extra): self.unpacked = unpacked self.extra = extra @@ -22,8 +22,20 @@ class ExtraData(ValueError): def __str__(self): return "unpack(b) received extra data." + class PackException(Exception): - pass + """Deprecated. Use Exception instead to catch all exception during packing.""" + class PackValueError(PackException, ValueError): - pass + """PackValueError is raised when type of input data is supported but it's value is unsupported. + + Deprecated. Use ValueError instead. + """ + + +class PackOverflowError(PackValueError, OverflowError): + """PackOverflowError is raised when integer value is out of range of msgpack support [-2**31, 2**32). + + Deprecated. Use ValueError instead. + """ diff --git a/msgpack/fallback.py b/msgpack/fallback.py index 348e017..d8c5d73 100644 --- a/msgpack/fallback.py +++ b/msgpack/fallback.py @@ -51,6 +51,7 @@ from msgpack.exceptions import ( OutOfData, UnpackValueError, PackValueError, + PackOverflowError, ExtraData) from msgpack import ExtType @@ -363,17 +364,17 @@ class Unpacker(object): obj = self._fb_read(n, write_bytes) typ = TYPE_RAW if n > self._max_str_len: - raise ValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) + raise UnpackValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) elif b & 0b11110000 == 0b10010000: n = b & 0b00001111 typ = TYPE_ARRAY if n > self._max_array_len: - raise ValueError("%s exceeds max_array_len(%s)", n, self._max_array_len) + raise UnpackValueError("%s exceeds max_array_len(%s)", n, self._max_array_len) elif b & 0b11110000 == 0b10000000: n = b & 0b00001111 typ = TYPE_MAP if n > self._max_map_len: - raise ValueError("%s exceeds max_map_len(%s)", n, self._max_map_len) + raise UnpackValueError("%s exceeds max_map_len(%s)", n, self._max_map_len) elif b == 0xc0: obj = None elif b == 0xc2: @@ -384,37 +385,37 @@ class Unpacker(object): typ = TYPE_BIN n = struct.unpack("B", self._fb_read(1, write_bytes))[0] if n > self._max_bin_len: - raise ValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len)) + raise UnpackValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len)) obj = self._fb_read(n, write_bytes) elif b == 0xc5: typ = TYPE_BIN n = struct.unpack(">H", self._fb_read(2, write_bytes))[0] if n > self._max_bin_len: - raise ValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len)) + raise UnpackValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len)) obj = self._fb_read(n, write_bytes) elif b == 0xc6: typ = TYPE_BIN n = struct.unpack(">I", self._fb_read(4, write_bytes))[0] if n > self._max_bin_len: - raise ValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len)) + raise UnpackValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len)) obj = self._fb_read(n, write_bytes) elif b == 0xc7: # ext 8 typ = TYPE_EXT L, n = struct.unpack('Bb', self._fb_read(2, write_bytes)) if L > self._max_ext_len: - raise ValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len)) + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len)) obj = self._fb_read(L, write_bytes) elif b == 0xc8: # ext 16 typ = TYPE_EXT L, n = struct.unpack('>Hb', self._fb_read(3, write_bytes)) if L > self._max_ext_len: - raise ValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len)) + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len)) obj = self._fb_read(L, write_bytes) elif b == 0xc9: # ext 32 typ = TYPE_EXT L, n = struct.unpack('>Ib', self._fb_read(5, write_bytes)) if L > self._max_ext_len: - raise ValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len)) + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len)) obj = self._fb_read(L, write_bytes) elif b == 0xca: obj = struct.unpack(">f", self._fb_read(4, write_bytes))[0] @@ -439,65 +440,65 @@ class Unpacker(object): elif b == 0xd4: # fixext 1 typ = TYPE_EXT if self._max_ext_len < 1: - raise ValueError("%s exceeds max_ext_len(%s)" % (1, self._max_ext_len)) + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (1, self._max_ext_len)) n, obj = struct.unpack('b1s', self._fb_read(2, write_bytes)) elif b == 0xd5: # fixext 2 typ = TYPE_EXT if self._max_ext_len < 2: - raise ValueError("%s exceeds max_ext_len(%s)" % (2, self._max_ext_len)) + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (2, self._max_ext_len)) n, obj = struct.unpack('b2s', self._fb_read(3, write_bytes)) elif b == 0xd6: # fixext 4 typ = TYPE_EXT if self._max_ext_len < 4: - raise ValueError("%s exceeds max_ext_len(%s)" % (4, self._max_ext_len)) + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (4, self._max_ext_len)) n, obj = struct.unpack('b4s', self._fb_read(5, write_bytes)) elif b == 0xd7: # fixext 8 typ = TYPE_EXT if self._max_ext_len < 8: - raise ValueError("%s exceeds max_ext_len(%s)" % (8, self._max_ext_len)) + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (8, self._max_ext_len)) n, obj = struct.unpack('b8s', self._fb_read(9, write_bytes)) elif b == 0xd8: # fixext 16 typ = TYPE_EXT if self._max_ext_len < 16: - raise ValueError("%s exceeds max_ext_len(%s)" % (16, self._max_ext_len)) + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (16, self._max_ext_len)) n, obj = struct.unpack('b16s', self._fb_read(17, write_bytes)) elif b == 0xd9: typ = TYPE_RAW n = struct.unpack("B", self._fb_read(1, write_bytes))[0] if n > self._max_str_len: - raise ValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) + raise UnpackValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) obj = self._fb_read(n, write_bytes) elif b == 0xda: typ = TYPE_RAW n = struct.unpack(">H", self._fb_read(2, write_bytes))[0] if n > self._max_str_len: - raise ValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) + raise UnpackValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) obj = self._fb_read(n, write_bytes) elif b == 0xdb: typ = TYPE_RAW n = struct.unpack(">I", self._fb_read(4, write_bytes))[0] if n > self._max_str_len: - raise ValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) + raise UnpackValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) obj = self._fb_read(n, write_bytes) elif b == 0xdc: n = struct.unpack(">H", self._fb_read(2, write_bytes))[0] if n > self._max_array_len: - raise ValueError("%s exceeds max_array_len(%s)", n, self._max_array_len) + raise UnpackValueError("%s exceeds max_array_len(%s)", n, self._max_array_len) typ = TYPE_ARRAY elif b == 0xdd: n = struct.unpack(">I", self._fb_read(4, write_bytes))[0] if n > self._max_array_len: - raise ValueError("%s exceeds max_array_len(%s)", n, self._max_array_len) + raise UnpackValueError("%s exceeds max_array_len(%s)", n, self._max_array_len) typ = TYPE_ARRAY elif b == 0xde: n = struct.unpack(">H", self._fb_read(2, write_bytes))[0] if n > self._max_map_len: - raise ValueError("%s exceeds max_map_len(%s)", n, self._max_map_len) + raise UnpackValueError("%s exceeds max_map_len(%s)", n, self._max_map_len) typ = TYPE_MAP elif b == 0xdf: n = struct.unpack(">I", self._fb_read(4, write_bytes))[0] if n > self._max_map_len: - raise ValueError("%s exceeds max_map_len(%s)", n, self._max_map_len) + raise UnpackValueError("%s exceeds max_map_len(%s)", n, self._max_map_len) typ = TYPE_MAP else: raise UnpackValueError("Unknown header: 0x%x" % b) @@ -683,7 +684,7 @@ class Packer(object): obj = self._default(obj) default_used = True continue - raise PackValueError("Integer value out of range") + raise PackOverflowError("Integer value out of range") if self._use_bin_type and check(obj, (bytes, memoryview)): n = len(obj) if n <= 0xff: @@ -778,7 +779,7 @@ class Packer(object): def pack_array_header(self, n): if n >= 2**32: - raise ValueError + raise PackValueError self._fb_pack_array_header(n) ret = self._buffer.getvalue() if self._autoreset: @@ -789,7 +790,7 @@ class Packer(object): def pack_map_header(self, n): if n >= 2**32: - raise ValueError + raise PackValueError self._fb_pack_map_header(n) ret = self._buffer.getvalue() if self._autoreset: @@ -807,7 +808,7 @@ class Packer(object): raise TypeError("data must have bytes type") L = len(data) if L > 0xffffffff: - raise ValueError("Too large data") + raise PackValueError("Too large data") if L == 1: self._buffer.write(b'\xd4') elif L == 2: diff --git a/test/test_limits.py b/test/test_limits.py index 3c1cf2a..197ef46 100644 --- a/test/test_limits.py +++ b/test/test_limits.py @@ -3,32 +3,35 @@ from __future__ import absolute_import, division, print_function, unicode_literals import pytest -from msgpack import packb, unpackb, Packer, Unpacker, ExtType +from msgpack import ( + packb, unpackb, Packer, Unpacker, ExtType, + PackOverflowError, PackValueError, UnpackValueError, +) def test_integer(): x = -(2 ** 63) assert unpackb(packb(x)) == x - with pytest.raises((OverflowError, ValueError)): + with pytest.raises(PackOverflowError): packb(x-1) x = 2 ** 64 - 1 assert unpackb(packb(x)) == x - with pytest.raises((OverflowError, ValueError)): + with pytest.raises(PackOverflowError): packb(x+1) def test_array_header(): packer = Packer() packer.pack_array_header(2**32-1) - with pytest.raises((OverflowError, ValueError)): + with pytest.raises(PackValueError): packer.pack_array_header(2**32) def test_map_header(): packer = Packer() packer.pack_map_header(2**32-1) - with pytest.raises((OverflowError, ValueError)): + with pytest.raises(PackValueError): packer.pack_array_header(2**32) @@ -41,7 +44,7 @@ def test_max_str_len(): assert unpacker.unpack() == d unpacker = Unpacker(max_str_len=2, encoding='utf-8') - with pytest.raises(ValueError): + with pytest.raises(UnpackValueError): unpacker.feed(packed) unpacker.unpack() @@ -55,7 +58,7 @@ def test_max_bin_len(): assert unpacker.unpack() == d unpacker = Unpacker(max_bin_len=2) - with pytest.raises(ValueError): + with pytest.raises(UnpackValueError): unpacker.feed(packed) unpacker.unpack() @@ -69,7 +72,7 @@ def test_max_array_len(): assert unpacker.unpack() == d unpacker = Unpacker(max_array_len=2) - with pytest.raises(ValueError): + with pytest.raises(UnpackValueError): unpacker.feed(packed) unpacker.unpack() @@ -83,7 +86,7 @@ def test_max_map_len(): assert unpacker.unpack() == d unpacker = Unpacker(max_map_len=2) - with pytest.raises(ValueError): + with pytest.raises(UnpackValueError): unpacker.feed(packed) unpacker.unpack() @@ -97,7 +100,7 @@ def test_max_ext_len(): assert unpacker.unpack() == d unpacker = Unpacker(max_ext_len=2) - with pytest.raises(ValueError): + with pytest.raises(UnpackValueError): unpacker.feed(packed) unpacker.unpack() |