Commit 56e2c80a authored by Vitja Makarov's avatar Vitja Makarov

Merge remote branch 'upstream/master'

parents 30872e93 30482ee8
...@@ -4,10 +4,9 @@ redistribute, modify and distribute modified versions." ...@@ -4,10 +4,9 @@ redistribute, modify and distribute modified versions."
------------------ ------------------
Cython, which derives from Pyrex, is licensed under the Python Cython, which derives from Pyrex, is licensed under the Apache 2.0
Software Foundation License. More precisely, all modifications Software License. More precisely, all modifications and new code
made to go from Pyrex to Cython are so licensed. made to go from Pyrex to Cython are so licensed.
See LICENSE.txt for more details. See LICENSE.txt for more details.
...@@ -4113,12 +4113,26 @@ class RaiseStatNode(StatNode): ...@@ -4113,12 +4113,26 @@ class RaiseStatNode(StatNode):
if self.exc_tb: if self.exc_tb:
self.exc_tb.analyse_types(env) self.exc_tb.analyse_types(env)
self.exc_tb = self.exc_tb.coerce_to_pyobject(env) self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
env.use_utility_code(raise_utility_code) # special cases for builtin exceptions
self.builtin_exc_name = None
if self.exc_type and not self.exc_value and not self.exc_tb:
exc = self.exc_type
import ExprNodes
if isinstance(exc, ExprNodes.SimpleCallNode) and not exc.args:
exc = exc.function # extract the exception type
if exc.is_name and exc.entry.is_builtin:
self.builtin_exc_name = exc.name
if self.builtin_exc_name == 'MemoryError':
self.exc_type = None # has a separate implementation
nogil_check = Node.gil_error nogil_check = Node.gil_error
gil_message = "Raising exception" gil_message = "Raising exception"
def generate_execution_code(self, code): def generate_execution_code(self, code):
if self.builtin_exc_name == 'MemoryError':
code.putln('PyErr_NoMemory(); %s' % code.error_goto(self.pos))
return
if self.exc_type: if self.exc_type:
self.exc_type.generate_evaluation_code(code) self.exc_type.generate_evaluation_code(code)
type_code = self.exc_type.py_result() type_code = self.exc_type.py_result()
...@@ -4134,6 +4148,7 @@ class RaiseStatNode(StatNode): ...@@ -4134,6 +4148,7 @@ class RaiseStatNode(StatNode):
tb_code = self.exc_tb.py_result() tb_code = self.exc_tb.py_result()
else: else:
tb_code = "0" tb_code = "0"
code.globalstate.use_utility_code(raise_utility_code)
code.putln( code.putln(
"__Pyx_Raise(%s, %s, %s);" % ( "__Pyx_Raise(%s, %s, %s);" % (
type_code, type_code,
......
...@@ -389,20 +389,19 @@ class CythonBase(object): ...@@ -389,20 +389,19 @@ class CythonBase(object):
value) value)
def is_initialized(self, cython_func, local_name): def is_initialized(self, cython_func, local_name):
islocal = local_name in cython_func.locals
if islocal:
cyvar = cython_func.locals[local_name] cyvar = cython_func.locals[local_name]
cur_lineno = self.get_cython_lineno()
if '->' in cyvar.cname: if '->' in cyvar.cname:
# Closed over free variable # Closed over free variable
if self.get_cython_lineno() >= cython_func.lineno + 1: if cur_lineno > cython_func.lineno:
if cyvar.type == PythonObject: if cyvar.type == PythonObject:
return long(gdb.parse_and_eval(cyvar.cname)) return long(gdb.parse_and_eval(cyvar.cname))
return True return True
return False return False
cur_lineno = self.get_cython_lineno() return cur_lineno > cyvar.lineno
return (local_name in cython_func.arguments or
(islocal and cur_lineno > cyvar.lineno))
class SourceFileDescriptor(object): class SourceFileDescriptor(object):
def __init__(self, filename, lexer, formatter=None): def __init__(self, filename, lexer, formatter=None):
......
...@@ -2074,8 +2074,8 @@ class ExecutionControlCommandBase(gdb.Command): ...@@ -2074,8 +2074,8 @@ class ExecutionControlCommandBase(gdb.Command):
self.finish_executing(result) self.finish_executing(result)
def run(self, *args): def run(self, args, from_tty):
self.finish_executing(gdb.execute('run', to_string=True)) self.finish_executing(gdb.execute('run ' + args, to_string=True))
def cont(self, *args): def cont(self, *args):
self.finish_executing(gdb.execute('cont', to_string=True)) self.finish_executing(gdb.execute('cont', to_string=True))
......
...@@ -59,6 +59,8 @@ class _TestInfo(object): ...@@ -59,6 +59,8 @@ class _TestInfo(object):
self.test_method = test_method self.test_method = test_method
self.outcome = outcome self.outcome = outcome
self.err = err self.err = err
self.stdout = test_result.stdout and test_result.stdout.getvalue().strip() or ''
self.stderr = test_result.stdout and test_result.stderr.getvalue().strip() or ''
def get_elapsed_time(self): def get_elapsed_time(self):
"""Return the time that shows how long the test method took to """Return the time that shows how long the test method took to
...@@ -118,8 +120,21 @@ class _XMLTestResult(_TextTestResult): ...@@ -118,8 +120,21 @@ class _XMLTestResult(_TextTestResult):
self.stream.write(short_str) self.stream.write(short_str)
self.callback = callback self.callback = callback
def _patch_standard_output(self):
"""Replace the stdout and stderr streams with string-based streams
in order to capture the tests' output.
"""
(self.old_stdout, self.old_stderr) = (sys.stdout, sys.stderr)
(sys.stdout, sys.stderr) = (self.stdout, self.stderr) = \
(StringIO(), StringIO())
def _restore_standard_output(self):
"Restore the stdout and stderr streams."
(sys.stdout, sys.stderr) = (self.old_stdout, self.old_stderr)
def startTest(self, test): def startTest(self, test):
"Called before execute each test method." "Called before execute each test method."
self._patch_standard_output()
self.start_time = time.time() self.start_time = time.time()
TestResult.startTest(self, test) TestResult.startTest(self, test)
...@@ -129,6 +144,7 @@ class _XMLTestResult(_TextTestResult): ...@@ -129,6 +144,7 @@ class _XMLTestResult(_TextTestResult):
def stopTest(self, test): def stopTest(self, test):
"Called after execute each test method." "Called after execute each test method."
self._restore_standard_output()
_TextTestResult.stopTest(self, test) _TextTestResult.stopTest(self, test)
self.stop_time = time.time() self.stop_time = time.time()
...@@ -138,17 +154,17 @@ class _XMLTestResult(_TextTestResult): ...@@ -138,17 +154,17 @@ class _XMLTestResult(_TextTestResult):
def addSuccess(self, test): def addSuccess(self, test):
"Called when a test executes successfully." "Called when a test executes successfully."
self._prepare_callback(_TestInfo(self, test), \ self._prepare_callback(_TestInfo(self, test),
self.successes, 'OK', '.') self.successes, 'OK', '.')
def addFailure(self, test, err): def addFailure(self, test, err):
"Called when a test method fails." "Called when a test method fails."
self._prepare_callback(_TestInfo(self, test, _TestInfo.FAILURE, err), \ self._prepare_callback(_TestInfo(self, test, _TestInfo.FAILURE, err),
self.failures, 'FAIL', 'F') self.failures, 'FAIL', 'F')
def addError(self, test, err): def addError(self, test, err):
"Called when a test method raises an error." "Called when a test method raises an error."
self._prepare_callback(_TestInfo(self, test, _TestInfo.ERROR, err), \ self._prepare_callback(_TestInfo(self, test, _TestInfo.ERROR, err),
self.errors, 'ERROR', 'E') self.errors, 'ERROR', 'E')
def printErrorList(self, flavour, errors): def printErrorList(self, flavour, errors):
...@@ -230,19 +246,17 @@ class _XMLTestResult(_TextTestResult): ...@@ -230,19 +246,17 @@ class _XMLTestResult(_TextTestResult):
_report_testcase = staticmethod(_report_testcase) _report_testcase = staticmethod(_report_testcase)
def _report_output(test_runner, xml_testsuite, xml_document): def _report_output(test_runner, xml_testsuite, xml_document, stdout, stderr):
"Appends the system-out and system-err sections to the XML document." "Appends the system-out and system-err sections to the XML document."
systemout = xml_document.createElement('system-out') systemout = xml_document.createElement('system-out')
xml_testsuite.appendChild(systemout) xml_testsuite.appendChild(systemout)
stdout = test_runner.stdout.getvalue()
systemout_text = xml_document.createCDATASection(stdout) systemout_text = xml_document.createCDATASection(stdout)
systemout.appendChild(systemout_text) systemout.appendChild(systemout_text)
systemerr = xml_document.createElement('system-err') systemerr = xml_document.createElement('system-err')
xml_testsuite.appendChild(systemerr) xml_testsuite.appendChild(systemerr)
stderr = test_runner.stderr.getvalue()
systemerr_text = xml_document.createCDATASection(stderr) systemerr_text = xml_document.createCDATASection(stderr)
systemerr.appendChild(systemerr_text) systemerr.appendChild(systemerr_text)
...@@ -262,9 +276,15 @@ class _XMLTestResult(_TextTestResult): ...@@ -262,9 +276,15 @@ class _XMLTestResult(_TextTestResult):
# Build the XML file # Build the XML file
testsuite = _XMLTestResult._report_testsuite(suite, tests, doc) testsuite = _XMLTestResult._report_testsuite(suite, tests, doc)
stdout, stderr = [], []
for test in tests: for test in tests:
_XMLTestResult._report_testcase(suite, test, testsuite, doc) _XMLTestResult._report_testcase(suite, test, testsuite, doc)
_XMLTestResult._report_output(test_runner, testsuite, doc) if test.stdout:
stdout.extend(['*****************', test.get_description(), test.stdout])
if test.stderr:
stderr.extend(['*****************', test.get_description(), test.stderr])
_XMLTestResult._report_output(test_runner, testsuite, doc,
'\n'.join(stdout), '\n'.join(stderr))
xml_content = doc.toprettyxml(indent='\t') xml_content = doc.toprettyxml(indent='\t')
if type(test_runner.output) is str: if type(test_runner.output) is str:
...@@ -297,24 +317,9 @@ class XMLTestRunner(TextTestRunner): ...@@ -297,24 +317,9 @@ class XMLTestRunner(TextTestRunner):
return _XMLTestResult(self.stream, self.descriptions, \ return _XMLTestResult(self.stream, self.descriptions, \
self.verbosity, self.elapsed_times) self.verbosity, self.elapsed_times)
def _patch_standard_output(self):
"""Replace the stdout and stderr streams with string-based streams
in order to capture the tests' output.
"""
(self.old_stdout, self.old_stderr) = (sys.stdout, sys.stderr)
(sys.stdout, sys.stderr) = (self.stdout, self.stderr) = \
(StringIO(), StringIO())
def _restore_standard_output(self):
"Restore the stdout and stderr streams."
(sys.stdout, sys.stderr) = (self.old_stdout, self.old_stderr)
def run(self, test): def run(self, test):
"Run the given test case or test suite." "Run the given test case or test suite."
try:
# Prepare the test execution # Prepare the test execution
self._patch_standard_output()
result = self._make_result() result = self._make_result()
# Print a nice header # Print a nice header
...@@ -354,7 +359,5 @@ class XMLTestRunner(TextTestRunner): ...@@ -354,7 +359,5 @@ class XMLTestRunner(TextTestRunner):
self.stream.writeln() self.stream.writeln()
self.stream.writeln('Generating XML reports...') self.stream.writeln('Generating XML reports...')
result.generate_reports(self) result.generate_reports(self)
finally:
self._restore_standard_output()
return result return result
cimport cython
@cython.test_assert_path_exists(
'//RaiseStatNode',
'//RaiseStatNode[@builtin_exc_name = "MemoryError"]')
def raise_me_type():
"""
>>> try: raise_me_type()
... except MemoryError: pass
... else: print('NOT RAISED!')
"""
raise MemoryError
@cython.test_assert_path_exists(
'//RaiseStatNode',
'//RaiseStatNode[@builtin_exc_name = "MemoryError"]')
def raise_me_instance():
"""
>>> try: raise_me_instance()
... except MemoryError: pass
... else: print('NOT RAISED!')
"""
raise MemoryError()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment