Merge lp:~mnordhoff/bzr/st-size-exceptions into lp:bzr

Proposed by Matt Nordhoff
Status: Merged
Approved by: John A Meinel
Approved revision: not available
Merged at revision: not available
Proposed branch: lp:~mnordhoff/bzr/st-size-exceptions
Merge into: lp:bzr
Diff against target: 67 lines (+13/-9)
3 files modified
bzrlib/_static_tuple_c.c (+8/-4)
bzrlib/_static_tuple_py.py (+3/-3)
bzrlib/tests/test__static_tuple.py (+2/-2)
To merge this branch: bzr merge lp:~mnordhoff/bzr/st-size-exceptions
Reviewer Review Type Date Requested Status
John A Meinel Approve
Review via email: mp+13770@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Matt Nordhoff (mnordhoff) wrote :

This makes the changes I suggested in bug #457979:

> Lookie:
>
> if (size < 0) {
> PyErr_BadInternalCall();
> return NULL;
> }
>
> if (size < 0 || size > 255) {
> /* Too big or too small */
> PyErr_SetString(PyExc_ValueError, "StaticTuple(...)"
> " takes from 0 to 255 items");
> return NULL;
> }
>
> Not only is this redundant, but PyErr_BadInternalCall() throws a
> TypeError, meaning two different exception classes are used.
>
> ISTM StaticTuple_New should throw a ValueError, since you do
> StaticTuple_New(length), and StaticTuple_new_constructor should throw a
> TypeError, since you do StaticTuple(foo, bar, baz) (currently it lets
> StaticTuple_New handle throw the error).
>
> FYI, the Python version of StaticTuple throws a ValueError when it's
> either <0 or >255. IMO, that should be a TypeError, same as
> StaticTuple_new_constructor.

* bzrlib/_static_tuple_c.c:
(StaticTuple_New): Raise a ValueError when size <0, just like when it's >255.
(StaticTuple_new_constructor): Raise a TypeError when this happens, instead of letting StaticTuple_New raise its ValueError.

* bzrlib/_static_tuple_py.py:
(StaticTuple.__init__): Change the ValueError to a TypeError as well. Move the length check before the type checks, to match StaticTuple_new_constructor, and copy over its error message, since I like it better and it doesn't refer to "key bits".

* bzrlib/tests/test__static_tuple.py:
(TestStaticTuple.test_create_bad_args): Make the relevant type adjustments.

Revision history for this message
John A Meinel (jameinel) wrote :

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Matt Nordhoff wrote:
> Matt Nordhoff has proposed merging lp:~mnordhoff/bzr/st-size-exceptions into lp:bzr.
>
> Requested reviews:
> bzr-core (bzr-core)
>
>
> This makes the changes I suggested in bug #457979:
>
>> Lookie:
>>
>> if (size < 0) {
>> PyErr_BadInternalCall();
>> return NULL;
>> }
>>
>> if (size < 0 || size > 255) {
>> /* Too big or too small */
>> PyErr_SetString(PyExc_ValueError, "StaticTuple(...)"
>> " takes from 0 to 255 items");
>> return NULL;
>> }
>>
>> Not only is this redundant, but PyErr_BadInternalCall() throws a
>> TypeError, meaning two different exception classes are used.
>>
>> ISTM StaticTuple_New should throw a ValueError, since you do
>> StaticTuple_New(length), and StaticTuple_new_constructor should throw a
>> TypeError, since you do StaticTuple(foo, bar, baz) (currently it lets
>> StaticTuple_New handle throw the error).
>>
>> FYI, the Python version of StaticTuple throws a ValueError when it's
>> either <0 or >255. IMO, that should be a TypeError, same as
>> StaticTuple_new_constructor.
>
> * bzrlib/_static_tuple_c.c:
> (StaticTuple_New): Raise a ValueError when size <0, just like when it's >255.
> (StaticTuple_new_constructor): Raise a TypeError when this happens, instead of letting StaticTuple_New raise its ValueError.
>
> * bzrlib/_static_tuple_py.py:
> (StaticTuple.__init__): Change the ValueError to a TypeError as well. Move the length check before the type checks, to match StaticTuple_new_constructor, and copy over its error message, since I like it better and it doesn't refer to "key bits".
>
> * bzrlib/tests/test__static_tuple.py:
> (TestStaticTuple.test_create_bad_args): Make the relevant type adjustments.
>

I'm happy to have them the same. Regardless of what we make this, it
isn't something you should ever be catching, so the specific exception
isn't particularly meaningful.

It is arguable that "TypeError" should be reserved for when the *type*
of the argument passed is invalid. (Such as passing a dict rather than a
string/unicode/etc.)

Everything else would be considered a ValueError. (Having a tuple that
holds only strings but is 266 entries long is closer to a ValueError
than a TypeError.)

John
=:->

 review needs_fixing
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkrgdD4ACgkQJdeBCYSNAAPlJwCePnGWlGEZapi4rhFv6le6DrYq
cIUAoJtXJiAbJ0mszyScsrMm38vcwCHE
=0f8p
-----END PGP SIGNATURE-----

review: Needs Fixing
Revision history for this message
Martin Pool (mbp) wrote :

John you voted 'needs fixing' but I'm not clear what fixes you want to see.

Revision history for this message
John A Meinel (jameinel) wrote :

I think we had talked about it a while on IRC, and it seems that invalid arguments are pretty much always a type error. So we can go ahead and merge it as is.

review: Approve

Updating diff...

An updated diff will be available in a few minutes. Reload to see the changes.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'bzrlib/_static_tuple_c.c'
--- bzrlib/_static_tuple_c.c 2009-10-27 14:07:16 +0000
+++ bzrlib/_static_tuple_c.c 2010-02-17 20:49:16 +0000
@@ -140,10 +140,6 @@
140StaticTuple_New(Py_ssize_t size)140StaticTuple_New(Py_ssize_t size)
141{141{
142 StaticTuple *stuple;142 StaticTuple *stuple;
143 if (size < 0) {
144 PyErr_BadInternalCall();
145 return NULL;
146 }
147143
148 if (size < 0 || size > 255) {144 if (size < 0 || size > 255) {
149 /* Too big or too small */145 /* Too big or too small */
@@ -280,6 +276,14 @@
280 return NULL;276 return NULL;
281 }277 }
282 len = PyTuple_GET_SIZE(args);278 len = PyTuple_GET_SIZE(args);
279 if (len < 0 || len > 255) {
280 /* Check the length here so we can raise a TypeError instead of
281 * StaticTuple_New's ValueError.
282 */
283 PyErr_SetString(PyExc_TypeError, "StaticTuple(...)"
284 " takes from 0 to 255 items");
285 return NULL;
286 }
283 self = (StaticTuple *)StaticTuple_New(len);287 self = (StaticTuple *)StaticTuple_New(len);
284 if (self == NULL) {288 if (self == NULL) {
285 return NULL;289 return NULL;
286290
=== modified file 'bzrlib/_static_tuple_py.py'
--- bzrlib/_static_tuple_py.py 2009-11-28 21:54:08 +0000
+++ bzrlib/_static_tuple_py.py 2010-02-17 20:49:16 +0000
@@ -34,15 +34,15 @@
3434
35 def __init__(self, *args):35 def __init__(self, *args):
36 """Create a new 'StaticTuple'"""36 """Create a new 'StaticTuple'"""
37 num_keys = len(args)
38 if num_keys < 0 or num_keys > 255:
39 raise TypeError('StaticTuple(...) takes from 0 to 255 items')
37 for bit in args:40 for bit in args:
38 if type(bit) not in (str, StaticTuple, unicode, int, long, float,41 if type(bit) not in (str, StaticTuple, unicode, int, long, float,
39 None.__class__, bool):42 None.__class__, bool):
40 raise TypeError('StaticTuple can only point to'43 raise TypeError('StaticTuple can only point to'
41 ' StaticTuple, str, unicode, int, long, float, bool, or'44 ' StaticTuple, str, unicode, int, long, float, bool, or'
42 ' None not %s' % (type(bit),))45 ' None not %s' % (type(bit),))
43 num_keys = len(args)
44 if num_keys < 0 or num_keys > 255:
45 raise ValueError('must have 1 => 256 key bits')
46 # We don't need to pass args to tuple.__init__, because that was46 # We don't need to pass args to tuple.__init__, because that was
47 # already handled in __new__.47 # already handled in __new__.
48 tuple.__init__(self)48 tuple.__init__(self)
4949
=== modified file 'bzrlib/tests/test__static_tuple.py'
--- bzrlib/tests/test__static_tuple.py 2009-12-22 16:28:47 +0000
+++ bzrlib/tests/test__static_tuple.py 2010-02-17 20:49:16 +0000
@@ -77,9 +77,9 @@
77 def test_create_bad_args(self):77 def test_create_bad_args(self):
78 args_256 = ['a']*25678 args_256 = ['a']*256
79 # too many args79 # too many args
80 self.assertRaises(ValueError, self.module.StaticTuple, *args_256)80 self.assertRaises(TypeError, self.module.StaticTuple, *args_256)
81 args_300 = ['a']*30081 args_300 = ['a']*300
82 self.assertRaises(ValueError, self.module.StaticTuple, *args_300)82 self.assertRaises(TypeError, self.module.StaticTuple, *args_300)
83 # not a string83 # not a string
84 self.assertRaises(TypeError, self.module.StaticTuple, object())84 self.assertRaises(TypeError, self.module.StaticTuple, object())
8585