Skip to content

Commit

Permalink
Merge e94fdcc into d79baa4
Browse files Browse the repository at this point in the history
  • Loading branch information
Jonathan Rocher committed May 22, 2015
2 parents d79baa4 + e94fdcc commit 14f5b93
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 22 deletions.
52 changes: 30 additions & 22 deletions traits/ctraits.c
Expand Up @@ -310,9 +310,17 @@ fatal_trait_error ( void ) {
+----------------------------------------------------------------------------*/

static int
invalid_attribute_error ( void ) {
invalid_attribute_error ( PyObject * name ) {

PyErr_SetString( PyExc_TypeError, "attribute name must be string" );
// Build error message by collecting the type of the object received
PyTypeObject* obj_type = name->ob_type;
const char* type_name = obj_type->tp_name;
PyObject * ob_repr = PyObject_Repr(name);
const char* obj_repr_str = PyString_AsString(ob_repr);
const char* fmt = "attribute name must be string. Got %s (%s).";
PyObject * err_msg = PyString_FromFormat(fmt, obj_repr_str, type_name);

PyErr_SetObject( PyExc_TypeError, err_msg );

return -1;
}
Expand Down Expand Up @@ -363,7 +371,7 @@ static int
bad_delegate_error ( has_traits_object * obj, PyObject * name ) {

if ( !Py2to3_SimpleString_Check( name ) ) {
return invalid_attribute_error();
return invalid_attribute_error( name );
}
PyErr_Format(
DelegationError,
Expand All @@ -384,7 +392,7 @@ static int
bad_delegate_error2 ( has_traits_object * obj, PyObject * name ) {

if ( !Py2to3_SimpleString_Check( name ) ) {
return invalid_attribute_error();
return invalid_attribute_error( name );
}

PyErr_Format(
Expand All @@ -406,7 +414,7 @@ static int
delegation_recursion_error ( has_traits_object * obj, PyObject * name ) {

if ( !Py2to3_SimpleString_Check( name ) ) {
return invalid_attribute_error();
return invalid_attribute_error( name );
}

PyErr_Format(
Expand All @@ -424,7 +432,7 @@ static int
delegation_recursion_error2 ( has_traits_object * obj, PyObject * name ) {

if ( !Py2to3_SimpleString_Check( name ) ) {
return invalid_attribute_error();
return invalid_attribute_error( name );
}

PyErr_Format(
Expand All @@ -447,7 +455,7 @@ static int
delete_readonly_error ( has_traits_object * obj, PyObject * name ) {

if ( !Py2to3_SimpleString_Check( name ) ) {
return invalid_attribute_error();
return invalid_attribute_error( name );
}

PyErr_Format(
Expand All @@ -468,7 +476,7 @@ static int
set_readonly_error ( has_traits_object * obj, PyObject * name ) {

if ( !Py2to3_SimpleString_Check( name ) ) {
return invalid_attribute_error();
return invalid_attribute_error( name );
}

PyErr_Format(
Expand All @@ -489,7 +497,7 @@ static int
set_disallow_error ( has_traits_object * obj, PyObject * name ) {

if ( !Py2to3_SimpleString_Check( name ) ) {
return invalid_attribute_error();
return invalid_attribute_error( name );
}

PyErr_Format(
Expand All @@ -510,7 +518,7 @@ static int
set_delete_property_error ( has_traits_object * obj, PyObject * name ) {

if ( !Py2to3_SimpleString_Check( name ) ) {
return invalid_attribute_error();
return invalid_attribute_error( name );
}

PyErr_Format(
Expand Down Expand Up @@ -977,7 +985,7 @@ has_traits_getattro ( has_traits_object * obj, PyObject * name ) {
// unambiguously, so we have to reckeck in case the marker value is
// returned. Make sure to pick an unlikely marker value.
if((value==bad_attr_marker) && !Py2to3_AttrNameCheck(name)) {
invalid_attribute_error();
invalid_attribute_error( name );
return NULL;
}
if( value != NULL ){
Expand Down Expand Up @@ -1281,7 +1289,7 @@ _has_traits_items_event ( has_traits_object * obj, PyObject * args ) {
}

if ( !Py2to3_AttrNameCheck( name ) ) {
invalid_attribute_error();
invalid_attribute_error( name );
return NULL;
}
retry:
Expand Down Expand Up @@ -1713,7 +1721,7 @@ getattr_trait ( trait_object * trait,
nname = Py2to3_NormaliseAttrName(name);

if( nname == NULL ){
invalid_attribute_error();
invalid_attribute_error( name );
return NULL;
}

Expand Down Expand Up @@ -1778,7 +1786,7 @@ getattr_delegate ( trait_object * trait,
nname = Py2to3_NormaliseAttrName(name);

if( nname == NULL ){
invalid_attribute_error();
invalid_attribute_error( name );
Py_DECREF( delegate );
return NULL;
}
Expand Down Expand Up @@ -1834,7 +1842,7 @@ getattr_disallow ( trait_object * trait,
if ( Py2to3_SimpleString_Check( name ) )
unknown_attribute_error( obj, name );
else
invalid_attribute_error();
invalid_attribute_error( name );

return NULL;
}
Expand Down Expand Up @@ -1955,7 +1963,7 @@ setattr_python ( trait_object * traito,

nname = Py2to3_NormaliseAttrName( name );
if( nname == NULL )
return invalid_attribute_error();
return invalid_attribute_error( name );

if ( PyDict_SetItem( dict, nname, value ) >= 0 ){
Py2to3_FinishNormaliseAttrName(name,nname);
Expand All @@ -1971,7 +1979,7 @@ setattr_python ( trait_object * traito,
if ( dict != NULL ) {
PyObject *nname = Py2to3_NormaliseAttrName( name );
if( nname == NULL )
return invalid_attribute_error();
return invalid_attribute_error( name );

if ( PyDict_DelItem( dict, nname ) >= 0 ){
Py2to3_FinishNormaliseAttrName(name,nname);
Expand All @@ -1991,7 +1999,7 @@ setattr_python ( trait_object * traito,
return -1;
}

return invalid_attribute_error();
return invalid_attribute_error( name );
}

/*-----------------------------------------------------------------------------
Expand Down Expand Up @@ -2220,7 +2228,7 @@ setattr_trait ( trait_object * traito,

nname = Py2to3_NormaliseAttrName(name);
if( nname == NULL )
return invalid_attribute_error();
return invalid_attribute_error( name );

old_value = PyDict_GetItem( dict, nname );
if ( old_value == NULL ) {
Expand Down Expand Up @@ -2303,7 +2311,7 @@ setattr_trait ( trait_object * traito,
nname = Py2to3_NormaliseAttrName(name);
if( nname == NULL ){
Py_DECREF( value );
return invalid_attribute_error();
return invalid_attribute_error( name );
}

new_value = (traitd->flags & TRAIT_SETATTR_ORIGINAL_VALUE)?
Expand Down Expand Up @@ -2723,7 +2731,7 @@ setattr_readonly ( trait_object * traito,

nname = Py2to3_NormaliseAttrName(name);
if( nname == NULL ){
return invalid_attribute_error();
return invalid_attribute_error( name );
}

result = PyDict_GetItem( dict, nname );
Expand Down Expand Up @@ -2757,7 +2765,7 @@ setattr_constant ( trait_object * traito,
);
return -1;
}
return invalid_attribute_error();
return invalid_attribute_error( name );
}

/*-----------------------------------------------------------------------------
Expand Down
33 changes: 33 additions & 0 deletions traits/tests/test_trait_exceptions.py
@@ -0,0 +1,33 @@
#------------------------------------------------------------------------------
# Copyright (c) 2015, Enthought, Inc.
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in enthought/LICENSE.txt and may be redistributed only
# under the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
# Thanks for using Enthought open source!
#------------------------------------------------------------------------------

from traits.testing.unittest_tools import unittest
from traits.api import HasTraits, Int


class A(HasTraits):
x = Int(5)


class TestGetAttr(unittest.TestCase):
def setUp(self):
self.a = A()

def test_bad__getattribute__(self):
# Argument to __getattribute__ must be a string
self.assertEqual(self.a.__getattribute__("x"), 5)

with self.assertRaises(TypeError) as e:
self.a.__getattribute__(2)

# Error message contains value and type of bad attribute name
self.assertIn("2", e.exception.message)
self.assertIn("int", e.exception.message)

0 comments on commit 14f5b93

Please sign in to comment.