~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_source.py

(mbp) Refuse to build with pyrex 0.9.4*

Show diffs side-by-side

added added

removed removed

Lines of Context:
369
369
            self.fail(
370
370
                "these files contain an assert statement and should not:\n%s"
371
371
                % '\n'.join(badfiles))
 
372
 
 
373
    def test_extension_exceptions(self):
 
374
        """Extension functions should propagate exceptions.
 
375
 
 
376
        Either they should return an object, have an 'except' clause, or have a
 
377
        "# cannot_raise" to indicate that we've audited them and defined them as not
 
378
        raising exceptions.
 
379
        """
 
380
        both_exc_and_no_exc = []
 
381
        missing_except = []
 
382
        class_re = re.compile(r'^(cdef\s+)?class (\w+).*:', re.MULTILINE)
 
383
        except_re = re.compile(r'cdef\s*' # start with cdef
 
384
                               r'([\w *]*?)\s*' # this is the return signature
 
385
                               r'(\w+)\s*\(' # the function name
 
386
                               r'[^)]*\)\s*' # parameters
 
387
                               r'(.*)\s*:' # the except clause
 
388
                               r'\s*(#\s*cannot[- _]raise)?' # cannot raise comment
 
389
                              )
 
390
        for fname, text in self.get_source_file_contents(
 
391
                extensions=('.pyx',)):
 
392
            known_classes = set([m[1] for m in class_re.findall(text)])
 
393
            cdefs = except_re.findall(text)
 
394
            for sig, func, exc_clause, no_exc_comment in cdefs:
 
395
                if not sig or sig in known_classes:
 
396
                    sig = 'object'
 
397
                if exc_clause and no_exc_comment:
 
398
                    both_exc_and_no_exc.append((fname, func))
 
399
                if sig != 'object' and not (exc_clause or no_exc_comment):
 
400
                    missing_except.append((fname, func))
 
401
        error_msg = []
 
402
        if both_exc_and_no_exc:
 
403
            error_msg.append('The following functions had "cannot raise" comments'
 
404
                             ' but did have an except clause set:')
 
405
            for fname, func in both_exc_and_no_exc:
 
406
                error_msg.append('%s:%s' % (fname, func))
 
407
            error_msg.extend(('', ''))
 
408
        if missing_except:
 
409
            error_msg.append('The following functions have fixed return types,'
 
410
                             ' but no except clause.')
 
411
            error_msg.append('Either add an except or append "# cannot_raise".')
 
412
            for fname, func in missing_except:
 
413
                error_msg.append('%s:%s' % (fname, func))
 
414
            error_msg.extend(('', ''))
 
415
        if error_msg:
 
416
            self.fail('\n'.join(error_msg))