Skip to content

Commit

Permalink
Merge pull request #313 from enthought/enh/cython-disallow-getattr
Browse files Browse the repository at this point in the history
Cython port: handle Disallow
  • Loading branch information
jvkersch committed Jun 14, 2016
2 parents 2198310 + 80d46c4 commit 5705222
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 6 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -14,3 +14,6 @@ docs/build/

# Auto-generated by setup.py
traits/_version.py

# Cython C files
traits/ctraits.c
37 changes: 31 additions & 6 deletions traits/ctraits.pyx
Expand Up @@ -158,6 +158,26 @@ cdef object invalid_attribute_error():
raise TypeError('Attribute name must be a string.')


cdef object unknown_attribute_error(obj, name):
raise AttributeError(
u"'{0:.50}' object has no attribute '{1:.400}'".format(
str(type(obj)), name
)
)


cdef int set_disallow_error(obj, name) except? -1:
"""Raises an undefined attribute error.
"""
if not isinstance(name, basestring):
invalid_attribute_error()
else:
raise TraitError(
(u"Cannot set the undefined '{0:.400}' attribute of a "
u"'{1:.50}' object.").format(name, str(type(obj)))
)
return -1


cdef object validate_trait_type(cTrait trait, CHasTraits obj, object name, object value):
""" Verifies a Python value is of a specified type (or None). """
Expand Down Expand Up @@ -997,7 +1017,7 @@ cdef class CHasTraits:
if trait is None:
trait = self.ctrait_dict.get(name, None)

if trait.setattr == setattr_dissalow:
if trait.setattr == setattr_disallow:
raise NotImplementedError('Check logic in C code')
if trait.setattr(trait, trait, self, name, event_object) > 0:
return None
Expand Down Expand Up @@ -1362,20 +1382,25 @@ cdef object getattr_delegate(cTrait trait, CHasTraits obj, object name):
raise TypeError('Attribute name must be a string.')



cdef object getattr_disallow(cTrait trait, CHasTraits obj, object name):
raise NotImplementedError('getattr disallow NOT IMPL.')
if isinstance(name, basestring):
unknown_attribute_error(obj, name)
else:
invalid_attribute_error()


cdef object getattr_constant(cTrait trait, CHasTraits obj, object name):
return trait.internal_default_value


cdef bint has_notifiers(object tnotifiers, object onotifiers):
if (tnotifiers is not None and len(tnotifiers) > 0) or \
(onotifiers is not None and len(onotifiers) > 0):
return 1
else:
return 0


cdef int call_notifiers(list tnotifiers, list onotifiers, CHasTraits obj,
object name, object old_value, object new_value) except? -1:

Expand Down Expand Up @@ -1622,9 +1647,9 @@ cdef int setattr_delegate(cTrait traito, cTrait traitd, CHasTraits obj, object n
)


cdef int setattr_disallow(cTrait traito, cTrait traitd, CHasTraits obj, object name, object value) except? -1:
return set_disallow_error(obj, name)

cdef int setattr_dissalow(cTrait traito, cTrait traitd, CHasTraits obj, object name, object value) except? -1:
raise NotImplementedError('No support for dissalow')

cdef int setattr_readonly(cTrait traito, cTrait traitd, CHasTraits obj, object name, object value) except? -1:
""" Assigns a value to a specified read-only trait attribute. """
Expand Down Expand Up @@ -1684,7 +1709,7 @@ setattr_handlers[1] = setattr_python
setattr_handlers[2] = setattr_event
setattr_handlers[3] = setattr_delegate
setattr_handlers[4] = setattr_event
setattr_handlers[5] = setattr_dissalow
setattr_handlers[5] = setattr_disallow
setattr_handlers[6] = setattr_readonly
setattr_handlers[7] = setattr_constant
setattr_handlers[8] = setattr_generic
Expand Down
35 changes: 35 additions & 0 deletions traits/tests/test_disallow.py
@@ -0,0 +1,35 @@
""" Unit tests for the Disallow singleton.
"""
from traits.testing.unittest_tools import unittest
from ..api import Disallow, HasTraits, TraitError


class A(HasTraits):

x = Disallow


class B(HasTraits):

_ = Disallow


class TestDisallow(unittest.TestCase):

def test_trait_get_set(self):
a = A()

with self.assertRaises(AttributeError):
a.x

with self.assertRaises(TraitError):
a.x = 123

def test_wildcard_get_set(self):
b = B()

with self.assertRaises(AttributeError):
b.some_attribute

with self.assertRaises(TraitError):
b.some_attribute = 'foo'

0 comments on commit 5705222

Please sign in to comment.