Edgewall Software

Ticket #88: strict_errors.diff

File strict_errors.diff, 10.6 KB (added by cmlenz, 17 years ago)

Patch enabling stricter error reporting (against r501)

  • genshi/template/tests/text.py

     
    3737        #if foo
    3838          bar
    3939        #end 'if foo'""")
    40         self.assertEqual('\n', str(tmpl.generate()))
     40        self.assertEqual('\n', str(tmpl.generate(foo=False)))
    4141
    4242    def test_latin1_encoded(self):
    4343        text = u'$foo\xf6$bar'.encode('iso-8859-1')
  • genshi/template/tests/eval.py

     
    1616import unittest
    1717
    1818from genshi.core import Markup
    19 from genshi.template.eval import Expression, Suite, Undefined
     19from genshi.template.eval import Expression, Suite, UndefinedError
    2020
    2121
    2222class ExpressionTestCase(unittest.TestCase):
     
    4040    def test_builtins(self):
    4141        expr = Expression('Markup')
    4242        self.assertEqual(expr.evaluate({}), Markup)
    43         expr = Expression('Undefined')
    44         self.assertEqual(expr.evaluate({}), Undefined)
    4543
    4644    def test_str_literal(self):
    4745        self.assertEqual('foo', Expression('"foo"').evaluate({}))
     
    323321
    324322    def test_error_access_undefined(self):
    325323        expr = Expression("nothing", filename='index.html', lineno=50)
    326         self.assertEqual(Undefined, type(expr.evaluate({})))
    327 
    328     def test_error_call_undefined(self):
    329         expr = Expression("nothing()", filename='index.html', lineno=50)
    330324        try:
    331325            expr.evaluate({})
    332             self.fail('Expected NameError')
    333         except NameError, e:
     326            self.fail('Expected UndefinedError')
     327        except UndefinedError, e:
    334328            exc_type, exc_value, exc_traceback = sys.exc_info()
    335329            frame = exc_traceback.tb_next
    336330            frames = []
    337331            while frame.tb_next:
    338332                frame = frame.tb_next
    339333                frames.append(frame)
    340             self.assertEqual('Variable "nothing" is not defined', str(e))
    341             self.assertEqual("<Expression 'nothing()'>",
    342                              frames[-3].tb_frame.f_code.co_name)
     334            self.assertEqual('"nothing" not defined', str(e))
     335            self.assertEqual("<Expression 'nothing'>",
     336                             frames[-2].tb_frame.f_code.co_name)
    343337            self.assertEqual('index.html',
    344                              frames[-3].tb_frame.f_code.co_filename)
    345             self.assertEqual(50, frames[-3].tb_lineno)
     338                             frames[-2].tb_frame.f_code.co_filename)
     339            self.assertEqual(50, frames[-2].tb_lineno)
    346340
    347341    def test_error_getattr_undefined(self):
    348         expr = Expression("nothing.nil", filename='index.html', lineno=50)
     342        class Something(object):
     343            def __repr__(self):
     344                return '<Something>'
     345        expr = Expression('something.nil', filename='index.html', lineno=50)
    349346        try:
    350             expr.evaluate({})
    351             self.fail('Expected NameError')
    352         except NameError, e:
     347            expr.evaluate({'something': Something()})
     348            self.fail('Expected UndefinedError')
     349        except UndefinedError, e:
    353350            exc_type, exc_value, exc_traceback = sys.exc_info()
    354351            frame = exc_traceback.tb_next
    355352            frames = []
    356353            while frame.tb_next:
    357354                frame = frame.tb_next
    358355                frames.append(frame)
    359             self.assertEqual('Variable "nothing" is not defined', str(e))
    360             self.assertEqual("<Expression 'nothing.nil'>",
    361                              frames[-3].tb_frame.f_code.co_name)
     356            self.assertEqual('<Something> has no member named "nil"', str(e))
     357            self.assertEqual("<Expression 'something.nil'>",
     358                             frames[-2].tb_frame.f_code.co_name)
    362359            self.assertEqual('index.html',
    363                              frames[-3].tb_frame.f_code.co_filename)
    364             self.assertEqual(50, frames[-3].tb_lineno)
     360                             frames[-2].tb_frame.f_code.co_filename)
     361            self.assertEqual(50, frames[-2].tb_lineno)
    365362
    366     def test_error_getitem_undefined(self):
    367         expr = Expression("nothing[0]", filename='index.html', lineno=50)
     363    def test_error_getitem_undefined_string(self):
     364        class Something(object):
     365            def __repr__(self):
     366                return '<Something>'
     367        expr = Expression('something["nil"]', filename='index.html', lineno=50)
    368368        try:
    369             expr.evaluate({})
    370             self.fail('Expected NameError')
    371         except NameError, e:
     369            expr.evaluate({'something': Something()})
     370            self.fail('Expected UndefinedError')
     371        except UndefinedError, e:
    372372            exc_type, exc_value, exc_traceback = sys.exc_info()
    373373            frame = exc_traceback.tb_next
    374374            frames = []
    375375            while frame.tb_next:
    376376                frame = frame.tb_next
    377377                frames.append(frame)
    378             self.assertEqual('Variable "nothing" is not defined', str(e))
    379             self.assertEqual("<Expression 'nothing[0]'>",
    380                              frames[-3].tb_frame.f_code.co_name)
     378            self.assertEqual('<Something> has no member named "nil"', str(e))
     379            self.assertEqual('''<Expression 'something["nil"]'>''',
     380                             frames[-2].tb_frame.f_code.co_name)
    381381            self.assertEqual('index.html',
    382                              frames[-3].tb_frame.f_code.co_filename)
    383             self.assertEqual(50, frames[-3].tb_lineno)
     382                             frames[-2].tb_frame.f_code.co_filename)
     383            self.assertEqual(50, frames[-2].tb_lineno)
    384384
    385     def test_error_getattr_nested_undefined(self):
    386         expr = Expression("nothing.nil", filename='index.html', lineno=50)
    387         val = expr.evaluate({'nothing': object()})
    388         assert isinstance(val, Undefined)
    389         self.assertEqual("nil", val._name)
    390385
    391     def test_error_getitem_nested_undefined_string(self):
    392         expr = Expression("nothing['bla']", filename='index.html', lineno=50)
    393         val = expr.evaluate({'nothing': object()})
    394         assert isinstance(val, Undefined)
    395         self.assertEqual("bla", val._name)
    396 
    397     def test_error_getitem_nested_undefined_int(self):
    398         expr = Expression("nothing[0]", filename='index.html', lineno=50)
    399         self.assertRaises(TypeError, expr.evaluate, {'nothing': object()})
    400 
    401 
    402386class SuiteTestCase(unittest.TestCase):
    403387
    404388    def test_assign(self):
  • genshi/template/eval.py

     
    2424import sys
    2525
    2626from genshi.core import Markup
     27from genshi.template.base import TemplateRuntimeError
    2728from genshi.util import flatten
    2829
    29 __all__ = ['Expression', 'Suite', 'Undefined']
     30__all__ = ['Expression', 'Suite']
    3031
    3132
    3233class Code(object):
     
    148149                           '_lookup_item': _lookup_item}, data
    149150
    150151
    151 class Undefined(object):
    152     """Represents a reference to an undefined variable.
    153    
    154     Unlike the Python runtime, template expressions can refer to an undefined
    155     variable without causing a `NameError` to be raised. The result will be an
    156     instance of the `Undefined´ class, which is treated the same as `False` in
    157     conditions, and acts as an empty collection in iterations:
    158    
    159     >>> foo = Undefined('foo')
    160     >>> bool(foo)
    161     False
    162     >>> list(foo)
    163     []
    164     >>> print foo
    165     undefined
    166    
    167     However, calling an undefined variable, or trying to access an attribute
    168     of that variable, will raise an exception that includes the name used to
    169     reference that undefined variable.
    170    
    171     >>> foo('bar')
    172     Traceback (most recent call last):
    173         ...
    174     NameError: Variable "foo" is not defined
    175 
    176     >>> foo.bar
    177     Traceback (most recent call last):
    178         ...
    179     NameError: Variable "foo" is not defined
     152class UndefinedError(TemplateRuntimeError):
     153    """Exception thrown when a template expression attempts to access a variable
     154    not defined in the context.
    180155    """
    181     __slots__ = ['_name']
     156    def __init__(self, name, owner=None):
     157        if owner is not None:
     158            message = '%r has no member named "%s"' % (owner, name)
     159        else:
     160            message = '"%s" not defined' % name
     161        TemplateRuntimeError.__init__(self, message)
    182162
    183     def __init__(self, name):
    184         self._name = name
    185163
    186     def __call__(self, *args, **kwargs):
    187         __traceback_hide__ = True
    188         self.throw()
    189 
    190     def __getattr__(self, name):
    191         __traceback_hide__ = True
    192         self.throw()
    193 
    194     def __iter__(self):
    195         return iter([])
    196 
    197     def __nonzero__(self):
    198         return False
    199 
    200     def __repr__(self):
    201         return 'undefined'
    202 
    203     def throw(self):
    204         __traceback_hide__ = True
    205         raise NameError('Variable "%s" is not defined' % self._name)
    206 
    207 
    208164def _parse(source, mode='eval'):
    209165    if isinstance(source, unicode):
    210166        source = '\xef\xbb\xbf' + source.encode('utf-8')
     
    238194                    code.co_lnotab, (), ())
    239195
    240196BUILTINS = __builtin__.__dict__.copy()
    241 BUILTINS.update({'Markup': Markup, 'Undefined': Undefined})
    242 _UNDEF = Undefined(None)
     197BUILTINS.update({'Markup': Markup})
     198UNDEFINED = object()
    243199
    244200def _lookup_name(data, name):
    245201    __traceback_hide__ = True
    246     val = data.get(name, _UNDEF)
    247     if val is _UNDEF:
     202    val = data.get(name, UNDEFINED)
     203    if val is UNDEFINED:
    248204        val = BUILTINS.get(name, val)
    249         if val is _UNDEF:
    250             return Undefined(name)
     205        if val is UNDEFINED:
     206            raise UndefinedError(name)
    251207    return val
    252208
    253209def _lookup_attr(data, obj, key):
    254210    __traceback_hide__ = True
    255     if type(obj) is Undefined:
    256         obj.throw()
    257211    if hasattr(obj, key):
    258212        return getattr(obj, key)
    259213    try:
    260214        return obj[key]
    261215    except (KeyError, TypeError):
    262         return Undefined(key)
     216        raise UndefinedError(key, owner=obj)
    263217
    264218def _lookup_item(data, obj, key):
    265219    __traceback_hide__ = True
    266     if type(obj) is Undefined:
    267         obj.throw()
    268220    if len(key) == 1:
    269221        key = key[0]
    270222    try:
    271223        return obj[key]
    272224    except (AttributeError, KeyError, IndexError, TypeError), e:
    273225        if isinstance(key, basestring):
    274             val = getattr(obj, key, _UNDEF)
    275             if val is _UNDEF:
    276                 val = Undefined(key)
     226            val = getattr(obj, key, UNDEFINED)
     227            if val is UNDEFINED:
     228                raise UndefinedError(key, owner=obj)
    277229            return val
    278230        raise
    279231