Skip to content

Commit

Permalink
Merge ab4c5a1 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 + ab4c5a1 commit c52e711
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 22 deletions.
51 changes: 29 additions & 22 deletions traits/ctraits.c
Expand Up @@ -310,9 +310,16 @@ 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).";

PyErr_Format( PyExc_TypeError, fmt, obj_repr_str, type_name );

return -1;
}
Expand Down Expand Up @@ -363,7 +370,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 +391,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 +413,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 +431,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 +454,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 +475,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 +496,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 +517,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 +984,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 +1288,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 +1720,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 +1785,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 +1841,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 +1962,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 +1978,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 +1998,7 @@ setattr_python ( trait_object * traito,
return -1;
}

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

/*-----------------------------------------------------------------------------
Expand Down Expand Up @@ -2220,7 +2227,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 +2310,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 +2730,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 +2764,7 @@ setattr_constant ( trait_object * traito,
);
return -1;
}
return invalid_attribute_error();
return invalid_attribute_error( name );
}

/*-----------------------------------------------------------------------------
Expand Down
34 changes: 34 additions & 0 deletions traits/tests/test_trait_exceptions.py
@@ -0,0 +1,34 @@
#------------------------------------------------------------------------------
# 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
exception_msg = str(e.exception)
self.assertIn("2", exception_msg)
self.assertIn("int", exception_msg)

0 comments on commit c52e711

Please sign in to comment.