Navigation

Source code for sympy.utilities.pytest

"""py.test hacks to support XFAIL/XPASS"""from__future__importprint_function,divisionimportsysimportfunctoolsimportosfromsympy.core.compatibilityimportget_function_nametry:importpyfrompy.testimportskip,raisesUSE_PYTEST=getattr(sys,'_running_pytest',False)exceptImportError:USE_PYTEST=FalseON_TRAVIS=os.getenv('TRAVIS_BUILD_NUMBER',None)ifnotUSE_PYTEST:

[docs]defraises(expectedException,code=None):""" Tests that ``code`` raises the exception ``expectedException``. ``code`` may be a callable, such as a lambda expression or function name. If ``code`` is not given or None, ``raises`` will return a context manager for use in ``with`` statements; the code to execute then comes from the scope of the ``with``. ``raises()`` does nothing if the callable raises the expected exception, otherwise it raises an AssertionError. Examples ======== >>> from sympy.utilities.pytest import raises >>> raises(ZeroDivisionError, lambda: 1/0) >>> raises(ZeroDivisionError, lambda: 1/2) Traceback (most recent call last): ... AssertionError: DID NOT RAISE >>> with raises(ZeroDivisionError): ... n = 1/0 >>> with raises(ZeroDivisionError): ... n = 1/2 Traceback (most recent call last): ... AssertionError: DID NOT RAISE Note that you cannot test multiple statements via ``with raises``: >>> with raises(ZeroDivisionError): ... n = 1/0 # will execute and raise, aborting the ``with`` ... n = 9999/0 # never executed This is just what ``with`` is supposed to do: abort the contained statement sequence at the first exception and let the context manager deal with the exception. To test multiple statements, you'll need a separate ``with`` for each: >>> with raises(ZeroDivisionError): ... n = 1/0 # will execute and raise >>> with raises(ZeroDivisionError): ... n = 9999/0 # will also execute and raise """ifcodeisNone:returnRaisesContext(expectedException)elifcallable(code):try:code()exceptexpectedException:returnraiseAssertionError("DID NOT RAISE")elifisinstance(code,str):raiseTypeError('\'raises(xxx, "code")\' has been phased out; ''change \'raises(xxx, "expression")\' ''to \'raises(xxx, lambda: expression)\', ''\'raises(xxx, "statement")\' ''to \'with raises(xxx): statement\'')else:raiseTypeError('raises() expects a callable for the 2nd argument.')

classRaisesContext(object):def__init__(self,expectedException):self.expectedException=expectedExceptiondef__enter__(self):returnNonedef__exit__(self,exc_type,exc_value,traceback):ifexc_typeisNone:raiseAssertionError("DID NOT RAISE")returnissubclass(exc_type,self.expectedException)classXFail(Exception):passclassXPass(Exception):passclassSkipped(Exception):passdefXFAIL(func):defwrapper():try:func()exceptExceptionase:message=str(e)ifmessage!="Timeout":raiseXFail(get_function_name(func))else:raiseSkipped("Timeout")raiseXPass(get_function_name(func))wrapper=functools.update_wrapper(wrapper,func)returnwrapperdefskip(str):raiseSkipped(str)defSKIP(reason):"""Similar to :func:`skip`, but this is a decorator. """defwrapper(func):deffunc_wrapper():raiseSkipped(reason)func_wrapper=functools.update_wrapper(func_wrapper,func)returnfunc_wrapperreturnwrapperdefslow(func):func._slow=Truedeffunc_wrapper():func()func_wrapper=functools.update_wrapper(func_wrapper,func)func_wrapper.__wrapped__=funcreturnfunc_wrapperelse:XFAIL=py.test.mark.xfailslow=py.test.mark.slow